Add all formats used as writeonly storage texture in StorageTextureTests

This patch changes all the tests related to write-only storage textures
in dawn_end2end_tests StorageTextureTests to make them test all the
texture formats that support being used as storage textures in WebGPU.

BUG=dawn:267
TEST=dawn_end2end_tests

Change-Id: I4e49efc21f768a9b7645bf334bd41a97fd4838e7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/22663
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
Jiawei Shao 2020-06-06 00:45:40 +00:00 committed by Commit Bot service account
parent 45aed839e9
commit a2fe305797
1 changed files with 107 additions and 54 deletions

View File

@ -285,8 +285,8 @@ class StorageTextureTests : public DawnTest {
ostream << R"(for (uint layer = 0; layer < layerCount; ++layer) { ostream << R"(for (uint layer = 0; layer < layerCount; ++layer) {
for (uint y = 0; y < size.y; ++y) { for (uint y = 0; y < size.y; ++y) {
for (uint x = 0; x < size.x; ++x) { for (uint x = 0; x < size.x; ++x) {
uint value = 1 + x + size.x * (y + size.y * layer); uint value = )"
)" << kComputeExpectedValueGLSL << ";\n"
<< prefix << "vec4 expected = " << GetExpectedPixelValue(format) << ";\n" << prefix << "vec4 expected = " << GetExpectedPixelValue(format) << ";\n"
<< prefix << R"(vec4 pixel = imageLoad(storageImage, )"; << prefix << R"(vec4 pixel = imageLoad(storageImage, )";
if (is2DArray) { if (is2DArray) {
@ -307,6 +307,48 @@ class StorageTextureTests : public DawnTest {
return ostream.str(); return ostream.str();
} }
std::string CommonWriteOnlyTestCode(wgpu::TextureFormat format, bool is2DArray = false) {
std::ostringstream ostream;
const char* prefix = utils::GetColorTextureComponentTypePrefix(format);
ostream << R"(
#version 450
)" << GetGLSLImageDeclaration(format, "writeonly", is2DArray)
<< R"(
void main() {
)";
if (is2DArray) {
ostream << R"(ivec3 size = imageSize(storageImage);
const uint layerCount = size.z;
)";
} else {
ostream << R"(ivec2 size = imageSize(storageImage);
const uint layerCount = 1;
)";
}
ostream << R"(for (uint layer = 0; layer < layerCount; ++layer) {
for (uint y = 0; y < size.y; ++y) {
for (uint x = 0; x < size.x; ++x) {
uint value = )"
<< kComputeExpectedValueGLSL << ";\n"
<< prefix << "vec4 expected = " << GetExpectedPixelValue(format) << ";\n";
if (is2DArray) {
ostream << "ivec3 texcoord = ivec3(x, y, layer);\n";
} else {
ostream << "ivec2 texcoord = ivec2(x, y);\n";
}
ostream << R"( imageStore(storageImage, texcoord, expected);
}
}
}
})";
return ostream.str();
}
static std::vector<uint8_t> GetExpectedData(wgpu::TextureFormat format, static std::vector<uint8_t> GetExpectedData(wgpu::TextureFormat format,
uint32_t arrayLayerCount = 1) { uint32_t arrayLayerCount = 1) {
const uint32_t texelSizeInBytes = utils::GetTexelBlockSizeInBytes(format); const uint32_t texelSizeInBytes = utils::GetTexelBlockSizeInBytes(format);
@ -528,6 +570,14 @@ class StorageTextureTests : public DawnTest {
queue.Submit(1, &commandBuffer); queue.Submit(1, &commandBuffer);
} }
void CheckOutputStorageTexture(wgpu::Texture writeonlyStorageTexture,
wgpu::TextureFormat format,
uint32_t arrayLayerCount = 1) {
const uint32_t texelSize = utils::GetTexelBlockSizeInBytes(format);
const std::vector<uint8_t>& expectedData = GetExpectedData(format, arrayLayerCount);
CheckOutputStorageTexture(writeonlyStorageTexture, texelSize, expectedData);
}
void CheckOutputStorageTexture(wgpu::Texture writeonlyStorageTexture, void CheckOutputStorageTexture(wgpu::Texture writeonlyStorageTexture,
uint32_t texelSize, uint32_t texelSize,
const std::vector<uint8_t>& expectedData) { const std::vector<uint8_t>& expectedData) {
@ -580,17 +630,7 @@ class StorageTextureTests : public DawnTest {
gl_PointSize = 1.0f; gl_PointSize = 1.0f;
})"; })";
const char* kCommonWriteOnlyTestCode_uimage2D = R"( const char* kComputeExpectedValueGLSL = "1 + x + size.x * (y + size.y * layer)";
#version 450
layout(set = 0, binding = 0, r32ui) uniform writeonly uimage2D dstImage;
void main() {
for (uint y = 0; y < 4; ++y) {
for (uint x = 0; x < 4; ++x) {
uvec4 pixel = uvec4(1u + x + y * 4u, 0, 0, 1u);
imageStore(dstImage, ivec2(x, y), pixel);
}
}
})";
}; };
// Test that using read-only storage texture and write-only storage texture in BindGroupLayout is // Test that using read-only storage texture and write-only storage texture in BindGroupLayout is
@ -754,16 +794,28 @@ TEST_P(StorageTextureTests, WriteonlyStorageTextureInComputeShader) {
// bug in spvc parser is fixed. // bug in spvc parser is fixed.
DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed()); DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed());
// Prepare the write-only storage texture. for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
// TODO(jiawei.shao@intel.com): test more texture formats. if (!utils::TextureFormatSupportsStorageTexture(format)) {
constexpr uint32_t kTexelSizeR32Uint = 4u; continue;
wgpu::Texture writeonlyStorageTexture = CreateTexture( }
wgpu::TextureFormat::R32Uint, wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopySrc);
WriteIntoStorageTextureInComputePass(writeonlyStorageTexture, // TODO(jiawei.shao@intel.com): investigate why this test fails with RGBA8Snorm on Linux
kCommonWriteOnlyTestCode_uimage2D); // Intel OpenGL driver.
CheckOutputStorageTexture(writeonlyStorageTexture, kTexelSizeR32Uint, if (format == wgpu::TextureFormat::RGBA8Snorm && IsIntel() && IsOpenGL() && IsLinux()) {
GetExpectedData(wgpu::TextureFormat::R32Uint)); continue;
}
// Prepare the write-only storage texture.
wgpu::Texture writeonlyStorageTexture =
CreateTexture(format, wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopySrc);
// Write the expected pixel values into the write-only storage texture.
const std::string computeShader = CommonWriteOnlyTestCode(format);
WriteIntoStorageTextureInComputePass(writeonlyStorageTexture, computeShader.c_str());
// Verify the pixel data in the write-only storage texture is expected.
CheckOutputStorageTexture(writeonlyStorageTexture, format);
}
} }
// Test that write-only storage textures are supported in fragment shader. // Test that write-only storage textures are supported in fragment shader.
@ -774,16 +826,29 @@ TEST_P(StorageTextureTests, WriteonlyStorageTextureInFragmentShader) {
// bug in spvc parser is fixed. // bug in spvc parser is fixed.
DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed()); DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed());
// Prepare the write-only storage texture. for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
// TODO(jiawei.shao@intel.com): test more texture formats. if (!utils::TextureFormatSupportsStorageTexture(format)) {
constexpr uint32_t kTexelSizeR32Uint = 4u; continue;
wgpu::Texture writeonlyStorageTexture = CreateTexture( }
wgpu::TextureFormat::R32Uint, wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopySrc);
WriteIntoStorageTextureInRenderPass(writeonlyStorageTexture, kSimpleVertexShader, // TODO(jiawei.shao@intel.com): investigate why this test fails with RGBA8Snorm on Linux
kCommonWriteOnlyTestCode_uimage2D); // Intel OpenGL driver.
CheckOutputStorageTexture(writeonlyStorageTexture, kTexelSizeR32Uint, if (format == wgpu::TextureFormat::RGBA8Snorm && IsIntel() && IsOpenGL() && IsLinux()) {
GetExpectedData(wgpu::TextureFormat::R32Uint)); continue;
}
// Prepare the write-only storage texture.
wgpu::Texture writeonlyStorageTexture =
CreateTexture(format, wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopySrc);
// Write the expected pixel values into the write-only storage texture.
const std::string fragmentShader = CommonWriteOnlyTestCode(format);
WriteIntoStorageTextureInRenderPass(writeonlyStorageTexture, kSimpleVertexShader,
fragmentShader.c_str());
// Verify the pixel data in the write-only storage texture is expected.
CheckOutputStorageTexture(writeonlyStorageTexture, format);
}
} }
// Verify 2D array read-only storage texture works correctly. // Verify 2D array read-only storage texture works correctly.
@ -832,33 +897,21 @@ TEST_P(StorageTextureTests, Writeonly2DArrayStorageTexture) {
// bug in spvc parser is fixed. // bug in spvc parser is fixed.
DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed()); DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed());
// Prepare the write-only storage texture.
constexpr uint32_t kArrayLayerCount = 3u; constexpr uint32_t kArrayLayerCount = 3u;
wgpu::Texture writeonlyStorageTexture = CreateTexture(
wgpu::TextureFormat::R32Uint, wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopySrc,
kWidth, kHeight, kArrayLayerCount);
const char* kComputeShader = R"( constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::R32Uint;
#version 450
layout(set = 0, binding = 0, r32ui) uniform writeonly uimage2DArray dstImage;
void main() {
ivec3 size = imageSize(dstImage);
for (uint layer = 0; layer < size.z; ++layer) {
for (uint y = 0; y < size.y; ++y) {
for (uint x = 0; x < size.x; ++x) {
uint expected = 1u + x + size.x * (y + size.y * layer);
uvec4 pixel = uvec4(expected, 0, 0, 1u);
imageStore(dstImage, ivec3(x, y, layer), pixel);
}
}
}
})";
WriteIntoStorageTextureInComputePass(writeonlyStorageTexture, kComputeShader); // Prepare the write-only storage texture.
wgpu::Texture writeonlyStorageTexture =
CreateTexture(kTextureFormat, wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopySrc,
kWidth, kHeight, kArrayLayerCount);
constexpr uint32_t kTexelSizeR32Uint = 4u; // Write the expected pixel values into the write-only storage texture.
CheckOutputStorageTexture(writeonlyStorageTexture, kTexelSizeR32Uint, const std::string computeShader = CommonWriteOnlyTestCode(kTextureFormat, true);
GetExpectedData(wgpu::TextureFormat::R32Uint, kArrayLayerCount)); WriteIntoStorageTextureInComputePass(writeonlyStorageTexture, computeShader.c_str());
// Verify the pixel data in the write-only storage texture is expected.
CheckOutputStorageTexture(writeonlyStorageTexture, kTextureFormat, kArrayLayerCount);
} }
DAWN_INSTANTIATE_TEST(StorageTextureTests, DAWN_INSTANTIATE_TEST(StorageTextureTests,