mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 13:00:32 +00:00
Handle initialising texture levels that might not be ready
* This could happen with a missed call to glGenerateMipmap
This commit is contained in:
@@ -1108,6 +1108,82 @@ bool GLResourceManager::Serialise_InitialState(GLResource res)
|
||||
SERIALISE_ELEMENT(int, mips, 0);
|
||||
SERIALISE_ELEMENT(bool, isCompressed, false);
|
||||
|
||||
// if number of mips isn't sufficient, make sure to initialise
|
||||
// the lower levels - this could happen if e.g. a texture is
|
||||
// init'd with glTexImage(level = 0), then after we stop tracking
|
||||
// it glGenerateMipmap is called
|
||||
{
|
||||
GLuint live = GetLiveResource(Id).name;
|
||||
|
||||
GLsizei w = (GLsizei)width;
|
||||
GLsizei h = (GLsizei)height;
|
||||
GLsizei d = (GLsizei)depth;
|
||||
|
||||
int liveMips = GetNumMips(gl, textype, live, width, height, depth);
|
||||
|
||||
GLenum targets[] = {
|
||||
eGL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
eGL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
eGL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
eGL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
|
||||
};
|
||||
|
||||
int count = ARRAY_COUNT(targets);
|
||||
|
||||
if(textype != eGL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
targets[0] = textype;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
for(int m = 1; m < mips; m++)
|
||||
{
|
||||
w = RDCMAX(1, w >> 1);
|
||||
h = RDCMAX(1, h >> 1);
|
||||
d = RDCMAX(1, d >> 1);
|
||||
|
||||
if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY ||
|
||||
textype == eGL_TEXTURE_1D_ARRAY ||
|
||||
textype == eGL_TEXTURE_2D_ARRAY)
|
||||
d = (GLsizei)depth;
|
||||
|
||||
if(m >= liveMips)
|
||||
{
|
||||
for(int t=0; t < count; t++)
|
||||
{
|
||||
if(isCompressed)
|
||||
{
|
||||
GLsizei compSize = (GLsizei)GetCompressedByteSize(w, h, d, internalformat, m);
|
||||
|
||||
vector<byte> dummy;
|
||||
dummy.resize(compSize);
|
||||
|
||||
if(dim == 1)
|
||||
gl.glCompressedTextureImage1DEXT(live, targets[t], m, internalformat, w, 0, compSize, &dummy[0]);
|
||||
else if(dim == 2)
|
||||
gl.glCompressedTextureImage2DEXT(live, targets[t], m, internalformat, w, h, 0, compSize, &dummy[0]);
|
||||
else if(dim == 3)
|
||||
gl.glCompressedTextureImage3DEXT(live, targets[t], m, internalformat, w, h, d, 0, compSize, &dummy[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dim == 1)
|
||||
gl.glTextureImage1DEXT(live, targets[t], m, internalformat, (GLsizei)w, 0,
|
||||
GetBaseFormat(internalformat), GetDataType(internalformat), NULL);
|
||||
else if(dim == 2)
|
||||
gl.glTextureImage2DEXT(live, targets[t], m, internalformat, (GLsizei)w, (GLsizei)h, 0,
|
||||
GetBaseFormat(internalformat), GetDataType(internalformat), NULL);
|
||||
else if(dim == 3)
|
||||
gl.glTextureImage3DEXT(live, targets[t], m, internalformat, (GLsizei)w, (GLsizei)h, (GLsizei)d, 0,
|
||||
GetBaseFormat(internalformat), GetDataType(internalformat), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLuint tex = 0;
|
||||
|
||||
if(textype != eGL_TEXTURE_BUFFER)
|
||||
|
||||
@@ -25,6 +25,70 @@
|
||||
#include "gl_hookset.h"
|
||||
#include "gl_resources.h"
|
||||
|
||||
size_t GetCompressedByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum internalformat, int mip)
|
||||
{
|
||||
if(!IsCompressedFormat(internalformat))
|
||||
{
|
||||
RDCERR("Not compressed format");
|
||||
return GetByteSize(w, h, d, GetBaseFormat(internalformat), GetDataType(internalformat));
|
||||
}
|
||||
|
||||
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:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d) / 2;
|
||||
// BC2
|
||||
case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d);
|
||||
// BC3
|
||||
case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d);
|
||||
// BC4
|
||||
case eGL_COMPRESSED_RED_RGTC1:
|
||||
case eGL_COMPRESSED_SIGNED_RED_RGTC1:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d) / 2;
|
||||
// BC5
|
||||
case eGL_COMPRESSED_RG_RGTC2:
|
||||
case eGL_COMPRESSED_SIGNED_RG_RGTC2:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d);
|
||||
// BC6
|
||||
case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
|
||||
case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d);
|
||||
// BC7
|
||||
case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
|
||||
case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d);
|
||||
// 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:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d) / 2;
|
||||
// EAC
|
||||
case eGL_COMPRESSED_RGBA8_ETC2_EAC:
|
||||
case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d);
|
||||
case eGL_COMPRESSED_R11_EAC:
|
||||
case eGL_COMPRESSED_SIGNED_R11_EAC:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d) / 2;
|
||||
case eGL_COMPRESSED_RG11_EAC:
|
||||
case eGL_COMPRESSED_SIGNED_RG11_EAC:
|
||||
return (AlignUp4(w) * AlignUp4(h) * d);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RDCERR("Unrecognised compressed format");
|
||||
return GetByteSize(w, h, d, GetBaseFormat(internalformat), GetDataType(internalformat));
|
||||
}
|
||||
|
||||
size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type)
|
||||
{
|
||||
size_t elemSize = 0;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
struct GLHookSet;
|
||||
|
||||
size_t GetCompressedByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum internalformat, int mip);
|
||||
size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type);
|
||||
GLenum GetBaseFormat(GLenum internalFormat);
|
||||
GLenum GetDataType(GLenum internalFormat);
|
||||
|
||||
Reference in New Issue
Block a user