Add tests about clearing with big integer values

This patch adds several dawn_end2end_tests as a preparation to support
clearing color attachments with arbitrary 32-bit integer values on
D3D12.

Bug: dawn:537
Test: dawn_end2end_tests
Change-Id: I5e5232d4ebb2ed0e0da007fea101ed13f972ce9e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/98103
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Jiawei Shao 2022-08-03 15:54:35 +00:00 committed by Dawn LUCI CQ
parent 0e141c2d86
commit 3c797eba3b

View File

@ -497,6 +497,225 @@ TEST_P(RenderPassLoadOpTests, LoadOpClearNormalizedFormatsOutOfBound) {
}
}
// Test clearing multiple color attachments with different big integers can still work correctly.
TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigInt32ValuesOnMultipleColorAttachments) {
// TODO(http://crbug.com/dawn/537): Implemement a workaround to enable clearing integer formats
// to large values on D3D12.
DAWN_SUPPRESS_TEST_IF(IsD3D12());
// TODO(crbug.com/dawn/1109): Re-enable once fixed on Mac Mini 8,1s w/ 11.5.
DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && IsMacOS(11, 5));
// TODO(crbug.com/dawn/1463): Re-enable, might be the same as above just on
// 12.4 instead of 11.5.
DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && IsMacOS(12, 4));
constexpr int32_t kMaxInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
constexpr int32_t kMinInt32RepresentableInFloat = -kMaxInt32RepresentableInFloat;
using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<int32_t, 4>>;
constexpr std::array<TestCase, kMaxColorAttachments> kTestCases = {{
{wgpu::TextureFormat::R32Sint,
{kMaxInt32RepresentableInFloat, 0, 0, 0},
{kMaxInt32RepresentableInFloat, 0, 0, 0}},
{wgpu::TextureFormat::R32Sint,
{kMaxInt32RepresentableInFloat + 1, 0, 0, 0},
{kMaxInt32RepresentableInFloat + 1, 0, 0, 0}},
{wgpu::TextureFormat::R32Sint,
{kMinInt32RepresentableInFloat, 0, 0, 0},
{kMinInt32RepresentableInFloat, 0, 0, 0}},
{wgpu::TextureFormat::R32Sint,
{kMinInt32RepresentableInFloat - 1, 0, 0, 0},
{kMinInt32RepresentableInFloat - 1, 0, 0, 0}},
{wgpu::TextureFormat::RG32Sint,
{kMaxInt32RepresentableInFloat, kMaxInt32RepresentableInFloat + 1, 0, 0},
{kMaxInt32RepresentableInFloat, kMaxInt32RepresentableInFloat + 1, 0, 0}},
{wgpu::TextureFormat::RG32Sint,
{kMinInt32RepresentableInFloat, kMinInt32RepresentableInFloat - 1, 0, 0},
{kMinInt32RepresentableInFloat, kMinInt32RepresentableInFloat - 1, 0, 0}},
{wgpu::TextureFormat::RGBA32Sint,
{kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
kMaxInt32RepresentableInFloat + 1, kMinInt32RepresentableInFloat - 1},
{kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
kMaxInt32RepresentableInFloat + 1, kMinInt32RepresentableInFloat - 1}},
{wgpu::TextureFormat::RGBA32Sint,
{kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
kMaxInt32RepresentableInFloat - 1, kMinInt32RepresentableInFloat + 1},
{kMaxInt32RepresentableInFloat, kMinInt32RepresentableInFloat,
kMaxInt32RepresentableInFloat - 1, kMinInt32RepresentableInFloat + 1}},
}};
std::array<wgpu::Texture, kMaxColorAttachments> textures;
wgpu::TextureDescriptor textureDescriptor = {};
textureDescriptor.size = {1, 1, 1};
textureDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment;
std::array<wgpu::RenderPassColorAttachment, kMaxColorAttachments> colorAttachmentsInfo;
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
textureDescriptor.format = std::get<0>(kTestCases[i]);
textures[i] = device.CreateTexture(&textureDescriptor);
colorAttachmentsInfo[i].view = textures[i].CreateView();
colorAttachmentsInfo[i].loadOp = wgpu::LoadOp::Clear;
colorAttachmentsInfo[i].storeOp = wgpu::StoreOp::Store;
colorAttachmentsInfo[i].clearValue = std::get<1>(kTestCases[i]);
}
wgpu::RenderPassDescriptor renderPassDescriptor = {};
renderPassDescriptor.colorAttachmentCount = kMaxColorAttachments;
renderPassDescriptor.colorAttachments = colorAttachmentsInfo.data();
wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
renderPass.End();
std::array<wgpu::Buffer, kMaxColorAttachments> outputBuffers;
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
wgpu::BufferDescriptor bufferDescriptor = {};
bufferDescriptor.size = sizeof(int32_t) * 4;
bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
outputBuffers[i] = device.CreateBuffer(&bufferDescriptor);
wgpu::ImageCopyTexture imageCopyTexture =
utils::CreateImageCopyTexture(textures[i], 0, {0, 0, 0});
wgpu::ImageCopyBuffer imageCopyBuffer =
utils::CreateImageCopyBuffer(outputBuffers[i], 0, kTextureBytesPerRowAlignment);
encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &textureDescriptor.size);
}
wgpu::CommandBuffer commandBuffer = encoder.Finish();
queue.Submit(1, &commandBuffer);
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
const uint8_t* expected =
reinterpret_cast<const uint8_t*>(std::get<2>(kTestCases[i]).data());
EXPECT_BUFFER_U8_RANGE_EQ(expected, outputBuffers[i], 0,
sizeof(std::get<2>(kTestCases[i])));
}
}
// Test clearing multiple color attachments with different big unsigned integers can still work
// correctly.
TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigUInt32ValuesOnMultipleColorAttachments) {
// TODO(http://crbug.com/dawn/537): Implemement a workaround to enable clearing integer formats
// to large values on D3D12.
DAWN_SUPPRESS_TEST_IF(IsD3D12());
// TODO(crbug.com/dawn/1109): Re-enable once fixed on Mac Mini 8,1s w/ 11.5.
DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && IsMacOS(11, 5));
// TODO(crbug.com/dawn/1463): Re-enable, might be the same as above just on
// 12.4 instead of 11.5.
DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && IsMacOS(12, 4));
constexpr int32_t kMaxUInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
using TestCase = std::tuple<wgpu::TextureFormat, wgpu::Color, std::array<uint32_t, 4>>;
std::array<float, 4> testColorForRGBA32Float = {
kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat - 1,
kMaxUInt32RepresentableInFloat - 2, kMaxUInt32RepresentableInFloat - 3};
std::array<uint32_t, 4> expectedDataForRGBA32Float;
for (uint32_t i = 0; i < expectedDataForRGBA32Float.size(); ++i) {
expectedDataForRGBA32Float[i] = *(reinterpret_cast<uint32_t*>(&testColorForRGBA32Float[i]));
}
const std::array<TestCase, kMaxColorAttachments> kTestCases = {{
{wgpu::TextureFormat::R32Uint,
{kMaxUInt32RepresentableInFloat, 0, 0, 0},
{kMaxUInt32RepresentableInFloat, 0, 0, 0}},
{wgpu::TextureFormat::R32Uint,
{kMaxUInt32RepresentableInFloat + 1, 0, 0, 0},
{kMaxUInt32RepresentableInFloat + 1, 0, 0, 0}},
{wgpu::TextureFormat::RG32Uint,
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat, 0, 0},
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat, 0, 0}},
{wgpu::TextureFormat::RG32Uint,
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1, 0, 0},
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1, 0, 0}},
{wgpu::TextureFormat::RGBA32Uint,
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1,
kMaxUInt32RepresentableInFloat - 1, kMaxUInt32RepresentableInFloat - 2},
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat + 1,
kMaxUInt32RepresentableInFloat - 1, kMaxUInt32RepresentableInFloat - 2}},
{wgpu::TextureFormat::RGBA32Sint,
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat - 1,
kMaxUInt32RepresentableInFloat - 2, kMaxUInt32RepresentableInFloat - 3},
{static_cast<int32_t>(kMaxUInt32RepresentableInFloat),
static_cast<int32_t>(kMaxUInt32RepresentableInFloat - 1),
static_cast<int32_t>(kMaxUInt32RepresentableInFloat - 2),
static_cast<int32_t>(kMaxUInt32RepresentableInFloat - 3)}},
{wgpu::TextureFormat::RGBA32Float,
{kMaxUInt32RepresentableInFloat, kMaxUInt32RepresentableInFloat - 1,
kMaxUInt32RepresentableInFloat - 2, kMaxUInt32RepresentableInFloat - 3},
expectedDataForRGBA32Float},
{wgpu::TextureFormat::Undefined,
{kMaxUInt32RepresentableInFloat + 1, kMaxUInt32RepresentableInFloat + 1, 0, 0},
{0, 0, 0, 0}},
}};
std::array<wgpu::Texture, kMaxColorAttachments> textures;
wgpu::TextureDescriptor textureDescriptor = {};
textureDescriptor.size = {1, 1, 1};
textureDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment;
std::array<wgpu::RenderPassColorAttachment, kMaxColorAttachments> colorAttachmentsInfo;
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
wgpu::TextureFormat format = std::get<0>(kTestCases[i]);
if (format == wgpu::TextureFormat::Undefined) {
textures[i] = nullptr;
colorAttachmentsInfo[i].view = nullptr;
continue;
}
textureDescriptor.format = format;
textures[i] = device.CreateTexture(&textureDescriptor);
colorAttachmentsInfo[i].view = textures[i].CreateView();
colorAttachmentsInfo[i].loadOp = wgpu::LoadOp::Clear;
colorAttachmentsInfo[i].storeOp = wgpu::StoreOp::Store;
colorAttachmentsInfo[i].clearValue = std::get<1>(kTestCases[i]);
}
wgpu::RenderPassDescriptor renderPassDescriptor = {};
renderPassDescriptor.colorAttachmentCount = kMaxColorAttachments;
renderPassDescriptor.colorAttachments = colorAttachmentsInfo.data();
wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
renderPass.End();
std::array<wgpu::Buffer, kMaxColorAttachments> outputBuffers;
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
wgpu::TextureFormat format = std::get<0>(kTestCases[i]);
if (format == wgpu::TextureFormat::Undefined) {
continue;
}
wgpu::BufferDescriptor bufferDescriptor = {};
bufferDescriptor.size = sizeof(int32_t) * 4;
bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
outputBuffers[i] = device.CreateBuffer(&bufferDescriptor);
wgpu::ImageCopyTexture imageCopyTexture =
utils::CreateImageCopyTexture(textures[i], 0, {0, 0, 0});
wgpu::ImageCopyBuffer imageCopyBuffer =
utils::CreateImageCopyBuffer(outputBuffers[i], 0, kTextureBytesPerRowAlignment);
encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &textureDescriptor.size);
}
wgpu::CommandBuffer commandBuffer = encoder.Finish();
queue.Submit(1, &commandBuffer);
for (uint32_t i = 0; i < kMaxColorAttachments - 1; ++i) {
const uint8_t* expected =
reinterpret_cast<const uint8_t*>(std::get<2>(kTestCases[i]).data());
EXPECT_BUFFER_U8_RANGE_EQ(expected, outputBuffers[i], 0,
sizeof(std::get<2>(kTestCases[i])));
}
}
DAWN_INSTANTIATE_TEST(RenderPassLoadOpTests,
D3D12Backend(),
MetalBackend(),