CopyTextureForBrowser: Support flipY option
This CL enable CopyTextureForBrowser to accept options. The first supported option is flipY, which can be implemented through scale and offset uniforms. BUG=dawn:465 Change-Id: Ia90153ee63a50e0e40beb1c13c63764d19a0b809 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/34402 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
6f5151f657
commit
bb913a94da
11
dawn.json
11
dawn.json
|
@ -507,6 +507,13 @@
|
|||
{"name": "compute stage", "type": "programmable stage descriptor"}
|
||||
]
|
||||
},
|
||||
"copy texture for browser options": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
"members": [
|
||||
{"name": "flipY", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
"create ready compute pipeline callback": {
|
||||
"category": "callback",
|
||||
"args": [
|
||||
|
@ -1044,10 +1051,12 @@
|
|||
},
|
||||
{
|
||||
"name": "copy texture for browser",
|
||||
"extensible": true,
|
||||
"args": [
|
||||
{"name": "source", "type": "texture copy view", "annotation": "const*"},
|
||||
{"name": "destination", "type": "texture copy view", "annotation": "const*"},
|
||||
{"name": "copy size", "type": "extent 3D", "annotation": "const*"}
|
||||
{"name": "copy size", "type": "extent 3D", "annotation": "const*"},
|
||||
{"name": "options", "type": "copy texture for browser options", "annotation": "const*"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -93,6 +93,16 @@ namespace dawn_native {
|
|||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateCopyTextureForBrowserOptions(
|
||||
const CopyTextureForBrowserOptions* options) {
|
||||
if (options->nextInChain != nullptr) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"CopyTextureForBrowserOptions: nextInChain must be nullptr");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
RenderPipelineBase* GetOrCreateCopyTextureForBrowserPipeline(DeviceBase* device) {
|
||||
InternalPipelineStore* store = device->GetInternalPipelineStore();
|
||||
|
||||
|
@ -162,7 +172,8 @@ namespace dawn_native {
|
|||
MaybeError ValidateCopyTextureForBrowser(DeviceBase* device,
|
||||
const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options) {
|
||||
DAWN_TRY(device->ValidateObject(source->texture));
|
||||
DAWN_TRY(device->ValidateObject(destination->texture));
|
||||
|
||||
|
@ -180,6 +191,8 @@ namespace dawn_native {
|
|||
DAWN_TRY(ValidateCopyTextureFormatConversion(source->texture->GetFormat().format,
|
||||
destination->texture->GetFormat().format));
|
||||
|
||||
DAWN_TRY(ValidateCopyTextureForBrowserOptions(options));
|
||||
|
||||
// TODO(shaobo.yan@intel.com): Support the simplest case for now that source and destination
|
||||
// texture has the same size and do full texture blit. Will address sub texture blit in
|
||||
// future and remove these validations.
|
||||
|
@ -197,7 +210,8 @@ namespace dawn_native {
|
|||
MaybeError DoCopyTextureForBrowser(DeviceBase* device,
|
||||
const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options) {
|
||||
// TODO(shaobo.yan@intel.com): In D3D12 and Vulkan, compatible texture format can directly
|
||||
// copy to each other. This can be a potential fast path.
|
||||
RenderPipelineBase* pipeline = GetOrCreateCopyTextureForBrowserPipeline(device);
|
||||
|
@ -213,20 +227,24 @@ namespace dawn_native {
|
|||
bgDesc.entries = bindGroupEntries;
|
||||
|
||||
// Prepare binding 0 resource: uniform buffer.
|
||||
// TODO(shaobo.yan@intel.com): Will use scale vector and offset vector to replace the
|
||||
// 4x4 rotation matrix here.
|
||||
const float rotationMatrix[] = {
|
||||
float uniformData[] = {
|
||||
1.0, 1.0, // scale
|
||||
0.0, 0.0 // offset
|
||||
};
|
||||
|
||||
BufferDescriptor rotationUniformDesc = {};
|
||||
rotationUniformDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform;
|
||||
rotationUniformDesc.size = sizeof(rotationMatrix);
|
||||
Ref<BufferBase> rotationUniform = AcquireRef(device->CreateBuffer(&rotationUniformDesc));
|
||||
// Handle flipY.
|
||||
if (options && options->flipY) {
|
||||
uniformData[1] *= -1.0;
|
||||
uniformData[3] += 1.0;
|
||||
}
|
||||
|
||||
device->GetDefaultQueue()->WriteBuffer(rotationUniform.Get(), 0, rotationMatrix,
|
||||
sizeof(rotationMatrix));
|
||||
BufferDescriptor uniformDesc = {};
|
||||
uniformDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform;
|
||||
uniformDesc.size = sizeof(uniformData);
|
||||
Ref<BufferBase> uniformBuffer = AcquireRef(device->CreateBuffer(&uniformDesc));
|
||||
|
||||
device->GetDefaultQueue()->WriteBuffer(uniformBuffer.Get(), 0, uniformData,
|
||||
sizeof(uniformData));
|
||||
|
||||
// Prepare binding 1 resource: sampler
|
||||
// Use default configuration, filterMode set to Nearest for min and mag.
|
||||
|
@ -242,8 +260,8 @@ namespace dawn_native {
|
|||
|
||||
// Set bind group entries.
|
||||
bindGroupEntries[0].binding = 0;
|
||||
bindGroupEntries[0].buffer = rotationUniform.Get();
|
||||
bindGroupEntries[0].size = sizeof(rotationMatrix);
|
||||
bindGroupEntries[0].buffer = uniformBuffer.Get();
|
||||
bindGroupEntries[0].size = sizeof(uniformData);
|
||||
bindGroupEntries[1].binding = 1;
|
||||
bindGroupEntries[1].sampler = sampler.Get();
|
||||
bindGroupEntries[2].binding = 2;
|
||||
|
|
|
@ -22,16 +22,19 @@ namespace dawn_native {
|
|||
class DeviceBase;
|
||||
struct Extent3D;
|
||||
struct TextureCopyView;
|
||||
struct CopyTextureForBrowserOptions;
|
||||
|
||||
MaybeError ValidateCopyTextureForBrowser(DeviceBase* device,
|
||||
const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize);
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options);
|
||||
|
||||
MaybeError DoCopyTextureForBrowser(DeviceBase* device,
|
||||
const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize);
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options);
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
|
|
|
@ -312,18 +312,23 @@ namespace dawn_native {
|
|||
|
||||
void QueueBase::CopyTextureForBrowser(const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
GetDevice()->ConsumedError(CopyTextureForBrowserInternal(source, destination, copySize));
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options) {
|
||||
GetDevice()->ConsumedError(
|
||||
CopyTextureForBrowserInternal(source, destination, copySize, options));
|
||||
}
|
||||
|
||||
MaybeError QueueBase::CopyTextureForBrowserInternal(const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
MaybeError QueueBase::CopyTextureForBrowserInternal(
|
||||
const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options) {
|
||||
if (GetDevice()->IsValidationEnabled()) {
|
||||
DAWN_TRY(ValidateCopyTextureForBrowser(GetDevice(), source, destination, copySize));
|
||||
DAWN_TRY(
|
||||
ValidateCopyTextureForBrowser(GetDevice(), source, destination, copySize, options));
|
||||
}
|
||||
|
||||
return DoCopyTextureForBrowser(GetDevice(), source, destination, copySize);
|
||||
return DoCopyTextureForBrowser(GetDevice(), source, destination, copySize, options);
|
||||
}
|
||||
|
||||
MaybeError QueueBase::ValidateSubmit(uint32_t commandCount,
|
||||
|
|
|
@ -47,7 +47,8 @@ namespace dawn_native {
|
|||
const Extent3D* writeSize);
|
||||
void CopyTextureForBrowser(const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize);
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options);
|
||||
|
||||
void TrackTask(std::unique_ptr<TaskInFlight> task, ExecutionSerial serial);
|
||||
void Tick(ExecutionSerial finishedSerial);
|
||||
|
@ -68,7 +69,8 @@ namespace dawn_native {
|
|||
const Extent3D* writeSize);
|
||||
MaybeError CopyTextureForBrowserInternal(const TextureCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize);
|
||||
const Extent3D* copySize,
|
||||
const CopyTextureForBrowserOptions* options);
|
||||
|
||||
virtual MaybeError SubmitImpl(uint32_t commandCount,
|
||||
CommandBufferBase* const* commands) = 0;
|
||||
|
|
|
@ -53,11 +53,15 @@ class CopyTextureForBrowserTests : public DawnTest {
|
|||
uint32_t height,
|
||||
uint32_t srcTexelsPerRow,
|
||||
RGBA8* dstData,
|
||||
uint32_t dstTexelsPerRow) {
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int x = 0; x < width; ++x) {
|
||||
unsigned int src = x + y * srcTexelsPerRow;
|
||||
unsigned int dst = x + y * dstTexelsPerRow;
|
||||
uint32_t dstTexelsPerRow,
|
||||
const wgpu::CopyTextureForBrowserOptions* options) {
|
||||
bool isFlipY = options != nullptr && options->flipY;
|
||||
for (uint32_t y = 0; y < height; ++y) {
|
||||
for (uint32_t x = 0; x < width; ++x) {
|
||||
uint32_t srcYIndex =
|
||||
isFlipY ? (height - y - 1) * srcTexelsPerRow : y * srcTexelsPerRow;
|
||||
uint32_t src = x + srcYIndex;
|
||||
uint32_t dst = x + y * dstTexelsPerRow;
|
||||
dstData[dst] = srcData[src];
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +69,8 @@ class CopyTextureForBrowserTests : public DawnTest {
|
|||
|
||||
void DoTest(const TextureSpec& srcSpec,
|
||||
const TextureSpec& dstSpec,
|
||||
const wgpu::Extent3D& copySize) {
|
||||
const wgpu::Extent3D& copySize,
|
||||
const wgpu::CopyTextureForBrowserOptions* options) {
|
||||
wgpu::TextureDescriptor srcDescriptor;
|
||||
srcDescriptor.size = srcSpec.textureSize;
|
||||
srcDescriptor.format = kTextureFormat;
|
||||
|
@ -119,7 +124,7 @@ class CopyTextureForBrowserTests : public DawnTest {
|
|||
|
||||
// Perform a copy here for testing.
|
||||
device.GetDefaultQueue().CopyTextureForBrowser(&srcTextureCopyView, &dstTextureCopyView,
|
||||
©Size);
|
||||
©Size, options);
|
||||
|
||||
// Texels in single slice.
|
||||
const uint32_t texelCountInCopyRegion = utils::GetTexelCountInCopyRegion(
|
||||
|
@ -134,7 +139,7 @@ class CopyTextureForBrowserTests : public DawnTest {
|
|||
(srcSpec.copyOrigin.x + srcSpec.copyOrigin.y * copyLayout.texelBlocksPerRow);
|
||||
PackTextureData(&textureArrayCopyData[expectedTexelArrayDataStartIndex], copySize.width,
|
||||
copySize.height, copyLayout.texelBlocksPerRow, expected.data(),
|
||||
copySize.width);
|
||||
copySize.width, options);
|
||||
|
||||
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, dstSpec.copyOrigin.x,
|
||||
dstSpec.copyOrigin.y, copySize.width, copySize.height,
|
||||
|
@ -160,7 +165,7 @@ TEST_P(CopyTextureForBrowserTests, PassthroughCopy) {
|
|||
// Tests skip due to crbug.com/dawn/592.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
||||
|
||||
// OpenGL tests fails due to 'WriteTexture' unimplemented.
|
||||
// OpenGL tests fails because 'WriteTexture' is unimplemented.
|
||||
// Related bug : crbug.com/dawn/483
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||
|
@ -172,14 +177,16 @@ TEST_P(CopyTextureForBrowserTests, PassthroughCopy) {
|
|||
textureSpec.copyOrigin = {0, 0, 0};
|
||||
textureSpec.level = 0;
|
||||
textureSpec.textureSize = {kWidth, kHeight, 1};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
|
||||
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1}, &options);
|
||||
}
|
||||
|
||||
TEST_P(CopyTextureForBrowserTests, VerifyCopyOnXDirection) {
|
||||
// Tests skip due to crbug.com/dawn/592.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
||||
|
||||
// OpenGL tests fails due to 'WriteTexture' unimplemented.
|
||||
// OpenGL tests fails because 'WriteTexture' is unimplemented.
|
||||
// Related bug : crbug.com/dawn/483
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||
|
@ -191,14 +198,16 @@ TEST_P(CopyTextureForBrowserTests, VerifyCopyOnXDirection) {
|
|||
textureSpec.copyOrigin = {0, 0, 0};
|
||||
textureSpec.level = 0;
|
||||
textureSpec.textureSize = {kWidth, kHeight, 1};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
|
||||
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1}, &options);
|
||||
}
|
||||
|
||||
TEST_P(CopyTextureForBrowserTests, VerifyCopyOnYDirection) {
|
||||
// Tests skip due to crbug.com/dawn/592.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
||||
|
||||
// OpenGL tests fails due to 'WriteTexture' unimplemented.
|
||||
// OpenGL tests fails because 'WriteTexture' is unimplemented.
|
||||
// Related bug : crbug.com/dawn/483
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||
|
@ -210,14 +219,16 @@ TEST_P(CopyTextureForBrowserTests, VerifyCopyOnYDirection) {
|
|||
textureSpec.copyOrigin = {0, 0, 0};
|
||||
textureSpec.level = 0;
|
||||
textureSpec.textureSize = {kWidth, kHeight, 1};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
|
||||
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1}, &options);
|
||||
}
|
||||
|
||||
TEST_P(CopyTextureForBrowserTests, VerifyCopyFromLargeTexture) {
|
||||
// Tests skip due to crbug.com/dawn/592.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
||||
|
||||
// OpenGL tests fails due to 'WriteTexture' unimplemented.
|
||||
// OpenGL tests fails because 'WriteTexture' is unimplemented.
|
||||
// Related bug : crbug.com/dawn/483
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||
|
@ -229,7 +240,51 @@ TEST_P(CopyTextureForBrowserTests, VerifyCopyFromLargeTexture) {
|
|||
textureSpec.copyOrigin = {0, 0, 0};
|
||||
textureSpec.level = 0;
|
||||
textureSpec.textureSize = {kWidth, kHeight, 1};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
|
||||
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1}, &options);
|
||||
}
|
||||
|
||||
TEST_P(CopyTextureForBrowserTests, VerifyFlipY) {
|
||||
// Tests skip due to crbug.com/dawn/592.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
||||
|
||||
// OpenGL tests fails because 'WriteTexture' is unimplemented.
|
||||
// Related bug : crbug.com/dawn/483
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
|
||||
constexpr uint32_t kWidth = 901;
|
||||
constexpr uint32_t kHeight = 1001;
|
||||
|
||||
TextureSpec textureSpec;
|
||||
textureSpec.copyOrigin = {0, 0, 0};
|
||||
textureSpec.level = 0;
|
||||
textureSpec.textureSize = {kWidth, kHeight, 1};
|
||||
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
options.flipY = true;
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1}, &options);
|
||||
}
|
||||
|
||||
TEST_P(CopyTextureForBrowserTests, VerifyFlipYInSlimTexture) {
|
||||
// Tests skip due to crbug.com/dawn/592.
|
||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
||||
|
||||
// OpenGL tests fails because 'WriteTexture' is unimplemented.
|
||||
// Related bug : crbug.com/dawn/483
|
||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
||||
|
||||
constexpr uint32_t kWidth = 1;
|
||||
constexpr uint32_t kHeight = 1001;
|
||||
|
||||
TextureSpec textureSpec;
|
||||
textureSpec.copyOrigin = {0, 0, 0};
|
||||
textureSpec.level = 0;
|
||||
textureSpec.textureSize = {kWidth, kHeight, 1};
|
||||
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
options.flipY = true;
|
||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1}, &options);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(CopyTextureForBrowserTests,
|
||||
|
|
Loading…
Reference in New Issue