From e6582161b04beaa368f3081897912ede89d7800d Mon Sep 17 00:00:00 2001 From: Geoff Lang Date: Mon, 16 Sep 2019 12:39:18 -0400 Subject: [PATCH] Convert DXT1 RGB data to DXT3 RGBA when uploading to the GPU. DXT1 has a specific 'BLACK' code that results in transparent black pixels when sampled. D3D does not have specific RGB-only DXT1 formats like OpenGL does so when this code is encountered, we sample 0 alpha for these pixels when GL would expect 1 because the alpha channel should not exist. Work around this by converting to DXT3 RGBA, adding an extra block of 1.0 alpha pixels for each color block. Mac Intel OpenGL requires additional workarounds to always sample 1.0 alpha. Set the texture swizzle parameters to force it. BUG=angleproject:3729 Change-Id: Ia3647085acd97bb01af4e95ef3f6f21dcfb6a554 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1804880 Commit-Queue: Geoff Lang Reviewed-by: Ian Elliott --- include/platform/FeaturesGL.h | 6 +++ .../ANGLE_load_functions_table.json | 4 +- .../code_generation_hashes/D3D11_format.json | 4 +- src/image_util/loadimage.cpp | 40 ++++++++++++++++ src/image_util/loadimage.h | 10 ++++ .../d3d/d3d11/texture_format_map.json | 2 + .../d3d11/texture_format_table_autogen.cpp | 16 +++---- .../renderer/d3d/d3d9/formatutils9.cpp | 2 +- src/libANGLE/renderer/gl/TextureGL.cpp | 47 +++++++++++++------ src/libANGLE/renderer/gl/renderergl_utils.cpp | 2 + .../renderer/load_functions_data.json | 6 +++ .../renderer/load_functions_table_autogen.cpp | 44 ++++++++++++++++- .../gl_tests/DXT1CompressedTextureTest.cpp | 38 +++++++++++++++ 13 files changed, 191 insertions(+), 30 deletions(-) diff --git a/include/platform/FeaturesGL.h b/include/platform/FeaturesGL.h index 1f320a251..77dcc7052 100644 --- a/include/platform/FeaturesGL.h +++ b/include/platform/FeaturesGL.h @@ -352,6 +352,12 @@ struct FeaturesGL : FeatureSetBase "reset_texture_generates_errors", FeatureCategory::OpenGLWorkarounds, "Calling glTexImage2D with zero size generates errors.", &members, "http://anglebug.com/3859"}; + + // Mac Intel samples transparent black from GL_COMPRESSED_RGB_S3TC_DXT1_EXT + Feature rgbDXT1TexturesSampleZeroAlpha = { + "rgb_dxt1_textures_sample_zero_alpha", FeatureCategory::OpenGLWorkarounds, + "Sampling BLACK texels from RGB DXT1 textures returns transparent black on Mac.", &members, + "http://anglebug.com/3729"}; }; inline FeaturesGL::FeaturesGL() = default; diff --git a/scripts/code_generation_hashes/ANGLE_load_functions_table.json b/scripts/code_generation_hashes/ANGLE_load_functions_table.json index 771cdcf5f..341d84a16 100644 --- a/scripts/code_generation_hashes/ANGLE_load_functions_table.json +++ b/scripts/code_generation_hashes/ANGLE_load_functions_table.json @@ -2,7 +2,7 @@ "src/libANGLE/renderer/gen_load_functions_table.py": "e65c50e84fc38ad34d0eb0bebb84aab6", "src/libANGLE/renderer/load_functions_data.json": - "16264b125e5410a4791a0c2697a4ff77", + "9d7a6eae5190f725e4dc410537bfa660", "src/libANGLE/renderer/load_functions_table_autogen.cpp": - "99e876f3871810c6a7fee8f4ff81b0e6" + "a0b59e47d968007d1344c84a7e61f9fc" } \ No newline at end of file diff --git a/scripts/code_generation_hashes/D3D11_format.json b/scripts/code_generation_hashes/D3D11_format.json index fcaf48bf2..2c809f287 100644 --- a/scripts/code_generation_hashes/D3D11_format.json +++ b/scripts/code_generation_hashes/D3D11_format.json @@ -6,7 +6,7 @@ "src/libANGLE/renderer/d3d/d3d11/texture_format_data.json": "d7483ece817e819588f4ca157716dc7b", "src/libANGLE/renderer/d3d/d3d11/texture_format_map.json": - "511730c698bfc3da18f745d2036c70c7", + "e70603310b68f658c7d73003705eebc8", "src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp": - "2e6fef6d2b8bfb0da5a90f5e6aa550b8" + "baeaa3bb5a7cf728f38339753970711b" } \ No newline at end of file diff --git a/src/image_util/loadimage.cpp b/src/image_util/loadimage.cpp index ff5ba4833..d8890b173 100644 --- a/src/image_util/loadimage.cpp +++ b/src/image_util/loadimage.cpp @@ -1459,6 +1459,46 @@ void LoadRGB32FToRGB16F(size_t width, } } +void LoadRGBDXT1ToRGBADXT3(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + constexpr size_t kBlockWidth = 4; + constexpr size_t kBlockHeight = 4; + constexpr size_t kBlockDepth = 1; + constexpr size_t kBlockSize = 8; + + const size_t columns = (width + (kBlockWidth - 1)) / kBlockWidth; + const size_t rows = (height + (kBlockHeight - 1)) / kBlockHeight; + const size_t layers = (depth + (kBlockDepth - 1)) / kBlockDepth; + + for (size_t z = 0; z < layers; ++z) + { + for (size_t y = 0; y < rows; ++y) + { + for (size_t x = 0; x < columns; x++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch) + + (x * kBlockSize); + uint8_t *dest = priv::OffsetDataPointer(output, y, z, outputRowPitch, + outputDepthPitch) + + (x * kBlockSize * 2); + + // DXT3 has a block for alpha then a block for color + memset(dest, 0xFF, kBlockSize); + memcpy(dest + kBlockSize, source, kBlockSize); + } + } + } +} + void LoadR32ToR16(size_t width, size_t height, size_t depth, diff --git a/src/image_util/loadimage.h b/src/image_util/loadimage.h index 21e0a9e95..5efb4e8d9 100644 --- a/src/image_util/loadimage.h +++ b/src/image_util/loadimage.h @@ -529,6 +529,16 @@ inline void LoadCompressedToNative(size_t width, size_t outputRowPitch, size_t outputDepthPitch); +void LoadRGBDXT1ToRGBADXT3(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + void LoadR32ToR16(size_t width, size_t height, size_t depth, diff --git a/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json b/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json index 2d7875ae3..59990fda6 100644 --- a/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json +++ b/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json @@ -64,6 +64,8 @@ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM_SRGB", "GL_DEPTH_COMPONENT24": "D24_UNORM_S8_UINT", "GL_DEPTH_COMPONENT32_OES": "D24_UNORM_S8_UINT", + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": "BC3_RGBA_UNORM_BLOCK", + "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT": "BC3_RGBA_UNORM_SRGB_BLOCK", "GL_ETC1_RGB8_OES": "R8G8B8A8_UNORM", "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": "BC1_RGB_UNORM_BLOCK", "GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE": "BC1_RGB_UNORM_BLOCK", diff --git a/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp index 594ee848c..7a739d276 100644 --- a/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp +++ b/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp @@ -731,13 +731,13 @@ const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &dev case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: { static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, - angle::FormatID::BC1_RGB_UNORM_BLOCK, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_BC1_UNORM, + angle::FormatID::BC3_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC3_UNORM, GL_RGBA8, nullptr); return info; @@ -1235,13 +1235,13 @@ const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &dev case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: { static constexpr Format info(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, - angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK, - DXGI_FORMAT_BC1_UNORM_SRGB, - DXGI_FORMAT_BC1_UNORM_SRGB, + angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC3_UNORM_SRGB, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC3_UNORM_SRGB, GL_RGBA8, nullptr); return info; diff --git a/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp index 72188bb11..53bdf56d6 100644 --- a/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp +++ b/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp @@ -332,7 +332,7 @@ static D3D9FormatMap BuildD3D9FormatMap() InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 ); - InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> ); + InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadRGBDXT1ToRGBADXT3 ); InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> ); InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> ); InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> ); diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp index b9d664edb..4f7d2866e 100644 --- a/src/libANGLE/renderer/gl/TextureGL.cpp +++ b/src/libANGLE/renderer/gl/TextureGL.cpp @@ -68,13 +68,22 @@ bool GetDepthStencilWorkaround(GLenum format) return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL; } -LevelInfoGL GetLevelInfo(GLenum originalInternalFormat, GLenum destinationInternalFormat) +bool GetEmulatedAlphaChannel(const angle::FeaturesGL &features, GLenum internalFormat) +{ + return features.rgbDXT1TexturesSampleZeroAlpha.enabled && + internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT; +} + +LevelInfoGL GetLevelInfo(const angle::FeaturesGL &features, + GLenum originalInternalFormat, + GLenum destinationInternalFormat) { GLenum originalFormat = gl::GetUnsizedFormat(originalInternalFormat); GLenum destinationFormat = gl::GetUnsizedFormat(destinationInternalFormat); return LevelInfoGL(originalFormat, destinationInternalFormat, GetDepthStencilWorkaround(originalFormat), - GetLUMAWorkaroundInfo(originalFormat, destinationFormat), false); + GetLUMAWorkaroundInfo(originalFormat, destinationFormat), + GetEmulatedAlphaChannel(features, originalFormat)); } gl::Texture::DirtyBits GetLevelWorkaroundDirtyBits() @@ -257,7 +266,7 @@ angle::Result TextureGL::setImageHelper(const gl::Context *context, } setLevelInfo(context, target, level, 1, - GetLevelInfo(internalFormat, texImageFormat.internalFormat)); + GetLevelInfo(features, internalFormat, texImageFormat.internalFormat)); return angle::Result::Continue; } @@ -298,7 +307,7 @@ angle::Result TextureGL::setSubImage(const gl::Context *context, size_t level = static_cast(index.getLevelIndex()); ASSERT(getLevelInfo(target, level).lumaWorkaround.enabled == - GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); + GetLevelInfo(features, format, texSubImageFormat.format).lumaWorkaround.enabled); stateManager->bindTexture(getType(), mTextureID); if (features.unpackOverlappingRowsSeparatelyUnpackBuffer.enabled && unpackBuffer && @@ -541,7 +550,8 @@ angle::Result TextureGL::setCompressedImage(const gl::Context *context, static_cast(imageSize), pixels)); } - LevelInfoGL levelInfo = GetLevelInfo(internalFormat, compressedTexImageFormat.internalFormat); + LevelInfoGL levelInfo = + GetLevelInfo(features, internalFormat, compressedTexImageFormat.internalFormat); ASSERT(!levelInfo.lumaWorkaround.enabled); setLevelInfo(context, target, level, 1, levelInfo); @@ -586,8 +596,9 @@ angle::Result TextureGL::setCompressedSubImage(const gl::Context *context, static_cast(imageSize), pixels)); } - ASSERT(!getLevelInfo(target, level).lumaWorkaround.enabled && - !GetLevelInfo(format, compressedTexSubImageFormat.format).lumaWorkaround.enabled); + ASSERT( + !getLevelInfo(target, level).lumaWorkaround.enabled && + !GetLevelInfo(features, format, compressedTexSubImageFormat.format).lumaWorkaround.enabled); return angle::Result::Continue; } @@ -676,7 +687,8 @@ angle::Result TextureGL::copyImage(const gl::Context *context, } } - LevelInfoGL levelInfo = GetLevelInfo(internalFormat, copyTexImageFormat.internalFormat); + LevelInfoGL levelInfo = + GetLevelInfo(features, internalFormat, copyTexImageFormat.internalFormat); gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0); if (levelInfo.lumaWorkaround.enabled) @@ -1077,7 +1089,7 @@ angle::Result TextureGL::setStorage(const gl::Context *context, } setLevelInfo(context, type, 0, levels, - GetLevelInfo(internalFormat, texStorageFormat.internalFormat)); + GetLevelInfo(features, internalFormat, texStorageFormat.internalFormat)); return angle::Result::Continue; } @@ -1098,7 +1110,7 @@ angle::Result TextureGL::setImageExternal(const gl::Context *context, nativegl::GetTexImageFormat(functions, features, internalFormat, format, type); setLevelInfo(context, target, level, 1, - GetLevelInfo(internalFormat, texImageFormat.internalFormat)); + GetLevelInfo(features, internalFormat, texImageFormat.internalFormat)); return angle::Result::Continue; } @@ -1149,7 +1161,7 @@ angle::Result TextureGL::setStorageMultisample(const gl::Context *context, } setLevelInfo(context, type, 0, 1, - GetLevelInfo(internalformat, texStorageFormat.internalFormat)); + GetLevelInfo(features, internalformat, texStorageFormat.internalFormat)); return angle::Result::Continue; } @@ -1191,7 +1203,7 @@ angle::Result TextureGL::setStorageExternalMemory(const gl::Context *context, } setLevelInfo(context, type, 0, levels, - GetLevelInfo(internalFormat, texStorageFormat.internalFormat)); + GetLevelInfo(features, internalFormat, texStorageFormat.internalFormat)); return angle::Result::Continue; } @@ -1263,13 +1275,16 @@ angle::Result TextureGL::setEGLImageTarget(const gl::Context *context, gl::TextureType type, egl::Image *image) { + const angle::FeaturesGL &features = GetFeaturesGL(context); + ImageGL *imageGL = GetImplAs(image); GLenum imageNativeInternalFormat = GL_NONE; ANGLE_TRY(imageGL->setTexture2D(context, type, this, &imageNativeInternalFormat)); - setLevelInfo(context, type, 0, 1, - GetLevelInfo(image->getFormat().info->internalFormat, imageNativeInternalFormat)); + setLevelInfo( + context, type, 0, 1, + GetLevelInfo(features, image->getFormat().info->internalFormat, imageNativeInternalFormat)); return angle::Result::Continue; } @@ -1707,7 +1722,8 @@ void TextureGL::setLevelInfo(const gl::Context *context, { ASSERT(levelCount > 0); - bool updateWorkarounds = levelInfo.depthStencilWorkaround || levelInfo.lumaWorkaround.enabled; + bool updateWorkarounds = levelInfo.depthStencilWorkaround || levelInfo.lumaWorkaround.enabled || + levelInfo.emulatedAlphaChannel; for (size_t i = level; i < level + levelCount; i++) { @@ -1717,6 +1733,7 @@ void TextureGL::setLevelInfo(const gl::Context *context, updateWorkarounds |= curLevelInfo.depthStencilWorkaround; updateWorkarounds |= curLevelInfo.lumaWorkaround.enabled; + updateWorkarounds |= curLevelInfo.emulatedAlphaChannel; curLevelInfo = levelInfo; } diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp index d516750a3..0925c210d 100644 --- a/src/libANGLE/renderer/gl/renderergl_utils.cpp +++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp @@ -1556,6 +1556,8 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature features->resettingTexturesGeneratesErrors.enabled = IsApple() || (IsWindows() && IsAMD(device)); + + features->rgbDXT1TexturesSampleZeroAlpha.enabled = IsApple(); } void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) diff --git a/src/libANGLE/renderer/load_functions_data.json b/src/libANGLE/renderer/load_functions_data.json index cb337f610..3f4247edd 100644 --- a/src/libANGLE/renderer/load_functions_data.json +++ b/src/libANGLE/renderer/load_functions_data.json @@ -608,6 +608,9 @@ } }, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { + "BC3_RGBA_UNORM_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadRGBDXT1ToRGBADXT3" + }, "NONE": { "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>" } @@ -842,6 +845,9 @@ } }, "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT": { + "BC3_RGBA_UNORM_SRGB_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadRGBDXT1ToRGBADXT3" + }, "NONE": { "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>" } diff --git a/src/libANGLE/renderer/load_functions_table_autogen.cpp b/src/libANGLE/renderer/load_functions_table_autogen.cpp index 4866c3ca8..c88c2aec9 100644 --- a/src/libANGLE/renderer/load_functions_table_autogen.cpp +++ b/src/libANGLE/renderer/load_functions_table_autogen.cpp @@ -832,6 +832,18 @@ LoadImageFunctionInfo COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_to_default(GLenum t } } +LoadImageFunctionInfo COMPRESSED_RGB_S3TC_DXT1_EXT_to_BC3_RGBA_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBDXT1ToRGBADXT3, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + LoadImageFunctionInfo COMPRESSED_RGB_S3TC_DXT1_EXT_to_default(GLenum type) { switch (type) @@ -1352,6 +1364,18 @@ LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default(GLenum type } } +LoadImageFunctionInfo COMPRESSED_SRGB_S3TC_DXT1_EXT_to_BC3_RGBA_UNORM_SRGB_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBDXT1ToRGBADXT3, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + LoadImageFunctionInfo COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default(GLenum type) { switch (type) @@ -3246,7 +3270,15 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat) case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: return COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_to_default; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return COMPRESSED_RGB_S3TC_DXT1_EXT_to_default; + { + switch (angleFormat) + { + case FormatID::BC3_RGBA_UNORM_BLOCK: + return COMPRESSED_RGB_S3TC_DXT1_EXT_to_BC3_RGBA_UNORM_BLOCK; + default: + return COMPRESSED_RGB_S3TC_DXT1_EXT_to_default; + } + } case GL_COMPRESSED_SIGNED_R11_EAC: { switch (angleFormat) @@ -3395,7 +3427,15 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat) case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: return COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default; case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - return COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default; + { + switch (angleFormat) + { + case FormatID::BC3_RGBA_UNORM_SRGB_BLOCK: + return COMPRESSED_SRGB_S3TC_DXT1_EXT_to_BC3_RGBA_UNORM_SRGB_BLOCK; + default: + return COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default; + } + } case GL_DEPTH24_STENCIL8: { switch (angleFormat) diff --git a/src/tests/gl_tests/DXT1CompressedTextureTest.cpp b/src/tests/gl_tests/DXT1CompressedTextureTest.cpp index be85ef22b..078a0768b 100644 --- a/src/tests/gl_tests/DXT1CompressedTextureTest.cpp +++ b/src/tests/gl_tests/DXT1CompressedTextureTest.cpp @@ -110,6 +110,44 @@ TEST_P(DXT1CompressedTextureTest, CompressedTexImage) EXPECT_GL_NO_ERROR(); } +// Verify that DXT1 RGB textures have 1.0 alpha when sampled +TEST_P(DXT1CompressedTextureTest, DXT1Alpha) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1")); + + GLTexture texture; + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + // Image using pixels with the code for transparent black: + // "BLACK, if color0 <= color1 and code(x,y) == 3" + constexpr uint8_t CompressedImageDXT1[] = {0, 0, 0, 0, 51, 204, 51, 204}; + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, + sizeof(CompressedImageDXT1), CompressedImageDXT1); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + constexpr GLint kDrawSize = 4; + // The image is one 4x4 block, make the viewport only 4x4. + glViewport(0, 0, kDrawSize, kDrawSize); + + drawQuad(mTextureProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + for (GLint y = 0; y < kDrawSize; y++) + { + for (GLint x = 0; x < kDrawSize; x++) + { + EXPECT_PIXEL_EQ(x, y, 0, 0, 0, 255) << "at (" << x << ", " << y << ")"; + } + } +} + TEST_P(DXT1CompressedTextureTest, CompressedTexStorage) { ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));