supporting full glCopyImageSubData

This commit is contained in:
Kanglai Qian
2020-12-24 16:31:00 +08:00
committed by Baldur Karlsson
parent c1ecd9d375
commit 47c7b38f93
3 changed files with 241 additions and 13 deletions
+180
View File
@@ -278,6 +278,186 @@ size_t GetCompressedByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum internalfor
return GetByteSize(w, h, d, GetBaseFormat(internalformat), GetDataType(internalformat));
}
rdcpair<uint32_t, uint32_t> GetCompressedBlockSize(GLenum internalformat)
{
if(!IsCompressedFormat(internalformat))
{
RDCERR("Not compressed format %s", ToStr(internalformat).c_str());
return make_rdcpair(1u, 1u);
}
uint32_t astc[2] = {0, 0};
switch(internalformat)
{
// BC1
case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
// BC2
case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
// BC3
case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
// BC4
case eGL_COMPRESSED_RED_RGTC1:
case eGL_COMPRESSED_SIGNED_RED_RGTC1:
// BC5
case eGL_COMPRESSED_RG_RGTC2:
case eGL_COMPRESSED_SIGNED_RG_RGTC2:
// BC6
case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
// BC7
case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
// ETC1
case eGL_ETC1_RGB8_OES:
// ETC2
case eGL_COMPRESSED_RGB8_ETC2:
case eGL_COMPRESSED_SRGB8_ETC2:
case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
// EAC
case eGL_COMPRESSED_RGBA8_ETC2_EAC:
case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
case eGL_COMPRESSED_R11_EAC:
case eGL_COMPRESSED_SIGNED_R11_EAC:
case eGL_COMPRESSED_RG11_EAC:
case eGL_COMPRESSED_SIGNED_RG11_EAC:
return make_rdcpair(4u, 4u);
// ASTC
case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
astc[0] = 4;
astc[1] = 4;
break;
case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
astc[0] = 5;
astc[1] = 4;
break;
case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
astc[0] = 5;
astc[1] = 5;
break;
case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
astc[0] = 6;
astc[1] = 5;
break;
case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
astc[0] = 6;
astc[1] = 6;
break;
case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
astc[0] = 8;
astc[1] = 5;
break;
case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
astc[0] = 8;
astc[1] = 6;
break;
case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
astc[0] = 8;
astc[1] = 8;
break;
case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
astc[0] = 10;
astc[1] = 5;
break;
case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
astc[0] = 10;
astc[1] = 6;
break;
case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
astc[0] = 10;
astc[1] = 8;
break;
case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
astc[0] = 10;
astc[1] = 10;
break;
case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
astc[0] = 12;
astc[1] = 10;
break;
case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
astc[0] = 12;
astc[1] = 12;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
astc[0] = 4;
astc[1] = 4;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
astc[0] = 5;
astc[1] = 4;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
astc[0] = 5;
astc[1] = 5;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
astc[0] = 6;
astc[1] = 5;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
astc[0] = 6;
astc[1] = 6;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
astc[0] = 8;
astc[1] = 5;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
astc[0] = 8;
astc[1] = 6;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
astc[0] = 8;
astc[1] = 8;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
astc[0] = 10;
astc[1] = 5;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
astc[0] = 10;
astc[1] = 6;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
astc[0] = 10;
astc[1] = 8;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
astc[0] = 10;
astc[1] = 10;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
astc[0] = 12;
astc[1] = 10;
break;
case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
astc[0] = 12;
astc[1] = 12;
break;
// PVRTC
case eGL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
case eGL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
case eGL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT: return make_rdcpair(4u, 4u);
default: break;
}
if(astc[0] > 0 && astc[1] > 0)
{
return make_rdcpair(astc[0], astc[1]);
}
RDCERR("Unrecognised compressed format %s", ToStr(internalformat).c_str());
return make_rdcpair(1u, 1u);
}
size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type)
{
size_t elemSize = 1;
+1
View File
@@ -29,6 +29,7 @@
#include "gl_common.h"
size_t GetCompressedByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum internalformat);
rdcpair<uint32_t, uint32_t> GetCompressedBlockSize(GLenum internalformat);
size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type);
GLenum GetBaseFormat(GLenum internalFormat);
GLenum GetDataType(GLenum internalFormat);
@@ -1324,7 +1324,7 @@ void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint s
if(dstrecord)
GetResourceManager()->MarkResourceFrameReferenced(dstrecord->GetResourceID(),
eFrameRef_CompleteWrite);
eFrameRef_PartialWrite);
}
SERIALISE_TIME_CALL(GL.glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
@@ -1352,7 +1352,7 @@ void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint s
GetContextRecord()->AddChunk(scope.Get());
GetResourceManager()->MarkDirtyResource(dstrecord->GetResourceID());
GetResourceManager()->MarkResourceFrameReferenced(dstrecord->GetResourceID(),
eFrameRef_CompleteWrite);
eFrameRef_PartialWrite);
GetResourceManager()->MarkResourceFrameReferenced(srcrecord->GetResourceID(), eFrameRef_Read);
}
else if(IsBackgroundCapturing(m_State))
@@ -1372,22 +1372,69 @@ void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint s
{
TextureData &dstData = m_Textures[dstrecord->GetResourceID()];
if(srcX == 0 || srcY == 0 || srcZ == 0 || dstX == 0 || dstY == 0 || dstZ == 0)
GLsizei srcLevelWidth = RDCMAX(1, srcData.width >> srcLevel);
GLsizei srcLevelHeight = (srcData.curType != eGL_TEXTURE_1D_ARRAY)
? RDCMAX(1, srcData.height >> srcLevel)
: srcData.height;
GLsizei srcLevelDepth = (srcData.curType != eGL_TEXTURE_2D_ARRAY &&
srcData.curType != eGL_TEXTURE_CUBE_MAP_ARRAY)
? RDCMAX(1, srcData.depth >> srcLevel)
: srcData.depth;
GLsizei dstLevelWidth = RDCMAX(1, dstData.width >> dstLevel);
GLsizei dstLevelHeight = (dstData.curType != eGL_TEXTURE_1D_ARRAY)
? RDCMAX(1, dstData.height >> dstLevel)
: dstData.height;
GLsizei dstLevelDepth = (dstData.curType != eGL_TEXTURE_2D_ARRAY &&
dstData.curType != eGL_TEXTURE_CUBE_MAP_ARRAY)
? RDCMAX(1, dstData.depth >> dstLevel)
: dstData.depth;
if(srcX == 0 && srcY == 0 && srcZ == 0 && dstX == 0 && dstY == 0 && dstZ == 0 &&
srcLevelWidth == dstLevelWidth && srcLevelHeight == dstLevelHeight &&
srcLevelDepth == dstLevelDepth)
{
// we only support whole copies - sub-copies will not work correctly.
RDCASSERT(srcWidth == RDCMAX(1, srcData.width >> srcLevel));
RDCASSERT(srcHeight == RDCMAX(1, srcData.height >> srcLevel));
RDCASSERT(srcDepth == RDCMAX(1, srcData.depth >> srcLevel));
RDCASSERT(srcWidth == RDCMAX(1, dstData.width >> dstLevel));
RDCASSERT(srcHeight == RDCMAX(1, dstData.height >> dstLevel));
RDCASSERT(srcDepth == RDCMAX(1, dstData.depth >> dstLevel));
dstData.compressedData[dstLevel] = srcData.compressedData[srcLevel];
}
else
{
RDCWARN("glCopyImageSubData doesn't support offsetted copies of compressed data");
size_t srcSliceSize =
GetCompressedByteSize(srcLevelWidth, srcLevelHeight, 1, srcData.internalFormat);
size_t dstSliceSize =
GetCompressedByteSize(dstLevelWidth, dstLevelHeight, 1, dstData.internalFormat);
rdcpair<uint32_t, uint32_t> srcBlockSize = GetCompressedBlockSize(srcData.internalFormat);
rdcpair<uint32_t, uint32_t> dstBlockSize = GetCompressedBlockSize(dstData.internalFormat);
RDCASSERT(srcWidth % srcBlockSize.first == 0);
RDCASSERT(srcWidth % dstBlockSize.first == 0);
RDCASSERT(srcHeight % srcBlockSize.second == 0);
RDCASSERT(srcHeight % dstBlockSize.second == 0);
for(size_t z = 0; z < (size_t)srcDepth; z++)
{
size_t srcLineSize = GetCompressedByteSize(srcLevelWidth, (GLsizei)srcBlockSize.second,
1, srcData.internalFormat);
size_t dstLineSize = GetCompressedByteSize(dstLevelWidth, (GLsizei)dstBlockSize.second,
1, dstData.internalFormat);
size_t srcOffset =
srcSliceSize * (srcZ + z) + srcLineSize * (srcY / (GLsizei)srcBlockSize.second);
srcOffset +=
GetCompressedByteSize(srcX, (GLsizei)srcBlockSize.second, 1, srcData.internalFormat);
size_t dstOffset =
dstSliceSize * (dstZ + z) + dstLineSize * (dstY / (GLsizei)dstBlockSize.second);
dstOffset +=
GetCompressedByteSize(dstX, (GLsizei)dstBlockSize.second, 1, dstData.internalFormat);
size_t blockSize = GetCompressedByteSize(srcWidth, (GLsizei)dstBlockSize.second, 1,
srcData.internalFormat);
bytebuf &srcCd = srcData.compressedData[srcLevel];
bytebuf &dstCd = dstData.compressedData[dstLevel];
for(size_t y = 0; y < (size_t)srcHeight; y += srcBlockSize.second)
{
if(dstCd.size() < dstOffset + blockSize || srcCd.size() < srcOffset + blockSize)
break;
memcpy(dstCd.data() + dstOffset, srcCd.data() + srcOffset, blockSize);
srcOffset += srcLineSize;
dstOffset += dstLineSize;
}
}
}
}
}