From 602b28c614c8aacfeebe48976233b98255049654 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 2 Nov 2014 22:47:52 +0000 Subject: [PATCH] Abstract out function to copy uniform values between programs * This needs to be refactored to use the program interface query API so we can get the location of uniform blocks and set them * We also need to copy over sampler uniform values (getting away with it for now as we're generally replacing the pixel shader, so there aren't any samplers used in the cases I've tested). --- renderdoc/driver/gl/gl_debug.cpp | 186 +++++++++++++++---------------- renderdoc/driver/gl/gl_replay.h | 2 + 2 files changed, 94 insertions(+), 94 deletions(-) diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 4d3c98a8a..b67f70068 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -817,6 +817,96 @@ void GLReplay::RenderHighlightBox(float w, float h, float scale) gl.glDrawArrays(eGL_LINE_LOOP, 0, 4); } +void GLReplay::CopyProgramUniforms(WrappedOpenGL &gl, GLuint progSrc, GLuint progDst) +{ + // copy across uniforms + GLint numUniforms = 0; + gl.glGetProgramiv(progSrc, eGL_ACTIVE_UNIFORMS, &numUniforms); + + for(GLint i=0; i < numUniforms; i++) + { + char uniName[1024] = {}; + GLint uniSize = 0; + GLenum uniType = eGL_NONE; + gl.glGetActiveUniform(progSrc, i, 1024, NULL, &uniSize, &uniType, uniName); + + double dv[16]; + float *fv = (float *)dv; + int32_t *iv = (int32_t *)dv; + uint32_t *uv = (uint32_t *)dv; + + bool isArray = false; + + if(uniSize > 1) + { + isArray = true; + + size_t len = strlen(uniName); + + if(uniName[len-3] == '[' && uniName[len-2] == '0' && uniName[len-1] == ']') + uniName[len-3] = 0; + } + else + { + uniSize = 1; + } + + for(GLint arr=0; arr < uniSize; arr++) + { + string name = uniName; + + if(isArray) + name += StringFormat::Fmt("[%d]", arr); + + GLint origloc = gl.glGetUniformLocation(progSrc, name.c_str()); + GLint newloc = gl.glGetUniformLocation(progDst, name.c_str()); + + if(origloc != -1 && newloc != -1) + { + if(uniType == eGL_FLOAT_MAT4) + { + gl.glGetUniformfv(progSrc, origloc, fv); + gl.glProgramUniformMatrix4fv(progDst, newloc, 1, false, fv); + } + else if(uniType == eGL_FLOAT) + { + gl.glGetUniformfv(progSrc, origloc, fv); + gl.glProgramUniform1fv(progDst, newloc, 1, fv); + } + else if(uniType == eGL_FLOAT_VEC2) + { + gl.glGetUniformfv(progSrc, origloc, fv); + gl.glProgramUniform2fv(progDst, newloc, 1, fv); + } + else if(uniType == eGL_FLOAT_VEC3) + { + gl.glGetUniformfv(progSrc, origloc, fv); + gl.glProgramUniform3fv(progDst, newloc, 1, fv); + } + else if(uniType == eGL_FLOAT_VEC4) + { + gl.glGetUniformfv(progSrc, origloc, fv); + gl.glProgramUniform4fv(progDst, newloc, 1, fv); + } + else if(uniType == eGL_INT) + { + gl.glGetUniformiv(progSrc, origloc, iv); + gl.glProgramUniform1iv(progDst, newloc, 1, iv); + } + else if(uniType == eGL_UNSIGNED_INT) + { + gl.glGetUniformuiv(progSrc, origloc, uv); + gl.glProgramUniform1uiv(progDst, newloc, 1, uv); + } + else + { + RDCERR("Uniform type '%hs' not being copied to new program", ToStr::Get(uniType).c_str()); + } + } + } + } +} + ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector &passEvents) { WrappedOpenGL &gl = *m_pDriver; @@ -911,53 +1001,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl { gl.glUseProgram(progDetails.colOutProg); - { - // copy across uniforms - GLint numUniforms = 0; - gl.glGetProgramiv(curProg, eGL_ACTIVE_UNIFORMS, &numUniforms); - - for(GLint i=0; i < numUniforms; i++) - { - char uniName[1024] = {}; - GLint uniSize = 0; - GLenum uniType = eGL_NONE; - gl.glGetActiveUniform(curProg, i, 1024, NULL, &uniSize, &uniType, uniName); - - GLint origloc = gl.glGetUniformLocation(curProg, uniName); - GLint newloc = gl.glGetUniformLocation(progDetails.colOutProg, uniName); - - double dv[16]; - float *fv = (float *)dv; - - if(uniSize > 1) - { - RDCERR("Array elements beyond [0] not being copied to new program"); - } - - if(origloc != -1 && newloc != -1) - { - if(uniType == eGL_FLOAT_MAT4) - { - gl.glGetUniformfv(curProg, origloc, fv); - gl.glUniformMatrix4fv(newloc, 1, false, fv); - } - else if(uniType == eGL_FLOAT_VEC3) - { - gl.glGetUniformfv(curProg, origloc, fv); - gl.glUniform3fv(newloc, 1, fv); - } - else if(uniType == eGL_FLOAT_VEC4) - { - gl.glGetUniformfv(curProg, origloc, fv); - gl.glUniform4fv(newloc, 1, fv); - } - else - { - RDCERR("Uniform type '%hs' not being copied to new program", ToStr::Get(uniType).c_str()); - } - } - } - } + CopyProgramUniforms(gl, curProg, progDetails.colOutProg); float black[] = { 0.0f, 0.0f, 0.0f, 0.5f }; gl.glClearBufferfv(eGL_COLOR, 0, black); @@ -974,53 +1018,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl { gl.glUseProgram(progDetails.colOutProg); - { - // copy across uniforms - GLint numUniforms = 0; - gl.glGetProgramiv(curProg, eGL_ACTIVE_UNIFORMS, &numUniforms); - - for(GLint i=0; i < numUniforms; i++) - { - char uniName[1024] = {}; - GLint uniSize = 0; - GLenum uniType = eGL_NONE; - gl.glGetActiveUniform(curProg, i, 1024, NULL, &uniSize, &uniType, uniName); - - GLint origloc = gl.glGetUniformLocation(curProg, uniName); - GLint newloc = gl.glGetUniformLocation(progDetails.colOutProg, uniName); - - double dv[16]; - float *fv = (float *)dv; - - if(uniSize > 1) - { - RDCERR("Array elements beyond [0] not being copied to new program"); - } - - if(origloc != -1 && newloc != -1) - { - if(uniType == eGL_FLOAT_MAT4) - { - gl.glGetUniformfv(curProg, origloc, fv); - gl.glUniformMatrix4fv(newloc, 1, false, fv); - } - else if(uniType == eGL_FLOAT_VEC3) - { - gl.glGetUniformfv(curProg, origloc, fv); - gl.glUniform3fv(newloc, 1, fv); - } - else if(uniType == eGL_FLOAT_VEC4) - { - gl.glGetUniformfv(curProg, origloc, fv); - gl.glUniform4fv(newloc, 1, fv); - } - else - { - RDCERR("Uniform type '%hs' not being copied to new program", ToStr::Get(uniType).c_str()); - } - } - } - } + CopyProgramUniforms(gl, curProg, progDetails.colOutProg); float wireCol[] = { 200.0f/255.0f, 255.0f/255.0f, 0.0f/255.0f, 0.0f }; gl.glClearBufferfv(eGL_COLOR, 0, wireCol); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 0695e5243..358c89ee2 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -137,6 +137,8 @@ class GLReplay : public IReplayDriver void GetMapping(WrappedOpenGL &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping); + void CopyProgramUniforms(WrappedOpenGL &gl, GLuint progSrc, GLuint progDst); + struct OutputWindow : public GLWindowingData { struct