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 <geofflang@chromium.org>
Reviewed-by: Ian Elliott <ianelliott@google.com>
This commit is contained in:
Geoff Lang 2019-09-16 12:39:18 -04:00 коммит произвёл Commit Bot
Родитель 80a1c9e64b
Коммит e6582161b0
13 изменённых файлов: 191 добавлений и 30 удалений

Просмотреть файл

@ -352,6 +352,12 @@ struct FeaturesGL : FeatureSetBase
"reset_texture_generates_errors", FeatureCategory::OpenGLWorkarounds, "reset_texture_generates_errors", FeatureCategory::OpenGLWorkarounds,
"Calling glTexImage2D with zero size generates errors.", &members, "Calling glTexImage2D with zero size generates errors.", &members,
"http://anglebug.com/3859"}; "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; inline FeaturesGL::FeaturesGL() = default;

Просмотреть файл

@ -2,7 +2,7 @@
"src/libANGLE/renderer/gen_load_functions_table.py": "src/libANGLE/renderer/gen_load_functions_table.py":
"e65c50e84fc38ad34d0eb0bebb84aab6", "e65c50e84fc38ad34d0eb0bebb84aab6",
"src/libANGLE/renderer/load_functions_data.json": "src/libANGLE/renderer/load_functions_data.json":
"16264b125e5410a4791a0c2697a4ff77", "9d7a6eae5190f725e4dc410537bfa660",
"src/libANGLE/renderer/load_functions_table_autogen.cpp": "src/libANGLE/renderer/load_functions_table_autogen.cpp":
"99e876f3871810c6a7fee8f4ff81b0e6" "a0b59e47d968007d1344c84a7e61f9fc"
} }

Просмотреть файл

@ -6,7 +6,7 @@
"src/libANGLE/renderer/d3d/d3d11/texture_format_data.json": "src/libANGLE/renderer/d3d/d3d11/texture_format_data.json":
"d7483ece817e819588f4ca157716dc7b", "d7483ece817e819588f4ca157716dc7b",
"src/libANGLE/renderer/d3d/d3d11/texture_format_map.json": "src/libANGLE/renderer/d3d/d3d11/texture_format_map.json":
"511730c698bfc3da18f745d2036c70c7", "e70603310b68f658c7d73003705eebc8",
"src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp": "src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp":
"2e6fef6d2b8bfb0da5a90f5e6aa550b8" "baeaa3bb5a7cf728f38339753970711b"
} }

Просмотреть файл

