From 8318720561ed4e1597f3759069baaa46c601871e Mon Sep 17 00:00:00 2001 From: baldurk Date: Sun, 25 Jan 2015 19:31:13 +0000 Subject: [PATCH] Re-implement GL RenderMesh in the new terms - much simpler! * Still missing several features: - solid shading of 'secondary' data - highlighting of vertices/faces/supporting faces - helpers like axis markers or frustum - post VS data and re-projection --- renderdoc/data/glsl/debuguniforms.h | 5 + renderdoc/driver/gl/gl_common.cpp | 52 +++++ renderdoc/driver/gl/gl_common.h | 1 + renderdoc/driver/gl/gl_debug.cpp | 280 ++++++++++++++++-------- renderdoc/driver/gl/gl_replay.cpp | 2 +- renderdocui/Code/CommonPipelineState.cs | 12 + 6 files changed, 258 insertions(+), 94 deletions(-) diff --git a/renderdoc/data/glsl/debuguniforms.h b/renderdoc/data/glsl/debuguniforms.h index c8f8f0509..b8c3765cd 100644 --- a/renderdoc/data/glsl/debuguniforms.h +++ b/renderdoc/data/glsl/debuguniforms.h @@ -113,6 +113,11 @@ BINDING(0) uniform HistogramCBufferData #define RESTYPE_TEX2DMS 0xA #define RESTYPE_TEXTYPEMAX 0xA +#define MESHDISPLAY_SOLID 0x1 +#define MESHDISPLAY_FACELIT 0x2 +#define MESHDISPLAY_SECONDARY 0x3 +#define MESHDISPLAY_SECONDARY_ALPHA 0x4 + #define TEXDISPLAY_TYPEMASK 0xF #define TEXDISPLAY_UINT_TEX 0x10 #define TEXDISPLAY_SINT_TEX 0x20 diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index 4a617a9c5..b844d3ce8 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -659,6 +659,58 @@ ResourceFormat MakeResourceFormat(WrappedOpenGL &gl, GLenum target, GLenum fmt) return ret; } +GLenum MakeGLPrimitiveTopology(PrimitiveTopology Topo) +{ + switch(Topo) + { + default: return eGL_NONE; + case eTopology_PointList: return eGL_POINTS; + case eTopology_LineStrip: return eGL_LINE_STRIP; + case eTopology_LineLoop: return eGL_LINE_LOOP; + case eTopology_LineList: return eGL_LINES; + case eTopology_LineStrip_Adj: return eGL_LINE_STRIP_ADJACENCY; + case eTopology_LineList_Adj: return eGL_LINES_ADJACENCY; + case eTopology_TriangleStrip: return eGL_TRIANGLE_STRIP; + case eTopology_TriangleFan: return eGL_TRIANGLE_FAN; + case eTopology_TriangleList: return eGL_TRIANGLES; + case eTopology_TriangleStrip_Adj: return eGL_TRIANGLE_STRIP_ADJACENCY; + case eTopology_TriangleList_Adj: return eGL_TRIANGLES_ADJACENCY; + case eTopology_PatchList_1CPs: + case eTopology_PatchList_2CPs: + case eTopology_PatchList_3CPs: + case eTopology_PatchList_4CPs: + case eTopology_PatchList_5CPs: + case eTopology_PatchList_6CPs: + case eTopology_PatchList_7CPs: + case eTopology_PatchList_8CPs: + case eTopology_PatchList_9CPs: + case eTopology_PatchList_10CPs: + case eTopology_PatchList_11CPs: + case eTopology_PatchList_12CPs: + case eTopology_PatchList_13CPs: + case eTopology_PatchList_14CPs: + case eTopology_PatchList_15CPs: + case eTopology_PatchList_16CPs: + case eTopology_PatchList_17CPs: + case eTopology_PatchList_18CPs: + case eTopology_PatchList_19CPs: + case eTopology_PatchList_20CPs: + case eTopology_PatchList_21CPs: + case eTopology_PatchList_22CPs: + case eTopology_PatchList_23CPs: + case eTopology_PatchList_24CPs: + case eTopology_PatchList_25CPs: + case eTopology_PatchList_26CPs: + case eTopology_PatchList_27CPs: + case eTopology_PatchList_28CPs: + case eTopology_PatchList_29CPs: + case eTopology_PatchList_30CPs: + case eTopology_PatchList_31CPs: + case eTopology_PatchList_32CPs: + return eGL_PATCHES; + } +} + PrimitiveTopology MakePrimitiveTopology(const GLHookSet &gl, GLenum Topo) { switch(Topo) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 9ff3d6931..0f6b79736 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -87,6 +87,7 @@ GLenum ShaderEnum(size_t idx); ResourceFormat MakeResourceFormat(WrappedOpenGL &gl, GLenum target, GLenum fmt); GLenum MakeGLFormat(WrappedOpenGL &gl, GLenum target, ResourceFormat fmt); PrimitiveTopology MakePrimitiveTopology(const GLHookSet &gl, GLenum Topo); +GLenum MakeGLPrimitiveTopology(PrimitiveTopology Topo); const char *BlendString(GLenum blendenum); const char *SamplerString(GLenum smpenum); diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 487ae179d..c55234373 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1008,6 +1008,8 @@ bool GLReplay::RenderTexture(TextureDisplay cfg) gl.glBlendFunc(eGL_SRC_ALPHA, eGL_ONE_MINUS_SRC_ALPHA); } + gl.glDisable(eGL_DEPTH_TEST); + gl.glEnable(eGL_FRAMEBUFFER_SRGB); gl.glBindVertexArray(DebugData.emptyVAO); @@ -1452,61 +1454,12 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) { -#if 0 WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(m_DebugCtx); - - GLuint curFBO = 0; - gl.glGetIntegerv(eGL_FRAMEBUFFER_BINDING, (GLint*)&curFBO); - OutputWindow *outw = NULL; - for(auto it = m_OutputWindows.begin(); it != m_OutputWindows.end(); ++it) - { - if(it->second.BlitData.windowFBO == curFBO) - { - outw = &it->second; - break; - } - } - - if(!outw) return; - - const auto &attr = m_CurPipelineState.m_VtxIn.attributes[0]; - const auto &vb = m_CurPipelineState.m_VtxIn.vbuffers[attr.BufferSlot]; - - if(vb.Buffer == ResourceId()) + if(cfg.position.buf == ResourceId()) return; - MakeCurrentReplayContext(&m_ReplayCtx); - - GLint viewport[4]; - gl.glGetIntegerv(eGL_VIEWPORT, viewport); - - gl.glGetIntegerv(eGL_FRAMEBUFFER_BINDING, (GLint*)&curFBO); - - if(outw->BlitData.replayFBO == 0) - { - gl.glGenFramebuffers(1, &outw->BlitData.replayFBO); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, outw->BlitData.replayFBO); - - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, outw->BlitData.backbuffer, 0); - } - else - { - gl.glBindFramebuffer(eGL_FRAMEBUFFER, outw->BlitData.replayFBO); - } - - gl.glViewport(0, 0, (GLsizei)DebugData.outWidth, (GLsizei)DebugData.outHeight); - - GLuint curProg = 0; - gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg); - - gl.glUseProgram(DebugData.meshProg); - - float wireCol[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - GLint colLoc = gl.glGetUniformLocation(DebugData.meshProg, "RENDERDOC_GenericFS_Color"); - gl.glUniform4fv(colLoc, 1, wireCol); + MakeCurrentReplayContext(m_DebugCtx); Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth/DebugData.outHeight); @@ -1519,62 +1472,203 @@ void GLReplay::RenderMesh(uint32_t frameID, uint32_t eventID, const vectorGetResourceManager()->GetLiveResource(vb.Buffer).name); + for(uint32_t i=0; i < 2; i++) + { + if(fmts[i]->buf == ResourceId()) continue; - if(attr.Format.compType == eCompType_Float && attr.Format.compByteWidth == 4) - { - gl.glVertexAttribPointer(0, attr.Format.compCount, eGL_FLOAT, GL_FALSE, 0, (void *)intptr_t(vb.Offset + attr.RelativeOffset)); - } - else if(attr.Format.compType == eCompType_Float && attr.Format.compByteWidth == 2) - { - gl.glVertexAttribPointer(0, attr.Format.compCount, eGL_HALF_FLOAT, GL_FALSE, 0, (void *)intptr_t(vb.Offset + attr.RelativeOffset)); - } - else - { - RDCERR("Not handling mesh display of unsupported format"); - return; + if(fmts[i]->specialFormat != eSpecial_Unknown) + { + if(fmts[i]->specialFormat == eSpecial_R10G10B10A2) + { + if(fmts[i]->compType == eCompType_UInt) + gl.glVertexAttribIFormat(i, 4, eGL_UNSIGNED_INT_2_10_10_10_REV, 0); + if(fmts[i]->compType == eCompType_SInt) + gl.glVertexAttribIFormat(i, 4, eGL_INT_2_10_10_10_REV, 0); + } + else if(fmts[i]->specialFormat == eSpecial_R11G11B10) + { + gl.glVertexAttribFormat(i, 4, eGL_UNSIGNED_INT_10F_11F_11F_REV, GL_FALSE, 0); + } + else + { + RDCWARN("Unsupported special vertex attribute format: %x", fmts[i]->specialFormat); + } + } + else if(fmts[i]->compType == eCompType_Float || + fmts[i]->compType == eCompType_UNorm || + fmts[i]->compType == eCompType_SNorm) + { + GLenum fmttype = eGL_UNSIGNED_INT; + + if(fmts[i]->compByteWidth == 4) + { + if(fmts[i]->compType == eCompType_Float) fmttype = eGL_FLOAT; + else if(fmts[i]->compType == eCompType_UNorm) fmttype = eGL_UNSIGNED_INT; + else if(fmts[i]->compType == eCompType_SNorm) fmttype = eGL_INT; + } + else if(fmts[i]->compByteWidth == 2) + { + if(fmts[i]->compType == eCompType_Float) fmttype = eGL_HALF_FLOAT; + else if(fmts[i]->compType == eCompType_UNorm) fmttype = eGL_UNSIGNED_SHORT; + else if(fmts[i]->compType == eCompType_SNorm) fmttype = eGL_SHORT; + } + else if(fmts[i]->compByteWidth == 1) + { + if(fmts[i]->compType == eCompType_UNorm) fmttype = eGL_UNSIGNED_BYTE; + else if(fmts[i]->compType == eCompType_SNorm) fmttype = eGL_BYTE; + } + + gl.glVertexAttribFormat(i, fmts[i]->compCount, fmttype, fmts[i]->compType != eCompType_Float, 0); + } + else if(fmts[i]->compType == eCompType_UInt || + fmts[i]->compType == eCompType_SInt) + { + GLenum fmttype = eGL_UNSIGNED_INT; + + if(fmts[i]->compByteWidth == 4) + { + if(fmts[i]->compType == eCompType_UInt) fmttype = eGL_UNSIGNED_INT; + else if(fmts[i]->compType == eCompType_SInt) fmttype = eGL_INT; + } + else if(fmts[i]->compByteWidth == 2) + { + if(fmts[i]->compType == eCompType_UInt) fmttype = eGL_UNSIGNED_SHORT; + else if(fmts[i]->compType == eCompType_SInt) fmttype = eGL_SHORT; + } + else if(fmts[i]->compByteWidth == 1) + { + if(fmts[i]->compType == eCompType_UInt) fmttype = eGL_UNSIGNED_BYTE; + else if(fmts[i]->compType == eCompType_SInt) fmttype = eGL_BYTE; + } + + gl.glVertexAttribIFormat(i, fmts[i]->compCount, fmttype, 0); + } + else if(fmts[i]->compType == eCompType_Double) + { + gl.glVertexAttribLFormat(i, fmts[i]->compCount, eGL_DOUBLE, 0); + } + + gl.glBindVertexBuffer(i, m_pDriver->GetResourceManager()->GetCurrentResource(fmts[i]->buf).name, fmts[i]->offset, fmts[i]->stride); } + // enable position attribute gl.glEnableVertexAttribArray(0); + + GLenum topo = MakeGLPrimitiveTopology(cfg.position.topo); + gl.glDisable(eGL_DEPTH_TEST); + + GLuint prog = DebugData.meshProg; + + if(cfg.solidShadeMode == eShade_Lit) { - GLint depthTest = GL_FALSE; - gl.glGetIntegerv(eGL_DEPTH_TEST, (GLint*)&depthTest); - GLenum polyMode = eGL_FILL; - if(!VendorCheck[VendorCheck_AMD_polygon_mode_query]) - gl.glGetIntegerv(eGL_POLYGON_MODE, (GLint*)&polyMode); + // pick program with GS for per-face lighting + } + + GLint colLoc = gl.glGetUniformLocation(prog, "RENDERDOC_GenericFS_Color"); + GLint mvpLoc = gl.glGetUniformLocation(prog, "ModelViewProj"); + GLint fmtLoc = gl.glGetUniformLocation(prog, "Mesh_DisplayFormat"); + + gl.glUseProgram(prog); + + if(cfg.position.unproject) + { + // calc reproject matrix + } + + gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); + + // solid render + if(cfg.solidShadeMode != eShade_None && topo != eGL_PATCHES) + { + if(cfg.solidShadeMode == eShade_Lit) + { + // set GS-specific uniform + } + + float wireCol[] = { 0.8f, 0.8f, 0.0f, 1.0f }; + gl.glUniform4fv(colLoc, 1, wireCol); + + GLint OutputDisplayFormat = (int)cfg.solidShadeMode; + if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha) + OutputDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA; + gl.glUniform1i(fmtLoc, OutputDisplayFormat); + + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + + if(cfg.position.idxbuf != ResourceId()) + { + GLenum idxtype = eGL_UNSIGNED_BYTE; + if(cfg.position.idxByteWidth == 2) + idxtype = eGL_UNSIGNED_SHORT; + else if(cfg.position.idxByteWidth == 4) + idxtype = eGL_UNSIGNED_INT; + + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name); + gl.glDrawElements(topo, cfg.position.numVerts, idxtype, (const void *)(cfg.position.idxoffs)); + } + else + { + gl.glDrawArrays(topo, 0, cfg.position.numVerts); + } + } + + colLoc = gl.glGetUniformLocation(prog, "RENDERDOC_GenericFS_Color"); + mvpLoc = gl.glGetUniformLocation(prog, "ModelViewProj"); + fmtLoc = gl.glGetUniformLocation(prog, "Mesh_DisplayFormat"); + + gl.glUseProgram(prog); + + gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); + + // wireframe render + if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || topo == eGL_PATCHES) + { + float wireCol[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + gl.glUniform4fv(colLoc, 1, wireCol); - gl.glDisable(eGL_DEPTH_TEST); gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); - ReplayLog(frameID, 0, events[0], eReplay_OnlyDraw); + if(topo == eGL_PATCHES) topo = eGL_POINTS; - if(depthTest) - gl.glEnable(eGL_DEPTH_TEST); - if(polyMode != eGL_LINE) - gl.glPolygonMode(eGL_FRONT_AND_BACK, polyMode); + if(cfg.position.idxbuf != ResourceId()) + { + GLenum idxtype = eGL_UNSIGNED_BYTE; + if(cfg.position.idxByteWidth == 2) + idxtype = eGL_UNSIGNED_SHORT; + else if(cfg.position.idxByteWidth == 4) + idxtype = eGL_UNSIGNED_INT; + + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name); + gl.glDrawElements(topo, cfg.position.numVerts, idxtype, (const void *)(cfg.position.idxoffs)); + } + else + { + gl.glDrawArrays(topo, 0, cfg.position.numVerts); + } + } + + if(!cfg.position.unproject) + { + // draw axis markers + } + + if(cfg.highlightVert != ~0U) + { + // show highlighted vertex } - gl.glBindVertexArray(curVAO); - gl.glBindBuffer(eGL_ARRAY_BUFFER, curArr); - - gl.glUseProgram(curProg); - gl.glViewport(viewport[0], viewport[1], (GLsizei)viewport[2], (GLsizei)viewport[3]); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, curFBO); -#endif + if(cfg.position.unproject) + { + // 'fake' helper frustum + } + + // set this back as most other things want fill, and we don't want to have to a) track it + // b) set fill explicitly everywhere else + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); } diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index e0c743e6a..afc9274ba 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -1100,7 +1100,7 @@ void GLReplay::SavePipelineState() fmt.special = true; fmt.specialFormat = eSpecial_R11G11B10; fmt.compCount = 3; - fmt.compType = eCompType_SInt; + fmt.compType = eCompType_Float; fmt.strname = "GL_UNSIGNED_INT_10F_11F_11F_REV"; break; } diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index 2b3bada3c..f3a11449b 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -406,6 +406,18 @@ namespace renderdocui.Code ret[a].InstanceRate = (int)m_GL.m_VtxIn.vbuffers[attrs[i].BufferSlot].Divisor; ret[a].Format = attrs[i].Format; + if (m_GL.m_VS.ShaderDetails != null) + { + foreach (var isig in m_GL.m_VS.ShaderDetails.InputSig) + { + if (isig.regIndex == attrs[i].BufferSlot) + { + ret[a].Name = isig.varName; + break; + } + } + } + a++; }