mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 08:57:26 +00:00
OpenGL: Support B2T and T2T copies with BC formats
This patch implements the creation, buffer-to-texture copies and texture-to-texture copies with BC formats on OpenGL backend. Note that OpenGL SPEC also has the same issue about texture-to-texture copies with compressed textures as Vulkan SPEC, so we have to skip the related case. The texture-to-buffer copies with BC formats and related end2end tests will be supported in the following patches. BUG=dawn:42 TEST=dawn_end2end_tests Change-Id: I76b16862259cb2df77f202ed7ed433d41aa3cd47 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10220 Commit-Queue: Jiawei Shao <jiawei.shao@intel.com> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
23edf95528
commit
9d9d76c590
@@ -169,6 +169,8 @@ namespace dawn_native { namespace opengl {
|
||||
const char* vendor = reinterpret_cast<const char*>(mFunctions.GetString(GL_VENDOR));
|
||||
mPCIInfo.vendorId = GetVendorIdFromVendors(vendor);
|
||||
|
||||
InitializeSupportedExtensions();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -182,6 +184,43 @@ namespace dawn_native { namespace opengl {
|
||||
// all share the same backing OpenGL context.
|
||||
return {new Device(this, descriptor, mFunctions)};
|
||||
}
|
||||
|
||||
void InitializeSupportedExtensions() {
|
||||
// TextureCompressionBC
|
||||
{
|
||||
// BC1, BC2 and BC3 are not supported in OpenGL or OpenGL ES core features.
|
||||
bool supportsS3TC =
|
||||
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc");
|
||||
|
||||
// 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
|
||||
// GL_EXT_texture_compression_s3tc on desktop OpenGL drivers.
|
||||
// (https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_texture_sRGB.txt)
|
||||
bool supportsTextureSRGB = mFunctions.IsGLExtensionSupported("GL_EXT_texture_sRGB");
|
||||
|
||||
// GL_EXT_texture_compression_s3tc_srgb is an extension in OpenGL ES.
|
||||
bool supportsS3TCSRGB =
|
||||
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_s3tc_srgb");
|
||||
|
||||
// BC4 and BC5
|
||||
bool supportsRGTC =
|
||||
mFunctions.IsAtLeastGL(3, 0) ||
|
||||
mFunctions.IsGLExtensionSupported("GL_ARB_texture_compression_rgtc") ||
|
||||
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_rgtc");
|
||||
|
||||
// BC6 and BC7
|
||||
bool supportsBPTC =
|
||||
mFunctions.IsAtLeastGL(4, 2) ||
|
||||
mFunctions.IsGLExtensionSupported("GL_ARB_texture_compression_bptc") ||
|
||||
mFunctions.IsGLExtensionSupported("GL_EXT_texture_compression_bptc");
|
||||
|
||||
if (supportsS3TC && (supportsTextureSRGB || supportsS3TCSRGB) && supportsRGTC &&
|
||||
supportsBPTC) {
|
||||
mSupportedExtensions.EnableExtension(
|
||||
dawn_native::Extension::TextureCompressionBC);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation of the OpenGL backend's BackendConnection
|
||||
|
||||
@@ -352,6 +352,28 @@ namespace dawn_native { namespace opengl {
|
||||
gl.DeleteFramebuffers(1, &readFbo);
|
||||
gl.DeleteFramebuffers(1, &writeFbo);
|
||||
}
|
||||
|
||||
// OpenGL SPEC requires the source/destination region must be a region that is contained
|
||||
// within srcImage/dstImage. Here the size of the image refers to the virtual size, while
|
||||
// Dawn validates texture copy extent with the physical size, so we need to re-calculate the
|
||||
// texture copy extent to ensure it should fit in the virtual size of the subresource.
|
||||
Extent3D ComputeTextureCopyExtent(const TextureCopy& textureCopy,
|
||||
const Extent3D& copySize) {
|
||||
Extent3D validTextureCopyExtent = copySize;
|
||||
const TextureBase* texture = textureCopy.texture.Get();
|
||||
Extent3D virtualSizeAtLevel = texture->GetMipLevelVirtualSize(textureCopy.mipLevel);
|
||||
if (textureCopy.origin.x + copySize.width > virtualSizeAtLevel.width) {
|
||||
ASSERT(texture->GetFormat().isCompressed);
|
||||
validTextureCopyExtent.width = virtualSizeAtLevel.width - textureCopy.origin.x;
|
||||
}
|
||||
if (textureCopy.origin.y + copySize.height > virtualSizeAtLevel.height) {
|
||||
ASSERT(texture->GetFormat().isCompressed);
|
||||
validTextureCopyExtent.height = virtualSizeAtLevel.height - textureCopy.origin.y;
|
||||
}
|
||||
|
||||
return validTextureCopyExtent;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CommandBuffer::CommandBuffer(CommandEncoderBase* encoder,
|
||||
@@ -436,28 +458,60 @@ namespace dawn_native { namespace opengl {
|
||||
gl.ActiveTexture(GL_TEXTURE0);
|
||||
gl.BindTexture(target, texture->GetHandle());
|
||||
|
||||
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||
src.rowPitch / texture->GetFormat().blockByteSize);
|
||||
const Format& formatInfo = texture->GetFormat();
|
||||
gl.PixelStorei(
|
||||
GL_UNPACK_ROW_LENGTH,
|
||||
src.rowPitch / texture->GetFormat().blockByteSize * formatInfo.blockWidth);
|
||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.imageHeight);
|
||||
switch (texture->GetDimension()) {
|
||||
case dawn::TextureDimension::e2D:
|
||||
if (texture->GetArrayLayers() > 1) {
|
||||
gl.TexSubImage3D(
|
||||
target, dst.mipLevel, dst.origin.x, dst.origin.y,
|
||||
dst.arrayLayer, copySize.width, copySize.height, 1,
|
||||
format.format, format.type,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||
} else {
|
||||
gl.TexSubImage2D(
|
||||
target, dst.mipLevel, dst.origin.x, dst.origin.y,
|
||||
copySize.width, copySize.height, format.format, format.type,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
if (texture->GetFormat().isCompressed) {
|
||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, formatInfo.blockByteSize);
|
||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, formatInfo.blockWidth);
|
||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, formatInfo.blockHeight);
|
||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1);
|
||||
|
||||
ASSERT(texture->GetDimension() == dawn::TextureDimension::e2D);
|
||||
uint64_t copyDataSize =
|
||||
(copySize.width / texture->GetFormat().blockWidth) *
|
||||
(copySize.height / texture->GetFormat().blockHeight) *
|
||||
texture->GetFormat().blockByteSize;
|
||||
Extent3D copyExtent = ComputeTextureCopyExtent(dst, copySize);
|
||||
|
||||
if (texture->GetArrayLayers() > 1) {
|
||||
gl.CompressedTexSubImage3D(
|
||||
target, dst.mipLevel, dst.origin.x, dst.origin.y, dst.arrayLayer,
|
||||
copyExtent.width, copyExtent.height, 1, format.internalFormat,
|
||||
copyDataSize,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||
} else {
|
||||
gl.CompressedTexSubImage2D(
|
||||
target, dst.mipLevel, dst.origin.x, dst.origin.y, copyExtent.width,
|
||||
copyExtent.height, format.internalFormat, copyDataSize,
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||
}
|
||||
} else {
|
||||
switch (texture->GetDimension()) {
|
||||
case dawn::TextureDimension::e2D:
|
||||
if (texture->GetArrayLayers() > 1) {
|
||||
gl.TexSubImage3D(target, dst.mipLevel, dst.origin.x,
|
||||
dst.origin.y, dst.arrayLayer, copySize.width,
|
||||
copySize.height, 1, format.format, format.type,
|
||||
reinterpret_cast<void*>(
|
||||
static_cast<uintptr_t>(src.offset)));
|
||||
} else {
|
||||
gl.TexSubImage2D(target, dst.mipLevel, dst.origin.x,
|
||||
dst.origin.y, copySize.width, copySize.height,
|
||||
format.format, format.type,
|
||||
reinterpret_cast<void*>(
|
||||
static_cast<uintptr_t>(src.offset)));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
|
||||
|
||||
@@ -474,6 +528,12 @@ namespace dawn_native { namespace opengl {
|
||||
const GLFormat& format = texture->GetGLFormat();
|
||||
GLenum target = texture->GetGLTarget();
|
||||
|
||||
// TODO(jiawei.shao@intel.com): support texture-to-buffer copy with compressed
|
||||
// texture formats.
|
||||
if (texture->GetFormat().isCompressed) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
texture->EnsureSubresourceContentInitialized(src.mipLevel, 1, src.arrayLayer,
|
||||
1);
|
||||
// The only way to move data from a texture to a buffer in GL is via
|
||||
@@ -520,7 +580,12 @@ namespace dawn_native { namespace opengl {
|
||||
mCommands.NextCommand<CopyTextureToTextureCmd>();
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
auto& copySize = copy->copySize;
|
||||
|
||||
// TODO(jiawei.shao@intel.com): add workaround for the case that imageExtentSrc
|
||||
// is not equal to imageExtentDst. For example when copySize fits in the virtual
|
||||
// size of the source image but does not fit in the one of the destination
|
||||
// image.
|
||||
Extent3D copySize = ComputeTextureCopyExtent(dst, copy->copySize);
|
||||
Texture* srcTexture = ToBackend(src.texture.Get());
|
||||
Texture* dstTexture = ToBackend(dst.texture.Get());
|
||||
srcTexture->EnsureSubresourceContentInitialized(src.mipLevel, 1, src.arrayLayer,
|
||||
|
||||
@@ -94,6 +94,22 @@ namespace dawn_native { namespace opengl {
|
||||
AddFormat(dawn::TextureFormat::Depth24Plus, GL_DEPTH_COMPONENT32F, GL_DEPTH, GL_FLOAT, Type::DepthStencil);
|
||||
AddFormat(dawn::TextureFormat::Depth24PlusStencil8, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, Type::DepthStencil);
|
||||
|
||||
// Block compressed formats
|
||||
AddFormat(dawn::TextureFormat::BC1RGBAUnorm, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC1RGBAUnormSrgb, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC2RGBAUnorm, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC2RGBAUnormSrgb, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC3RGBAUnorm, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC3RGBAUnormSrgb, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC4RSnorm, GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC4RUnorm, GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC5RGSnorm, GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC5RGUnorm, GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC6HRGBSfloat, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_HALF_FLOAT, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC6HRGBUfloat, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_HALF_FLOAT, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC7RGBAUnorm, GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
AddFormat(dawn::TextureFormat::BC7RGBAUnormSrgb, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, Type::Float);
|
||||
|
||||
// clang-format on
|
||||
|
||||
return table;
|
||||
|
||||
@@ -54,9 +54,26 @@ namespace dawn_native { namespace opengl {
|
||||
DAWN_TRY(LoadDesktopGLProcs(getProc, mMajorVersion, mMinorVersion));
|
||||
}
|
||||
|
||||
InitializeSupportedGLExtensions();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void OpenGLFunctions::InitializeSupportedGLExtensions() {
|
||||
int32_t numExtensions;
|
||||
GetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
|
||||
|
||||
for (int32_t i = 0; i < numExtensions; ++i) {
|
||||
const char* extensionName = reinterpret_cast<const char*>(GetStringi(GL_EXTENSIONS, i));
|
||||
mSupportedGLExtensionsSet.insert(extensionName);
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenGLFunctions::IsGLExtensionSupported(const char* extension) const {
|
||||
ASSERT(extension != nullptr);
|
||||
return mSupportedGLExtensionsSet.count(extension) != 0;
|
||||
}
|
||||
|
||||
bool OpenGLFunctions::IsAtLeastGL(uint32_t majorVersion, uint32_t minorVersion) {
|
||||
return mStandard == Standard::Desktop &&
|
||||
std::tie(mMajorVersion, mMinorVersion) >= std::tie(majorVersion, minorVersion);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef DAWNNATIVE_OPENGL_OPENGLFUNCTIONS_H_
|
||||
#define DAWNNATIVE_OPENGL_OPENGLFUNCTIONS_H_
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include "dawn_native/opengl/OpenGLFunctionsBase_autogen.h"
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
@@ -26,7 +28,11 @@ namespace dawn_native { namespace opengl {
|
||||
bool IsAtLeastGL(uint32_t majorVersion, uint32_t minorVersion);
|
||||
bool IsAtLeastGLES(uint32_t majorVersion, uint32_t minorVersion);
|
||||
|
||||
bool IsGLExtensionSupported(const char* extension) const;
|
||||
|
||||
private:
|
||||
void InitializeSupportedGLExtensions();
|
||||
|
||||
uint32_t mMajorVersion;
|
||||
uint32_t mMinorVersion;
|
||||
|
||||
@@ -35,6 +41,8 @@ namespace dawn_native { namespace opengl {
|
||||
ES,
|
||||
};
|
||||
Standard mStandard;
|
||||
|
||||
std::unordered_set<std::string> mSupportedGLExtensionsSet;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::opengl
|
||||
|
||||
@@ -187,6 +187,11 @@ namespace dawn_native { namespace opengl {
|
||||
GLint baseArrayLayer,
|
||||
uint32_t layerCount) {
|
||||
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
|
||||
// TODO(jiawei.shao@intel.com): initialize the textures with compressed formats.
|
||||
if (GetFormat().isCompressed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetFormat().HasDepthOrStencil()) {
|
||||
bool doDepthClear = GetFormat().HasDepth();
|
||||
bool doStencilClear = GetFormat().HasStencil();
|
||||
|
||||
22
src/dawn_native/opengl/supported_extensions.json
Normal file
22
src/dawn_native/opengl/supported_extensions.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"_comment": [
|
||||
"Copyright 2019 The Dawn Authors",
|
||||
"",
|
||||
"Licensed under the Apache License, Version 2.0 (the \"License\");",
|
||||
"you may not use this file except in compliance with the License.",
|
||||
"You may obtain a copy of the License at",
|
||||
"",
|
||||
" http://www.apache.org/licenses/LICENSE-2.0",
|
||||
"",
|
||||
"Unless required by applicable law or agreed to in writing, software",
|
||||
"distributed under the License is distributed on an \"AS IS\" BASIS,",
|
||||
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
|
||||
"See the License for the specific language governing permissions and",
|
||||
"limitations under the License."
|
||||
],
|
||||
|
||||
"supported_extensions": [
|
||||
"GL_EXT_texture_compression_s3tc",
|
||||
"GL_EXT_texture_compression_s3tc_srgb"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user