OpenGL ES: implement compressed texture support.
SwANGLE does not support GL_EXT_texture_compression_s3tc. However, it does support GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3 and GL_ANGLE_texture_compression_dxt5, which should be sufficient for Dawn's purposes. Note that sRGB formats may be problematic for OpenGL ES in general, but ANGLE does support them, so we can satisfy the requirements for Dawn's texture_compression_bc and exercise the codepaths on ES. glPixelStorei is not only unsupported for CompressedTexSubImage*D() but causes asserts in ANGLE and validation errors elsewhere. The fix is to scope the glPixelStorei() calls to the non-compressed codepath. Bug: dawn:580 Change-Id: I68fa019eda2aee37a097e697cfc87bcdc28c1f12 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/42120 Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
eea1209b12
commit
7e79207ae9
|
@ -208,7 +208,10 @@ namespace dawn_native { namespace opengl {
|
||||||
{
|
{
|
||||||
// BC1, BC2 and BC3 are not supported in OpenGL or OpenGL ES core features.
|
// BC1, BC2 and BC3 are not supported in OpenGL or OpenGL ES core features.
|
||||||
bool supportsS3TC =
|
bool supportsS3TC =
|
||||||
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc");
|
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc") ||
|
||||||
|
(mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_dxt1") &&
|
||||||
|
mFunctions.IsGLExtensionSupported("GL_ANGLE_texture_compression_dxt3") &&
|
||||||
|
mFunctions.IsGLExtensionSupported("GL_ANGLE_texture_compression_dxt5"));
|
||||||
|
|
||||||
// COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT and
|
// COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT and
|
||||||
// COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT requires both GL_EXT_texture_sRGB and
|
// COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT requires both GL_EXT_texture_sRGB and
|
||||||
|
@ -217,8 +220,14 @@ namespace dawn_native { namespace opengl {
|
||||||
bool supportsTextureSRGB = mFunctions.IsGLExtensionSupported("GL_EXT_texture_sRGB");
|
bool supportsTextureSRGB = mFunctions.IsGLExtensionSupported("GL_EXT_texture_sRGB");
|
||||||
|
|
||||||
// GL_EXT_texture_compression_s3tc_srgb is an extension in OpenGL ES.
|
// GL_EXT_texture_compression_s3tc_srgb is an extension in OpenGL ES.
|
||||||
|
// NVidia GLES drivers don't support this extension, but they do support
|
||||||
|
// GL_NV_sRGB_formats. (Note that GL_EXT_texture_sRGB does not exist on ES.
|
||||||
|
// GL_EXT_sRGB does (core in ES 3.0), but it does not automatically provide S3TC
|
||||||
|
// SRGB support even if S3TC is supported; see
|
||||||
|
// https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_sRGB.txt.)
|
||||||
bool supportsS3TCSRGB =
|
bool supportsS3TCSRGB =
|
||||||
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc_srgb");
|
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc_srgb") ||
|
||||||
|
mFunctions.IsGLExtensionSupported("GL_NV_sRGB_formats");
|
||||||
|
|
||||||
// BC4 and BC5
|
// BC4 and BC5
|
||||||
bool supportsRGTC =
|
bool supportsRGTC =
|
||||||
|
|
|
@ -630,9 +630,6 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
const Format& formatInfo = texture->GetFormat();
|
const Format& formatInfo = texture->GetFormat();
|
||||||
const TexelBlockInfo& blockInfo = formatInfo.GetAspectInfo(dst.aspect).block;
|
const TexelBlockInfo& blockInfo = formatInfo.GetAspectInfo(dst.aspect).block;
|
||||||
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
|
|
||||||
src.bytesPerRow / blockInfo.byteSize * blockInfo.width);
|
|
||||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.rowsPerImage * blockInfo.height);
|
|
||||||
|
|
||||||
if (formatInfo.isCompressed) {
|
if (formatInfo.isCompressed) {
|
||||||
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
|
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
|
||||||
|
@ -691,6 +688,10 @@ namespace dawn_native { namespace opengl {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||||
|
src.bytesPerRow / blockInfo.byteSize * blockInfo.width);
|
||||||
|
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
|
||||||
|
src.rowsPerImage * blockInfo.height);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
|
||||||
|
@ -714,12 +715,17 @@ namespace dawn_native { namespace opengl {
|
||||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, 0);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, 0);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||||
|
src.bytesPerRow / blockInfo.byteSize * blockInfo.width);
|
||||||
|
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.rowsPerImage * blockInfo.height);
|
||||||
switch (texture->GetDimension()) {
|
switch (texture->GetDimension()) {
|
||||||
case wgpu::TextureDimension::e2D:
|
case wgpu::TextureDimension::e2D:
|
||||||
if (texture->GetArrayLayers() > 1) {
|
if (texture->GetArrayLayers() > 1) {
|
||||||
|
@ -742,10 +748,10 @@ namespace dawn_native { namespace opengl {
|
||||||
case wgpu::TextureDimension::e3D:
|
case wgpu::TextureDimension::e3D:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1187,6 +1187,9 @@ TEST_P(CompressedTextureWriteTextureTest, Basic) {
|
||||||
|
|
||||||
// Test writing to multiple 2D texture array layers with BC formats.
|
// Test writing to multiple 2D texture array layers with BC formats.
|
||||||
TEST_P(CompressedTextureWriteTextureTest, WriteMultiple2DArrayLayers) {
|
TEST_P(CompressedTextureWriteTextureTest, WriteMultiple2DArrayLayers) {
|
||||||
|
// TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
|
||||||
|
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||||
|
|
||||||
CopyConfig config;
|
CopyConfig config;
|
||||||
config.textureDescriptor.usage = kDefaultBCFormatTextureUsage;
|
config.textureDescriptor.usage = kDefaultBCFormatTextureUsage;
|
||||||
config.textureDescriptor.size = {20, 24, 9};
|
config.textureDescriptor.size = {20, 24, 9};
|
||||||
|
@ -1206,6 +1209,9 @@ TEST_P(CompressedTextureWriteTextureTest, WriteMultiple2DArrayLayers) {
|
||||||
// subresource is different from its virtual size.
|
// subresource is different from its virtual size.
|
||||||
TEST_P(CompressedTextureWriteTextureTest,
|
TEST_P(CompressedTextureWriteTextureTest,
|
||||||
WriteIntoSubresourceWithPhysicalSizeNotEqualToVirtualSize) {
|
WriteIntoSubresourceWithPhysicalSizeNotEqualToVirtualSize) {
|
||||||
|
// TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
|
||||||
|
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||||
|
|
||||||
// Texture virtual size at mipLevel 2 will be {15, 15, 1} while the physical
|
// Texture virtual size at mipLevel 2 will be {15, 15, 1} while the physical
|
||||||
// size will be {16, 16, 1}.
|
// size will be {16, 16, 1}.
|
||||||
// Setting copyExtent.width or copyExtent.height to 16 fits in
|
// Setting copyExtent.width or copyExtent.height to 16 fits in
|
||||||
|
|
|
@ -1846,7 +1846,7 @@ TEST_P(CompressedTextureZeroInitTest, FullMipCopy) {
|
||||||
// Test that 1 lazy clear count happens when we copy to half the texture
|
// Test that 1 lazy clear count happens when we copy to half the texture
|
||||||
TEST_P(CompressedTextureZeroInitTest, HalfCopyBufferToTexture) {
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyBufferToTexture) {
|
||||||
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
||||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
|
||||||
|
|
||||||
wgpu::TextureDescriptor textureDescriptor;
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
textureDescriptor.usage =
|
textureDescriptor.usage =
|
||||||
|
@ -1865,6 +1865,9 @@ TEST_P(CompressedTextureZeroInitTest, HalfCopyBufferToTexture) {
|
||||||
// Test that 0 lazy clear count happens when we copy buffer to texture to a nonzero mip level
|
// Test that 0 lazy clear count happens when we copy buffer to texture to a nonzero mip level
|
||||||
// (with physical size different from the virtual mip size)
|
// (with physical size different from the virtual mip size)
|
||||||
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroMipLevel) {
|
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroMipLevel) {
|
||||||
|
// TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
|
||||||
|
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||||
|
|
||||||
wgpu::TextureDescriptor textureDescriptor;
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
textureDescriptor.usage =
|
textureDescriptor.usage =
|
||||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
@ -1888,7 +1891,7 @@ TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroMipLevel) {
|
||||||
// (with physical size different from the virtual mip size)
|
// (with physical size different from the virtual mip size)
|
||||||
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroMipLevel) {
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroMipLevel) {
|
||||||
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
||||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
|
||||||
|
|
||||||
wgpu::TextureDescriptor textureDescriptor;
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
textureDescriptor.usage =
|
textureDescriptor.usage =
|
||||||
|
@ -1911,6 +1914,9 @@ TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroMipLevel) {
|
||||||
|
|
||||||
// Test that 0 lazy clear count happens when we copy buffer to nonzero array layer
|
// Test that 0 lazy clear count happens when we copy buffer to nonzero array layer
|
||||||
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroArrayLayer) {
|
TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroArrayLayer) {
|
||||||
|
// TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
|
||||||
|
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||||
|
|
||||||
wgpu::TextureDescriptor textureDescriptor;
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
textureDescriptor.usage =
|
textureDescriptor.usage =
|
||||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled;
|
||||||
|
@ -1929,7 +1935,7 @@ TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroArrayLayer) {
|
||||||
// Test that 1 lazy clear count happens when we copy buffer to half texture to a nonzero array layer
|
// Test that 1 lazy clear count happens when we copy buffer to half texture to a nonzero array layer
|
||||||
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroArrayLayer) {
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroArrayLayer) {
|
||||||
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
||||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
|
||||||
|
|
||||||
wgpu::TextureDescriptor textureDescriptor;
|
wgpu::TextureDescriptor textureDescriptor;
|
||||||
textureDescriptor.usage =
|
textureDescriptor.usage =
|
||||||
|
@ -1948,6 +1954,9 @@ TEST_P(CompressedTextureZeroInitTest, HalfCopyToNonZeroArrayLayer) {
|
||||||
|
|
||||||
// full copy texture to texture, 0 lazy clears are needed
|
// full copy texture to texture, 0 lazy clears are needed
|
||||||
TEST_P(CompressedTextureZeroInitTest, FullCopyTextureToTextureMipLevel) {
|
TEST_P(CompressedTextureZeroInitTest, FullCopyTextureToTextureMipLevel) {
|
||||||
|
// TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
|
||||||
|
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
||||||
|
|
||||||
// create srcTexture and fill it with data
|
// create srcTexture and fill it with data
|
||||||
wgpu::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
|
wgpu::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
|
||||||
3, 1,
|
3, 1,
|
||||||
|
@ -1993,7 +2002,7 @@ TEST_P(CompressedTextureZeroInitTest, FullCopyTextureToTextureMipLevel) {
|
||||||
// half copy texture to texture, lazy clears are needed for noncopied half
|
// half copy texture to texture, lazy clears are needed for noncopied half
|
||||||
TEST_P(CompressedTextureZeroInitTest, HalfCopyTextureToTextureMipLevel) {
|
TEST_P(CompressedTextureZeroInitTest, HalfCopyTextureToTextureMipLevel) {
|
||||||
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
// TODO(crbug.com/dawn/643): diagnose and fix this failure on OpenGL.
|
||||||
DAWN_SKIP_TEST_IF(IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
|
||||||
|
|
||||||
// create srcTexture with data
|
// create srcTexture with data
|
||||||
wgpu::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
|
wgpu::TextureDescriptor srcDescriptor = CreateTextureDescriptor(
|
||||||
|
|
Loading…
Reference in New Issue