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
This commit is contained in:
baldurk
2015-01-25 19:31:13 +00:00
parent da2470dbcf
commit 8318720561
6 changed files with 258 additions and 94 deletions
+5
View File
@@ -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
+52
View File
@@ -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)
+1
View File
@@ -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);
+187 -93
View File
@@ -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<MeshFormat> &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 vector<MeshF
Matrix4f camMat = cam.GetMatrix();
Matrix4f ModelViewProj = projMat.Mul(camMat);
GLint mvpLoc = gl.glGetUniformLocation(DebugData.meshProg, "ModelViewProj");
gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data());
GLuint curVAO = 0;
gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint*)&curVAO);
GLuint curArr = 0;
gl.glGetIntegerv(eGL_ARRAY_BUFFER_BINDING, (GLint*)&curArr);
gl.glBindVertexArray(DebugData.meshVAO);
// TODO: we should probably use glBindVertexBuffer, glVertexAttribFormat, glVertexAttribBinding.
// For now just assume things about the format and vbuffer.
const MeshFormat *fmts[2] = { &cfg.position, &cfg.second };
gl.glBindBuffer(eGL_ARRAY_BUFFER, m_pDriver->GetResourceManager()->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);
}
+1 -1
View File
@@ -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;
}
+12
View File
@@ -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++;
}