remap all depth format for gles depth fetch

This commit is contained in:
Jimmy Lee
2017-07-17 18:39:03 -07:00
committed by Baldur Karlsson
parent 74b343afe3
commit 06502e12c4
15 changed files with 236 additions and 112 deletions
+1
View File
@@ -250,6 +250,7 @@ public:
RDCERR("Calling proxy-render functions on an image viewer");
}
bool IsTextureSupported(const ResourceFormat &format) { return true; }
bool NeedRemapForFetch(const ResourceFormat &format) { return false; }
ResourceId CreateProxyBuffer(const BufferDescription &templateBuf)
{
RDCERR("Calling proxy-render functions on an image viewer");
+61 -19
View File
@@ -2009,14 +2009,28 @@ string ToStrHelper<false, RemapTextureEnum>::Get(const RemapTextureEnum &el)
// If a remap is required, modify the params that are used when getting the proxy texture data
// for replay on the current driver.
void ReplayProxy::RemapProxyTextureIfNeeded(ResourceFormat &format, GetTextureDataParams &params)
void ReplayProxy::RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureDataParams &params)
{
if(m_Proxy->IsTextureSupported(format))
if(NeedRemapForFetch(tex.format))
{
// currently only OpenGL ES need to remap all the depth formats for fetch
// when depth read is not supported
params.remap = eRemap_RGBA32;
tex.format.compCount = 4;
tex.format.compByteWidth = 4;
tex.format.compType = CompType::Float;
tex.format.special = false;
tex.format.specialFormat = SpecialFormat::Unknown;
tex.creationFlags &= ~TextureCategory::DepthTarget;
return;
}
if(m_Proxy->IsTextureSupported(tex.format))
return;
if(format.special)
if(tex.format.special)
{
switch(format.specialFormat)
switch(tex.format.specialFormat)
{
case SpecialFormat::S8:
case SpecialFormat::D16S8: params.remap = eRemap_D32S8; break;
@@ -2026,19 +2040,19 @@ void ReplayProxy::RemapProxyTextureIfNeeded(ResourceFormat &format, GetTextureDa
case SpecialFormat::ETC2: params.remap = eRemap_RGBA8; break;
default:
RDCERR("Don't know how to remap special format %u, falling back to RGBA32",
format.specialFormat);
tex.format.specialFormat);
params.remap = eRemap_RGBA32;
break;
}
format.special = false;
tex.format.special = false;
}
else
{
if(format.compByteWidth == 4)
if(tex.format.compByteWidth == 4)
params.remap = eRemap_RGBA32;
else if(format.compByteWidth == 2)
else if(tex.format.compByteWidth == 2)
params.remap = eRemap_RGBA16;
else if(format.compByteWidth == 1)
else if(tex.format.compByteWidth == 1)
params.remap = eRemap_RGBA8;
}
@@ -2046,21 +2060,21 @@ void ReplayProxy::RemapProxyTextureIfNeeded(ResourceFormat &format, GetTextureDa
{
case eRemap_None: RDCERR("IsTextureSupported == false, but we have no remap"); break;
case eRemap_RGBA8:
format.compCount = 4;
format.compByteWidth = 1;
format.compType = CompType::UNorm;
tex.format.compCount = 4;
tex.format.compByteWidth = 1;
tex.format.compType = CompType::UNorm;
// Range adaptation is only needed when remapping a higher precision format down to RGBA8.
params.whitePoint = 1.0f;
break;
case eRemap_RGBA16:
format.compCount = 4;
format.compByteWidth = 2;
format.compType = CompType::UNorm;
tex.format.compCount = 4;
tex.format.compByteWidth = 2;
tex.format.compType = CompType::UNorm;
break;
case eRemap_RGBA32:
format.compCount = 4;
format.compByteWidth = 4;
format.compType = CompType::Float;
tex.format.compCount = 4;
tex.format.compByteWidth = 4;
tex.format.compType = CompType::Float;
break;
case eRemap_D32S8: RDCERR("Remapping depth/stencil formats not implemented."); break;
}
@@ -2083,7 +2097,7 @@ void ReplayProxy::EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t
TextureDescription tex = GetTexture(texid);
ProxyTextureProperties proxy;
RemapProxyTextureIfNeeded(tex.format, proxy.params);
RemapProxyTextureIfNeeded(tex, proxy.params);
proxy.id = m_Proxy->CreateProxyTexture(tex);
m_ProxyTextures[texid] = proxy;
@@ -2128,6 +2142,33 @@ void ReplayProxy::EnsureBufCached(ResourceId bufid)
}
}
bool ReplayProxy::NeedRemapForFetch(const ResourceFormat &_format)
{
ResourceFormat format = _format;
m_ToReplaySerialiser->Serialise("", format);
bool bNeedRemap;
if(m_RemoteServer)
{
bNeedRemap = m_Remote->NeedRemapForFetch(format);
m_FromReplaySerialiser->Serialise("", bNeedRemap);
}
else
{
if(!SendReplayCommand(eReplayProxy_NeedRemapForFetch))
{
return false;
}
m_FromReplaySerialiser->Serialise("", bNeedRemap);
}
return bNeedRemap;
}
bool ReplayProxy::Tick(int type, Serialiser *incomingPacket)
{
if(!m_RemoteServer)
@@ -2156,6 +2197,7 @@ bool ReplayProxy::Tick(int type, Serialiser *incomingPacket)
case eReplayProxy_GetLiveID: GetLiveID(ResourceId()); break;
case eReplayProxy_GetFrameRecord: GetFrameRecord(); break;
case eReplayProxy_IsRenderOutput: IsRenderOutput(ResourceId()); break;
case eReplayProxy_NeedRemapForFetch: NeedRemapForFetch(ResourceFormat()); break;
case eReplayProxy_HasResolver: HasCallstacks(); break;
case eReplayProxy_InitStackResolver: InitCallstackResolver(); break;
case eReplayProxy_HasStackResolver: GetCallstackResolver(); break;
+3 -1
View File
@@ -55,6 +55,7 @@ enum ReplayProxyPacket
eReplayProxy_GetLiveID,
eReplayProxy_GetFrameRecord,
eReplayProxy_IsRenderOutput,
eReplayProxy_NeedRemapForFetch,
eReplayProxy_FreeResource,
eReplayProxy_HasResolver,
@@ -491,8 +492,9 @@ private:
bool SendReplayCommand(ReplayProxyPacket type);
void EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t mip);
void RemapProxyTextureIfNeeded(ResourceFormat &format, GetTextureDataParams &params);
void RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureDataParams &params);
void EnsureBufCached(ResourceId bufid);
bool NeedRemapForFetch(const ResourceFormat &format);
struct TextureCacheEntry
{
+1 -1
View File
@@ -89,7 +89,7 @@ struct Vec4u
#ifndef OPENGL_ES
#define PRECISION
#else
#define PRECISION mediump
#define PRECISION highp
precision PRECISION float;
precision PRECISION int;
#endif
+1
View File
@@ -223,6 +223,7 @@ void main(void)
if(texdisplay.Channels.a == 1.0f)
col = vec4(col.aaa, 1);
else
//this is a splat because col has already gone through the if(texdisplay.Channels.x < 0.5f) statements
col = vec4(vec3(dot(col.rgb, vec3(1.0f))), 1.0f);
}
}
+5
View File
@@ -1886,6 +1886,11 @@ bool D3D11Replay::IsTextureSupported(const ResourceFormat &format)
return MakeDXGIFormat(format) != DXGI_FORMAT_UNKNOWN;
}
bool D3D11Replay::NeedRemapForFetch(const ResourceFormat &format)
{
return false;
}
ResourceId D3D11Replay::CreateProxyBuffer(const BufferDescription &templateBuf)
{
ResourceId ret;
+1
View File
@@ -125,6 +125,7 @@ public:
void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data,
size_t dataSize);
bool IsTextureSupported(const ResourceFormat &format);
bool NeedRemapForFetch(const ResourceFormat &format);
ResourceId CreateProxyBuffer(const BufferDescription &templateBuf);
void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize);
+5
View File
@@ -1338,6 +1338,11 @@ bool D3D12Replay::IsTextureSupported(const ResourceFormat &format)
return MakeDXGIFormat(format) != DXGI_FORMAT_UNKNOWN;
}
bool D3D12Replay::NeedRemapForFetch(const ResourceFormat &format)
{
return false;
}
void D3D12Replay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector<byte> &retData)
{
m_pDevice->GetDebugManager()->GetBufferData(buff, offset, len, retData);
+1
View File
@@ -123,6 +123,7 @@ public:
void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data,
size_t dataSize);
bool IsTextureSupported(const ResourceFormat &format);
bool NeedRemapForFetch(const ResourceFormat &format);
ResourceId CreateProxyBuffer(const BufferDescription &templateBuf);
void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize);
+7 -4
View File
@@ -1807,7 +1807,7 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
// Stencil texture sampling is not normalized in OpenGL
intIdx = 1;
float rangeScale;
float rangeScale = 1.0f;
switch(texDetails.internalFormat)
{
case eGL_STENCIL_INDEX1: rangeScale = 1.0f; break;
@@ -1817,8 +1817,8 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
// fall through
case eGL_DEPTH24_STENCIL8:
case eGL_DEPTH32F_STENCIL8:
case eGL_STENCIL_INDEX8: rangeScale = 256.0f; break;
case eGL_STENCIL_INDEX16: rangeScale = 65536.0f; break;
case eGL_STENCIL_INDEX8: rangeScale = 255.0f; break;
case eGL_STENCIL_INDEX16: rangeScale = 65535.0f; break;
}
cfg.rangemin *= rangeScale;
cfg.rangemax *= rangeScale;
@@ -1975,7 +1975,10 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
ubo->Channels.x = 1.0f;
ubo->Channels.y = 0.0f;
ubo->Channels.z = 0.0f;
ubo->Channels.w = 0.0f;
// to prevent depth only format from having non-zero values in other channels, we have to
// prevent splatting (the shader will splat the red channel when only the red channel contains
// a value of 1).
ubo->Channels.w = dsTexMode == eGL_DEPTH_COMPONENT ? 1.0f : 0.0f;
}
ubo->RangeMinimum = cfg.rangemin;
+140 -86
View File
@@ -2274,103 +2274,147 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip,
arraysize = texDetails.depth;
}
if(params.remap && intFormat != eGL_RGBA8 && intFormat != eGL_SRGB8_ALPHA8)
if(params.remap)
{
RDCASSERT(params.remap == eRemap_RGBA8);
GLenum remapFormat = eGL_RGBA8;
if(params.remap == eRemap_RGBA8)
remapFormat = eGL_RGBA8;
else if(params.remap == eRemap_RGBA16)
remapFormat = eGL_RGBA16;
else if(params.remap == eRemap_RGBA32)
remapFormat = eGL_RGBA32F;
MakeCurrentReplayContext(m_DebugCtx);
GLenum finalFormat = IsSRGBFormat(intFormat) ? eGL_SRGB8_ALPHA8 : eGL_RGBA8;
GLenum newtarget = (texType == eGL_TEXTURE_3D ? eGL_TEXTURE_3D : eGL_TEXTURE_2D);
// create temporary texture of width/height in RGBA8 format to render to
gl.glGenTextures(1, &tempTex);
gl.glBindTexture(newtarget, tempTex);
if(newtarget == eGL_TEXTURE_3D)
gl.glTextureImage3DEXT(tempTex, newtarget, 0, finalFormat, width, height, depth, 0,
GetBaseFormat(finalFormat), GetDataType(finalFormat), NULL);
else
gl.glTextureImage2DEXT(tempTex, newtarget, 0, finalFormat, width, height, 0,
GetBaseFormat(finalFormat), GetDataType(finalFormat), NULL);
gl.glTexParameteri(newtarget, eGL_TEXTURE_MAX_LEVEL, 0);
// create temp framebuffer
GLuint fbo = 0;
gl.glGenFramebuffers(1, &fbo);
gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbo);
gl.glTexParameteri(newtarget, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
gl.glTexParameteri(newtarget, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_R, eGL_CLAMP_TO_EDGE);
if(newtarget == eGL_TEXTURE_3D)
gl.glFramebufferTexture3D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_3D, tempTex, 0,
0);
else if(newtarget == eGL_TEXTURE_2D || newtarget == eGL_TEXTURE_2D_MULTISAMPLE)
gl.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, newtarget, tempTex, 0);
else
gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, tempTex, 0);
float col[] = {0.3f, 0.6f, 0.9f, 1.0f};
gl.glClearBufferfv(eGL_COLOR, 0, col);
// render to the temp texture to do the downcast
float oldW = DebugData.outWidth;
float oldH = DebugData.outHeight;
DebugData.outWidth = float(width);
DebugData.outHeight = float(height);
for(GLsizei d = 0; d < (newtarget == eGL_TEXTURE_3D ? depth : 1); d++)
if(intFormat != remapFormat)
{
TextureDisplay texDisplay;
MakeCurrentReplayContext(m_DebugCtx);
texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true;
texDisplay.HDRMul = -1.0f;
texDisplay.linearDisplayAsGamma = false;
texDisplay.overlay = DebugOverlay::NoOverlay;
texDisplay.FlipY = false;
texDisplay.mip = mip;
texDisplay.sampleIdx = ~0U;
texDisplay.CustomShader = ResourceId();
texDisplay.sliceFace = arrayIdx;
texDisplay.rangemin = params.blackPoint;
texDisplay.rangemax = params.whitePoint;
texDisplay.scale = 1.0f;
texDisplay.texid = tex;
texDisplay.typeHint = CompType::Typeless;
texDisplay.rawoutput = false;
texDisplay.offx = 0;
texDisplay.offy = 0;
GLenum finalFormat = IsSRGBFormat(intFormat) ? eGL_SRGB8_ALPHA8 : remapFormat;
GLenum newtarget = (texType == eGL_TEXTURE_3D ? eGL_TEXTURE_3D : eGL_TEXTURE_2D);
// create temporary texture of width/height in the new format to render to
gl.glGenTextures(1, &tempTex);
gl.glBindTexture(newtarget, tempTex);
if(newtarget == eGL_TEXTURE_3D)
gl.glTextureImage3DEXT(tempTex, newtarget, 0, finalFormat, width, height, depth, 0,
GetBaseFormat(finalFormat), GetDataType(finalFormat), NULL);
else
gl.glTextureImage2DEXT(tempTex, newtarget, 0, finalFormat, width, height, 0,
GetBaseFormat(finalFormat), GetDataType(finalFormat), NULL);
gl.glTexParameteri(newtarget, eGL_TEXTURE_MAX_LEVEL, 0);
// create temp framebuffer
GLuint fbo = 0;
gl.glGenFramebuffers(1, &fbo);
gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbo);
gl.glTexParameteri(newtarget, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST);
gl.glTexParameteri(newtarget, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST);
gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE);
gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE);
gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_R, eGL_CLAMP_TO_EDGE);
if(newtarget == eGL_TEXTURE_3D)
{
gl.glFramebufferTexture3D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_3D, tempTex,
0, (GLint)d);
texDisplay.sliceFace = (uint32_t)d;
0, 0);
else if(newtarget == eGL_TEXTURE_2D || newtarget == eGL_TEXTURE_2D_MULTISAMPLE)
gl.glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, newtarget, tempTex, 0);
else
gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, tempTex, 0);
float col[] = {0.3f, 0.6f, 0.9f, 1.0f};
gl.glClearBufferfv(eGL_COLOR, 0, col);
// render to the temp texture to do the downcast
float oldW = DebugData.outWidth;
float oldH = DebugData.outHeight;
DebugData.outWidth = float(width);
DebugData.outHeight = float(height);
for(GLsizei d = 0; d < (newtarget == eGL_TEXTURE_3D ? depth : 1); d++)
{
TextureDisplay texDisplay;
texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true;
texDisplay.HDRMul = -1.0f;
texDisplay.linearDisplayAsGamma = false;
texDisplay.overlay = DebugOverlay::NoOverlay;
texDisplay.FlipY = false;
texDisplay.mip = mip;
texDisplay.sampleIdx = ~0U;
texDisplay.CustomShader = ResourceId();
texDisplay.sliceFace = arrayIdx;
texDisplay.rangemin = params.blackPoint;
texDisplay.rangemax = params.whitePoint;
texDisplay.scale = 1.0f;
texDisplay.texid = tex;
texDisplay.typeHint = CompType::Typeless;
texDisplay.rawoutput = false;
texDisplay.offx = 0;
texDisplay.offy = 0;
if(newtarget == eGL_TEXTURE_3D)
{
gl.glFramebufferTexture3D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_3D, tempTex,
0, (GLint)d);
texDisplay.sliceFace = (uint32_t)d;
}
gl.glViewport(0, 0, width, height);
RenderTextureInternal(texDisplay, 0);
}
gl.glViewport(0, 0, width, height);
// do one more time for the stencil
if(GetBaseFormat(intFormat) == eGL_DEPTH_STENCIL)
{
TextureDisplay texDisplay;
RenderTextureInternal(texDisplay, 0);
texDisplay.Green = true;
texDisplay.Red = texDisplay.Blue = texDisplay.Alpha = false;
texDisplay.HDRMul = -1.0f;
texDisplay.linearDisplayAsGamma = false;
texDisplay.overlay = DebugOverlay::NoOverlay;
texDisplay.FlipY = false;
texDisplay.mip = mip;
texDisplay.sampleIdx = ~0U;
texDisplay.CustomShader = ResourceId();
texDisplay.sliceFace = arrayIdx;
texDisplay.rangemin = params.blackPoint;
texDisplay.rangemax = params.whitePoint;
texDisplay.scale = 1.0f;
texDisplay.texid = tex;
texDisplay.typeHint = CompType::Typeless;
texDisplay.rawoutput = false;
texDisplay.offx = 0;
texDisplay.offy = 0;
gl.glViewport(0, 0, width, height);
GLboolean color_mask[4];
gl.glGetBooleanv(eGL_COLOR_WRITEMASK, color_mask);
gl.glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
RenderTextureInternal(texDisplay, 0);
gl.glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
}
DebugData.outWidth = oldW;
DebugData.outHeight = oldH;
// rewrite the variables to temporary texture
texType = newtarget;
texname = tempTex;
intFormat = finalFormat;
if(newtarget != eGL_TEXTURE_3D)
depth = 1;
arraysize = 1;
samples = 1;
mip = 0;
arrayIdx = 0;
gl.glDeleteFramebuffers(1, &fbo);
}
DebugData.outWidth = oldW;
DebugData.outHeight = oldH;
// rewrite the variables to temporary texture
texType = newtarget;
texname = tempTex;
intFormat = finalFormat;
if(newtarget != eGL_TEXTURE_3D)
depth = 1;
arraysize = 1;
samples = 1;
mip = 0;
arrayIdx = 0;
gl.glDeleteFramebuffers(1, &fbo);
}
else if(params.resolve && samples > 1)
{
@@ -3232,6 +3276,16 @@ bool GLReplay::IsTextureSupported(const ResourceFormat &format)
return true;
}
bool GLReplay::NeedRemapForFetch(const ResourceFormat &format)
{
if(format.compType == CompType::Depth ||
(format.special && (format.specialFormat == SpecialFormat::D16S8 ||
format.specialFormat == SpecialFormat::D24S8 ||
format.specialFormat == SpecialFormat::D32S8)))
return IsGLES && !HasExt[NV_read_depth];
return false;
}
ResourceId GLReplay::CreateProxyBuffer(const BufferDescription &templateBuf)
{
WrappedOpenGL &gl = *m_pDriver;
+1
View File
@@ -214,6 +214,7 @@ public:
void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data,
size_t dataSize);
bool IsTextureSupported(const ResourceFormat &format);
bool NeedRemapForFetch(const ResourceFormat &format);
ResourceId CreateProxyBuffer(const BufferDescription &templateBuf);
void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize);
+5
View File
@@ -5254,6 +5254,11 @@ bool VulkanReplay::IsTextureSupported(const ResourceFormat &format)
return true;
}
bool VulkanReplay::NeedRemapForFetch(const ResourceFormat &format)
{
return false;
}
ResourceId VulkanReplay::CreateProxyBuffer(const BufferDescription &templateBuf)
{
VULKANNOTIMP("CreateProxyBuffer");
+1
View File
@@ -239,6 +239,7 @@ public:
void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data,
size_t dataSize);
bool IsTextureSupported(const ResourceFormat &format);
bool NeedRemapForFetch(const ResourceFormat &format);
ResourceId CreateProxyBuffer(const BufferDescription &templateBuf);
void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize);
+3 -1
View File
@@ -60,7 +60,7 @@ struct GetTextureDataParams
resolve(false),
remap(eRemap_None),
blackPoint(0.0f),
whitePoint(0.0f)
whitePoint(1.0f)
{
}
};
@@ -155,6 +155,8 @@ public:
virtual void InitCallstackResolver() = 0;
virtual bool HasCallstacks() = 0;
virtual Callstack::StackResolver *GetCallstackResolver() = 0;
virtual bool NeedRemapForFetch(const ResourceFormat &format) = 0;
};
class IReplayDriver : public IRemoteDriver