@ -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<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch) +
(x * kBlockSize);
uint8_t *dest = priv::OffsetDataPointer<uint8_t>(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, void LoadR32ToR16(size_t width,
size_t height, size_t height,
size_t depth, size_t depth,

Просмотреть файл

@ -529,6 +529,16 @@ inline void LoadCompressedToNative(size_t width,
size_t outputRowPitch, size_t outputRowPitch,
size_t outputDepthPitch); 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, void LoadR32ToR16(size_t width,
size_t height, size_t height,
size_t depth, size_t depth,

Просмотреть файл

@ -64,6 +64,8 @@
"GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM_SRGB", "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM_SRGB",
"GL_DEPTH_COMPONENT24": "D24_UNORM_S8_UINT", "GL_DEPTH_COMPONENT24": "D24_UNORM_S8_UINT",
"GL_DEPTH_COMPONENT32_OES": "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_OES": "R8G8B8A8_UNORM",
"GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": "BC1_RGB_UNORM_BLOCK", "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": "BC1_RGB_UNORM_BLOCK",
"GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE": "BC1_RGB_UNORM_BLOCK", "GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE": "BC1_RGB_UNORM_BLOCK",

Просмотреть файл

@ -731,13 +731,13 @@ const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &dev
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
{ {
static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
angle::FormatID::BC1_RGB_UNORM_BLOCK, angle::FormatID::BC3_RGBA_UNORM_BLOCK,
DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC3_UNORM,
DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC3_UNORM,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC3_UNORM,
GL_RGBA8, GL_RGBA8,
nullptr); nullptr);
return info; return info;
@ -1235,13 +1235,13 @@ const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &dev
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
{ {
static constexpr Format info(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, static constexpr Format info(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK, angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK,
DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC3_UNORM_SRGB,
DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC3_UNORM_SRGB,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC3_UNORM_SRGB,
GL_RGBA8, GL_RGBA8,
nullptr); nullptr);
return info; return info;

Просмотреть файл

@ -332,7 +332,7 @@ static D3D9FormatMap BuildD3D9FormatMap()
InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 );
InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 ); 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_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_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> ); InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> );

Просмотреть файл

@ -68,13 +68,22 @@ bool GetDepthStencilWorkaround(GLenum format)
return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL; 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 originalFormat = gl::GetUnsizedFormat(originalInternalFormat);
GLenum destinationFormat = gl::GetUnsizedFormat(destinationInternalFormat); GLenum destinationFormat = gl::GetUnsizedFormat(destinationInternalFormat);
return LevelInfoGL(originalFormat, destinationInternalFormat, return LevelInfoGL(originalFormat, destinationInternalFormat,
GetDepthStencilWorkaround(originalFormat), GetDepthStencilWorkaround(originalFormat),
GetLUMAWorkaroundInfo(originalFormat, destinationFormat), false); GetLUMAWorkaroundInfo(originalFormat, destinationFormat),
GetEmulatedAlphaChannel(features, originalFormat));
} }
gl::Texture::DirtyBits GetLevelWorkaroundDirtyBits() gl::Texture::DirtyBits GetLevelWorkaroundDirtyBits()
@ -257,7 +266,7 @@ angle::Result TextureGL::setImageHelper(const gl::Context *context,
} }
setLevelInfo(context, target, level, 1, setLevelInfo(context, target, level, 1,
GetLevelInfo(internalFormat, texImageFormat.internalFormat)); GetLevelInfo(features, internalFormat, texImageFormat.internalFormat));
return angle::Result::Continue; return angle::Result::Continue;
} }
@ -298,7 +307,7 @@ angle::Result TextureGL::setSubImage(const gl::Context *context,
size_t level = static_cast<size_t>(index.getLevelIndex()); size_t level = static_cast<size_t>(index.getLevelIndex());
ASSERT(getLevelInfo(target, level).lumaWorkaround.enabled == ASSERT(getLevelInfo(target, level).lumaWorkaround.enabled ==
GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); GetLevelInfo(features, format, texSubImageFormat.format).lumaWorkaround.enabled);
stateManager->bindTexture(getType(), mTextureID); stateManager->bindTexture(getType(), mTextureID);
if (features.unpackOverlappingRowsSeparatelyUnpackBuffer.enabled && unpackBuffer && if (features.unpackOverlappingRowsSeparatelyUnpackBuffer.enabled && unpackBuffer &&
@ -541,7 +550,8 @@ angle::Result TextureGL::setCompressedImage(const gl::Context *context,
static_cast<GLsizei>(imageSize), pixels)); static_cast<GLsizei>(imageSize), pixels));
} }
LevelInfoGL levelInfo = GetLevelInfo(internalFormat, compressedTexImageFormat.internalFormat); LevelInfoGL levelInfo =
GetLevelInfo(features, internalFormat, compressedTexImageFormat.internalFormat);
ASSERT(!levelInfo.lumaWorkaround.enabled); ASSERT(!levelInfo.lumaWorkaround.enabled);
setLevelInfo(context, target, level, 1, levelInfo); setLevelInfo(context, target, level, 1, levelInfo);
@ -586,8 +596,9 @@ angle::Result TextureGL::setCompressedSubImage(const gl::Context *context,
static_cast<GLsizei>(imageSize), pixels)); static_cast<GLsizei>(imageSize), pixels));
} }
ASSERT(!getLevelInfo(target, level).lumaWorkaround.enabled && ASSERT(
!GetLevelInfo(format, compressedTexSubImageFormat.format).lumaWorkaround.enabled); !getLevelInfo(target, level).lumaWorkaround.enabled &&
!GetLevelInfo(features, format, compressedTexSubImageFormat.format).lumaWorkaround.enabled);
return angle::Result::Continue; 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); gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0);
if (levelInfo.lumaWorkaround.enabled) if (levelInfo.lumaWorkaround.enabled)
@ -1077,7 +1089,7 @@ angle::Result TextureGL::setStorage(const gl::Context *context,
} }
setLevelInfo(context, type, 0, levels, setLevelInfo(context, type, 0, levels,
GetLevelInfo(internalFormat, texStorageFormat.internalFormat)); GetLevelInfo(features, internalFormat, texStorageFormat.internalFormat));
return angle::Result::Continue; return angle::Result::Continue;
} }
@ -1098,7 +1110,7 @@ angle::Result TextureGL::setImageExternal(const gl::Context *context,
nativegl::GetTexImageFormat(functions, features, internalFormat, format, type); nativegl::GetTexImageFormat(functions, features, internalFormat, format, type);
setLevelInfo(context, target, level, 1, setLevelInfo(context, target, level, 1,
GetLevelInfo(internalFormat, texImageFormat.internalFormat)); GetLevelInfo(features, internalFormat, texImageFormat.internalFormat));
return angle::Result::Continue; return angle::Result::Continue;
} }
@ -1149,7 +1161,7 @@ angle::Result TextureGL::setStorageMultisample(const gl::Context *context,
} }
setLevelInfo(context, type, 0, 1, setLevelInfo(context, type, 0, 1,
GetLevelInfo(internalformat, texStorageFormat.internalFormat)); GetLevelInfo(features, internalformat, texStorageFormat.internalFormat));
return angle::Result::Continue; return angle::Result::Continue;
} }
@ -1191,7 +1203,7 @@ angle::Result TextureGL::setStorageExternalMemory(const gl::Context *context,
} }
setLevelInfo(context, type, 0, levels, setLevelInfo(context, type, 0, levels,
GetLevelInfo(internalFormat, texStorageFormat.internalFormat)); GetLevelInfo(features, internalFormat, texStorageFormat.internalFormat));
return angle::Result::Continue; return angle::Result::Continue;
} }
@ -1263,13 +1275,16 @@ angle::Result TextureGL::setEGLImageTarget(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
egl::Image *image) egl::Image *image)
{ {
const angle::FeaturesGL &features = GetFeaturesGL(context);
ImageGL *imageGL = GetImplAs<ImageGL>(image); ImageGL *imageGL = GetImplAs<ImageGL>(image);
GLenum imageNativeInternalFormat = GL_NONE; GLenum imageNativeInternalFormat = GL_NONE;
ANGLE_TRY(imageGL->setTexture2D(context, type, this, &imageNativeInternalFormat)); ANGLE_TRY(imageGL->setTexture2D(context, type, this, &imageNativeInternalFormat));
setLevelInfo(context, type, 0, 1, setLevelInfo(
GetLevelInfo(image->getFormat().info->internalFormat, imageNativeInternalFormat)); context, type, 0, 1,
GetLevelInfo(features, image->getFormat().info->internalFormat, imageNativeInternalFormat));
return angle::Result::Continue; return angle::Result::Continue;
} }
@ -1707,7 +1722,8 @@ void TextureGL::setLevelInfo(const gl::Context *context,
{ {
ASSERT(levelCount > 0); 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++) 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.depthStencilWorkaround;
updateWorkarounds |= curLevelInfo.lumaWorkaround.enabled; updateWorkarounds |= curLevelInfo.lumaWorkaround.enabled;
updateWorkarounds |= curLevelInfo.emulatedAlphaChannel;
curLevelInfo = levelInfo; curLevelInfo = levelInfo;
} }

