Improve GL Pixel History per PR feedback

- Blit fragments and read back results in batch
- Modify per fragment callbacks to reduce number of full replays
- Use defines in the primitiveId shader to toggle between float/int
  output
This commit is contained in:
Orson Baines
2022-11-22 21:48:00 -07:00
committed by Baldur Karlsson
parent c0b931eb15
commit 5b5d2aa191
11 changed files with 554 additions and 409 deletions
-1
View File
@@ -433,7 +433,6 @@ set(data
data/glsl/pixelhistory_mscopy.comp
data/glsl/pixelhistory_mscopy_depth.comp
data/glsl/pixelhistory_primid.frag
data/glsl/pixelhistory_primid_legacy.frag
data/glsl/shaderdebug_sample.vert
data/glsl/texdisplay.frag
data/glsl/texremap.frag
-1
View File
@@ -66,7 +66,6 @@ DECLARE_EMBED(glsl_gles_texsample_h);
DECLARE_EMBED(glsl_pixelhistory_mscopy_comp);
DECLARE_EMBED(glsl_pixelhistory_mscopy_depth_comp);
DECLARE_EMBED(glsl_pixelhistory_primid_frag);
DECLARE_EMBED(glsl_pixelhistory_primid_legacy_frag);
DECLARE_EMBED(glsl_shaderdebug_sample_vert);
DECLARE_EMBED(glsl_texremap_frag);
DECLARE_EMBED(glsl_discard_frag);
@@ -28,5 +28,9 @@ IO_LOCATION(0) out vec4 color_out;
void main(void)
{
#ifdef INT_BITS_TO_FLOAT_NOT_SUPPORTED
color_out = vec4(float(gl_PrimitiveID));
#else
color_out = vec4(intBitsToFloat(gl_PrimitiveID));
#endif
}
@@ -1,32 +0,0 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2020-2022 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "glsl_globals.h"
IO_LOCATION(0) out vec4 color_out;
void main(void)
{
color_out = vec4(float(gl_PrimitiveID));
}
-1
View File
@@ -156,7 +156,6 @@ RESOURCE_glsl_histogram_comp TYPE_EMBED "glsl/histogram.comp"
RESOURCE_glsl_pixelhistory_mscopy_comp TYPE_EMBED "glsl/pixelhistory_mscopy.comp"
RESOURCE_glsl_pixelhistory_mscopy_depth_comp TYPE_EMBED "glsl/pixelhistory_mscopy_depth.comp"
RESOURCE_glsl_pixelhistory_primid_frag TYPE_EMBED "glsl/pixelhistory_primid.frag"
RESOURCE_glsl_pixelhistory_primid_legacy_frag TYPE_EMBED "glsl/pixelhistory_primid_legacy.frag"
RESOURCE_glsl_glsl_ubos_h TYPE_EMBED "glsl/glsl_ubos.h"
RESOURCE_glsl_gl_texsample_h TYPE_EMBED "glsl/gl_texsample.h"
RESOURCE_glsl_vk_texsample_h TYPE_EMBED "glsl/vk_texsample.h"
-1
View File
@@ -65,7 +65,6 @@
#define RESOURCE_glsl_vk_depthms2buffer_comp 448
#define RESOURCE_glsl_vk_buffer2ms_comp 449
#define RESOURCE_glsl_vk_depthbuf2ms_frag 450
#define RESOURCE_glsl_pixelhistory_primid_legacy_frag 451
// Next default values for new objects
//
+40 -31
View File
@@ -36,19 +36,14 @@
#define OPENGL 1
#include "data/glsl/glsl_ubos_cpp.h"
bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint fragShader,
GLuint fragShaderSPIRV)
bool GLReplay::CreateFragmentShaderReplacementProgram(GLuint program, GLuint replacementProgram,
GLuint pipeline, GLuint fragShader,
GLuint fragShaderSPIRV)
{
WrappedOpenGL &drv = *m_pDriver;
ContextPair &ctx = drv.GetCtx();
// delete the old program if it exists
if(DebugData.overlayProg != 0)
drv.glDeleteProgram(DebugData.overlayProg);
DebugData.overlayProg = drv.glCreateProgram();
// these are the shaders to attach, and the programs to copy details from
GLuint shaders[4] = {0};
GLuint programs[4] = {0};
@@ -63,15 +58,15 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
bool HasSPIRVShaders = false;
bool HasGLSLShaders = false;
if(Program == 0)
if(program == 0)
{
if(Pipeline == 0)
if(pipeline == 0)
{
return false;
}
else
{
ResourceId id = m_pDriver->GetResourceManager()->GetResID(ProgramPipeRes(ctx, Pipeline));
ResourceId id = m_pDriver->GetResourceManager()->GetResID(ProgramPipeRes(ctx, pipeline));
const WrappedOpenGL::PipelineData &pipeDetails = m_pDriver->m_Pipelines[id];
// fetch the corresponding shaders and programs for each stage
@@ -116,7 +111,8 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
{
char buffer[1024] = {};
drv.glGetShaderInfoLog(tmpShaders[i], 1024, NULL, buffer);
RDCERR("Trying to recreate overlay program, couldn't compile shader:\n%s", buffer);
RDCERR("Trying to recreate replacement program, couldn't compile shader:\n%s",
buffer);
}
}
}
@@ -130,14 +126,14 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
else
{
const WrappedOpenGL::ProgramData &progDetails =
m_pDriver->m_Programs[m_pDriver->GetResourceManager()->GetResID(ProgramRes(ctx, Program))];
m_pDriver->m_Programs[m_pDriver->GetResourceManager()->GetResID(ProgramRes(ctx, program))];
// fetch any and all non-fragment shader shaders
for(size_t i = 0; i < 4; i++)
{
if(progDetails.stageShaders[i] != ResourceId())
{
programs[i] = Program;
programs[i] = program;
shaders[i] =
m_pDriver->GetResourceManager()->GetCurrentResource(progDetails.stageShaders[i]).name;
@@ -161,34 +157,34 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
// attach the shaders
for(size_t i = 0; i < 4; i++)
if(shaders[i])
drv.glAttachShader(DebugData.overlayProg, shaders[i]);
drv.glAttachShader(replacementProgram, shaders[i]);
if(HasSPIRVShaders)
{
RDCASSERT(fragShaderSPIRV);
drv.glAttachShader(DebugData.overlayProg, fragShaderSPIRV);
drv.glAttachShader(replacementProgram, fragShaderSPIRV);
}
else
{
drv.glAttachShader(DebugData.overlayProg, fragShader);
drv.glAttachShader(replacementProgram, fragShader);
}
// copy the vertex attribs over from the source program
if(vsRefl && programs[0] && !HasSPIRVShaders)
CopyProgramAttribBindings(programs[0], DebugData.overlayProg, vsRefl);
CopyProgramAttribBindings(programs[0], replacementProgram, vsRefl);
// link the overlay program
drv.glLinkProgram(DebugData.overlayProg);
drv.glLinkProgram(replacementProgram);
// detach the shaders
for(size_t i = 0; i < 4; i++)
if(shaders[i])
drv.glDetachShader(DebugData.overlayProg, shaders[i]);
drv.glDetachShader(replacementProgram, shaders[i]);
if(HasSPIRVShaders)
drv.glDetachShader(DebugData.overlayProg, fragShaderSPIRV);
drv.glDetachShader(replacementProgram, fragShaderSPIRV);
else
drv.glDetachShader(DebugData.overlayProg, fragShader);
drv.glDetachShader(replacementProgram, fragShader);
// delete any temporaries
for(size_t i = 0; i < 4; i++)
@@ -198,10 +194,10 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
// check that the link succeeded
char buffer[1024] = {};
GLint status = 0;
drv.glGetProgramiv(DebugData.overlayProg, eGL_LINK_STATUS, &status);
drv.glGetProgramiv(replacementProgram, eGL_LINK_STATUS, &status);
if(status == 0)
{
drv.glGetProgramInfoLog(DebugData.overlayProg, 1024, NULL, buffer);
drv.glGetProgramInfoLog(replacementProgram, 1024, NULL, buffer);
RDCERR("Error linking overlay program: %s", buffer);
return false;
}
@@ -210,7 +206,7 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
// same program is bound to multiple stages. It's just inefficient
{
PerStageReflections dstStages;
m_pDriver->FillReflectionArray(ProgramRes(ctx, DebugData.overlayProg), dstStages);
m_pDriver->FillReflectionArray(ProgramRes(ctx, replacementProgram), dstStages);
for(size_t i = 0; i < 4; i++)
{
@@ -219,7 +215,7 @@ bool GLReplay::CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint frag
PerStageReflections stages;
m_pDriver->FillReflectionArray(ProgramRes(ctx, programs[i]), stages);
CopyProgramUniforms(stages, programs[i], dstStages, DebugData.overlayProg);
CopyProgramUniforms(stages, programs[i], dstStages, replacementProgram);
}
}
}
@@ -479,12 +475,18 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
RDCWARN("Quad overdraw not supported on GLES", glslVer);
}
// delete the old program if it exists
if(DebugData.overlayProg != 0)
drv.glDeleteProgram(DebugData.overlayProg);
DebugData.overlayProg = drv.glCreateProgram();
// we bind the separable program created for each shader, and copy
// uniforms and attrib bindings from the 'real' programs, wherever
// they are.
bool spirvOverlay =
CreateOverlayProgram(rs.Program.name, rs.Pipeline.name, DebugData.fixedcolFragShader,
DebugData.fixedcolFragShaderSPIRV);
bool spirvOverlay = CreateFragmentShaderReplacementProgram(
rs.Program.name, DebugData.overlayProg, rs.Pipeline.name, DebugData.fixedcolFragShader,
DebugData.fixedcolFragShaderSPIRV);
drv.glUseProgram(DebugData.overlayProg);
GLint overlayFixedColLocation = 0;
@@ -2029,11 +2031,18 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FloatVector clearCol, Debug
drv.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog);
drv.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&pipe);
// delete the old program if it exists
if(DebugData.overlayProg != 0)
drv.glDeleteProgram(DebugData.overlayProg);
DebugData.overlayProg = drv.glCreateProgram();
// replace fragment shader. This is exactly what we did
// at the start of this function for the single-event case, but now we have
// to do it for every event
spirvOverlay = CreateOverlayProgram(prog, pipe, DebugData.quadoverdrawFragShader,
DebugData.quadoverdrawFragShaderSPIRV);
spirvOverlay = CreateFragmentShaderReplacementProgram(
prog, DebugData.overlayProg, pipe, DebugData.quadoverdrawFragShader,
DebugData.quadoverdrawFragShaderSPIRV);
drv.glUseProgram(DebugData.overlayProg);
drv.glBindProgramPipeline(0);
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -277,6 +277,9 @@ public:
GLint yoffset = 0, GLint zoffset = 0, GLsizei width = 65536,
GLsizei height = 65536, GLsizei depth = 65536);
bool CreateFragmentShaderReplacementProgram(GLuint program, GLuint replacedProgram, GLuint pipeline,
GLuint fragShader, GLuint fragShaderSPIRV);
private:
void OpenGLFillCBufferVariables(ResourceId shader, GLuint prog, bool bufferBacked, rdcstr prefix,
const rdcarray<ShaderConstant> &variables,
@@ -286,8 +289,6 @@ private:
float *minval, float *maxval);
void CreateCustomShaderTex(uint32_t w, uint32_t h);
bool CreateOverlayProgram(GLuint Program, GLuint Pipeline, GLuint fragShader,
GLuint fragShaderSPIRV);
struct OutputWindow : public GLWindowingData
{
-1
View File
@@ -700,7 +700,6 @@
<None Include="data\glsl\pixelhistory_mscopy.comp" />
<None Include="data\glsl\pixelhistory_mscopy_depth.comp" />
<None Include="data\glsl\pixelhistory_primid.frag" />
<None Include="data\glsl\pixelhistory_primid_legacy.frag" />
<None Include="data\glsl\quadresolve.frag" />
<None Include="data\glsl\quadwrite.frag" />
<None Include="data\glsl\shaderdebug_sample.vert" />
-3
View File
@@ -1030,9 +1030,6 @@
<None Include="data\glsl\pixelhistory_primid.frag">
<Filter>Resources\glsl</Filter>
</None>
<None Include="data\glsl\pixelhistory_primid_legacy.frag">
<Filter>Resources\glsl</Filter>
</None>
<None Include="data\glsl\quadresolve.frag">
<Filter>Resources\glsl</Filter>
</None>