Support all BC formats on D3D12, Metal and Vulkan
This patch adds the support of all BC formats on D3D12, Metal and
Vulkan and related end2end tests.
BUG=dawn:42
TEST=dawn_end2end_tests
Change-Id: I50caf687d3cfee7df80070952f55f96dc363a830
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8900
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index a29983f..afe10f3 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -191,11 +191,34 @@
case dawn::TextureFormat::Depth24PlusStencil8:
return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
- // TODO(jiawei.shao@intel.com): support all BC formats
+ case dawn::TextureFormat::BC1RGBAUnorm:
+ return DXGI_FORMAT_BC1_UNORM;
+ case dawn::TextureFormat::BC1RGBAUnormSrgb:
+ return DXGI_FORMAT_BC1_UNORM_SRGB;
+ case dawn::TextureFormat::BC2RGBAUnorm:
+ return DXGI_FORMAT_BC2_UNORM;
+ case dawn::TextureFormat::BC2RGBAUnormSrgb:
+ return DXGI_FORMAT_BC2_UNORM_SRGB;
+ case dawn::TextureFormat::BC3RGBAUnorm:
+ return DXGI_FORMAT_BC3_UNORM;
+ case dawn::TextureFormat::BC3RGBAUnormSrgb:
+ return DXGI_FORMAT_BC3_UNORM_SRGB;
+ case dawn::TextureFormat::BC4RSnorm:
+ return DXGI_FORMAT_BC4_SNORM;
+ case dawn::TextureFormat::BC4RUnorm:
+ return DXGI_FORMAT_BC4_UNORM;
case dawn::TextureFormat::BC5RGSnorm:
return DXGI_FORMAT_BC5_SNORM;
case dawn::TextureFormat::BC5RGUnorm:
return DXGI_FORMAT_BC5_UNORM;
+ case dawn::TextureFormat::BC6HRGBSfloat:
+ return DXGI_FORMAT_BC6H_SF16;
+ case dawn::TextureFormat::BC6HRGBUfloat:
+ return DXGI_FORMAT_BC6H_UF16;
+ case dawn::TextureFormat::BC7RGBAUnorm:
+ return DXGI_FORMAT_BC7_UNORM;
+ case dawn::TextureFormat::BC7RGBAUnormSrgb:
+ return DXGI_FORMAT_BC7_UNORM_SRGB;
default:
UNREACHABLE();
diff --git a/src/dawn_native/metal/TextureMTL.mm b/src/dawn_native/metal/TextureMTL.mm
index 9b7bb52..5e12f7a 100644
--- a/src/dawn_native/metal/TextureMTL.mm
+++ b/src/dawn_native/metal/TextureMTL.mm
@@ -217,11 +217,34 @@
case dawn::TextureFormat::Depth24PlusStencil8:
return MTLPixelFormatDepth32Float_Stencil8;
- // TODO(jiawei.shao@intel.com): support all BC formats
+ case dawn::TextureFormat::BC1RGBAUnorm:
+ return MTLPixelFormatBC1_RGBA;
+ case dawn::TextureFormat::BC1RGBAUnormSrgb:
+ return MTLPixelFormatBC1_RGBA_sRGB;
+ case dawn::TextureFormat::BC2RGBAUnorm:
+ return MTLPixelFormatBC2_RGBA;
+ case dawn::TextureFormat::BC2RGBAUnormSrgb:
+ return MTLPixelFormatBC2_RGBA_sRGB;
+ case dawn::TextureFormat::BC3RGBAUnorm:
+ return MTLPixelFormatBC3_RGBA;
+ case dawn::TextureFormat::BC3RGBAUnormSrgb:
+ return MTLPixelFormatBC3_RGBA_sRGB;
+ case dawn::TextureFormat::BC4RSnorm:
+ return MTLPixelFormatBC4_RSnorm;
+ case dawn::TextureFormat::BC4RUnorm:
+ return MTLPixelFormatBC4_RUnorm;
case dawn::TextureFormat::BC5RGSnorm:
return MTLPixelFormatBC5_RGSnorm;
case dawn::TextureFormat::BC5RGUnorm:
return MTLPixelFormatBC5_RGUnorm;
+ case dawn::TextureFormat::BC6HRGBSfloat:
+ return MTLPixelFormatBC6H_RGBFloat;
+ case dawn::TextureFormat::BC6HRGBUfloat:
+ return MTLPixelFormatBC6H_RGBUfloat;
+ case dawn::TextureFormat::BC7RGBAUnorm:
+ return MTLPixelFormatBC7_RGBAUnorm;
+ case dawn::TextureFormat::BC7RGBAUnormSrgb:
+ return MTLPixelFormatBC7_RGBAUnorm_sRGB;
default:
UNREACHABLE();
diff --git a/src/tests/end2end/CompressedTextureFormatTests.cpp b/src/tests/end2end/CompressedTextureFormatTests.cpp
index 51789cc..157ae9e 100644
--- a/src/tests/end2end/CompressedTextureFormatTests.cpp
+++ b/src/tests/end2end/CompressedTextureFormatTests.cpp
@@ -235,11 +235,23 @@
}
// Return the BC block size in bytes.
- // TODO(jiawei.shao@intel.com): support all BC formats.
static uint32_t CompressedFormatBlockSizeInBytes(dawn::TextureFormat format) {
switch (format) {
+ case dawn::TextureFormat::BC1RGBAUnorm:
+ case dawn::TextureFormat::BC1RGBAUnormSrgb:
+ case dawn::TextureFormat::BC4RSnorm:
+ case dawn::TextureFormat::BC4RUnorm:
+ return 8;
+ case dawn::TextureFormat::BC2RGBAUnorm:
+ case dawn::TextureFormat::BC2RGBAUnormSrgb:
+ case dawn::TextureFormat::BC3RGBAUnorm:
+ case dawn::TextureFormat::BC3RGBAUnormSrgb:
case dawn::TextureFormat::BC5RGSnorm:
case dawn::TextureFormat::BC5RGUnorm:
+ case dawn::TextureFormat::BC6HRGBSfloat:
+ case dawn::TextureFormat::BC6HRGBUfloat:
+ case dawn::TextureFormat::BC7RGBAUnorm:
+ case dawn::TextureFormat::BC7RGBAUnormSrgb:
return 16;
default:
UNREACHABLE();
@@ -248,9 +260,43 @@
}
// Return the pre-prepared one-block BC texture data.
- // TODO(jiawei.shao@intel.com): prepare texture data for all BC formats.
static std::vector<uint8_t> GetOneBlockBCFormatTextureData(dawn::TextureFormat bcFormat) {
switch (bcFormat) {
+ // The expected data represents 4x4 pixel images with the left side dark red and the
+ // right side dark green. We specify the same compressed data in both sRGB and non-sRGB
+ // tests, but the rendering result should be different because for sRGB formats, the
+ // red, green, and blue components are converted from an sRGB color space to a linear
+ // color space as part of filtering.
+ case dawn::TextureFormat::BC1RGBAUnorm:
+ case dawn::TextureFormat::BC1RGBAUnormSrgb:
+ return {0x0, 0xC0, 0x60, 0x6, 0x50, 0x50, 0x50, 0x50};
+ case dawn::TextureFormat::BC7RGBAUnorm:
+ case dawn::TextureFormat::BC7RGBAUnormSrgb:
+ return {0x50, 0x18, 0xfc, 0xf, 0x0, 0x30, 0xe3, 0xe1,
+ 0xe1, 0xe1, 0xc1, 0xf, 0xfc, 0xc0, 0xf, 0xfc};
+
+ // The expected data represents 4x4 pixel images with the left side dark red and the
+ // right side dark green. The pixels in the left side of the block all have an alpha
+ // value equal to 0x88. We specify the same compressed data in both sRGB and non-sRGB
+ // tests, but the rendering result should be different because for sRGB formats, the
+ // red, green, and blue components are converted from an sRGB color space to a linear
+ // color space as part of filtering, and any alpha component is left unchanged.
+ case dawn::TextureFormat::BC2RGBAUnorm:
+ case dawn::TextureFormat::BC2RGBAUnormSrgb:
+ return {0x88, 0xFF, 0x88, 0xFF, 0x88, 0xFF, 0x88, 0xFF,
+ 0x0, 0xC0, 0x60, 0x6, 0x50, 0x50, 0x50, 0x50};
+ case dawn::TextureFormat::BC3RGBAUnorm:
+ case dawn::TextureFormat::BC3RGBAUnormSrgb:
+ return {0x88, 0xFF, 0x40, 0x2, 0x24, 0x40, 0x2, 0x24,
+ 0x0, 0xC0, 0x60, 0x6, 0x50, 0x50, 0x50, 0x50};
+
+ // The expected data represents 4x4 pixel images with the left side red and the
+ // right side black.
+ case dawn::TextureFormat::BC4RSnorm:
+ return {0x7F, 0x0, 0x40, 0x2, 0x24, 0x40, 0x2, 0x24};
+ case dawn::TextureFormat::BC4RUnorm:
+ return {0xFF, 0x0, 0x40, 0x2, 0x24, 0x40, 0x2, 0x24};
+
// The expected data represents 4x4 pixel images with the left side red and the right
// side green and was encoded with DirectXTex from Microsoft.
case dawn::TextureFormat::BC5RGSnorm:
@@ -259,6 +305,13 @@
case dawn::TextureFormat::BC5RGUnorm:
return {0xff, 0x0, 0x40, 0x2, 0x24, 0x40, 0x2, 0x24,
0xff, 0x0, 0x9, 0x90, 0x0, 0x9, 0x90, 0x0};
+ case dawn::TextureFormat::BC6HRGBSfloat:
+ return {0xe3, 0x1f, 0x0, 0x0, 0x0, 0xe0, 0x1f, 0x0,
+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff};
+ case dawn::TextureFormat::BC6HRGBUfloat:
+ return {0xe3, 0x3d, 0x0, 0x0, 0x0, 0xe0, 0x3d, 0x0,
+ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff};
+
default:
UNREACHABLE();
return {};
@@ -267,32 +320,68 @@
// Return the texture data that is decoded from the result of GetOneBlockBCFormatTextureData in
// RGBA8 formats.
- // TODO(jiawei.shao@intel.com): prepare texture data for all BC formats.
static std::vector<RGBA8> GetExpectedData(dawn::TextureFormat bcFormat,
const dawn::Extent3D& testRegion) {
+ constexpr RGBA8 kRed(255, 0, 0, 255);
+ constexpr RGBA8 kGreen(0, 255, 0, 255);
+ constexpr RGBA8 kBlack(0, 0, 0, 255);
+ constexpr RGBA8 kDarkRed(198, 0, 0, 255);
+ constexpr RGBA8 kDarkGreen(0, 207, 0, 255);
+ constexpr RGBA8 kDarkRedSRGB(144, 0, 0, 255);
+ constexpr RGBA8 kDarkGreenSRGB(0, 159, 0, 255);
+
+ constexpr uint8_t kLeftAlpha = 0x88;
+ constexpr uint8_t kRightAlpha = 0xFF;
+
switch (bcFormat) {
+ case dawn::TextureFormat::BC1RGBAUnorm:
+ case dawn::TextureFormat::BC7RGBAUnorm:
+ return FillExpectedData(testRegion, kDarkRed, kDarkGreen);
+
+ case dawn::TextureFormat::BC2RGBAUnorm:
+ case dawn::TextureFormat::BC3RGBAUnorm: {
+ constexpr RGBA8 kLeftColor = RGBA8(kDarkRed.r, 0, 0, kLeftAlpha);
+ constexpr RGBA8 kRightColor = RGBA8(0, kDarkGreen.g, 0, kRightAlpha);
+ return FillExpectedData(testRegion, kLeftColor, kRightColor);
+ }
+
+ case dawn::TextureFormat::BC1RGBAUnormSrgb:
+ case dawn::TextureFormat::BC7RGBAUnormSrgb:
+ return FillExpectedData(testRegion, kDarkRedSRGB, kDarkGreenSRGB);
+
+ case dawn::TextureFormat::BC2RGBAUnormSrgb:
+ case dawn::TextureFormat::BC3RGBAUnormSrgb: {
+ constexpr RGBA8 kLeftColor = RGBA8(kDarkRedSRGB.r, 0, 0, kLeftAlpha);
+ constexpr RGBA8 kRightColor = RGBA8(0, kDarkGreenSRGB.g, 0, kRightAlpha);
+ return FillExpectedData(testRegion, kLeftColor, kRightColor);
+ }
+
+ case dawn::TextureFormat::BC4RSnorm:
+ case dawn::TextureFormat::BC4RUnorm:
+ return FillExpectedData(testRegion, kRed, kBlack);
+
case dawn::TextureFormat::BC5RGSnorm:
case dawn::TextureFormat::BC5RGUnorm:
- return FillExpectedDataWithPureRedAndPureGreen(testRegion);
+ case dawn::TextureFormat::BC6HRGBSfloat:
+ case dawn::TextureFormat::BC6HRGBUfloat:
+ return FillExpectedData(testRegion, kRed, kGreen);
+
default:
UNREACHABLE();
return {};
}
}
- // Get one kind of expected data that is filled with pure green and pure red.
- static std::vector<RGBA8> FillExpectedDataWithPureRedAndPureGreen(
- const dawn::Extent3D& testRegion) {
+ static std::vector<RGBA8> FillExpectedData(const dawn::Extent3D& testRegion,
+ RGBA8 leftColorInBlock,
+ RGBA8 rightColorInBlock) {
ASSERT(testRegion.depth == 1);
- constexpr RGBA8 kRed(255, 0, 0, 255);
- constexpr RGBA8 kGreen(0, 255, 0, 255);
-
- std::vector<RGBA8> expectedData(testRegion.width * testRegion.height, kRed);
+ std::vector<RGBA8> expectedData(testRegion.width * testRegion.height, leftColorInBlock);
for (uint32_t y = 0; y < testRegion.height; ++y) {
for (uint32_t x = 0; x < testRegion.width; ++x) {
if (x % kBCBlockWidthInTexels >= kBCBlockWidthInTexels / 2) {
- expectedData[testRegion.width * y + x] = kGreen;
+ expectedData[testRegion.width * y + x] = rightColorInBlock;
}
}
}
@@ -313,9 +402,15 @@
return sizeAtLevel;
}
- // TODO(jiawei.shao@intel.com): support all BC formats.
- const std::array<dawn::TextureFormat, 2> kBCFormats = {dawn::TextureFormat::BC5RGSnorm,
- dawn::TextureFormat::BC5RGUnorm};
+ const std::array<dawn::TextureFormat, 14> kBCFormats = {
+ dawn::TextureFormat::BC1RGBAUnorm, dawn::TextureFormat::BC1RGBAUnormSrgb,
+ dawn::TextureFormat::BC2RGBAUnorm, dawn::TextureFormat::BC2RGBAUnormSrgb,
+ dawn::TextureFormat::BC3RGBAUnorm, dawn::TextureFormat::BC3RGBAUnormSrgb,
+ dawn::TextureFormat::BC4RSnorm, dawn::TextureFormat::BC4RUnorm,
+ dawn::TextureFormat::BC5RGSnorm, dawn::TextureFormat::BC5RGUnorm,
+ dawn::TextureFormat::BC6HRGBSfloat, dawn::TextureFormat::BC6HRGBUfloat,
+ dawn::TextureFormat::BC7RGBAUnorm, dawn::TextureFormat::BC7RGBAUnormSrgb};
+
// Tthe block width and height in texels are 4 for all BC formats.
static constexpr uint32_t kBCBlockWidthInTexels = 4;
static constexpr uint32_t kBCBlockHeightInTexels = 4;