Просмотреть файл

@ -1556,6 +1556,8 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
features->resettingTexturesGeneratesErrors.enabled = features->resettingTexturesGeneratesErrors.enabled =
IsApple() || (IsWindows() && IsAMD(device)); IsApple() || (IsWindows() && IsAMD(device));
features->rgbDXT1TexturesSampleZeroAlpha.enabled = IsApple();
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)

Просмотреть файл

@ -608,6 +608,9 @@
} }
}, },
"GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": {
"BC3_RGBA_UNORM_BLOCK": {
"GL_UNSIGNED_BYTE": "LoadRGBDXT1ToRGBADXT3"
},
"NONE": { "NONE": {
"GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>" "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>"
} }
@ -842,6 +845,9 @@
} }
}, },
"GL_COMPRESSED_SRGB_S3TC_DXT1_EXT": { "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT": {
"BC3_RGBA_UNORM_SRGB_BLOCK": {
"GL_UNSIGNED_BYTE": "LoadRGBDXT1ToRGBADXT3"
},
"NONE": { "NONE": {
"GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>" "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>"
} }

Просмотреть файл

@ -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) LoadImageFunctionInfo COMPRESSED_RGB_S3TC_DXT1_EXT_to_default(GLenum type)
{ {
switch (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) LoadImageFunctionInfo COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default(GLenum type)
{ {
switch (type) switch (type)
@ -3246,7 +3270,15 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat)
case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
return COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_to_default; return COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_to_default;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 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: case GL_COMPRESSED_SIGNED_R11_EAC:
{ {
switch (angleFormat) switch (angleFormat)
@ -3395,7 +3427,15 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat)
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
return COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default; return COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default;
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: 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: case GL_DEPTH24_STENCIL8:
{ {
switch (angleFormat) switch (angleFormat)

Просмотреть файл

@ -110,6 +110,44 @@ TEST_P(DXT1CompressedTextureTest, CompressedTexImage)
EXPECT_GL_NO_ERROR(); 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) TEST_P(DXT1CompressedTextureTest, CompressedTexStorage)
{ {
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1")); ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));