Limit Clear Color Values to 2^24 For Integer Formats

Adds validation to ensure clear colors do not exceed 2^24 and a
corresponding unit test. Also removes intermediate float conversions
that are no longer necessary.

Bug: dawn:525
Change-Id: I020b98de85384c20da51158de79eab87f60dcf6d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/29040
Commit-Queue: Brandon Jones <brandon1.jones@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Brandon Jones
2020-10-01 19:56:49 +00:00
committed by Commit Bot service account
parent da5828c06b
commit 16ebcf601d
8 changed files with 150 additions and 55 deletions

View File

@@ -238,28 +238,37 @@ TEST_P(RenderPassLoadOpTests, LoadOpClearOnIntegerFormats) {
// This test verifies that input double values are being rounded to floats internally when
// clearing.
TEST_P(RenderPassLoadOpTests, LoadOpClearLargeIntegerValueRounding) {
// Intel GPUs fail when we attempt to clear to a value that exceeds 2147483647 on a RGBA32Uint
// texture.
// Bug: dawn:530
DAWN_SKIP_TEST_IF(IsIntel() && IsD3D12());
TEST_P(RenderPassLoadOpTests, LoadOpClear2ToThe24IntegerFormats) {
constexpr double k2ToThe24Double = 16777216.0;
constexpr uint32_t k2ToThe24Uint = static_cast<uint32_t>(k2ToThe24Double);
// RGBA32Uint
{
constexpr wgpu::Color kClearColor = {4194966911.0, 3555555555.0, 2555555555.0,
1555555555.0};
constexpr std::array<uint32_t, 4> kExpectedPixelValue = {4194966784, 3555555584, 2555555584,
1555555584};
constexpr wgpu::Color kClearColor = {k2ToThe24Double, k2ToThe24Double, k2ToThe24Double,
k2ToThe24Double};
constexpr std::array<uint32_t, 4> kExpectedPixelValue = {k2ToThe24Uint, k2ToThe24Uint,
k2ToThe24Uint, k2ToThe24Uint};
TestIntegerClearColor<uint32_t>(wgpu::TextureFormat::RGBA32Uint, kClearColor,
kExpectedPixelValue);
}
// RGBA32Sint
constexpr int32_t k2ToThe24Sint = static_cast<int32_t>(k2ToThe24Double);
// RGBA32Sint For +2^24
{
constexpr wgpu::Color kClearColor = {2147483447.0, -2147483447.0, 1000000555.0,
-1000000555.0};
constexpr std::array<int32_t, 4> kExpectedPixelValue = {2147483392, -2147483392, 1000000576,
-1000000576};
constexpr wgpu::Color kClearColor = {k2ToThe24Double, k2ToThe24Double, k2ToThe24Double,
k2ToThe24Double};
constexpr std::array<int32_t, 4> kExpectedPixelValue = {k2ToThe24Sint, k2ToThe24Sint,
k2ToThe24Sint, k2ToThe24Sint};
TestIntegerClearColor<int32_t>(wgpu::TextureFormat::RGBA32Sint, kClearColor,
kExpectedPixelValue);
}
// RGBA32Sint For -2^24
{
constexpr wgpu::Color kClearColor = {-k2ToThe24Double, -k2ToThe24Double, -k2ToThe24Double,
-k2ToThe24Double};
constexpr std::array<int32_t, 4> kExpectedPixelValue = {-k2ToThe24Sint, -k2ToThe24Sint,
-k2ToThe24Sint, -k2ToThe24Sint};
TestIntegerClearColor<int32_t>(wgpu::TextureFormat::RGBA32Sint, kClearColor,
kExpectedPixelValue);
}

View File

@@ -762,6 +762,94 @@ namespace {
}
}
// Tests that values that require more than 24 bits to express are not allowed for integer
// formats.
TEST_F(RenderPassDescriptorValidationTest, ExceedValidColorClearRange) {
std::array<wgpu::TextureFormat, 2> formats = {wgpu::TextureFormat::RGBA32Sint,
wgpu::TextureFormat::RGBA32Uint};
constexpr double k2toThe24 = 16777216.0;
double kLargerThan2toPower24 = nextafter(k2toThe24, k2toThe24 + 1);
for (wgpu::TextureFormat format : formats) {
wgpu::TextureView color = Create2DAttachment(device, 1, 1, format);
// Tests that 16777216.0 is a valid clear color.
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.r = k2toThe24;
renderPass.cColorAttachments[0].clearColor.g = k2toThe24;
renderPass.cColorAttachments[0].clearColor.b = k2toThe24;
renderPass.cColorAttachments[0].clearColor.a = k2toThe24;
AssertBeginRenderPassSuccess(&renderPass);
}
// Tests that 16777216.01 cannot be used as a clear color.
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.r = kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.g = kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.b = kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.a = kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
// Tests that -16777216.0 is a valid clear color for Sint, but not for Uint
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.r = -k2toThe24;
renderPass.cColorAttachments[0].clearColor.g = -k2toThe24;
renderPass.cColorAttachments[0].clearColor.b = -k2toThe24;
renderPass.cColorAttachments[0].clearColor.a = -k2toThe24;
if (format == wgpu::TextureFormat::RGBA32Sint) {
AssertBeginRenderPassSuccess(&renderPass);
} else if (format == wgpu::TextureFormat::RGBA32Uint) {
AssertBeginRenderPassError(&renderPass);
}
}
// Tests that -16777216.01 cannot be used as a clear color.
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.r = -kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.g = -kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.b = -kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
{
utils::ComboRenderPassDescriptor renderPass({color}, nullptr);
renderPass.cColorAttachments[0].clearColor.a = -kLargerThan2toPower24;
AssertBeginRenderPassError(&renderPass);
}
}
}
TEST_F(RenderPassDescriptorValidationTest, ValidateDepthStencilReadOnly) {
wgpu::TextureView colorView =
Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);