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:
parent
6db3a24c19
commit
670858da9b
11
dawn.json
11
dawn.json
|
@ -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": [
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in New Issue