mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-08 21:19:14 +00:00
Some Vulkan drivers don't handle multiple entrypoints well. In addition, SPIRV-Cross translation can be wrong for shader modules with multiple entrypoints. Always emit a single SPIR-V entrypoint to workaround these issues. This allows updating CopyTextureForBrowser to use a single shader module, and it fixes some tests with multiple entrypoints. Fixed: dawn:948, dawn:959, dawn:1013 Change-Id: Ie129a32a54845316d11917331937ca44fba3d347 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/60640 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com>
606 lines
26 KiB
C++
606 lines
26 KiB
C++
// Copyright 2020 The Dawn Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "tests/DawnTest.h"
|
|
|
|
#include "common/Constants.h"
|
|
#include "common/Math.h"
|
|
#include "utils/ComboRenderPipelineDescriptor.h"
|
|
#include "utils/TestUtils.h"
|
|
#include "utils/TextureUtils.h"
|
|
#include "utils/WGPUHelpers.h"
|
|
|
|
namespace {
|
|
static constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::RGBA8Unorm;
|
|
|
|
// Set default texture size to single line texture for color conversion tests.
|
|
static constexpr uint64_t kDefaultTextureWidth = 10;
|
|
static constexpr uint64_t kDefaultTextureHeight = 1;
|
|
|
|
// Dst texture format copyTextureForBrowser accept
|
|
static const wgpu::TextureFormat kDstTextureFormats[] = {
|
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::BGRA8Unorm,
|
|
wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RG8Unorm,
|
|
wgpu::TextureFormat::RGBA16Float, wgpu::TextureFormat::RG16Float,
|
|
wgpu::TextureFormat::RGB10A2Unorm};
|
|
|
|
static const wgpu::Origin3D kOrigins[] = {{1, 1}, {1, 2}, {2, 1}};
|
|
|
|
static const wgpu::Extent3D kCopySizes[] = {{1, 1}, {2, 1}, {1, 2}, {2, 2}};
|
|
|
|
static const wgpu::AlphaOp kAlphaOps[] = {wgpu::AlphaOp::DontChange, wgpu::AlphaOp::Premultiply,
|
|
wgpu::AlphaOp::Unpremultiply};
|
|
} // anonymous namespace
|
|
|
|
class CopyTextureForBrowserTests : public DawnTest {
|
|
protected:
|
|
struct TextureSpec {
|
|
wgpu::Origin3D copyOrigin = {};
|
|
wgpu::Extent3D textureSize = {kDefaultTextureWidth, kDefaultTextureHeight};
|
|
uint32_t level = 0;
|
|
wgpu::TextureFormat format = kTextureFormat;
|
|
};
|
|
|
|
// This fixed source texture data is for color conversion tests.
|
|
// The source data can fill a texture in default width and height.
|
|
static std::vector<RGBA8> GetFixedSourceTextureData() {
|
|
std::vector<RGBA8> sourceTextureData{
|
|
// Take RGBA8Unorm as example:
|
|
// R channel has different values
|
|
RGBA8(0, 255, 255, 255), // r = 0.0
|
|
RGBA8(102, 255, 255, 255), // r = 0.4
|
|
RGBA8(153, 255, 255, 255), // r = 0.6
|
|
|
|
// G channel has different values
|
|
RGBA8(255, 0, 255, 255), // g = 0.0
|
|
RGBA8(255, 102, 255, 255), // g = 0.4
|
|
RGBA8(255, 153, 255, 255), // g = 0.6
|
|
|
|
// B channel has different values
|
|
RGBA8(255, 255, 0, 255), // b = 0.0
|
|
RGBA8(255, 255, 102, 255), // b = 0.4
|
|
RGBA8(255, 255, 153, 255), // b = 0.6
|
|
|
|
// A channel set to 0
|
|
RGBA8(255, 255, 255, 0) // a = 0
|
|
};
|
|
|
|
return sourceTextureData;
|
|
}
|
|
|
|
enum class TextureCopyRole {
|
|
SOURCE,
|
|
DEST,
|
|
};
|
|
|
|
// Source texture contains red pixels and dst texture contains green pixels at start.
|
|
static std::vector<RGBA8> GetTextureData(const utils::TextureDataCopyLayout& layout,
|
|
TextureCopyRole textureRole,
|
|
wgpu::AlphaOp alphaOp = wgpu::AlphaOp::DontChange) {
|
|
std::array<uint8_t, 4> alpha = {0, 102, 153, 255}; // 0.0, 0.4, 0.6, 1.0
|
|
std::vector<RGBA8> textureData(layout.texelBlockCount);
|
|
for (uint32_t layer = 0; layer < layout.mipSize.depthOrArrayLayers; ++layer) {
|
|
const uint32_t sliceOffset = layout.texelBlocksPerImage * layer;
|
|
for (uint32_t y = 0; y < layout.mipSize.height; ++y) {
|
|
const uint32_t rowOffset = layout.texelBlocksPerRow * y;
|
|
for (uint32_t x = 0; x < layout.mipSize.width; ++x) {
|
|
// Source textures will have variable pixel data to cover cases like
|
|
// flipY.
|
|
if (textureRole == TextureCopyRole::SOURCE) {
|
|
switch (alphaOp) {
|
|
case wgpu::AlphaOp::DontChange:
|
|
textureData[sliceOffset + rowOffset + x] = RGBA8(
|
|
static_cast<uint8_t>((x + layer * x) % 256),
|
|
static_cast<uint8_t>((y + layer * y) % 256),
|
|
static_cast<uint8_t>(x % 256), static_cast<uint8_t>(x % 256));
|
|
break;
|
|
case wgpu::AlphaOp::Premultiply:
|
|
// For premultiply alpha test cases, we expect each channel in dst
|
|
// texture will equal to the alpha channel value.
|
|
textureData[sliceOffset + rowOffset + x] = RGBA8(
|
|
static_cast<uint8_t>(255), static_cast<uint8_t>(255),
|
|
static_cast<uint8_t>(255), static_cast<uint8_t>(alpha[x % 4]));
|
|
break;
|
|
case wgpu::AlphaOp::Unpremultiply:
|
|
// For unpremultiply alpha test cases, we expect each channel in dst
|
|
// texture will equal to 1.0.
|
|
textureData[sliceOffset + rowOffset + x] =
|
|
RGBA8(static_cast<uint8_t>(alpha[x % 4]),
|
|
static_cast<uint8_t>(alpha[x % 4]),
|
|
static_cast<uint8_t>(alpha[x % 4]),
|
|
static_cast<uint8_t>(alpha[x % 4]));
|
|
break;
|
|
default:
|
|
UNREACHABLE();
|
|
break;
|
|
}
|
|
} else { // Dst textures will have be init as `green` to ensure subrect
|
|
// copy not cross bound.
|
|
textureData[sliceOffset + rowOffset + x] =
|
|
RGBA8(static_cast<uint8_t>(0), static_cast<uint8_t>(255),
|
|
static_cast<uint8_t>(0), static_cast<uint8_t>(255));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return textureData;
|
|
}
|
|
|
|
void SetUp() override {
|
|
DawnTest::SetUp();
|
|
// crbug.com/dawn/948: Tint required for multiple entrypoints in a module.
|
|
// CopyTextureForBrowser uses and internal pipeline with a multi-entrypoint
|
|
// shader module.
|
|
DAWN_TEST_UNSUPPORTED_IF(!HasToggleEnabled("use_tint_generator"));
|
|
|
|
testPipeline = MakeTestPipeline();
|
|
|
|
uint32_t uniformBufferData[] = {
|
|
0, // copy have flipY option
|
|
4, // channelCount
|
|
0,
|
|
0, // uvec2, subrect copy src origin
|
|
0,
|
|
0, // uvec2, subrect copy dst origin
|
|
0,
|
|
0, // uvec2, subrect copy size
|
|
static_cast<uint32_t>(wgpu::AlphaOp::DontChange), // AlphaOp: DontChange
|
|
};
|
|
|
|
wgpu::BufferDescriptor uniformBufferDesc = {};
|
|
uniformBufferDesc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Uniform;
|
|
uniformBufferDesc.size = sizeof(uniformBufferData);
|
|
uniformBuffer = device.CreateBuffer(&uniformBufferDesc);
|
|
}
|
|
|
|
// Do the bit-by-bit comparison between the source and destination texture with GPU (compute
|
|
// shader) instead of CPU after executing CopyTextureForBrowser() to avoid the errors caused by
|
|
// comparing a value generated on CPU to the one generated on GPU.
|
|
wgpu::ComputePipeline MakeTestPipeline() {
|
|
wgpu::ShaderModule csModule = utils::CreateShaderModule(device, R"(
|
|
[[block]] struct Uniforms {
|
|
dstTextureFlipY : u32;
|
|
channelCount : u32;
|
|
srcCopyOrigin : vec2<u32>;
|
|
dstCopyOrigin : vec2<u32>;
|
|
copySize : vec2<u32>;
|
|
alphaOp : u32;
|
|
};
|
|
[[block]] struct OutputBuf {
|
|
result : array<u32>;
|
|
};
|
|
[[group(0), binding(0)]] var src : texture_2d<f32>;
|
|
[[group(0), binding(1)]] var dst : texture_2d<f32>;
|
|
[[group(0), binding(2)]] var<storage, read_write> output : OutputBuf;
|
|
[[group(0), binding(3)]] var<uniform> uniforms : Uniforms;
|
|
fn aboutEqual(value : f32, expect : f32) -> bool {
|
|
// The value diff should be smaller than the hard coded tolerance.
|
|
return abs(value - expect) < 0.001;
|
|
}
|
|
[[stage(compute), workgroup_size(1, 1, 1)]]
|
|
fn main([[builtin(global_invocation_id)]] GlobalInvocationID : vec3<u32>) {
|
|
let srcSize = textureDimensions(src);
|
|
let dstSize = textureDimensions(dst);
|
|
let dstTexCoord = vec2<u32>(GlobalInvocationID.xy);
|
|
let nonCoveredColor = vec4<f32>(0.0, 1.0, 0.0, 1.0); // should be green
|
|
|
|
var success : bool = true;
|
|
if (dstTexCoord.x < uniforms.dstCopyOrigin.x ||
|
|
dstTexCoord.y < uniforms.dstCopyOrigin.y ||
|
|
dstTexCoord.x >= uniforms.dstCopyOrigin.x + uniforms.copySize.x ||
|
|
dstTexCoord.y >= uniforms.dstCopyOrigin.y + uniforms.copySize.y) {
|
|
success = success &&
|
|
all(textureLoad(dst, vec2<i32>(dstTexCoord), 0) == nonCoveredColor);
|
|
} else {
|
|
// Calculate source texture coord.
|
|
var srcTexCoord = dstTexCoord - uniforms.dstCopyOrigin +
|
|
uniforms.srcCopyOrigin;
|
|
// Note that |flipY| equals flip src texture firstly and then do copy from src
|
|
// subrect to dst subrect. This helps on blink part to handle some input texture
|
|
// which is flipped and need to unpack flip during the copy.
|
|
// We need to calculate the expect y coord based on this rule.
|
|
if (uniforms.dstTextureFlipY == 1u) {
|
|
srcTexCoord.y = u32(srcSize.y) - srcTexCoord.y - 1u;
|
|
}
|
|
|
|
var srcColor = textureLoad(src, vec2<i32>(srcTexCoord), 0);
|
|
var dstColor = textureLoad(dst, vec2<i32>(dstTexCoord), 0);
|
|
|
|
// Expect the dst texture channels should be all equal to alpha value
|
|
// after premultiply.
|
|
// TODO(crbug.com/1217153): if wgsl support `constexpr` and allow it
|
|
// to be case selector, Replace 0u/1u/2u with a constexpr variable with
|
|
// meaningful name.
|
|
switch(uniforms.alphaOp) {
|
|
case 0u: { // AlphaOp: DontChange
|
|
break;
|
|
}
|
|
case 1u: { // AlphaOp: Premultiply
|
|
srcColor = vec4<f32>(srcColor.rgb * srcColor.a, srcColor.a);
|
|
break;
|
|
}
|
|
case 2u: { // AlphaOp: Unpremultiply
|
|
if (srcColor.a != 0.0) {
|
|
srcColor = vec4<f32>(srcColor.rgb / srcColor.a, srcColor.a);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Not use loop and variable index format to workaround
|
|
// crbug.com/tint/638.
|
|
if (uniforms.channelCount == 2u) { // All have rg components.
|
|
success = success &&
|
|
aboutEqual(dstColor.r, srcColor.r) &&
|
|
aboutEqual(dstColor.g, srcColor.g);
|
|
} else {
|
|
success = success &&
|
|
aboutEqual(dstColor.r, srcColor.r) &&
|
|
aboutEqual(dstColor.g, srcColor.g) &&
|
|
aboutEqual(dstColor.b, srcColor.b) &&
|
|
aboutEqual(dstColor.a, srcColor.a);
|
|
}
|
|
}
|
|
let outputIndex = GlobalInvocationID.y * u32(dstSize.x) + GlobalInvocationID.x;
|
|
if (success) {
|
|
output.result[outputIndex] = 1u;
|
|
} else {
|
|
output.result[outputIndex] = 0u;
|
|
}
|
|
}
|
|
)");
|
|
|
|
wgpu::ComputePipelineDescriptor csDesc;
|
|
csDesc.compute.module = csModule;
|
|
csDesc.compute.entryPoint = "main";
|
|
|
|
return device.CreateComputePipeline(&csDesc);
|
|
}
|
|
static uint32_t GetTextureFormatComponentCount(wgpu::TextureFormat format) {
|
|
switch (format) {
|
|
case wgpu::TextureFormat::RGBA8Unorm:
|
|
case wgpu::TextureFormat::BGRA8Unorm:
|
|
case wgpu::TextureFormat::RGB10A2Unorm:
|
|
case wgpu::TextureFormat::RGBA16Float:
|
|
case wgpu::TextureFormat::RGBA32Float:
|
|
return 4;
|
|
case wgpu::TextureFormat::RG8Unorm:
|
|
case wgpu::TextureFormat::RG16Float:
|
|
return 2;
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
}
|
|
|
|
void DoColorConversionTest(const TextureSpec& srcSpec, const TextureSpec& dstSpec) {
|
|
DoTest(srcSpec, dstSpec, {kDefaultTextureWidth, kDefaultTextureHeight}, {}, true);
|
|
}
|
|
|
|
void DoTest(const TextureSpec& srcSpec,
|
|
const TextureSpec& dstSpec,
|
|
const wgpu::Extent3D& copySize = {kDefaultTextureWidth, kDefaultTextureHeight},
|
|
const wgpu::CopyTextureForBrowserOptions options = {},
|
|
bool useFixedTestValue = false) {
|
|
// Create and initialize src texture.
|
|
wgpu::TextureDescriptor srcDescriptor;
|
|
srcDescriptor.size = srcSpec.textureSize;
|
|
srcDescriptor.format = srcSpec.format;
|
|
srcDescriptor.mipLevelCount = srcSpec.level + 1;
|
|
srcDescriptor.usage =
|
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
|
wgpu::Texture srcTexture = device.CreateTexture(&srcDescriptor);
|
|
|
|
const utils::TextureDataCopyLayout srcCopyLayout =
|
|
utils::GetTextureDataCopyLayoutForTextureAtLevel(
|
|
kTextureFormat,
|
|
{srcSpec.textureSize.width, srcSpec.textureSize.height,
|
|
copySize.depthOrArrayLayers},
|
|
srcSpec.level);
|
|
|
|
std::vector<RGBA8> srcTextureArrayCopyData;
|
|
if (useFixedTestValue) { // Use fixed value for color conversion tests.
|
|
srcTextureArrayCopyData = GetFixedSourceTextureData();
|
|
} else { // For other tests, the input format is always kTextureFormat.
|
|
|
|
srcTextureArrayCopyData =
|
|
GetTextureData(srcCopyLayout, TextureCopyRole::SOURCE, options.alphaOp);
|
|
}
|
|
|
|
wgpu::ImageCopyTexture srcImageTextureInit =
|
|
utils::CreateImageCopyTexture(srcTexture, srcSpec.level, {0, 0});
|
|
|
|
wgpu::TextureDataLayout srcTextureDataLayout;
|
|
srcTextureDataLayout.offset = 0;
|
|
srcTextureDataLayout.bytesPerRow = srcCopyLayout.bytesPerRow;
|
|
srcTextureDataLayout.rowsPerImage = srcCopyLayout.rowsPerImage;
|
|
|
|
device.GetQueue().WriteTexture(&srcImageTextureInit, srcTextureArrayCopyData.data(),
|
|
srcTextureArrayCopyData.size() * sizeof(RGBA8),
|
|
&srcTextureDataLayout, &srcCopyLayout.mipSize);
|
|
|
|
bool testSubRectCopy = srcSpec.copyOrigin.x > 0 || srcSpec.copyOrigin.y > 0 ||
|
|
dstSpec.copyOrigin.x > 0 || dstSpec.copyOrigin.y > 0 ||
|
|
srcSpec.textureSize.width > copySize.width ||
|
|
srcSpec.textureSize.height > copySize.height ||
|
|
dstSpec.textureSize.width > copySize.width ||
|
|
dstSpec.textureSize.height > copySize.height;
|
|
|
|
// Create and init dst texture.
|
|
wgpu::Texture dstTexture;
|
|
wgpu::TextureDescriptor dstDescriptor;
|
|
dstDescriptor.size = dstSpec.textureSize;
|
|
dstDescriptor.format = dstSpec.format;
|
|
dstDescriptor.mipLevelCount = dstSpec.level + 1;
|
|
dstDescriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled |
|
|
wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
|
|
dstTexture = device.CreateTexture(&dstDescriptor);
|
|
|
|
if (testSubRectCopy) {
|
|
// For subrect copy tests, dst texture use kTextureFormat always.
|
|
const utils::TextureDataCopyLayout dstCopyLayout =
|
|
utils::GetTextureDataCopyLayoutForTextureAtLevel(
|
|
kTextureFormat,
|
|
{dstSpec.textureSize.width, dstSpec.textureSize.height,
|
|
copySize.depthOrArrayLayers},
|
|
dstSpec.level);
|
|
|
|
const std::vector<RGBA8> dstTextureArrayCopyData =
|
|
GetTextureData(dstCopyLayout, TextureCopyRole::DEST);
|
|
|
|
wgpu::TextureDataLayout dstTextureDataLayout;
|
|
dstTextureDataLayout.offset = 0;
|
|
dstTextureDataLayout.bytesPerRow = dstCopyLayout.bytesPerRow;
|
|
dstTextureDataLayout.rowsPerImage = dstCopyLayout.rowsPerImage;
|
|
|
|
wgpu::ImageCopyTexture dstImageTextureInit =
|
|
utils::CreateImageCopyTexture(dstTexture, dstSpec.level, {0, 0});
|
|
|
|
device.GetQueue().WriteTexture(&dstImageTextureInit, dstTextureArrayCopyData.data(),
|
|
dstTextureArrayCopyData.size() * sizeof(RGBA8),
|
|
&dstTextureDataLayout, &dstCopyLayout.mipSize);
|
|
}
|
|
|
|
// Perform the texture to texture copy
|
|
wgpu::ImageCopyTexture srcImageCopyTexture =
|
|
utils::CreateImageCopyTexture(srcTexture, srcSpec.level, srcSpec.copyOrigin);
|
|
wgpu::ImageCopyTexture dstImageCopyTexture =
|
|
utils::CreateImageCopyTexture(dstTexture, dstSpec.level, dstSpec.copyOrigin);
|
|
device.GetQueue().CopyTextureForBrowser(&srcImageCopyTexture, &dstImageCopyTexture,
|
|
©Size, &options);
|
|
|
|
// Update uniform buffer based on test config
|
|
uint32_t uniformBufferData[] = {
|
|
options.flipY, // copy have flipY option
|
|
GetTextureFormatComponentCount(dstSpec.format), // channelCount
|
|
srcSpec.copyOrigin.x,
|
|
srcSpec.copyOrigin.y, // src texture copy origin
|
|
dstSpec.copyOrigin.x,
|
|
dstSpec.copyOrigin.y, // dst texture copy origin
|
|
copySize.width,
|
|
copySize.height, // copy size
|
|
static_cast<uint32_t>(options.alphaOp) // alphaOp
|
|
};
|
|
|
|
device.GetQueue().WriteBuffer(uniformBuffer, 0, uniformBufferData,
|
|
sizeof(uniformBufferData));
|
|
|
|
// Create output buffer to store result
|
|
wgpu::BufferDescriptor outputDesc;
|
|
outputDesc.size = dstSpec.textureSize.width * dstSpec.textureSize.height * sizeof(uint32_t);
|
|
outputDesc.usage =
|
|
wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
|
|
wgpu::Buffer outputBuffer = device.CreateBuffer(&outputDesc);
|
|
|
|
// Create texture views for test.
|
|
wgpu::TextureViewDescriptor srcTextureViewDesc = {};
|
|
srcTextureViewDesc.baseMipLevel = srcSpec.level;
|
|
wgpu::TextureView srcTextureView = srcTexture.CreateView(&srcTextureViewDesc);
|
|
|
|
wgpu::TextureViewDescriptor dstTextureViewDesc = {};
|
|
dstTextureViewDesc.baseMipLevel = dstSpec.level;
|
|
wgpu::TextureView dstTextureView = dstTexture.CreateView(&dstTextureViewDesc);
|
|
|
|
// Create bind group based on the config.
|
|
wgpu::BindGroup bindGroup = utils::MakeBindGroup(
|
|
device, testPipeline.GetBindGroupLayout(0),
|
|
{{0, srcTextureView}, {1, dstTextureView}, {2, outputBuffer}, {3, uniformBuffer}});
|
|
|
|
// Start a pipeline to check pixel value in bit form.
|
|
wgpu::CommandEncoder testEncoder = device.CreateCommandEncoder();
|
|
|
|
wgpu::CommandBuffer testCommands;
|
|
{
|
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
|
|
pass.SetPipeline(testPipeline);
|
|
pass.SetBindGroup(0, bindGroup);
|
|
pass.Dispatch(dstSpec.textureSize.width,
|
|
dstSpec.textureSize.height); // Verify dst texture content
|
|
pass.EndPass();
|
|
|
|
testCommands = encoder.Finish();
|
|
}
|
|
queue.Submit(1, &testCommands);
|
|
|
|
std::vector<uint32_t> expectResult(dstSpec.textureSize.width * dstSpec.textureSize.height,
|
|
1);
|
|
EXPECT_BUFFER_U32_RANGE_EQ(expectResult.data(), outputBuffer, 0,
|
|
dstSpec.textureSize.width * dstSpec.textureSize.height);
|
|
}
|
|
|
|
wgpu::Buffer uniformBuffer; // Uniform buffer to store dst texture meta info.
|
|
wgpu::ComputePipeline testPipeline;
|
|
};
|
|
|
|
// Verify CopyTextureForBrowserTests works with internal pipeline.
|
|
// The case do copy without any transform.
|
|
TEST_P(CopyTextureForBrowserTests, PassthroughCopy) {
|
|
constexpr uint32_t kWidth = 10;
|
|
constexpr uint32_t kHeight = 1;
|
|
|
|
TextureSpec textureSpec;
|
|
textureSpec.textureSize = {kWidth, kHeight};
|
|
|
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight});
|
|
}
|
|
|
|
TEST_P(CopyTextureForBrowserTests, VerifyCopyOnXDirection) {
|
|
constexpr uint32_t kWidth = 1000;
|
|
constexpr uint32_t kHeight = 1;
|
|
|
|
TextureSpec textureSpec;
|
|
textureSpec.textureSize = {kWidth, kHeight};
|
|
|
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight});
|
|
}
|
|
|
|
TEST_P(CopyTextureForBrowserTests, VerifyCopyOnYDirection) {
|
|
constexpr uint32_t kWidth = 1;
|
|
constexpr uint32_t kHeight = 1000;
|
|
|
|
TextureSpec textureSpec;
|
|
textureSpec.textureSize = {kWidth, kHeight};
|
|
|
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight});
|
|
}
|
|
|
|
TEST_P(CopyTextureForBrowserTests, VerifyCopyFromLargeTexture) {
|
|
constexpr uint32_t kWidth = 899;
|
|
constexpr uint32_t kHeight = 999;
|
|
|
|
TextureSpec textureSpec;
|
|
textureSpec.textureSize = {kWidth, kHeight};
|
|
|
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight});
|
|
}
|
|
|
|
TEST_P(CopyTextureForBrowserTests, VerifyFlipY) {
|
|
constexpr uint32_t kWidth = 901;
|
|
constexpr uint32_t kHeight = 1001;
|
|
|
|
TextureSpec textureSpec;
|
|
textureSpec.textureSize = {kWidth, kHeight};
|
|
|
|
wgpu::CopyTextureForBrowserOptions options = {};
|
|
options.flipY = true;
|
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight}, options);
|
|
}
|
|
|
|
TEST_P(CopyTextureForBrowserTests, VerifyFlipYInSlimTexture) {
|
|
constexpr uint32_t kWidth = 1;
|
|
constexpr uint32_t kHeight = 1001;
|
|
|
|
TextureSpec textureSpec;
|
|
textureSpec.textureSize = {kWidth, kHeight};
|
|
|
|
wgpu::CopyTextureForBrowserOptions options = {};
|
|
options.flipY = true;
|
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight}, options);
|
|
}
|
|
|
|
// Verify |CopyTextureForBrowser| doing color conversion correctly when
|
|
// the source texture is RGBA8Unorm format.
|
|
TEST_P(CopyTextureForBrowserTests, FromRGBA8UnormCopy) {
|
|
// Skip OpenGLES backend because it fails on using RGBA8Unorm as
|
|
// source texture format.
|
|
DAWN_SUPPRESS_TEST_IF(IsOpenGLES());
|
|
|
|
for (wgpu::TextureFormat dstFormat : kDstTextureFormats) {
|
|
TextureSpec srcTextureSpec = {}; // default format is RGBA8Unorm
|
|
|
|
TextureSpec dstTextureSpec;
|
|
dstTextureSpec.format = dstFormat;
|
|
|
|
DoColorConversionTest(srcTextureSpec, dstTextureSpec);
|
|
}
|
|
}
|
|
|
|
// Verify |CopyTextureForBrowser| doing color conversion correctly when
|
|
// the source texture is BGRAUnorm format.
|
|
TEST_P(CopyTextureForBrowserTests, FromBGRA8UnormCopy) {
|
|
// Skip OpenGLES backend because it fails on using BGRA8Unorm as
|
|
// source texture format.
|
|
DAWN_SUPPRESS_TEST_IF(IsOpenGLES());
|
|
|
|
for (wgpu::TextureFormat dstFormat : kDstTextureFormats) {
|
|
TextureSpec srcTextureSpec;
|
|
srcTextureSpec.format = wgpu::TextureFormat::BGRA8Unorm;
|
|
|
|
TextureSpec dstTextureSpec;
|
|
dstTextureSpec.format = dstFormat;
|
|
|
|
DoColorConversionTest(srcTextureSpec, dstTextureSpec);
|
|
}
|
|
}
|
|
|
|
// Verify |CopyTextureForBrowser| doing subrect copy.
|
|
// Source texture is a full red texture and dst texture is a full
|
|
// green texture originally. After the subrect copy, affected part
|
|
// in dst texture should be red and other part should remain green.
|
|
TEST_P(CopyTextureForBrowserTests, CopySubRect) {
|
|
// Tests skip due to crbug.com/dawn/592.
|
|
DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
|
|
|
for (wgpu::Origin3D srcOrigin : kOrigins) {
|
|
for (wgpu::Origin3D dstOrigin : kOrigins) {
|
|
for (wgpu::Extent3D copySize : kCopySizes) {
|
|
for (bool flipY : {true, false}) {
|
|
TextureSpec srcTextureSpec;
|
|
srcTextureSpec.copyOrigin = srcOrigin;
|
|
srcTextureSpec.textureSize = {6, 7};
|
|
|
|
TextureSpec dstTextureSpec;
|
|
dstTextureSpec.copyOrigin = dstOrigin;
|
|
dstTextureSpec.textureSize = {8, 5};
|
|
wgpu::CopyTextureForBrowserOptions options = {};
|
|
options.flipY = flipY;
|
|
|
|
DoTest(srcTextureSpec, dstTextureSpec, copySize, options);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Verify |CopyTextureForBrowser| doing alphaOp.
|
|
// Test alpha ops: DontChange, Premultiply, Unpremultiply.
|
|
TEST_P(CopyTextureForBrowserTests, alphaOp) {
|
|
// Skip OpenGLES backend because it fails on using RGBA8Unorm as
|
|
// source texture format.
|
|
DAWN_SUPPRESS_TEST_IF(IsOpenGLES());
|
|
|
|
constexpr uint32_t kWidth = 10;
|
|
constexpr uint32_t kHeight = 10;
|
|
|
|
TextureSpec textureSpec;
|
|
textureSpec.textureSize = {kWidth, kHeight};
|
|
|
|
for (wgpu::AlphaOp alphaOp : kAlphaOps) {
|
|
wgpu::CopyTextureForBrowserOptions options = {};
|
|
options.alphaOp = alphaOp;
|
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight}, options);
|
|
}
|
|
}
|
|
|
|
DAWN_INSTANTIATE_TEST(CopyTextureForBrowserTests,
|
|
D3D12Backend(),
|
|
MetalBackend(),
|
|
OpenGLBackend(),
|
|
OpenGLESBackend(),
|
|
VulkanBackend());
|