Compat: Blit T2B copy for RG11B10Ufloat when not color renderable
Bug: 381214487
Change-Id: Ice2e19892bd79c91b147689d56911efa4ee2fe53
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/222254
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Shrek Shao <shrekshao@google.com>
diff --git a/src/dawn/native/BlitTextureToBuffer.cpp b/src/dawn/native/BlitTextureToBuffer.cpp
index 5e64a72..5343b9f 100644
--- a/src/dawn/native/BlitTextureToBuffer.cpp
+++ b/src/dawn/native/BlitTextureToBuffer.cpp
@@ -655,6 +655,39 @@
}
)";
+// Storing rg11b10ufloat texel values
+// Reference:
+// https://www.khronos.org/opengl/wiki/Small_Float_Formats
+constexpr std::string_view kEncodeRG11B10UfloatInU32 = R"(
+fn encodeVectorInU32General(v: vec4f) -> u32 {
+ const n_rg = 6; // number of mantissa bits (RG)
+ const n_b = 5; // number of mantissa bits (B)
+ const e_max = 31; // max exponent
+ const b = 15; // exponent bias
+
+ // Calculate the exponent (biased)
+ let rbe = select(i32(floor(log2(v.r))), -b, v.r == 0.0);
+ let gbe = select(i32(floor(log2(v.g))), -b, v.g == 0.0);
+ let bbe = select(i32(floor(log2(v.b))), -b, v.b == 0.0);
+
+ // Calculate the exponent bits value.
+ let re = clamp(rbe + b, 0, e_max);
+ let ge = clamp(gbe + b, 0, e_max);
+ let be = clamp(bbe + b, 0, e_max);
+
+ // Calculate the mantissa for each component.
+ let rm = u32(round( select(v.r * exp2(-f32(re - b)) - 1.0, v.r * exp2(f32(b-1)), re == 0) * f32(1 << n_rg) ));
+ let gm = u32(round( select(v.g * exp2(-f32(ge - b)) - 1.0, v.g * exp2(f32(b-1)), ge == 0) * f32(1 << n_rg) ));
+ let bm = u32(round( select(v.b * exp2(-f32(be - b)) - 1.0, v.b * exp2(f32(b-1)), be == 0) * f32(1 << n_b) ));
+
+ let red = u32(re << n_rg) | rm;
+ let green = u32(ge << n_rg) | gm;
+ let blue = u32(be << n_b) | bm;
+
+ return (blue << 22) | (green << 11) | red;
+}
+)";
+
// Directly loading float32 values into dst_buf
// No bit manipulation and packing is needed.
constexpr std::string_view kLoadR32Float = R"(
@@ -794,6 +827,16 @@
shader += kCommonEnd;
textureSampleType = wgpu::TextureSampleType::Float;
break;
+ case wgpu::TextureFormat::RG11B10Ufloat:
+ AppendFloatTextureHead();
+ shader += kDstBufferU32;
+ shader += kEncodeRG11B10UfloatInU32;
+ shader += kCommonHead;
+ shader += kCommonStart;
+ shader += kPackRGBAToU32;
+ shader += kCommonEnd;
+ textureSampleType = wgpu::TextureSampleType::Float;
+ break;
case wgpu::TextureFormat::R16Float:
case wgpu::TextureFormat::RG16Float:
AppendFloatTextureHead();
@@ -974,6 +1017,7 @@
case wgpu::TextureFormat::RGBA8Unorm:
case wgpu::TextureFormat::BGRA8Unorm:
case wgpu::TextureFormat::RGB9E5Ufloat:
+ case wgpu::TextureFormat::RG11B10Ufloat:
case wgpu::TextureFormat::R16Float:
case wgpu::TextureFormat::RG16Float:
case wgpu::TextureFormat::RGBA16Float:
diff --git a/src/dawn/native/Buffer.cpp b/src/dawn/native/Buffer.cpp
index d8dccb7..ba75553 100644
--- a/src/dawn/native/Buffer.cpp
+++ b/src/dawn/native/Buffer.cpp
@@ -129,6 +129,7 @@
device->IsToggleEnabled(Toggle::UseBlitForSnormTextureToBufferCopy) ||
device->IsToggleEnabled(Toggle::UseBlitForBGRA8UnormTextureToBufferCopy) ||
device->IsToggleEnabled(Toggle::UseBlitForRGB9E5UfloatTextureCopy) ||
+ device->IsToggleEnabled(Toggle::UseBlitForRG11B10UfloatTextureCopy) ||
device->IsToggleEnabled(Toggle::UseBlitForFloat16TextureCopy) ||
device->IsToggleEnabled(Toggle::UseBlitForFloat32TextureCopy) ||
device->IsToggleEnabled(Toggle::UseBlitForT2B);
diff --git a/src/dawn/native/CommandEncoder.cpp b/src/dawn/native/CommandEncoder.cpp
index cc5cac3..4f80264 100644
--- a/src/dawn/native/CommandEncoder.cpp
+++ b/src/dawn/native/CommandEncoder.cpp
@@ -971,6 +971,11 @@
device->IsToggleEnabled(Toggle::UseBlitForRGB9E5UfloatTextureCopy)) {
return true;
}
+ // RG11B10Ufloat
+ if (format.format == wgpu::TextureFormat::RG11B10Ufloat &&
+ device->IsToggleEnabled(Toggle::UseBlitForRG11B10UfloatTextureCopy)) {
+ return true;
+ }
// float16
if ((format.format == wgpu::TextureFormat::R16Float ||
format.format == wgpu::TextureFormat::RG16Float ||
diff --git a/src/dawn/native/Texture.cpp b/src/dawn/native/Texture.cpp
index bd96d05..1365d9d 100644
--- a/src/dawn/native/Texture.cpp
+++ b/src/dawn/native/Texture.cpp
@@ -544,6 +544,11 @@
device->IsToggleEnabled(Toggle::UseBlitForRGB9E5UfloatTextureCopy)) {
return true;
}
+ // RG11B10ufloat
+ if (format.format == wgpu::TextureFormat::RG11B10Ufloat &&
+ device->IsToggleEnabled(Toggle::UseBlitForRG11B10UfloatTextureCopy)) {
+ return true;
+ }
// float16
if ((format.format == wgpu::TextureFormat::R16Float ||
format.format == wgpu::TextureFormat::RG16Float ||
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index 3732ca4..a6224c8 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -430,6 +430,11 @@
"Use a blit instead of a copy command to copy rgb9e5ufloat texture to a texture or a buffer."
"Workaround for OpenGLES.",
"https://crbug.com/dawn/2079", ToggleStage::Device}},
+ {Toggle::UseBlitForRG11B10UfloatTextureCopy,
+ {"use_blit_for_rgb9e5ufloat_texture_copy",
+ "Use a blit instead of a copy command to copy rg11b10ufloat texture to a texture or a buffer."
+ "Workaround for OpenGLES.",
+ "https://crbug.com/381214487", ToggleStage::Device}},
{Toggle::UseBlitForFloat16TextureCopy,
{"use_blit_for_float_16_texture_copy",
"Use a blit instead of a copy command to copy float16 texture to a texture or a buffer."
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 07dcbae..88036dc 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -110,6 +110,7 @@
UseBlitForSnormTextureToBufferCopy,
UseBlitForBGRA8UnormTextureToBufferCopy,
UseBlitForRGB9E5UfloatTextureCopy,
+ UseBlitForRG11B10UfloatTextureCopy,
UseBlitForFloat16TextureCopy,
UseBlitForFloat32TextureCopy,
UseBlitForT2B,
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 67e7f7d..8fcae9e 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -400,6 +400,7 @@
gl.IsGLExtensionSupported("GL_EXT_color_buffer_float");
bool isFloat16Renderable =
isFloat32Renderable || gl.IsGLExtensionSupported("GL_EXT_color_buffer_half_float");
+ bool isRG11B10UfloatRenderable = isFloat32Renderable;
// TODO(crbug.com/dawn/343): Investigate emulation.
deviceToggles->Default(Toggle::DisableIndexedDrawBuffers, !supportsIndexedDrawBuffers);
@@ -429,6 +430,10 @@
// For OpenGL ES, use compute shader blit to emulate rgb9e5ufloat texture to buffer copies.
deviceToggles->Default(Toggle::UseBlitForRGB9E5UfloatTextureCopy, gl.GetVersion().IsES());
+ // Use compute shader blit to emulate rg11b10ufloat texture to buffer copies if not color
+ // renderable.
+ deviceToggles->Default(Toggle::UseBlitForRG11B10UfloatTextureCopy, !isRG11B10UfloatRenderable);
+
// Use compute shader blit to emulate float16 texture to buffer copies if not color renderable.
deviceToggles->Default(Toggle::UseBlitForFloat16TextureCopy, !isFloat16Renderable);
diff --git a/src/dawn/tests/end2end/CopyTests.cpp b/src/dawn/tests/end2end/CopyTests.cpp
index 1122f0a..9b4bb10 100644
--- a/src/dawn/tests/end2end/CopyTests.cpp
+++ b/src/dawn/tests/end2end/CopyTests.cpp
@@ -288,8 +288,6 @@
// GL_EXT_texture_format_BGRA8888 or GL_APPLE_texture_format_BGRA8888 is required for
// compat mode.
DAWN_TEST_UNSUPPORTED_IF(format == wgpu::TextureFormat::BGRA8Unorm);
- // TODO(crbug.com/388318201): GL_R11F_G11F_B10F: Framebuffer incomplete.
- DAWN_SUPPRESS_TEST_IF(format == wgpu::TextureFormat::RG11B10Ufloat);
}
// TODO(dawn:2129): Fail for Win ANGLE D3D11
diff --git a/src/dawn/tests/end2end/TextureFormatTests.cpp b/src/dawn/tests/end2end/TextureFormatTests.cpp
index a8fd8ca..cfffef9 100644
--- a/src/dawn/tests/end2end/TextureFormatTests.cpp
+++ b/src/dawn/tests/end2end/TextureFormatTests.cpp
@@ -940,9 +940,10 @@
// Test the RG11B10Ufloat format
TEST_P(TextureFormatTest, RG11B10Ufloat) {
- // TODO(crbug.com/388318201): investigate
- DAWN_SUPPRESS_TEST_IF(IsCompatibilityMode() &&
- HasToggleEnabled("gl_force_es_31_and_no_extensions"));
+ // TODO(crbug.com/388318201): sampling test also requires format to be color-renderable
+ DAWN_SUPPRESS_TEST_IF(!IsRG11B10UfloatRenderableSupported());
+ // TODO(crbug.com/388318201): expected: 0xf87e0000, actual: 0xfffff800
+ DAWN_SUPPRESS_TEST_IF(IsD3D11());
constexpr uint32_t kFloat11Zero = 0;
constexpr uint32_t kFloat11Infinity = 0x7C0;
@@ -985,18 +986,15 @@
{wgpu::TextureFormat::RG11B10Ufloat, 4, TextureComponentType::Float, 4}, textureData,
uncompressedData);
- // This format is renderable if "rg11b10ufloat-renderable" feature is enabled
- if (IsRG11B10UfloatRenderableSupported()) {
- // TODO(https://crbug.com/swiftshader/147) Rendering INFINITY and NaN isn't handled
- // correctly by swiftshader
- if ((IsVulkan() && IsSwiftshader()) || IsANGLE()) {
- WarningLog() << "Skip Rendering test because Swiftshader doesn't render INFINITY "
- "and NaN correctly for RG11B10Ufloat texture format.";
- } else {
- DoFormatRenderingTest(
- {wgpu::TextureFormat::RG11B10Ufloat, 4, TextureComponentType::Float, 4},
- uncompressedData, textureData, new ExpectRG11B10Ufloat(textureData));
- }
+ // TODO(https://crbug.com/swiftshader/147) Rendering INFINITY and NaN isn't handled
+ // correctly by swiftshader
+ if ((IsVulkan() && IsSwiftshader()) || IsANGLE()) {
+ WarningLog() << "Skip Rendering test because Swiftshader doesn't render INFINITY "
+ "and NaN correctly for RG11B10Ufloat texture format.";
+ } else {
+ DoFormatRenderingTest(
+ {wgpu::TextureFormat::RG11B10Ufloat, 4, TextureComponentType::Float, 4},
+ uncompressedData, textureData, new ExpectRG11B10Ufloat(textureData));
}
}