From 6be852bfa2067fff48b6c71034dae59d1b159bed Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 17 Jan 2017 16:54:03 +0000 Subject: [PATCH] Check for extensions needed when creating replay shaders * If a replay shader can't be created we'll just skip the replay functionality it is needed for. --- renderdoc/driver/gl/gl_common.h | 6 +- renderdoc/driver/gl/gl_debug.cpp | 99 ++++++++++++++++++++++---- renderdoc/driver/gl/gl_replay.h | 2 - renderdoc/driver/gl/gl_shader_refl.cpp | 1 + 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index 5c2fc395a..6d8970878 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -222,7 +222,11 @@ extern bool GLIsCore; EXT_TO_CHECK(ARB_draw_buffers_blend) \ EXT_TO_CHECK(ARB_viewport_array) \ EXT_TO_CHECK(ARB_ES3_compatibility) \ - EXT_TO_CHECK(ARB_transform_feedback2) + EXT_TO_CHECK(ARB_transform_feedback2) \ + EXT_TO_CHECK(ARB_texture_storage) \ + EXT_TO_CHECK(ARB_texture_storage_multisample) \ + EXT_TO_CHECK(ARB_gpu_shader5) \ + EXT_TO_CHECK(ARB_texture_view) // extensions we know we want to check for are precached, indexd by this enum enum ExtensionCheckEnum diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index f320d8925..3ce0e7edb 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -304,6 +304,7 @@ void GLReplay::InitDebugData() RDCLOG("GLSL version %d", glslVersion); GenerateGLSLShader(vs, eShaderGLSL, "", GetEmbeddedResource(glsl_blit_vert), 420); + if(HasExt[ARB_shader_image_load_store]) { string defines = ""; @@ -329,6 +330,15 @@ void GLReplay::InitDebugData() DebugData.quadoverdrawResolveProg = CreateShaderProgram(vs, fs); } + else + { + RDCWARN("GL_ARB_shader_image_load_store not supported, disabling quad overdraw feature."); + m_pDriver->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + "GL_ARB_shader_image_load_store not supported, disabling quad overdraw feature."); + DebugData.quadoverdrawFSProg = 0; + DebugData.quadoverdrawResolveProg = 0; + } GenerateGLSLShader(fs, eShaderGLSL, "", GetEmbeddedResource(glsl_checkerboard_frag), 420); DebugData.checkerProg = CreateShaderProgram(vs, fs); @@ -423,7 +433,7 @@ void GLReplay::InitDebugData() "#extension GL_ARB_compute_shader : require\n" "#extension GL_ARB_shader_storage_buffer_object : require\n"; - for(int t = 1; t <= RESTYPE_TEXTYPEMAX; t++) + for(int t = 1; HasExt[ARB_compute_shader] && t <= RESTYPE_TEXTYPEMAX; t++) { // float, uint, sint for(int i = 0; i < 3; i++) @@ -472,6 +482,14 @@ void GLReplay::InitDebugData() } } + if(!HasExt[ARB_compute_shader]) + { + RDCWARN("GL_ARB_compute_shader not supported, disabling min/max and histogram features."); + m_pDriver->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + "GL_ARB_compute_shader not supported, disabling min/max and histogram features."); + } + gl.glGenBuffers(1, &DebugData.minmaxTileResult); gl.glGenBuffers(1, &DebugData.minmaxResult); gl.glGenBuffers(1, &DebugData.histogramBuf); @@ -489,6 +507,7 @@ void GLReplay::InitDebugData() eGL_DYNAMIC_READ); } + if(HasExt[ARB_compute_shader]) { GenerateGLSLShader(cs, eShaderGLSL, "", GetEmbeddedResource(glsl_ms2array_comp), 420); DebugData.MS2Array = CreateCShaderProgram(cs); @@ -496,7 +515,17 @@ void GLReplay::InitDebugData() GenerateGLSLShader(cs, eShaderGLSL, "", GetEmbeddedResource(glsl_array2ms_comp), 420); DebugData.Array2MS = CreateCShaderProgram(cs); } + else + { + DebugData.MS2Array = 0; + DebugData.Array2MS = 0; + RDCWARN("GL_ARB_compute_shader not supported, disabling 2DMS save/load."); + m_pDriver->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_Medium, + eDbgSource_RuntimeWarning, + "GL_ARB_compute_shader not supported, disabling 2DMS save/load."); + } + if(HasExt[ARB_compute_shader]) { string defines = "#extension GL_ARB_compute_shader : require\n" @@ -504,9 +533,31 @@ void GLReplay::InitDebugData() GenerateGLSLShader(cs, eShaderGLSL, defines, GetEmbeddedResource(glsl_mesh_comp), 420); DebugData.meshPickProgram = CreateCShaderProgram(cs); } + else + { + DebugData.meshPickProgram = 0; + RDCWARN("GL_ARB_compute_shader not supported, disabling mesh picking."); + m_pDriver->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_Medium, + eDbgSource_RuntimeWarning, + "GL_ARB_compute_shader not supported, disabling mesh picking."); + } + + if(!HasExt[ARB_gpu_shader5]) + { + RDCWARN( + "ARB_gpu_shader5 not supported, pixel picking and saving of integer textures may be " + "inaccurate."); + m_pDriver->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_Medium, + eDbgSource_RuntimeWarning, + "ARB_gpu_shader5 not supported, pixel picking and saving of integer " + "textures may be inaccurate."); + } RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f); + DebugData.pickResultBuf = 0; + + if(DebugData.meshPickProgram) { gl.glGenBuffers(1, &DebugData.pickResultBuf); gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickResultBuf); @@ -621,17 +672,11 @@ void GLReplay::DeleteDebugData() m_PostVSData.clear(); - if(DebugData.overlayFBO) - { - gl.glDeleteFramebuffers(1, &DebugData.overlayFBO); - gl.glDeleteTextures(1, &DebugData.overlayTex); - } + gl.glDeleteFramebuffers(1, &DebugData.overlayFBO); + gl.glDeleteTextures(1, &DebugData.overlayTex); - if(DebugData.quadoverdrawFSProg) - { - gl.glDeleteProgram(DebugData.quadoverdrawFSProg); - gl.glDeleteProgram(DebugData.quadoverdrawResolveProg); - } + gl.glDeleteProgram(DebugData.quadoverdrawFSProg); + gl.glDeleteProgram(DebugData.quadoverdrawResolveProg); gl.glDeleteProgram(DebugData.texDisplayVSProg); for(int i = 0; i < 3; i++) @@ -652,9 +697,10 @@ void GLReplay::DeleteDebugData() gl.glDeleteFramebuffers(1, &DebugData.pickPixelFBO); gl.glDeleteTextures(1, &DebugData.pickPixelTex); + gl.glDeleteBuffers(1, &DebugData.genericUBO); + gl.glDeleteFramebuffers(1, &DebugData.customFBO); - if(DebugData.customTex != 0) - gl.glDeleteTextures(1, &DebugData.customTex); + gl.glDeleteTextures(1, &DebugData.customTex); gl.glDeleteVertexArrays(1, &DebugData.emptyVAO); @@ -672,11 +718,15 @@ void GLReplay::DeleteDebugData() gl.glDeleteProgram(DebugData.minmaxTileProgram[idx]); gl.glDeleteProgram(DebugData.histogramProgram[idx]); - if(t == 1) - gl.glDeleteProgram(DebugData.minmaxResultProgram[i]); + gl.glDeleteProgram(DebugData.minmaxResultProgram[i]); } } + gl.glDeleteProgram(DebugData.meshPickProgram); + gl.glDeleteBuffers(1, &DebugData.pickIBBuf); + gl.glDeleteBuffers(1, &DebugData.pickVBBuf); + gl.glDeleteBuffers(1, &DebugData.pickResultBuf); + gl.glDeleteProgram(DebugData.Array2MS); gl.glDeleteProgram(DebugData.MS2Array); @@ -701,6 +751,9 @@ bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uin if(texid == ResourceId() || m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end()) return false; + if(!HasExt[ARB_compute_shader]) + return false; + auto &texDetails = m_pDriver->m_Textures[texid]; FetchTexture details = GetTexture(texid); @@ -872,6 +925,9 @@ bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, if(m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end()) return false; + if(!HasExt[ARB_compute_shader]) + return false; + auto &texDetails = m_pDriver->m_Textures[texid]; FetchTexture details = GetTexture(texid); @@ -1045,6 +1101,9 @@ uint32_t GLReplay::PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t { WrappedOpenGL &gl = *m_pDriver; + if(!HasExt[ARB_compute_shader]) + return ~0U; + MakeCurrentReplayContext(m_DebugCtx); gl.glUseProgram(DebugData.meshPickProgram); @@ -1473,6 +1532,15 @@ void GLReplay::CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, G { WrappedOpenGL &gl = *m_pDriver; + if(!HasExt[ARB_compute_shader]) + return; + + if(!HasExt[ARB_texture_view]) + { + RDCWARN("Can't copy multisampled texture to array for serialisation without ARB_texture_view."); + return; + } + GLRenderState rs(&gl.GetHookset(), NULL, READING); rs.FetchState(m_pDriver->GetCtx(), m_pDriver); @@ -2781,6 +2849,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, FormatComponentType typeHin } else if(overlay == eTexOverlay_QuadOverdrawDraw || overlay == eTexOverlay_QuadOverdrawPass) { + if(DebugData.quadoverdrawFSProg) { SCOPED_TIMER("Quad Overdraw"); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 3e74739c3..7bdc881a5 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -348,8 +348,6 @@ private: GLuint UBOs[3]; - GLuint readFBO; - GLuint emptyVAO; } DebugData; diff --git a/renderdoc/driver/gl/gl_shader_refl.cpp b/renderdoc/driver/gl/gl_shader_refl.cpp index 4382709df..ac897c69c 100644 --- a/renderdoc/driver/gl/gl_shader_refl.cpp +++ b/renderdoc/driver/gl/gl_shader_refl.cpp @@ -1492,6 +1492,7 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, uint32_t ssboMembers = 0; GLint numSSBOs = 0; + if(HasExt[ARB_shader_storage_buffer_object]) { gl.glGetProgramInterfaceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, eGL_ACTIVE_RESOURCES, &numSSBOs);