Change wgpu::Color from floats to doubles

Change dawn.json to reflect changes in the WebGPU IDL. Also fixes any
conversion issues in Dawn.

Bug: dawn:525
Change-Id: Ifb46329f073bcf31d43342f20f4819eac061d5a1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28400
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Brandon Jones <brandon1.jones@intel.com>
This commit is contained in:
Brandon Jones 2020-09-22 16:51:36 +00:00 committed by Commit Bot service account
parent 6db3a24c19
commit 670858da9b
10 changed files with 138 additions and 58 deletions

View File

@ -264,10 +264,10 @@
"color": {
"category": "structure",
"members": [
{"name": "r", "type": "float"},
{"name": "g", "type": "float"},
{"name": "b", "type": "float"},
{"name": "a", "type": "float"}
{"name": "r", "type": "double"},
{"name": "g", "type": "double"},
{"name": "b", "type": "double"},
{"name": "a", "type": "double"}
]
},
"color write mask": {
@ -683,6 +683,9 @@
{"name": "stencil write mask", "type": "uint32_t", "default": "0xFFFFFFFF"}
]
},
"double": {
"category": "native"
},
"error callback": {
"category": "callback",
"args": [

View File

@ -193,17 +193,41 @@ namespace dawn_native {
return true;
}
std::array<int32_t, 4> ConvertToSignedIntegerColor(dawn_native::Color color) {
const std::array<int32_t, 4> outputValue = {
static_cast<int32_t>(color.r), static_cast<int32_t>(color.g),
static_cast<int32_t>(color.b), static_cast<int32_t>(color.a)};
// The below functions convert a dawn_native::Color (doubles) to floats, then to the desired
// data type. This intermediate conversion to float must be done to ensure all backends produce
// consistent results.
std::array<double, 4> ConvertToFloatToDoubleColor(dawn_native::Color color) {
const std::array<double, 4> outputValue = {
static_cast<double>(static_cast<float>(color.r)),
static_cast<double>(static_cast<float>(color.g)),
static_cast<double>(static_cast<float>(color.b)),
static_cast<double>(static_cast<float>(color.a))};
return outputValue;
}
std::array<uint32_t, 4> ConvertToUnsignedIntegerColor(dawn_native::Color color) {
const std::array<uint32_t, 4> outputValue = {
static_cast<uint32_t>(color.r), static_cast<uint32_t>(color.g),
static_cast<uint32_t>(color.b), static_cast<uint32_t>(color.a)};
std::array<float, 4> ConvertToFloatColor(dawn_native::Color color) {
const std::array<float, 4> outputValue = {
static_cast<float>(color.r), static_cast<float>(color.g), static_cast<float>(color.b),
static_cast<float>(color.a)};
return outputValue;
}
std::array<int32_t, 4> ConvertToFloatToSignedIntegerColor(dawn_native::Color color) {
const std::array<int32_t, 4> outputValue = {
static_cast<int32_t>(static_cast<float>(color.r)),
static_cast<int32_t>(static_cast<float>(color.g)),
static_cast<int32_t>(static_cast<float>(color.b)),
static_cast<int32_t>(static_cast<float>(color.a))};
return outputValue;
}
std::array<uint32_t, 4> ConvertToFloatToUnsignedIntegerColor(dawn_native::Color color) {
const std::array<uint32_t, 4> outputValue = {
static_cast<uint32_t>(static_cast<float>(color.r)),
static_cast<uint32_t>(static_cast<float>(color.g)),
static_cast<uint32_t>(static_cast<float>(color.b)),
static_cast<uint32_t>(static_cast<float>(color.a))};
return outputValue;
}
} // namespace dawn_native

View File

@ -63,8 +63,10 @@ namespace dawn_native {
bool IsFullBufferOverwrittenInTextureToBufferCopy(const CopyTextureToBufferCmd* copy);
std::array<int32_t, 4> ConvertToSignedIntegerColor(dawn_native::Color color);
std::array<uint32_t, 4> ConvertToUnsignedIntegerColor(dawn_native::Color color);
std::array<float, 4> ConvertToFloatColor(dawn_native::Color color);
std::array<double, 4> ConvertToFloatToDoubleColor(dawn_native::Color color);
std::array<int32_t, 4> ConvertToFloatToSignedIntegerColor(dawn_native::Color color);
std::array<uint32_t, 4> ConvertToFloatToUnsignedIntegerColor(dawn_native::Color color);
} // namespace dawn_native

View File

@ -514,7 +514,9 @@ namespace dawn_native { namespace d3d12 {
class IndexBufferTracker {
public:
void OnSetIndexBuffer(Buffer* buffer, wgpu::IndexFormat format, uint64_t offset,
void OnSetIndexBuffer(Buffer* buffer,
wgpu::IndexFormat format,
uint64_t offset,
uint64_t size) {
mD3D12BufferView.BufferLocation = buffer->GetVA() + offset;
mD3D12BufferView.SizeInBytes = size;
@ -1472,7 +1474,8 @@ namespace dawn_native { namespace d3d12 {
case Command::SetBlendColor: {
SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
commandList->OMSetBlendFactor(static_cast<const FLOAT*>(&cmd->color.r));
const std::array<float, 4> color = ConvertToFloatColor(cmd->color);
commandList->OMSetBlendFactor(color.data());
break;
}

View File

@ -62,12 +62,14 @@ namespace dawn_native { namespace metal {
auto& attachmentInfo = renderPass->colorAttachments[attachment];
switch (attachmentInfo.loadOp) {
case wgpu::LoadOp::Clear:
case wgpu::LoadOp::Clear: {
descriptor.colorAttachments[i].loadAction = MTLLoadActionClear;
const std::array<double, 4> clearColor =
ConvertToFloatToDoubleColor(attachmentInfo.clearColor);
descriptor.colorAttachments[i].clearColor = MTLClearColorMake(
attachmentInfo.clearColor.r, attachmentInfo.clearColor.g,
attachmentInfo.clearColor.b, attachmentInfo.clearColor.a);
clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
break;
}
case wgpu::LoadOp::Load:
descriptor.colorAttachments[i].loadAction = MTLLoadActionLoad;
@ -1263,10 +1265,12 @@ namespace dawn_native { namespace metal {
case Command::SetBlendColor: {
SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
[encoder setBlendColorRed:cmd->color.r
green:cmd->color.g
blue:cmd->color.b
alpha:cmd->color.a];
const std::array<double, 4> blendColor =
ConvertToFloatToDoubleColor(cmd->color);
[encoder setBlendColorRed:blendColor[0]
green:blendColor[1]
blue:blendColor[2]
alpha:blendColor[3]];
break;
}

View File

@ -937,14 +937,16 @@ namespace dawn_native { namespace opengl {
const Format& attachmentFormat = attachmentInfo->view->GetFormat();
if (attachmentFormat.HasComponentType(Format::Type::Float)) {
gl.ClearBufferfv(GL_COLOR, i, &attachmentInfo->clearColor.r);
const std::array<float, 4> appliedClearColor =
ConvertToFloatColor(attachmentInfo->clearColor);
gl.ClearBufferfv(GL_COLOR, i, appliedClearColor.data());
} else if (attachmentFormat.HasComponentType(Format::Type::Uint)) {
const std::array<uint32_t, 4> appliedClearColor =
ConvertToUnsignedIntegerColor(attachmentInfo->clearColor);
ConvertToFloatToUnsignedIntegerColor(attachmentInfo->clearColor);
gl.ClearBufferuiv(GL_COLOR, i, appliedClearColor.data());
} else if (attachmentFormat.HasComponentType(Format::Type::Sint)) {
const std::array<int32_t, 4> appliedClearColor =
ConvertToSignedIntegerColor(attachmentInfo->clearColor);
ConvertToFloatToSignedIntegerColor(attachmentInfo->clearColor);
gl.ClearBufferiv(GL_COLOR, i, appliedClearColor.data());
} else {
UNREACHABLE();
@ -1180,7 +1182,8 @@ namespace dawn_native { namespace opengl {
case Command::SetBlendColor: {
SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
gl.BlendColor(cmd->color.r, cmd->color.g, cmd->color.b, cmd->color.a);
const std::array<float, 4> blendColor = ConvertToFloatColor(cmd->color);
gl.BlendColor(blendColor[0], blendColor[1], blendColor[2], blendColor[3]);
break;
}

View File

@ -313,19 +313,20 @@ namespace dawn_native { namespace vulkan {
const Format& attachmentFormat = view->GetFormat();
if (attachmentFormat.HasComponentType(Format::Type::Float)) {
clearValues[attachmentCount].color.float32[0] = attachmentInfo.clearColor.r;
clearValues[attachmentCount].color.float32[1] = attachmentInfo.clearColor.g;
clearValues[attachmentCount].color.float32[2] = attachmentInfo.clearColor.b;
clearValues[attachmentCount].color.float32[3] = attachmentInfo.clearColor.a;
const std::array<float, 4> appliedClearColor =
ConvertToFloatColor(attachmentInfo.clearColor);
for (uint32_t i = 0; i < 4; ++i) {
clearValues[attachmentCount].color.float32[i] = appliedClearColor[i];
}
} else if (attachmentFormat.HasComponentType(Format::Type::Uint)) {
const std::array<uint32_t, 4> appliedClearColor =
ConvertToUnsignedIntegerColor(attachmentInfo.clearColor);
ConvertToFloatToUnsignedIntegerColor(attachmentInfo.clearColor);
for (uint32_t i = 0; i < 4; ++i) {
clearValues[attachmentCount].color.uint32[i] = appliedClearColor[i];
}
} else if (attachmentFormat.HasComponentType(Format::Type::Sint)) {
const std::array<int32_t, 4> appliedClearColor =
ConvertToSignedIntegerColor(attachmentInfo.clearColor);
ConvertToFloatToSignedIntegerColor(attachmentInfo.clearColor);
for (uint32_t i = 0; i < 4; ++i) {
clearValues[attachmentCount].color.int32[i] = appliedClearColor[i];
}
@ -1160,13 +1161,8 @@ namespace dawn_native { namespace vulkan {
case Command::SetBlendColor: {
SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
float blendConstants[4] = {
cmd->color.r,
cmd->color.g,
cmd->color.b,
cmd->color.a,
};
device->fn.CmdSetBlendConstants(commands, blendConstants);
const std::array<float, 4> blendConstants = ConvertToFloatColor(cmd->color);
device->fn.CmdSetBlendConstants(commands, blendConstants.data());
break;
}

View File

@ -326,7 +326,9 @@ class D3D12SharedHandleUsageTests : public D3D12ResourceTestBase {
hr = dxgiKeyedMutex->AcquireSync(0, INFINITE);
ASSERT_EQ(hr, S_OK);
const float colorRGBA[] = {clearColor.r, clearColor.g, clearColor.b, clearColor.a};
const float colorRGBA[] = {
static_cast<float>(clearColor.r), static_cast<float>(clearColor.g),
static_cast<float>(clearColor.b), static_cast<float>(clearColor.a)};
mD3d11DeviceContext->ClearRenderTargetView(d3d11RTV.Get(), colorRGBA);
hr = dxgiKeyedMutex->ReleaseSync(1);

View File

@ -126,7 +126,10 @@ class MultisampledRenderingTest : public DawnTest {
const wgpu::RenderPassDescriptor& renderPass,
const wgpu::RenderPipeline& pipeline,
const wgpu::Color& color) {
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, &color.r, sizeof(color));
const float uniformData[4] = {static_cast<float>(color.r), static_cast<float>(color.g),
static_cast<float>(color.b), static_cast<float>(color.a)};
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, uniformData,
sizeof(float) * 4);
}
utils::ComboRenderPassDescriptor CreateComboRenderPassDescriptorForTest(
@ -249,12 +252,12 @@ class MultisampledRenderingTest : public DawnTest {
return pipeline;
}
RGBA8 ExpectedMSAAColor(const wgpu::Color color, const float msaaCoverage) {
RGBA8 ExpectedMSAAColor(const wgpu::Color color, const double msaaCoverage) {
RGBA8 result;
result.r = static_cast<uint8_t>(std::min(255.0f, 256 * color.r * msaaCoverage));
result.g = static_cast<uint8_t>(std::min(255.0f, 256 * color.g * msaaCoverage));
result.b = static_cast<uint8_t>(std::min(255.0f, 256 * color.b * msaaCoverage));
result.a = static_cast<uint8_t>(std::min(255.0f, 256 * color.a * msaaCoverage));
result.r = static_cast<uint8_t>(std::min(255.0, 256 * color.r * msaaCoverage));
result.g = static_cast<uint8_t>(std::min(255.0, 256 * color.g * msaaCoverage));
result.b = static_cast<uint8_t>(std::min(255.0, 256 * color.b * msaaCoverage));
result.a = static_cast<uint8_t>(std::min(255.0, 256 * color.a * msaaCoverage));
return result;
}
};
@ -272,8 +275,9 @@ TEST_P(MultisampledRenderingTest, ResolveInto2DTexture) {
utils::ComboRenderPassDescriptor renderPass = CreateComboRenderPassDescriptorForTest(
{mMultisampledColorView}, {mResolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
kTestDepth);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
std::array<float, 4> kUniformData = {kGreen.r, kGreen.g, kGreen.b, kGreen.a};
constexpr uint32_t kSize = sizeof(kUniformData);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
}
wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
@ -409,9 +413,14 @@ TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargets) {
{mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);
std::array<wgpu::Color, 2> kUniformData = {kRed, kGreen};
std::array<float, 8> kUniformData = {
static_cast<float>(kRed.r), static_cast<float>(kRed.g),
static_cast<float>(kRed.b), static_cast<float>(kRed.a),
static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
constexpr uint32_t kSize = sizeof(kUniformData);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, &kUniformData[0].r, kSize);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
}
wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
@ -487,7 +496,6 @@ TEST_P(MultisampledRenderingTest, ResolveIntoOneMipmapLevelOf2DTexture) {
{mMultisampledColorView}, {resolveView}, wgpu::LoadOp::Clear, wgpu::LoadOp::Clear,
kTestDepth);
wgpu::RenderPipeline pipeline = CreateRenderPipelineWithOneOutputForTest(kTestDepth);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kGreen);
}
@ -644,9 +652,10 @@ TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithSampleMas
{mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);
std::array<wgpu::Color, 2> kUniformData = {kRed, kGreen};
std::array<float, 8> kUniformData = {kRed.r, kRed.g, kRed.b, kRed.a, // color1
kGreen.r, kGreen.g, kGreen.b, kGreen.a}; // color2
constexpr uint32_t kSize = sizeof(kUniformData);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, &kUniformData[0].r, kSize);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
}
wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
@ -799,9 +808,10 @@ TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithShaderOut
{mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);
std::array<wgpu::Color, 2> kUniformData = {kRed, kGreen};
std::array<float, 8> kUniformData = {kRed.r, kRed.g, kRed.b, kRed.a, // color1
kGreen.r, kGreen.g, kGreen.b, kGreen.a}; // color2
constexpr uint32_t kSize = sizeof(kUniformData);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, &kUniformData[0].r, kSize);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(), kSize);
}
wgpu::CommandBuffer commandBuffer = commandEncoder.Finish();
@ -888,9 +898,13 @@ TEST_P(MultisampledRenderingTest, ResolveIntoMultipleResolveTargetsWithAlphaToCo
{mMultisampledColorView, multisampledColorView2}, {mResolveView, resolveView2},
wgpu::LoadOp::Clear, wgpu::LoadOp::Clear, kTestDepth);
std::array<wgpu::Color, 2> kUniformData = {kRed, kGreen};
std::array<float, 8> kUniformData = {
static_cast<float>(kRed.r), static_cast<float>(kRed.g),
static_cast<float>(kRed.b), static_cast<float>(kRed.a),
static_cast<float>(kGreen.r), static_cast<float>(kGreen.g),
static_cast<float>(kGreen.b), static_cast<float>(kGreen.a)};
constexpr uint32_t kSize = sizeof(kUniformData);
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, &kUniformData[0].r,
EncodeRenderPassForTest(commandEncoder, renderPass, pipeline, kUniformData.data(),
kSize);
}

View File

@ -236,6 +236,35 @@ 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());
// RGBA32Uint
{
constexpr wgpu::Color kClearColor = {4194966911.0, 3555555555.0, 2555555555.0,
1555555555.0};
constexpr std::array<uint32_t, 4> kExpectedPixelValue = {4194966784, 3555555584, 2555555584,
1555555584};
TestIntegerClearColor<uint32_t>(wgpu::TextureFormat::RGBA32Uint, kClearColor,
kExpectedPixelValue);
}
// RGBA32Sint
{
constexpr wgpu::Color kClearColor = {2147483447.0, -2147483447.0, 1000000555.0,
-1000000555.0};
constexpr std::array<int32_t, 4> kExpectedPixelValue = {2147483392, -2147483392, 1000000576,
-1000000576};
TestIntegerClearColor<int32_t>(wgpu::TextureFormat::RGBA32Sint, kClearColor,
kExpectedPixelValue);
}
}
DAWN_INSTANTIATE_TEST(RenderPassLoadOpTests,
D3D12Backend(),
MetalBackend(),