mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Support creating typeless proxy textures in GL. Closes #1516
* Since GL requires a concrete texture format, we create the textures as UINT format, and then cast to the right view on display once we know. * The cast requires a copy - ARB_texture_view isn't always supported and even when they are they require immutable textures (ARB_texture_storage) which we don't want to require either.
This commit is contained in:
@@ -2245,7 +2245,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_RGBA32F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RGBA32I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RGBA32UI;
|
||||
else
|
||||
RDCERR("Unrecognised component type");
|
||||
@@ -2256,7 +2256,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_RGBA16F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RGBA16I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RGBA16UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_RGBA16_SNORM;
|
||||
@@ -2269,7 +2269,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
{
|
||||
if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RGBA8I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RGBA8UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_RGBA8_SNORM;
|
||||
@@ -2295,7 +2295,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_RGB32F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RGB32I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RGB32UI;
|
||||
else
|
||||
RDCERR("Unrecognised component type");
|
||||
@@ -2306,7 +2306,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_RGB16F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RGB16I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RGB16UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_RGB16_SNORM;
|
||||
@@ -2319,7 +2319,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
{
|
||||
if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RGB8I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RGB8UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_RGB8_SNORM;
|
||||
@@ -2345,7 +2345,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_RG32F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RG32I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RG32UI;
|
||||
else
|
||||
RDCERR("Unrecognised component type");
|
||||
@@ -2356,7 +2356,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_RG16F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RG16I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RG16UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_RG16_SNORM;
|
||||
@@ -2369,7 +2369,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
{
|
||||
if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_RG8I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_RG8UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_RG8_SNORM;
|
||||
@@ -2395,7 +2395,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_R32F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_R32I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_R32UI;
|
||||
else if(fmt.compType == CompType::Depth)
|
||||
ret = eGL_DEPTH_COMPONENT32F;
|
||||
@@ -2412,7 +2412,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
ret = eGL_R16F;
|
||||
else if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_R16I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_R16UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_R16_SNORM;
|
||||
@@ -2427,7 +2427,7 @@ GLenum MakeGLFormat(ResourceFormat fmt)
|
||||
{
|
||||
if(fmt.compType == CompType::SInt)
|
||||
ret = eGL_R8I;
|
||||
else if(fmt.compType == CompType::UInt)
|
||||
else if(fmt.compType == CompType::UInt || fmt.compType == CompType::Typeless)
|
||||
ret = eGL_R8UI;
|
||||
else if(fmt.compType == CompType::SNorm)
|
||||
ret = eGL_R8_SNORM;
|
||||
|
||||
@@ -2715,6 +2715,140 @@ void WrappedOpenGL::QueueResourceRelease(GLResource res)
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedOpenGL::CreateTextureImage(GLuint tex, GLenum internalFormat, GLenum internalFormatHint,
|
||||
GLenum textype, GLint dim, GLint width, GLint height,
|
||||
GLint depth, GLint samples, int mips)
|
||||
{
|
||||
if(textype == eGL_TEXTURE_BUFFER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint ppb = 0, pub = 0;
|
||||
|
||||
GL.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&ppb);
|
||||
GL.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&pub);
|
||||
|
||||
GL.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0);
|
||||
GL.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
if(textype == eGL_TEXTURE_2D_MULTISAMPLE)
|
||||
{
|
||||
GL.glTextureStorage2DMultisampleEXT(tex, textype, samples, internalFormat, width, height,
|
||||
GL_TRUE);
|
||||
}
|
||||
else if(textype == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
GL.glTextureStorage3DMultisampleEXT(tex, textype, samples, internalFormat, width, height, depth,
|
||||
GL_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_MAX_LEVEL, mips - 1);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
|
||||
|
||||
bool isCompressed = IsCompressedFormat(internalFormat);
|
||||
|
||||
GLenum baseFormat = eGL_RGBA;
|
||||
GLenum dataType = internalFormatHint != eGL_NONE ? internalFormatHint : eGL_UNSIGNED_BYTE;
|
||||
if(!isCompressed)
|
||||
{
|
||||
baseFormat = GetBaseFormat(internalFormat);
|
||||
|
||||
if(internalFormatHint == eGL_NONE)
|
||||
dataType = GetDataType(internalFormat);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
GLsizei w = (GLsizei)width;
|
||||
GLsizei h = (GLsizei)height;
|
||||
GLsizei d = (GLsizei)depth;
|
||||
|
||||
for(int m = 0; m < mips; m++)
|
||||
{
|
||||
for(int t = 0; t < count; t++)
|
||||
{
|
||||
if(isCompressed)
|
||||
{
|
||||
GLsizei compSize = (GLsizei)GetCompressedByteSize(w, h, d, internalFormat);
|
||||
|
||||
std::vector<byte> dummy;
|
||||
dummy.resize(compSize);
|
||||
|
||||
if(dim == 1)
|
||||
GL.glCompressedTextureImage1DEXT(tex, targets[t], m, internalFormat, w, 0, compSize,
|
||||
&dummy[0]);
|
||||
else if(dim == 2)
|
||||
GL.glCompressedTextureImage2DEXT(tex, targets[t], m, internalFormat, w, h, 0, compSize,
|
||||
&dummy[0]);
|
||||
else if(dim == 3)
|
||||
GL.glCompressedTextureImage3DEXT(tex, targets[t], m, internalFormat, w, h, d, 0,
|
||||
compSize, &dummy[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dim == 1)
|
||||
GL.glTextureImage1DEXT(tex, targets[t], m, internalFormat, w, 0, baseFormat, dataType,
|
||||
NULL);
|
||||
else if(dim == 2)
|
||||
GL.glTextureImage2DEXT(tex, targets[t], m, internalFormat, w, h, 0, baseFormat,
|
||||
dataType, NULL);
|
||||
else if(dim == 3)
|
||||
GL.glTextureImage3DEXT(tex, targets[t], m, internalFormat, w, h, d, 0, baseFormat,
|
||||
dataType, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
w = RDCMAX(1, w >> 1);
|
||||
if(textype != eGL_TEXTURE_1D_ARRAY)
|
||||
h = RDCMAX(1, h >> 1);
|
||||
if(textype != eGL_TEXTURE_2D_ARRAY && textype != eGL_TEXTURE_CUBE_MAP_ARRAY)
|
||||
d = RDCMAX(1, d >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
// register this texture and set up its texture details, so it's available for emulation
|
||||
// readback.
|
||||
GLResource res = TextureRes(GetCtx(), tex);
|
||||
ResourceId id = GetResourceManager()->RegisterResource(res);
|
||||
|
||||
WrappedOpenGL::TextureData &details = m_Textures[id];
|
||||
|
||||
details.resource = res;
|
||||
details.curType = textype;
|
||||
details.dimension = dim;
|
||||
details.emulated = details.view = false;
|
||||
details.width = width;
|
||||
details.height = height;
|
||||
details.depth = depth;
|
||||
details.samples = samples;
|
||||
details.creationFlags = TextureCategory::NoFlags;
|
||||
details.internalFormat = internalFormat;
|
||||
details.mipsValid = (1 << mips) - 1;
|
||||
}
|
||||
|
||||
GL.glBindBuffer(eGL_PIXEL_PACK_BUFFER, ppb);
|
||||
GL.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pub);
|
||||
}
|
||||
|
||||
void WrappedOpenGL::ReleaseResource(GLResource res)
|
||||
{
|
||||
switch(res.Namespace)
|
||||
|
||||
@@ -552,6 +552,10 @@ public:
|
||||
ContextPair &GetCtx();
|
||||
GLResourceRecord *GetContextRecord();
|
||||
|
||||
void CreateTextureImage(GLuint tex, GLenum internalFormat, GLenum internalFormatHint,
|
||||
GLenum textype, GLint dim, GLint width, GLint height, GLint depth,
|
||||
GLint samples, int mips);
|
||||
|
||||
void PushInternalShader() { m_InternalShader++; }
|
||||
void PopInternalShader() { m_InternalShader--; }
|
||||
bool IsInternalShader() { return m_InternalShader > 0; }
|
||||
|
||||
@@ -567,141 +567,6 @@ bool GLResourceManager::Prepare_InitialState(GLResource res)
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLResourceManager::CreateTextureImage(GLuint tex, GLenum internalFormat,
|
||||
GLenum internalFormatHint, GLenum textype, GLint dim,
|
||||
GLint width, GLint height, GLint depth, GLint samples,
|
||||
int mips)
|
||||
{
|
||||
if(textype == eGL_TEXTURE_BUFFER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint ppb = 0, pub = 0;
|
||||
|
||||
GL.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&ppb);
|
||||
GL.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&pub);
|
||||
|
||||
GL.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0);
|
||||
GL.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
if(textype == eGL_TEXTURE_2D_MULTISAMPLE)
|
||||
{
|
||||
GL.glTextureStorage2DMultisampleEXT(tex, textype, samples, internalFormat, width, height,
|
||||
GL_TRUE);
|
||||
}
|
||||
else if(textype == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
GL.glTextureStorage3DMultisampleEXT(tex, textype, samples, internalFormat, width, height, depth,
|
||||
GL_TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_MAX_LEVEL, mips - 1);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
|
||||
GL.glTextureParameteriEXT(tex, textype, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
|
||||
|
||||
bool isCompressed = IsCompressedFormat(internalFormat);
|
||||
|
||||
GLenum baseFormat = eGL_RGBA;
|
||||
GLenum dataType = internalFormatHint != eGL_NONE ? internalFormatHint : eGL_UNSIGNED_BYTE;
|
||||
if(!isCompressed)
|
||||
{
|
||||
baseFormat = GetBaseFormat(internalFormat);
|
||||
|
||||
if(internalFormatHint == eGL_NONE)
|
||||
dataType = GetDataType(internalFormat);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
GLsizei w = (GLsizei)width;
|
||||
GLsizei h = (GLsizei)height;
|
||||
GLsizei d = (GLsizei)depth;
|
||||
|
||||
for(int m = 0; m < mips; m++)
|
||||
{
|
||||
for(int t = 0; t < count; t++)
|
||||
{
|
||||
if(isCompressed)
|
||||
{
|
||||
GLsizei compSize = (GLsizei)GetCompressedByteSize(w, h, d, internalFormat);
|
||||
|
||||
std::vector<byte> dummy;
|
||||
dummy.resize(compSize);
|
||||
|
||||
if(dim == 1)
|
||||
GL.glCompressedTextureImage1DEXT(tex, targets[t], m, internalFormat, w, 0, compSize,
|
||||
&dummy[0]);
|
||||
else if(dim == 2)
|
||||
GL.glCompressedTextureImage2DEXT(tex, targets[t], m, internalFormat, w, h, 0, compSize,
|
||||
&dummy[0]);
|
||||
else if(dim == 3)
|
||||
GL.glCompressedTextureImage3DEXT(tex, targets[t], m, internalFormat, w, h, d, 0,
|
||||
compSize, &dummy[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dim == 1)
|
||||
GL.glTextureImage1DEXT(tex, targets[t], m, internalFormat, w, 0, baseFormat, dataType,
|
||||
NULL);
|
||||
else if(dim == 2)
|
||||
GL.glTextureImage2DEXT(tex, targets[t], m, internalFormat, w, h, 0, baseFormat,
|
||||
dataType, NULL);
|
||||
else if(dim == 3)
|
||||
GL.glTextureImage3DEXT(tex, targets[t], m, internalFormat, w, h, d, 0, baseFormat,
|
||||
dataType, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
w = RDCMAX(1, w >> 1);
|
||||
if(textype != eGL_TEXTURE_1D_ARRAY)
|
||||
h = RDCMAX(1, h >> 1);
|
||||
if(textype != eGL_TEXTURE_2D_ARRAY && textype != eGL_TEXTURE_CUBE_MAP_ARRAY)
|
||||
d = RDCMAX(1, d >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
// register this texture and set up its texture details, so it's available for emulation
|
||||
// readback.
|
||||
GLResource res = TextureRes(m_Driver->GetCtx(), tex);
|
||||
ResourceId id = RegisterResource(res);
|
||||
|
||||
WrappedOpenGL::TextureData &details = m_Driver->m_Textures[id];
|
||||
|
||||
details.resource = res;
|
||||
details.curType = textype;
|
||||
details.dimension = dim;
|
||||
details.emulated = details.view = false;
|
||||
details.width = width;
|
||||
details.height = height;
|
||||
details.depth = depth;
|
||||
details.samples = samples;
|
||||
details.creationFlags = TextureCategory::NoFlags;
|
||||
details.internalFormat = internalFormat;
|
||||
details.mipsValid = (1 << mips) - 1;
|
||||
}
|
||||
|
||||
GL.glBindBuffer(eGL_PIXEL_PACK_BUFFER, ppb);
|
||||
GL.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pub);
|
||||
}
|
||||
|
||||
void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, ResourceId origid,
|
||||
GLResource res)
|
||||
{
|
||||
@@ -840,9 +705,9 @@ void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, Resourc
|
||||
mips = 1;
|
||||
|
||||
// create texture of identical format/size to store initial contents
|
||||
CreateTextureImage(tex, details.internalFormat, details.internalFormatHint, details.curType,
|
||||
details.dimension, details.width, details.height, details.depth,
|
||||
details.samples, mips);
|
||||
m_Driver->CreateTextureImage(tex, details.internalFormat, details.internalFormatHint,
|
||||
details.curType, details.dimension, details.width,
|
||||
details.height, details.depth, details.samples, mips);
|
||||
|
||||
// we need to set maxlevel appropriately for number of mips to force the texture to be
|
||||
// complete.
|
||||
@@ -1576,10 +1441,10 @@ bool GLResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceId i
|
||||
GL.glGenTextures(1, &tex);
|
||||
GL.glBindTexture(TextureState.type, tex);
|
||||
|
||||
CreateTextureImage(tex, TextureState.internalformat, details.internalFormatHint,
|
||||
TextureState.type, TextureState.dim, TextureState.width,
|
||||
TextureState.height, TextureState.depth, TextureState.samples,
|
||||
TextureState.mips);
|
||||
m_Driver->CreateTextureImage(tex, TextureState.internalformat, details.internalFormatHint,
|
||||
TextureState.type, TextureState.dim, TextureState.width,
|
||||
TextureState.height, TextureState.depth,
|
||||
TextureState.samples, TextureState.mips);
|
||||
}
|
||||
else if(ser.IsWriting())
|
||||
{
|
||||
|
||||
@@ -285,9 +285,6 @@ private:
|
||||
bool Prepare_InitialState(GLResource res);
|
||||
uint64_t GetSize_InitialState(ResourceId resid, const GLInitialContents &initial);
|
||||
|
||||
void CreateTextureImage(GLuint tex, GLenum internalFormat, GLenum internalFormatHint,
|
||||
GLenum textype, GLint dim, GLint width, GLint height, GLint depth,
|
||||
GLint samples, int mips);
|
||||
void PrepareTextureInitialContents(ResourceId liveid, ResourceId origid, GLResource res);
|
||||
|
||||
void Create_InitialState(ResourceId id, GLResource live, bool hasData);
|
||||
|
||||
@@ -113,11 +113,195 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
|
||||
|
||||
MakeCurrentReplayContext(m_DebugCtx);
|
||||
|
||||
uint32_t numMips = m_CachedTextures[cfg.resourceId].mips;
|
||||
|
||||
GLuint castTexture = 0;
|
||||
|
||||
GLenum displayFormat = texDetails.internalFormat;
|
||||
|
||||
if(cfg.typeCast != CompType::Typeless &&
|
||||
cfg.typeCast != MakeResourceFormat(target, displayFormat).compType)
|
||||
{
|
||||
displayFormat = GetViewCastedFormat(displayFormat, cfg.typeCast);
|
||||
|
||||
// if the format didn't change we can't re-interpret this format anyway
|
||||
if(displayFormat != texDetails.internalFormat)
|
||||
{
|
||||
GLMarkerRegion region("Casting texture for view");
|
||||
|
||||
drv.glGenTextures(1, &castTexture);
|
||||
drv.glActiveTexture(eGL_TEXTURE0);
|
||||
drv.glBindTexture(target, castTexture);
|
||||
|
||||
// can't use texture views because the underlying image isn't immutable because we don't
|
||||
// want to rely on texture storage. We also can't rely on texture views, meaning we need a
|
||||
// fallback path ANYWAY, so might as well always use it. Yayyy opengl...
|
||||
drv.CreateTextureImage(castTexture, displayFormat, eGL_NONE, target, texDetails.dimension,
|
||||
texDetails.width, texDetails.height, texDetails.depth,
|
||||
texDetails.samples, (int)numMips);
|
||||
|
||||
bool isCompressed = IsCompressedFormat(displayFormat);
|
||||
|
||||
GLint values[4] = {};
|
||||
float fvalues[4] = {};
|
||||
|
||||
// ensure source texture is complete
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, values);
|
||||
|
||||
int prevMaxLevel = values[0];
|
||||
|
||||
int maxlevel = numMips - 1;
|
||||
GL.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel);
|
||||
|
||||
// copy state
|
||||
|
||||
if(!texDetails.emulated && (HasExt[ARB_texture_swizzle] || HasExt[EXT_texture_swizzle]))
|
||||
{
|
||||
GetTextureSwizzle(texname, target, (GLenum *)values);
|
||||
SetTextureSwizzle(castTexture, target, (GLenum *)values);
|
||||
}
|
||||
|
||||
if((target == eGL_TEXTURE_CUBE_MAP || target == eGL_TEXTURE_CUBE_MAP_ARRAY) &&
|
||||
HasExt[ARB_seamless_cubemap_per_texture])
|
||||
{
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_CUBE_MAP_SEAMLESS, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_CUBE_MAP_SEAMLESS, values);
|
||||
}
|
||||
|
||||
if(target != eGL_TEXTURE_2D_MULTISAMPLE && target != eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
if(HasExt[EXT_texture_sRGB_decode])
|
||||
{
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_SRGB_DECODE_EXT, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_SRGB_DECODE_EXT, values);
|
||||
}
|
||||
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_COMPARE_FUNC, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_COMPARE_FUNC, values);
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_COMPARE_MODE, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_COMPARE_MODE, values);
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MIN_FILTER, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_MIN_FILTER, values);
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAG_FILTER, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_MAG_FILTER, values);
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_WRAP_R, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_WRAP_R, values);
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_WRAP_S, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_WRAP_S, values);
|
||||
GL.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_WRAP_T, values);
|
||||
GL.glTextureParameterivEXT(castTexture, target, eGL_TEXTURE_WRAP_T, values);
|
||||
|
||||
if(HasExt[ARB_texture_border_clamp])
|
||||
{
|
||||
GL.glGetTextureParameterfvEXT(texname, target, eGL_TEXTURE_BORDER_COLOR, fvalues);
|
||||
GL.glTextureParameterfvEXT(castTexture, target, eGL_TEXTURE_BORDER_COLOR, fvalues);
|
||||
}
|
||||
|
||||
if(!IsGLES)
|
||||
{
|
||||
GL.glGetTextureParameterfvEXT(texname, target, eGL_TEXTURE_LOD_BIAS, fvalues);
|
||||
GL.glTextureParameterfvEXT(castTexture, target, eGL_TEXTURE_LOD_BIAS, fvalues);
|
||||
}
|
||||
|
||||
if(target != eGL_TEXTURE_RECTANGLE)
|
||||
{
|
||||
GL.glGetTextureParameterfvEXT(texname, target, eGL_TEXTURE_MIN_LOD, fvalues);
|
||||
GL.glTextureParameterfvEXT(castTexture, target, eGL_TEXTURE_MIN_LOD, fvalues);
|
||||
GL.glGetTextureParameterfvEXT(texname, target, eGL_TEXTURE_MAX_LOD, fvalues);
|
||||
GL.glTextureParameterfvEXT(castTexture, target, eGL_TEXTURE_MAX_LOD, fvalues);
|
||||
}
|
||||
}
|
||||
|
||||
// copy mip data
|
||||
for(uint32_t i = 0; i < numMips; i++)
|
||||
{
|
||||
int w = RDCMAX(texDetails.width >> i, 1);
|
||||
int h = RDCMAX(texDetails.height >> i, 1);
|
||||
int d = RDCMAX(texDetails.depth >> i, 1);
|
||||
|
||||
if(target == eGL_TEXTURE_CUBE_MAP)
|
||||
d *= 6;
|
||||
else if(target == eGL_TEXTURE_CUBE_MAP_ARRAY || target == eGL_TEXTURE_2D_ARRAY)
|
||||
d = texDetails.depth;
|
||||
|
||||
// glCopyImageSubData treats 1D arrays sanely - with depth as array size - but at odds
|
||||
// with the rest of the API.
|
||||
if(target == eGL_TEXTURE_1D_ARRAY)
|
||||
{
|
||||
h = 1;
|
||||
d = texDetails.height;
|
||||
}
|
||||
|
||||
if((isCompressed && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips] && (w < 4 || h < 4)) ||
|
||||
(isCompressed && VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] &&
|
||||
texDetails.curType == eGL_TEXTURE_CUBE_MAP) ||
|
||||
(isCompressed && IsGLES))
|
||||
{
|
||||
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(target != eGL_TEXTURE_CUBE_MAP)
|
||||
{
|
||||
targets[0] = target;
|
||||
count = 1;
|
||||
}
|
||||
|
||||
for(int trg = 0; trg < count; trg++)
|
||||
{
|
||||
size_t size = GetCompressedByteSize(w, h, d, displayFormat);
|
||||
|
||||
if(target == eGL_TEXTURE_CUBE_MAP)
|
||||
size /= 6;
|
||||
|
||||
byte *buf = new byte[size];
|
||||
|
||||
if(IsGLES)
|
||||
{
|
||||
texDetails.GetCompressedImageDataGLES(i, targets[trg], size, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// read to CPU
|
||||
GL.glGetCompressedTextureImageEXT(texname, targets[trg], i, buf);
|
||||
}
|
||||
|
||||
// write to GPU
|
||||
if(texDetails.dimension == 1)
|
||||
GL.glCompressedTextureSubImage1DEXT(castTexture, targets[trg], i, 0, w, displayFormat,
|
||||
(GLsizei)size, buf);
|
||||
else if(texDetails.dimension == 2)
|
||||
GL.glCompressedTextureSubImage2DEXT(castTexture, targets[trg], i, 0, 0, w, h,
|
||||
displayFormat, (GLsizei)size, buf);
|
||||
else if(texDetails.dimension == 3)
|
||||
GL.glCompressedTextureSubImage3DEXT(castTexture, targets[trg], i, 0, 0, 0, w, h, d,
|
||||
displayFormat, (GLsizei)size, buf);
|
||||
|
||||
delete[] buf;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.glCopyImageSubData(texname, target, i, 0, 0, 0, castTexture, target, i, 0, 0, 0, w, h,
|
||||
d);
|
||||
}
|
||||
}
|
||||
|
||||
GL.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&prevMaxLevel);
|
||||
|
||||
texname = castTexture;
|
||||
}
|
||||
}
|
||||
|
||||
RDCGLenum dsTexMode = eGL_NONE;
|
||||
if(IsDepthStencilFormat(texDetails.internalFormat))
|
||||
if(IsDepthStencilFormat(displayFormat))
|
||||
{
|
||||
// stencil-only, make sure we display it as such
|
||||
if(texDetails.internalFormat == eGL_STENCIL_INDEX8)
|
||||
if(displayFormat == eGL_STENCIL_INDEX8)
|
||||
{
|
||||
cfg.red = false;
|
||||
cfg.green = true;
|
||||
@@ -126,7 +310,7 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
|
||||
}
|
||||
|
||||
// depth-only, make sure we display it as such
|
||||
if(GetBaseFormat(texDetails.internalFormat) == eGL_DEPTH_COMPONENT)
|
||||
if(GetBaseFormat(displayFormat) == eGL_DEPTH_COMPONENT)
|
||||
{
|
||||
cfg.red = true;
|
||||
cfg.green = false;
|
||||
@@ -141,7 +325,7 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
|
||||
// Stencil texture sampling is not normalized in OpenGL
|
||||
intIdx = 1;
|
||||
float rangeScale = 1.0f;
|
||||
switch(texDetails.internalFormat)
|
||||
switch(displayFormat)
|
||||
{
|
||||
case eGL_STENCIL_INDEX1: rangeScale = 1.0f; break;
|
||||
case eGL_STENCIL_INDEX4: rangeScale = 16.0f; break;
|
||||
@@ -162,17 +346,15 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(IsUIntFormat(texDetails.internalFormat))
|
||||
if(IsUIntFormat(displayFormat))
|
||||
intIdx = 1;
|
||||
if(IsSIntFormat(texDetails.internalFormat))
|
||||
if(IsSIntFormat(displayFormat))
|
||||
intIdx = 2;
|
||||
}
|
||||
|
||||
drv.glBindProgramPipeline(0);
|
||||
drv.glUseProgram(DebugData.texDisplayProg[intIdx]);
|
||||
|
||||
uint32_t numMips = m_CachedTextures[cfg.resourceId].mips;
|
||||
|
||||
GLuint customProgram = 0;
|
||||
|
||||
if(cfg.customShaderId != ResourceId() &&
|
||||
@@ -393,7 +575,7 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
|
||||
if(cfg.overlay == DebugOverlay::Clipping)
|
||||
ubo->OutputDisplayFormat |= TEXDISPLAY_CLIPPING;
|
||||
|
||||
if(!IsSRGBFormat(texDetails.internalFormat) && cfg.linearDisplayAsGamma)
|
||||
if(!IsSRGBFormat(displayFormat) && cfg.linearDisplayAsGamma)
|
||||
ubo->OutputDisplayFormat |= TEXDISPLAY_GAMMA_CURVE;
|
||||
|
||||
ubo->RawOutput = cfg.rawOutput ? 1 : 0;
|
||||
@@ -490,5 +672,8 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
|
||||
if(dsTexMode != eGL_NONE && HasExt[ARB_stencil_texturing])
|
||||
drv.glTexParameteri(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, origDSTexMode);
|
||||
|
||||
if(castTexture)
|
||||
drv.glDeleteTextures(1, &castTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1048,6 +1048,267 @@ bool IsSRGBFormat(GLenum internalFormat)
|
||||
return false;
|
||||
}
|
||||
|
||||
GLenum GetViewCastedFormat(GLenum internalFormat, CompType typeCast)
|
||||
{
|
||||
switch(internalFormat)
|
||||
{
|
||||
case eGL_RGBA:
|
||||
case eGL_RGBA8:
|
||||
case eGL_RGBA8_SNORM:
|
||||
case eGL_RGBA8UI:
|
||||
case eGL_RGBA8I:
|
||||
case eGL_SRGB_ALPHA:
|
||||
case eGL_SRGB8_ALPHA8:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::UNorm: internalFormat = eGL_RGBA8; break;
|
||||
case CompType::SNorm: internalFormat = eGL_RGBA8_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_RGBA8UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RGBA8I; break;
|
||||
case CompType::UNormSRGB: internalFormat = eGL_SRGB8_ALPHA8; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RGB:
|
||||
case eGL_RGB8:
|
||||
case eGL_RGB8_SNORM:
|
||||
case eGL_RGB8UI:
|
||||
case eGL_RGB8I:
|
||||
case eGL_SRGB:
|
||||
case eGL_SRGB8:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::UNorm: internalFormat = eGL_RGB8; break;
|
||||
case CompType::SNorm: internalFormat = eGL_RGB8_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_RGB8UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RGB8I; break;
|
||||
case CompType::UNormSRGB: internalFormat = eGL_SRGB8; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RG:
|
||||
case eGL_RG8:
|
||||
case eGL_RG8_SNORM:
|
||||
case eGL_RG8UI:
|
||||
case eGL_RG8I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::UNorm: internalFormat = eGL_RG8; break;
|
||||
case CompType::SNorm: internalFormat = eGL_RG8_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_RG8UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RG8I; break;
|
||||
case CompType::UNormSRGB: internalFormat = eGL_SRG8_EXT; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RED:
|
||||
case eGL_R8:
|
||||
case eGL_R8_SNORM:
|
||||
case eGL_R8UI:
|
||||
case eGL_R8I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::UNorm: internalFormat = eGL_R8; break;
|
||||
case CompType::SNorm: internalFormat = eGL_R8_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_R8UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_R8I; break;
|
||||
case CompType::UNormSRGB: internalFormat = eGL_SR8_EXT; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RGBA16F:
|
||||
case eGL_RGBA16:
|
||||
case eGL_RGBA16_SNORM:
|
||||
case eGL_RGBA16UI:
|
||||
case eGL_RGBA16I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_RGBA16F; break;
|
||||
case CompType::UNorm: internalFormat = eGL_RGBA16; break;
|
||||
case CompType::SNorm: internalFormat = eGL_RGBA16_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_RGBA16UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RGBA16I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RGB16F:
|
||||
case eGL_RGB16:
|
||||
case eGL_RGB16_SNORM:
|
||||
case eGL_RGB16UI:
|
||||
case eGL_RGB16I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_RGB16F; break;
|
||||
case CompType::UNorm: internalFormat = eGL_RGB16; break;
|
||||
case CompType::SNorm: internalFormat = eGL_RGB16_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_RGB16UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RGB16I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RG16F:
|
||||
case eGL_RG16:
|
||||
case eGL_RG16_SNORM:
|
||||
case eGL_RG16UI:
|
||||
case eGL_RG16I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_RG16F; break;
|
||||
case CompType::UNorm: internalFormat = eGL_RG16; break;
|
||||
case CompType::SNorm: internalFormat = eGL_RG16_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_RG16UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RG16I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_R16F:
|
||||
case eGL_R16:
|
||||
case eGL_R16_SNORM:
|
||||
case eGL_R16UI:
|
||||
case eGL_R16I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_R16F; break;
|
||||
case CompType::UNorm: internalFormat = eGL_R16; break;
|
||||
case CompType::SNorm: internalFormat = eGL_R16_SNORM; break;
|
||||
case CompType::UInt: internalFormat = eGL_R16UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_R16I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RGBA32F:
|
||||
case eGL_RGBA32UI:
|
||||
case eGL_RGBA32I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_RGBA32F; break;
|
||||
case CompType::UInt: internalFormat = eGL_RGBA32UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RGBA32I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RGB32F:
|
||||
case eGL_RGB32UI:
|
||||
case eGL_RGB32I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_RGB32F; break;
|
||||
case CompType::UInt: internalFormat = eGL_RGB32UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RGB32I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RG32F:
|
||||
case eGL_RG32UI:
|
||||
case eGL_RG32I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_RG32F; break;
|
||||
case CompType::UInt: internalFormat = eGL_RG32UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_RG32I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_R32F:
|
||||
case eGL_R32UI:
|
||||
case eGL_R32I:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float: internalFormat = eGL_R32F; break;
|
||||
case CompType::UInt: internalFormat = eGL_R32UI; break;
|
||||
case CompType::SInt: internalFormat = eGL_R32I; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_RGB10_A2UI:
|
||||
case eGL_RGB10_A2:
|
||||
switch(typeCast)
|
||||
{
|
||||
case CompType::Float:
|
||||
case CompType::UNorm: internalFormat = eGL_RGB10_A2; break;
|
||||
case CompType::UInt: internalFormat = eGL_RGB10_A2UI; break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
|
||||
internalFormat = (typeCast == CompType::UNormSRGB) ? eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT
|
||||
: eGL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
|
||||
internalFormat = (typeCast == CompType::UNormSRGB) ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
|
||||
: eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
|
||||
internalFormat = (typeCast == CompType::UNormSRGB) ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
|
||||
: eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
|
||||
internalFormat = (typeCast == CompType::UNormSRGB) ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
|
||||
: eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RED_RGTC1:
|
||||
case eGL_COMPRESSED_SIGNED_RED_RGTC1:
|
||||
internalFormat = (typeCast == CompType::SNorm) ? eGL_COMPRESSED_SIGNED_RED_RGTC1
|
||||
: eGL_COMPRESSED_RED_RGTC1;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RG_RGTC2:
|
||||
case eGL_COMPRESSED_SIGNED_RG_RGTC2:
|
||||
internalFormat =
|
||||
(typeCast == CompType::SNorm) ? eGL_COMPRESSED_SIGNED_RG_RGTC2 : eGL_COMPRESSED_RG_RGTC2;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
|
||||
case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
|
||||
internalFormat = (typeCast == CompType::SNorm) ? eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB
|
||||
: eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
|
||||
case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
|
||||
internalFormat = (typeCast == CompType::UNormSRGB) ? eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB
|
||||
: eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_SIGNED_R11_EAC:
|
||||
case eGL_COMPRESSED_R11_EAC:
|
||||
internalFormat =
|
||||
(typeCast == CompType::SNorm) ? eGL_COMPRESSED_SIGNED_R11_EAC : eGL_COMPRESSED_R11_EAC;
|
||||
break;
|
||||
|
||||
case eGL_COMPRESSED_SIGNED_RG11_EAC:
|
||||
case eGL_COMPRESSED_RG11_EAC:
|
||||
internalFormat =
|
||||
(typeCast == CompType::SNorm) ? eGL_COMPRESSED_SIGNED_RG11_EAC : eGL_COMPRESSED_RG11_EAC;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
return internalFormat;
|
||||
}
|
||||
|
||||
GLenum TextureBinding(GLenum target)
|
||||
{
|
||||
switch(target)
|
||||
|
||||
@@ -52,6 +52,8 @@ bool IsUIntFormat(GLenum internalFormat);
|
||||
bool IsSIntFormat(GLenum internalFormat);
|
||||
bool IsSRGBFormat(GLenum internalFormat);
|
||||
|
||||
GLenum GetViewCastedFormat(GLenum internalFormat, CompType typeCast);
|
||||
|
||||
bool IsCubeFace(GLenum target);
|
||||
GLint CubeTargetIndex(GLenum face);
|
||||
GLenum TextureBinding(GLenum target);
|
||||
|
||||
Reference in New Issue
Block a user