From 761f8be4bd047c5821373466b0ccb22577d3ae0c Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 4 Jan 2019 11:48:35 +0000 Subject: [PATCH] Fix mesh view with double vertex attribute inputs --- renderdoc/data/glsl/mesh.vert | 22 +++++-- renderdoc/driver/gl/gl_common.h | 2 + renderdoc/driver/gl/gl_debug.cpp | 88 +++++++++++++++++++++++++-- renderdoc/driver/gl/gl_rendermesh.cpp | 33 ++++++++-- renderdoc/driver/gl/gl_replay.h | 5 +- 5 files changed, 130 insertions(+), 20 deletions(-) diff --git a/renderdoc/data/glsl/mesh.vert b/renderdoc/data/glsl/mesh.vert index a8f790ef5..ea6ad65b9 100644 --- a/renderdoc/data/glsl/mesh.vert +++ b/renderdoc/data/glsl/mesh.vert @@ -22,8 +22,18 @@ * THE SOFTWARE. ******************************************************************************/ -layout(location = 0) in vec4 position; -layout(location = 1) in vec4 IN_secondary; +// this allows overrides from outside to change to e.g. dvec4 + +#ifndef POSITION_TYPE +#define POSITION_TYPE vec4 +#endif + +#ifndef SECONDARY_TYPE +#define SECONDARY_TYPE vec4 +#endif + +layout(location = 0) in POSITION_TYPE position; +layout(location = 1) in SECONDARY_TYPE IN_secondary; #ifndef OPENGL_ES out gl_PerVertex @@ -41,21 +51,21 @@ void main(void) vec2 psprite[4] = vec2[](vec2(-1.0f, -1.0f), vec2(-1.0f, 1.0f), vec2(1.0f, -1.0f), vec2(1.0f, 1.0f)); - vec4 pos = position; + vec4 pos = vec4(position); if(Mesh.homogenousInput == 0u) { - pos = vec4(position.xyz, 1); + pos = vec4(pos.xyz, 1); } else { #ifdef VULKAN - pos = vec4(position.x, -position.y, position.z, position.w); + pos = vec4(pos.x, -pos.y, pos.z, pos.w); #endif } gl_Position = Mesh.mvp * pos; gl_Position.xy += Mesh.pointSpriteSize.xy * 0.01f * psprite[VERTEX_ID % 4] * gl_Position.w; - secondary = IN_secondary; + secondary = vec4(IN_secondary); norm = vec4(0, 0, 1, 1); #ifdef VULKAN diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 2ed0e19a2..5ffde79a3 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -640,6 +640,7 @@ extern bool IsGLES; EXT_TO_CHECK(40, 32, ARB_gpu_shader5) \ EXT_TO_CHECK(40, 32, ARB_sample_shading) \ EXT_TO_CHECK(40, 99, ARB_shader_subroutine) \ + EXT_TO_CHECK(40, 99, ARB_gpu_shader_fp64) \ EXT_TO_CHECK(40, 32, ARB_tessellation_shader) \ EXT_TO_CHECK(40, 32, ARB_texture_cube_map_array) \ EXT_TO_CHECK(40, 30, ARB_transform_feedback2) \ @@ -647,6 +648,7 @@ extern bool IsGLES; EXT_TO_CHECK(41, 31, ARB_separate_shader_objects) \ EXT_TO_CHECK(41, 99, ARB_viewport_array) \ EXT_TO_CHECK(41, 99, ARB_ES2_compatibility) \ + EXT_TO_CHECK(41, 99, ARB_vertex_attrib_64bit) \ EXT_TO_CHECK(42, 99, ARB_base_instance) \ EXT_TO_CHECK(42, 31, ARB_shader_atomic_counters) \ EXT_TO_CHECK(42, 31, ARB_shader_image_load_store) \ diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 85b69078a..b2f4d3262 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -338,21 +338,60 @@ void GLReplay::InitDebugData() GenerateGLSLShader(fs, shaderType, "", GetEmbeddedResource(glsl_mesh_frag), glslBaseVer); GenerateGLSLShader(gs, shaderType, "", GetEmbeddedResource(glsl_mesh_geom), glslBaseVer); - DebugData.meshProg = CreateShaderProgram(vs, fs); - DebugData.meshgsProg = CreateShaderProgram(vs, fs, gs); + DebugData.meshProg[0] = CreateShaderProgram(vs, fs); + DebugData.meshgsProg[0] = CreateShaderProgram(vs, fs, gs); GenerateGLSLShader(fs, shaderType, "", GetEmbeddedResource(glsl_trisize_frag), glslBaseVer); GenerateGLSLShader(gs, shaderType, "", GetEmbeddedResource(glsl_trisize_geom), glslBaseVer); DebugData.trisizeProg = CreateShaderProgram(vs, fs, gs); + + if(HasExt[ARB_gpu_shader_fp64] && HasExt[ARB_vertex_attrib_64bit]) + { + GenerateGLSLShader(fs, shaderType, "", GetEmbeddedResource(glsl_mesh_frag), glslBaseVer); + + std::string extensions = + "#extension GL_ARB_gpu_shader_fp64 : require\n" + "#extension GL_ARB_vertex_attrib_64bit : require\n"; + + // position only dvec4 + GenerateGLSLShader(vs, shaderType, extensions + "#define POSITION_TYPE dvec4", + GetEmbeddedResource(glsl_mesh_vert), glslBaseVer); + + DebugData.meshProg[1] = CreateShaderProgram(vs, fs); + DebugData.meshgsProg[1] = CreateShaderProgram(vs, fs, gs); + + // secondary only dvec4 + GenerateGLSLShader(vs, shaderType, extensions + "#define SECONDARY_TYPE dvec4", + GetEmbeddedResource(glsl_mesh_vert), glslBaseVer); + + DebugData.meshProg[2] = CreateShaderProgram(vs, fs); + DebugData.meshgsProg[2] = CreateShaderProgram(vs, fs, gs); + + // both dvec4 + GenerateGLSLShader(vs, shaderType, extensions + + "#define POSITION_TYPE dvec4\n" + "#define SECONDARY_TYPE dvec4", + GetEmbeddedResource(glsl_mesh_vert), glslBaseVer); + + DebugData.meshProg[3] = CreateShaderProgram(vs, fs); + DebugData.meshgsProg[3] = CreateShaderProgram(vs, fs, gs); + } + else + { + // we don't warn about the lack of double support, assuming that if the driver doesn't support + // it then it's highly unlikely that the capture uses it. + DebugData.meshProg[1] = DebugData.meshProg[2] = DebugData.meshProg[3] = 0; + DebugData.meshgsProg[1] = DebugData.meshgsProg[2] = DebugData.meshgsProg[3] = 0; + } } else { GenerateGLSLShader(vs, shaderType, "", GetEmbeddedResource(glsl_mesh_vert), glslBaseVer); GenerateGLSLShader(fs, shaderType, "", GetEmbeddedResource(glsl_mesh_frag), glslBaseVer); - DebugData.meshProg = CreateShaderProgram(vs, fs); - DebugData.meshgsProg = 0; + DebugData.meshProg[0] = CreateShaderProgram(vs, fs); + RDCEraseEl(DebugData.meshgsProg); DebugData.trisizeProg = 0; const char *warning_msg = @@ -361,6 +400,39 @@ void GLReplay::InitDebugData() RDCWARN(warning_msg); m_pDriver->AddDebugMessage(MessageCategory::Portability, MessageSeverity::Medium, MessageSource::RuntimeWarning, warning_msg); + + if(HasExt[ARB_gpu_shader_fp64] && HasExt[ARB_vertex_attrib_64bit]) + { + std::string extensions = + "#extension GL_ARB_gpu_shader_fp64 : require\n" + "#extension GL_ARB_vertex_attrib_64bit : require\n"; + + // position only dvec4 + GenerateGLSLShader(vs, shaderType, extensions + "#define POSITION_TYPE dvec4", + GetEmbeddedResource(glsl_mesh_vert), glslBaseVer); + + DebugData.meshProg[1] = CreateShaderProgram(vs, fs); + + // secondary only dvec4 + GenerateGLSLShader(vs, shaderType, extensions + "#define SECONDARY_TYPE dvec4", + GetEmbeddedResource(glsl_mesh_vert), glslBaseVer); + + DebugData.meshProg[2] = CreateShaderProgram(vs, fs); + + // both dvec4 + GenerateGLSLShader(vs, shaderType, extensions + + "#define POSITION_TYPE dvec4\n" + "#define SECONDARY_TYPE dvec4", + GetEmbeddedResource(glsl_mesh_vert), glslBaseVer); + + DebugData.meshProg[3] = CreateShaderProgram(vs, fs); + } + else + { + // we don't warn about the lack of double support, assuming that if the driver doesn't support + // it then it's highly unlikely that the capture uses it. + DebugData.meshProg[1] = DebugData.meshProg[2] = DebugData.meshProg[3] = 0; + } } RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.4f); @@ -829,8 +901,12 @@ void GLReplay::DeleteDebugData() drv.glDeleteProgram(DebugData.checkerProg); if(DebugData.fixedcolFragShader) drv.glDeleteShader(DebugData.fixedcolFragShader); - drv.glDeleteProgram(DebugData.meshProg); - drv.glDeleteProgram(DebugData.meshgsProg); + + for(size_t i = 0; i < ARRAY_COUNT(DebugData.meshProg); i++) + { + drv.glDeleteProgram(DebugData.meshProg[i]); + drv.glDeleteProgram(DebugData.meshgsProg[i]); + } drv.glDeleteProgram(DebugData.trisizeProg); drv.glDeleteSamplers(1, &DebugData.linearSampler); diff --git a/renderdoc/driver/gl/gl_rendermesh.cpp b/renderdoc/driver/gl/gl_rendermesh.cpp index a757f38ef..d3122a330 100644 --- a/renderdoc/driver/gl/gl_rendermesh.cpp +++ b/renderdoc/driver/gl/gl_rendermesh.cpp @@ -60,15 +60,11 @@ void GLReplay::RenderMesh(uint32_t eventId, const vector &secondaryD GLenum topo = MakeGLPrimitiveTopology(cfg.position.topology); - GLuint prog = DebugData.meshProg; - MeshUBOData uboParams = {}; MeshUBOData *uboptr = NULL; drv.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); - drv.glUseProgram(prog); - if(HasExt[EXT_framebuffer_sRGB]) drv.glEnable(eGL_FRAMEBUFFER_SRGB); @@ -109,6 +105,8 @@ void GLReplay::RenderMesh(uint32_t eventId, const vector &secondaryD drv.glEnableVertexAttribArray(0); drv.glDisableVertexAttribArray(1); + drv.glUseProgram(DebugData.meshProg[0]); + for(size_t i = 0; i < secondaryDraws.size(); i++) { const MeshFormat &fmt = secondaryDraws[i]; @@ -149,6 +147,8 @@ void GLReplay::RenderMesh(uint32_t eventId, const vector &secondaryD } } + int progidx = 0; + for(uint32_t i = 0; i < 2; i++) { if(meshData[i]->vertexResourceId == ResourceId()) @@ -239,6 +239,8 @@ void GLReplay::RenderMesh(uint32_t eventId, const vector &secondaryD else if(meshData[i]->format.compType == CompType::Double) { drv.glVertexAttribLFormat(i, meshData[i]->format.compCount, eGL_DOUBLE, 0); + + progidx |= (1 << i); } GLintptr offs = (GLintptr)meshData[i]->vertexByteOffset; @@ -256,6 +258,16 @@ void GLReplay::RenderMesh(uint32_t eventId, const vector &secondaryD drv.glVertexAttribDivisor(i, 0); } + GLuint prog = DebugData.meshProg[progidx]; + + if(prog == 0) + { + RDCWARN("Couldn't compile right double-compatible mesh display shader"); + prog = DebugData.meshProg[0]; + } + + drv.glUseProgram(prog); + // enable position attribute drv.glEnableVertexAttribArray(0); drv.glDisableVertexAttribArray(1); @@ -269,10 +281,16 @@ void GLReplay::RenderMesh(uint32_t eventId, const vector &secondaryD GLuint solidProg = prog; - if(cfg.solidShadeMode == SolidShade::Lit && DebugData.meshgsProg) + if(cfg.solidShadeMode == SolidShade::Lit && DebugData.meshgsProg[0]) { // pick program with GS for per-face lighting - solidProg = DebugData.meshgsProg; + solidProg = DebugData.meshgsProg[progidx]; + + if(solidProg == 0) + { + RDCWARN("Couldn't compile right double-compatible mesh display shader"); + solidProg = DebugData.meshgsProg[0]; + } ClearGLErrors(); drv.glUseProgram(solidProg); @@ -377,6 +395,9 @@ void GLReplay::RenderMesh(uint32_t eventId, const vector &secondaryD } } + // helpers always use basic float-input program + drv.glUseProgram(DebugData.meshProg[0]); + if(cfg.showBBox) { Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 7094490ee..5b45d8dd8 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -340,8 +340,9 @@ private: GLuint fixedcolFragShader; - GLuint meshProg; - GLuint meshgsProg; + // 0 = both floats, 1 = position doubles, 2 = secondary doubles, 3 = both doubles + GLuint meshProg[4]; + GLuint meshgsProg[4]; GLuint trisizeProg; GLuint meshVAO;