mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-28 09:26:52 +00:00
Implement proxied MSAA texture contents on OpenGL
This commit is contained in:
@@ -35,23 +35,23 @@ layout(binding = 2) writeonly uniform uimage2DMSArray dstMS;
|
||||
layout(push_constant) uniform multisamplePush
|
||||
{
|
||||
int numMultiSamples;
|
||||
int currentSample;
|
||||
int currentSlice;
|
||||
int sampleOffset;
|
||||
int sliceOffset;
|
||||
uint currentStencil;
|
||||
} mscopy;
|
||||
|
||||
#define numMultiSamples (mscopy.numMultiSamples)
|
||||
#define currentSample (mscopy.currentSample)
|
||||
#define currentSlice (mscopy.currentSlice)
|
||||
#define sampleOffset (mscopy.sampleOffset)
|
||||
#define sliceOffset (mscopy.sliceOffset)
|
||||
#define currentStencil (mscopy.currentStencil)
|
||||
|
||||
#else
|
||||
|
||||
uniform uvec4 mscopy;
|
||||
uniform ivec4 mscopy;
|
||||
|
||||
#define numMultiSamples (int(mscopy.x))
|
||||
#define currentSample (mscopy.y)
|
||||
#define currentSlice (mscopy.z)
|
||||
#define numMultiSamples (mscopy.x)
|
||||
#define sampleOffset (mscopy.y)
|
||||
#define sliceOffset (mscopy.z)
|
||||
#define currentStencil (mscopy.w)
|
||||
|
||||
#endif
|
||||
@@ -60,10 +60,10 @@ void main()
|
||||
{
|
||||
uvec3 id = gl_GlobalInvocationID;
|
||||
|
||||
int slice = int(id.z / numMultiSamples);
|
||||
int sampleIdx = int(id.z % numMultiSamples);
|
||||
int slice = sliceOffset + int(id.z / numMultiSamples);
|
||||
int sampleIdx = sampleOffset + int(id.z % numMultiSamples);
|
||||
|
||||
uvec4 data = texelFetch(srcArray, ivec3(int(id.x), int(id.y), int(id.z)), 0);
|
||||
uvec4 data = texelFetch(srcArray, ivec3(int(id.x), int(id.y), slice * numMultiSamples + sampleIdx), 0);
|
||||
|
||||
imageStore(dstMS, ivec3(int(id.x), int(id.y), slice), sampleIdx, data);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//#extension_nongles GL_ARB_sample_shading : require
|
||||
|
||||
layout(binding = 0) uniform sampler2DArray srcDepthArray;
|
||||
layout(binding = 1) uniform usampler2DArray srcStencilArray;
|
||||
// binding = 2 used as an image in the colour copy compute shaders
|
||||
@@ -43,12 +45,12 @@ layout(push_constant) uniform multisamplePush
|
||||
|
||||
#else
|
||||
|
||||
uniform uvec4 mscopy;
|
||||
uniform ivec4 mscopy;
|
||||
|
||||
#define numMultiSamples (int(mscopy.x))
|
||||
#define numMultiSamples (mscopy.x)
|
||||
#define currentSample (mscopy.y)
|
||||
#define currentSlice (mscopy.z)
|
||||
#define currentStencil (mscopy.w)
|
||||
#define currentStencil (uint(mscopy.w))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,7 +58,7 @@ void main()
|
||||
{
|
||||
ivec3 srcCoord = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), currentSlice*numMultiSamples + gl_SampleID);
|
||||
|
||||
if(currentStencil < 256)
|
||||
if(currentStencil < 256u)
|
||||
{
|
||||
uint stencil = texelFetch(srcStencilArray, srcCoord, 0).x;
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//#extension_nongles GL_ARB_sample_shading : require
|
||||
|
||||
layout(binding = 0) uniform sampler2DMSArray srcDepthMS;
|
||||
layout(binding = 1) uniform usampler2DMSArray srcStencilMS;
|
||||
@@ -43,12 +45,12 @@ layout(push_constant) uniform multisamplePush
|
||||
|
||||
#else
|
||||
|
||||
uniform uvec4 mscopy;
|
||||
uniform ivec4 mscopy;
|
||||
|
||||
#define numMultiSamples (int(mscopy.x))
|
||||
#define numMultiSamples (mscopy.x)
|
||||
#define currentSample (mscopy.y)
|
||||
#define currentSlice (mscopy.z)
|
||||
#define currentStencil (mscopy.w)
|
||||
#define currentStencil (uint(mscopy.w))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,7 +58,7 @@ void main()
|
||||
{
|
||||
ivec3 srcCoord = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), currentSlice);
|
||||
|
||||
if(currentStencil < 256)
|
||||
if(currentStencil < 256u)
|
||||
{
|
||||
uint stencil = texelFetch(srcStencilMS, srcCoord, currentSample).x;
|
||||
|
||||
|
||||
@@ -48,9 +48,9 @@ layout(push_constant) uniform multisamplePush
|
||||
|
||||
#else
|
||||
|
||||
uniform uvec4 mscopy;
|
||||
uniform ivec4 mscopy;
|
||||
|
||||
#define numMultiSamples (int(mscopy.x))
|
||||
#define numMultiSamples (mscopy.x)
|
||||
#define currentSample (mscopy.y)
|
||||
#define currentSlice (mscopy.z)
|
||||
#define currentStencil (mscopy.w)
|
||||
|
||||
@@ -522,6 +522,17 @@ void GLReplay::InitDebugData()
|
||||
"GL_ARB_compute_shader not supported, disabling 2DMS save/load.");
|
||||
}
|
||||
|
||||
if(glesShadersAreComplete && HasExt[ARB_texture_multisample])
|
||||
{
|
||||
GenerateGLSLShader(vs, shaderType, "", GetEmbeddedResource(glsl_blit_vert), glslBaseVer);
|
||||
|
||||
GenerateGLSLShader(fs, shaderType, "", GetEmbeddedResource(glsl_depthms2arr_frag), glslBaseVer);
|
||||
DebugData.DepthMS2Array = CreateShaderProgram(vs, fs);
|
||||
|
||||
GenerateGLSLShader(fs, shaderType, "", GetEmbeddedResource(glsl_deptharr2ms_frag), glslBaseVer);
|
||||
DebugData.DepthArray2MS = CreateShaderProgram(vs, fs);
|
||||
}
|
||||
|
||||
if(glesShadersAreComplete && HasExt[ARB_compute_shader])
|
||||
{
|
||||
string defines =
|
||||
@@ -806,6 +817,9 @@ void GLReplay::DeleteDebugData()
|
||||
drv.glDeleteProgram(DebugData.Array2MS);
|
||||
drv.glDeleteProgram(DebugData.MS2Array);
|
||||
|
||||
drv.glDeleteProgram(DebugData.DepthArray2MS);
|
||||
drv.glDeleteProgram(DebugData.DepthMS2Array);
|
||||
|
||||
drv.glDeleteBuffers(1, &DebugData.minmaxTileResult);
|
||||
drv.glDeleteBuffers(1, &DebugData.minmaxResult);
|
||||
drv.glDeleteBuffers(1, &DebugData.histogramBuf);
|
||||
|
||||
@@ -76,6 +76,14 @@ void GLReplay::CopyTex2DMSToArray(GLuint &destArray, GLuint srcMS, GLint width,
|
||||
drv.glTextureStorage3DEXT(destArray, eGL_TEXTURE_2D_ARRAY, 1, intFormat, width, height,
|
||||
arraySize * samples);
|
||||
|
||||
if(IsDepthStencilFormat(intFormat))
|
||||
{
|
||||
CopyDepthTex2DMSToArray(destArray, srcMS, width, height, arraySize, samples, intFormat);
|
||||
return;
|
||||
}
|
||||
|
||||
GLMarkerRegion renderoverlay("CopyTex2DMSToArray");
|
||||
|
||||
GLRenderState rs;
|
||||
rs.FetchState(m_pDriver);
|
||||
|
||||
@@ -118,7 +126,7 @@ void GLReplay::CopyTex2DMSToArray(GLuint &destArray, GLuint srcMS, GLint width,
|
||||
GLint loc = drv.glGetUniformLocation(DebugData.MS2Array, "mscopy");
|
||||
if(loc >= 0)
|
||||
{
|
||||
drv.glProgramUniform4ui(DebugData.MS2Array, loc, samples, 0, 0, 0);
|
||||
drv.glProgramUniform4i(DebugData.MS2Array, loc, samples, 0, 0, 0);
|
||||
|
||||
drv.glDispatchCompute((GLuint)width, (GLuint)height, GLuint(arraySize * samples));
|
||||
}
|
||||
@@ -128,3 +136,335 @@ void GLReplay::CopyTex2DMSToArray(GLuint &destArray, GLuint srcMS, GLint width,
|
||||
|
||||
rs.ApplyState(m_pDriver);
|
||||
}
|
||||
|
||||
void GLReplay::CopyDepthTex2DMSToArray(GLuint &destArray, GLuint srcMS, GLint width, GLint height,
|
||||
GLint arraySize, GLint samples, GLenum intFormat)
|
||||
{
|
||||
GLMarkerRegion renderoverlay("CopyDepthTex2DMSToArray");
|
||||
|
||||
WrappedOpenGL &drv = *m_pDriver;
|
||||
|
||||
GLRenderState rs;
|
||||
rs.FetchState(m_pDriver);
|
||||
|
||||
GLuint texs[3];
|
||||
drv.glGenTextures(3, texs);
|
||||
drv.glTextureView(texs[0], eGL_TEXTURE_2D_ARRAY, destArray, intFormat, 0, 1, 0,
|
||||
arraySize * samples);
|
||||
drv.glTextureView(texs[1], eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, srcMS, intFormat, 0, 1, 0, arraySize);
|
||||
drv.glTextureView(texs[2], eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, srcMS, intFormat, 0, 1, 0, arraySize);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
||||
GLuint fbo = 0;
|
||||
drv.glGenFramebuffers(1, &fbo);
|
||||
drv.glBindFramebuffer(eGL_FRAMEBUFFER, fbo);
|
||||
drv.glDrawBuffers(0, NULL);
|
||||
|
||||
drv.glUseProgram(DebugData.DepthMS2Array);
|
||||
drv.glViewport(0, 0, width, height);
|
||||
|
||||
drv.glDisable(eGL_CULL_FACE);
|
||||
drv.glDisable(eGL_BLEND);
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
if(!IsGLES)
|
||||
drv.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL);
|
||||
drv.glEnable(eGL_DEPTH_TEST);
|
||||
drv.glEnable(eGL_STENCIL_TEST);
|
||||
drv.glDepthFunc(eGL_ALWAYS);
|
||||
drv.glDepthMask(GL_TRUE);
|
||||
drv.glStencilOp(eGL_REPLACE, eGL_REPLACE, eGL_REPLACE);
|
||||
drv.glStencilMask(0xff);
|
||||
|
||||
uint32_t numStencil = 1;
|
||||
GLenum attach = eGL_DEPTH_ATTACHMENT;
|
||||
|
||||
switch(GetBaseFormat(intFormat))
|
||||
{
|
||||
case eGL_DEPTH_STENCIL:
|
||||
numStencil = 256;
|
||||
attach = eGL_DEPTH_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
case eGL_DEPTH:
|
||||
numStencil = 1;
|
||||
attach = eGL_DEPTH_ATTACHMENT;
|
||||
break;
|
||||
case eGL_STENCIL:
|
||||
numStencil = 256;
|
||||
attach = eGL_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
default: RDCERR("Unexpected base format! %s", ToStr(intFormat).c_str()); break;
|
||||
}
|
||||
|
||||
if(attach == eGL_DEPTH_STENCIL_ATTACHMENT || attach == eGL_DEPTH_ATTACHMENT)
|
||||
{
|
||||
// depth aspect
|
||||
drv.glActiveTexture(eGL_TEXTURE0);
|
||||
drv.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, texs[1]);
|
||||
drv.glBindSampler(0, DebugData.pointNoMipSampler);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_DEPTH_STENCIL_TEXTURE_MODE,
|
||||
eGL_DEPTH_COMPONENT);
|
||||
}
|
||||
|
||||
if(numStencil > 1)
|
||||
{
|
||||
// stencil aspect
|
||||
drv.glActiveTexture(eGL_TEXTURE1);
|
||||
drv.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, texs[2]);
|
||||
drv.glBindSampler(1, DebugData.pointNoMipSampler);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_DEPTH_STENCIL_TEXTURE_MODE,
|
||||
eGL_STENCIL_INDEX);
|
||||
}
|
||||
|
||||
GLint loc = drv.glGetUniformLocation(DebugData.DepthMS2Array, "mscopy");
|
||||
if(loc >= 0)
|
||||
{
|
||||
for(GLint i = 0; i < arraySize * samples; i++)
|
||||
{
|
||||
drv.glFramebufferTextureLayer(eGL_DRAW_FRAMEBUFFER, attach, texs[0], 0, i);
|
||||
|
||||
for(uint32_t s = 0; s < numStencil; s++)
|
||||
{
|
||||
uint32_t currentStencil = numStencil == 1 ? 1000 : s;
|
||||
|
||||
drv.glStencilFunc(eGL_ALWAYS, int(s), 0xff);
|
||||
|
||||
drv.glProgramUniform4i(DebugData.DepthMS2Array, loc, samples, i % samples, i / samples,
|
||||
currentStencil);
|
||||
|
||||
drv.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drv.glDeleteFramebuffers(1, &fbo);
|
||||
drv.glDeleteTextures(3, texs);
|
||||
|
||||
rs.ApplyState(m_pDriver);
|
||||
}
|
||||
|
||||
void GLReplay::CopyArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height,
|
||||
GLint arraySize, GLint samples, GLenum intFormat,
|
||||
uint32_t selectedSlice)
|
||||
{
|
||||
WrappedOpenGL &drv = *m_pDriver;
|
||||
|
||||
if(!HasExt[ARB_compute_shader])
|
||||
{
|
||||
RDCWARN(
|
||||
"Can't copy array to multisampled texture for serialisation without ARB_compute_shader.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!HasExt[ARB_texture_view])
|
||||
{
|
||||
RDCWARN("Can't copy array to multisampled texture for serialisation without ARB_texture_view.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!HasExt[ARB_texture_storage])
|
||||
{
|
||||
RDCWARN(
|
||||
"Can't copy array to multisampled texture for serialisation without ARB_texture_view, and "
|
||||
"ARB_texture_view requires ARB_texture_storage.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(IsDepthStencilFormat(intFormat))
|
||||
{
|
||||
CopyDepthArrayToTex2DMS(destMS, srcArray, width, height, arraySize, samples, intFormat,
|
||||
selectedSlice);
|
||||
return;
|
||||
}
|
||||
|
||||
GLMarkerRegion renderoverlay("CopyArrayToTex2DMS");
|
||||
|
||||
bool singleSliceMode = (selectedSlice != ~0U);
|
||||
|
||||
GLRenderState rs;
|
||||
rs.FetchState(m_pDriver);
|
||||
|
||||
GLenum viewClass;
|
||||
drv.glGetInternalformativ(eGL_TEXTURE_2D_ARRAY, intFormat, eGL_VIEW_COMPATIBILITY_CLASS,
|
||||
sizeof(GLenum), (GLint *)&viewClass);
|
||||
|
||||
GLenum fmt = eGL_R32UI;
|
||||
if(viewClass == eGL_VIEW_CLASS_8_BITS)
|
||||
fmt = eGL_R8UI;
|
||||
else if(viewClass == eGL_VIEW_CLASS_16_BITS)
|
||||
fmt = eGL_R16UI;
|
||||
else if(viewClass == eGL_VIEW_CLASS_24_BITS)
|
||||
fmt = eGL_RGB8UI;
|
||||
else if(viewClass == eGL_VIEW_CLASS_32_BITS)
|
||||
fmt = eGL_RGBA8UI;
|
||||
else if(viewClass == eGL_VIEW_CLASS_48_BITS)
|
||||
fmt = eGL_RGB16UI;
|
||||
else if(viewClass == eGL_VIEW_CLASS_64_BITS)
|
||||
fmt = eGL_RG32UI;
|
||||
else if(viewClass == eGL_VIEW_CLASS_96_BITS)
|
||||
fmt = eGL_RGB32UI;
|
||||
else if(viewClass == eGL_VIEW_CLASS_128_BITS)
|
||||
fmt = eGL_RGBA32UI;
|
||||
|
||||
GLuint texs[2];
|
||||
drv.glGenTextures(2, texs);
|
||||
drv.glTextureView(texs[0], eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, destMS, fmt, 0, 1, 0, arraySize);
|
||||
drv.glTextureView(texs[1], eGL_TEXTURE_2D_ARRAY, srcArray, fmt, 0, 1, 0, arraySize * samples);
|
||||
|
||||
drv.glBindImageTexture(2, texs[0], 0, GL_TRUE, 0, eGL_WRITE_ONLY, fmt);
|
||||
drv.glActiveTexture(eGL_TEXTURE0);
|
||||
drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, texs[1]);
|
||||
drv.glBindSampler(0, DebugData.pointNoMipSampler);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
||||
drv.glUseProgram(DebugData.Array2MS);
|
||||
|
||||
GLint loc = drv.glGetUniformLocation(DebugData.Array2MS, "mscopy");
|
||||
if(loc >= 0)
|
||||
{
|
||||
if(singleSliceMode)
|
||||
{
|
||||
GLint sampleOffset = (selectedSlice % samples);
|
||||
GLint sliceOffset = (selectedSlice / samples);
|
||||
drv.glProgramUniform4i(DebugData.Array2MS, loc, samples, sampleOffset, sliceOffset, 0);
|
||||
|
||||
drv.glDispatchCompute((GLuint)width, (GLuint)height, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
drv.glProgramUniform4i(DebugData.Array2MS, loc, samples, 0, 0, 0);
|
||||
|
||||
drv.glDispatchCompute((GLuint)width, (GLuint)height, GLuint(arraySize * samples));
|
||||
}
|
||||
}
|
||||
drv.glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
|
||||
|
||||
drv.glDeleteTextures(2, texs);
|
||||
|
||||
rs.ApplyState(m_pDriver);
|
||||
}
|
||||
|
||||
void GLReplay::CopyDepthArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height,
|
||||
GLint arraySize, GLint samples, GLenum intFormat,
|
||||
uint32_t selectedSlice)
|
||||
{
|
||||
GLMarkerRegion renderoverlay("CopyDepthArrayToTex2DMS");
|
||||
|
||||
bool singleSliceMode = (selectedSlice != ~0U);
|
||||
|
||||
WrappedOpenGL &drv = *m_pDriver;
|
||||
|
||||
GLRenderState rs;
|
||||
rs.FetchState(m_pDriver);
|
||||
|
||||
GLuint texs[3];
|
||||
drv.glGenTextures(3, texs);
|
||||
drv.glTextureView(texs[0], eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, destMS, intFormat, 0, 1, 0, arraySize);
|
||||
drv.glTextureView(texs[1], eGL_TEXTURE_2D_ARRAY, srcArray, intFormat, 0, 1, 0, arraySize * samples);
|
||||
drv.glTextureView(texs[2], eGL_TEXTURE_2D_ARRAY, srcArray, intFormat, 0, 1, 0, arraySize * samples);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
||||
GLuint fbo = 0;
|
||||
drv.glGenFramebuffers(1, &fbo);
|
||||
drv.glBindFramebuffer(eGL_FRAMEBUFFER, fbo);
|
||||
drv.glDrawBuffers(0, NULL);
|
||||
|
||||
drv.glUseProgram(DebugData.DepthArray2MS);
|
||||
drv.glViewport(0, 0, width, height);
|
||||
|
||||
drv.glDisable(eGL_CULL_FACE);
|
||||
drv.glDisable(eGL_BLEND);
|
||||
drv.glDisable(eGL_SCISSOR_TEST);
|
||||
if(!IsGLES)
|
||||
drv.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL);
|
||||
drv.glEnable(eGL_DEPTH_TEST);
|
||||
drv.glEnable(eGL_STENCIL_TEST);
|
||||
drv.glDepthFunc(eGL_ALWAYS);
|
||||
drv.glDepthMask(GL_TRUE);
|
||||
drv.glEnable(eGL_SAMPLE_SHADING);
|
||||
drv.glEnable(eGL_SAMPLE_MASK);
|
||||
drv.glStencilOp(eGL_REPLACE, eGL_REPLACE, eGL_REPLACE);
|
||||
drv.glStencilMask(0xff);
|
||||
|
||||
uint32_t numStencil = 1;
|
||||
GLenum attach = eGL_DEPTH_ATTACHMENT;
|
||||
|
||||
switch(GetBaseFormat(intFormat))
|
||||
{
|
||||
case eGL_DEPTH_STENCIL:
|
||||
numStencil = 256;
|
||||
attach = eGL_DEPTH_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
case eGL_DEPTH:
|
||||
numStencil = 1;
|
||||
attach = eGL_DEPTH_ATTACHMENT;
|
||||
break;
|
||||
case eGL_STENCIL:
|
||||
numStencil = 256;
|
||||
attach = eGL_STENCIL_ATTACHMENT;
|
||||
break;
|
||||
default: RDCERR("Unexpected base format! %s", ToStr(intFormat).c_str()); break;
|
||||
}
|
||||
|
||||
if(attach == eGL_DEPTH_STENCIL_ATTACHMENT || attach == eGL_DEPTH_ATTACHMENT)
|
||||
{
|
||||
// depth aspect
|
||||
drv.glActiveTexture(eGL_TEXTURE0);
|
||||
drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, texs[1]);
|
||||
drv.glBindSampler(0, DebugData.pointNoMipSampler);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_DEPTH_STENCIL_TEXTURE_MODE, eGL_DEPTH_COMPONENT);
|
||||
}
|
||||
|
||||
if(numStencil > 1)
|
||||
{
|
||||
// stencil aspect
|
||||
drv.glActiveTexture(eGL_TEXTURE1);
|
||||
drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, texs[2]);
|
||||
drv.glBindSampler(1, DebugData.pointNoMipSampler);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_DEPTH_STENCIL_TEXTURE_MODE, eGL_STENCIL_INDEX);
|
||||
}
|
||||
|
||||
GLint loc = drv.glGetUniformLocation(DebugData.DepthArray2MS, "mscopy");
|
||||
if(loc >= 0)
|
||||
{
|
||||
for(GLint i = 0; i < arraySize; i++)
|
||||
{
|
||||
if(singleSliceMode)
|
||||
{
|
||||
i = selectedSlice / samples;
|
||||
drv.glSampleMaski(0, 1U << (selectedSlice % samples));
|
||||
}
|
||||
|
||||
drv.glFramebufferTextureLayer(eGL_DRAW_FRAMEBUFFER, attach, texs[0], 0, i);
|
||||
|
||||
for(uint32_t s = 0; s < numStencil; s++)
|
||||
{
|
||||
uint32_t currentStencil = numStencil == 1 ? 1000 : s;
|
||||
|
||||
drv.glStencilFunc(eGL_ALWAYS, int(s), 0xff);
|
||||
|
||||
drv.glProgramUniform4i(DebugData.DepthArray2MS, loc, samples, 0, i, currentStencil);
|
||||
|
||||
drv.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
if(singleSliceMode)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drv.glDeleteFramebuffers(1, &fbo);
|
||||
drv.glDeleteTextures(3, texs);
|
||||
|
||||
rs.ApplyState(m_pDriver);
|
||||
}
|
||||
|
||||
@@ -3031,13 +3031,9 @@ void GLReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t
|
||||
drv.glCompressedTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, width, height, fmt,
|
||||
(GLsizei)dataSize, data);
|
||||
}
|
||||
else if(target == eGL_TEXTURE_2D_MULTISAMPLE)
|
||||
else if(target == eGL_TEXTURE_2D_MULTISAMPLE || target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
RDCUNIMPLEMENTED("multisampled proxy textures");
|
||||
}
|
||||
else if(target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
RDCUNIMPLEMENTED("multisampled proxy textures");
|
||||
RDCERR("Unexpected compressed MSAA texture!");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3089,13 +3085,53 @@ void GLReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t
|
||||
drv.glTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, width, height, baseformat, datatype,
|
||||
data);
|
||||
}
|
||||
else if(target == eGL_TEXTURE_2D_MULTISAMPLE)
|
||||
else if(target == eGL_TEXTURE_2D_MULTISAMPLE || target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
RDCUNIMPLEMENTED("multisampled proxy textures");
|
||||
}
|
||||
else if(target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY)
|
||||
{
|
||||
RDCUNIMPLEMENTED("multisampled proxy textures");
|
||||
// create a temporary 2D array texture to upload the data to. Must use TexStorage to allow
|
||||
// texture views inside CopyArrayToTex2DMS
|
||||
GLuint uploadTex = 0;
|
||||
drv.glGenTextures(1, &uploadTex);
|
||||
drv.glBindTexture(eGL_TEXTURE_2D_ARRAY, uploadTex);
|
||||
drv.glTextureStorage3DEXT(uploadTex, eGL_TEXTURE_2D_ARRAY, 1, texdetails.internalFormat,
|
||||
width, height, texdetails.samples * RDCMAX(1, texdetails.depth));
|
||||
drv.glTexParameteri(eGL_TEXTURE_2D_ARRAY, eGL_TEXTURE_MAX_LEVEL, 0);
|
||||
|
||||
// packed D24S8 is expected the wrong way around from comes in, so we re-swizzle it here
|
||||
if(texdetails.internalFormat == eGL_DEPTH24_STENCIL8)
|
||||
{
|
||||
const uint32_t *srcptr = (const uint32_t *)data;
|
||||
bytebuf swizzled;
|
||||
swizzled.resize(dataSize);
|
||||
uint32_t *dstptr = (uint32_t *)swizzled.data();
|
||||
|
||||
for(GLsizei y = 0; y < height; y++)
|
||||
{
|
||||
for(GLsizei x = 0; x < width; x++)
|
||||
{
|
||||
const uint32_t val = *srcptr;
|
||||
*dstptr = (val << 8) | ((val & 0xff000000) >> 24);
|
||||
srcptr++;
|
||||
dstptr++;
|
||||
}
|
||||
}
|
||||
|
||||
// upload the data to the given slice
|
||||
drv.glTextureSubImage3DEXT(uploadTex, eGL_TEXTURE_2D_ARRAY, 0, 0, 0, (GLint)arrayIdx, width,
|
||||
height, 1, baseformat, datatype, swizzled.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
// upload the data to the given slice
|
||||
drv.glTextureSubImage3DEXT(uploadTex, eGL_TEXTURE_2D_ARRAY, 0, 0, 0, (GLint)arrayIdx, width,
|
||||
height, 1, baseformat, datatype, data);
|
||||
}
|
||||
|
||||
// copy this slice into the 2D MSAA texture
|
||||
CopyArrayToTex2DMS(tex, uploadTex, width, height, 1, texdetails.samples,
|
||||
texdetails.internalFormat, arrayIdx);
|
||||
|
||||
// delete the temporary texture
|
||||
drv.glDeleteTextures(1, &uploadTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,9 +245,14 @@ private:
|
||||
void CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint fragShader);
|
||||
|
||||
void CopyArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height,
|
||||
GLint arraySize, GLint samples, GLenum intFormat);
|
||||
GLint arraySize, GLint samples, GLenum intFormat, uint32_t selectedSlice);
|
||||
void CopyTex2DMSToArray(GLuint &destArray, GLuint srcMS, GLint width, GLint height,
|
||||
GLint arraySize, GLint samples, GLenum intFormat);
|
||||
void CopyDepthArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height,
|
||||
GLint arraySize, GLint samples, GLenum intFormat,
|
||||
uint32_t selectedSlice);
|
||||
void CopyDepthTex2DMSToArray(GLuint &destArray, GLuint srcMS, GLint width, GLint height,
|
||||
GLint arraySize, GLint samples, GLenum intFormat);
|
||||
|
||||
struct OutputWindow : public GLWindowingData
|
||||
{
|
||||
@@ -317,6 +322,7 @@ private:
|
||||
GLuint pickResultBuf;
|
||||
|
||||
GLuint MS2Array, Array2MS;
|
||||
GLuint DepthMS2Array, DepthArray2MS;
|
||||
|
||||
GLuint pointSampler;
|
||||
GLuint pointNoMipSampler;
|
||||
|
||||
Reference in New Issue
Block a user