From 5580970f59264b95f10dd242021f29525b13370e Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Wed, 17 Jul 2019 00:00:10 +0000 Subject: [PATCH] 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 Reviewed-by: Austin Eng Commit-Queue: Jiawei Shao --- src/dawn_native/d3d12/TextureD3D12.cpp | 25 +++- src/dawn_native/metal/TextureMTL.mm | 25 +++- .../end2end/CompressedTextureFormatTests.cpp | 125 +++++++++++++++--- 3 files changed, 158 insertions(+), 17 deletions(-) diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp index a29983f0f6..afe10f3577 100644 --- a/src/dawn_native/d3d12/TextureD3D12.cpp +++ b/src/dawn_native/d3d12/TextureD3D12.cpp @@ -191,11 +191,34 @@ namespace dawn_native { namespace d3d12 { 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 9b7bb52db0..5e12f7a906 100644 --- a/src/dawn_native/metal/TextureMTL.mm +++ b/src/dawn_native/metal/TextureMTL.mm @@ -217,11 +217,34 @@ namespace dawn_native { namespace metal { 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 51789cc567..157ae9ea13 100644 --- a/src/tests/end2end/CompressedTextureFormatTests.cpp +++ b/src/tests/end2end/CompressedTextureFormatTests.cpp @@ -235,11 +235,23 @@ class CompressedTextureBCFormatTest : public DawnTest { } // 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 @@ class CompressedTextureBCFormatTest : public DawnTest { } // Return the pre-prepared one-block BC texture data. - // TODO(jiawei.shao@intel.com): prepare texture data for all BC formats. static std::vector 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 @@ class CompressedTextureBCFormatTest : public DawnTest { 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 @@ class CompressedTextureBCFormatTest : public DawnTest { // 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 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 FillExpectedDataWithPureRedAndPureGreen( - const dawn::Extent3D& testRegion) { + static std::vector 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 expectedData(testRegion.width * testRegion.height, kRed); + std::vector 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 @@ class CompressedTextureBCFormatTest : public DawnTest { return sizeAtLevel; } - // TODO(jiawei.shao@intel.com): support all BC formats. - const std::array kBCFormats = {dawn::TextureFormat::BC5RGSnorm, - dawn::TextureFormat::BC5RGUnorm}; + const std::array 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;