diff --git a/docs/behind_scenes/opengl_support.rst b/docs/behind_scenes/opengl_support.rst index d1b7d2f07..012dc6062 100644 --- a/docs/behind_scenes/opengl_support.rst +++ b/docs/behind_scenes/opengl_support.rst @@ -23,9 +23,7 @@ RenderDoc assumes a certain minimum feature set on replay. On desktop this means * GL_ARB_vertex_attrib_binding * GL_ARB_program_interface_query -* GL_ARB_shading_language_420pack * GL_ARB_separate_shader_objects -* GL_ARB_explicit_attrib_location * GL_ARB_sampler_objects These extensions should not require newer hardware than the base 3.2 context, but they might need an updated driver to be listed as available. Also note that this is the *minimum* required extension set to replay, some analysis features will be disabled unless you have more capable hardware features such as GL_ARB_shader_image_load_store, GL_ARB_compute_shader and GL_ARB_gpu_shader5. diff --git a/renderdoc/data/glsl/array2ms.comp b/renderdoc/data/glsl/array2ms.comp index c46d61b83..ad7560154 100644 --- a/renderdoc/data/glsl/array2ms.comp +++ b/renderdoc/data/glsl/array2ms.comp @@ -26,6 +26,9 @@ #extension GL_OES_texture_storage_multisample_2d_array : require #elif defined(OPENGL_CORE) #extension GL_ARB_compute_shader : require + +// safe to assume this extension in compute shaders as it pre-dates compute shaders +#extension GL_ARB_shading_language_420pack : require #endif #include "glsl_globals.h" diff --git a/renderdoc/data/glsl/checkerboard.frag b/renderdoc/data/glsl/checkerboard.frag index 2237019c5..9c5115561 100644 --- a/renderdoc/data/glsl/checkerboard.frag +++ b/renderdoc/data/glsl/checkerboard.frag @@ -22,10 +22,6 @@ * THE SOFTWARE. ******************************************************************************/ -#if !defined(OPENGL_ES) -#extension GL_ARB_shading_language_420pack : require -#endif - #define CHECKER_UBO #include "glsl_ubos.h" diff --git a/renderdoc/data/glsl/deptharr2ms.frag b/renderdoc/data/glsl/deptharr2ms.frag index e3ce21e82..5414a9d61 100644 --- a/renderdoc/data/glsl/deptharr2ms.frag +++ b/renderdoc/data/glsl/deptharr2ms.frag @@ -26,16 +26,14 @@ #extension GL_ARB_sample_shading : require #endif -#extension GL_ARB_shading_language_420pack : require - #include "glsl_globals.h" +#ifdef VULKAN + layout(binding = 0) uniform PRECISION sampler2DArray srcDepthArray; layout(binding = 1) uniform PRECISION usampler2DArray srcStencilArray; // binding = 2 used as an image in the colour copy compute shaders -#ifdef VULKAN - layout(push_constant) uniform multisamplePush { int numMultiSamples; @@ -52,6 +50,10 @@ mscopy; #else +uniform PRECISION sampler2DArray srcDepthArray; +uniform PRECISION usampler2DArray srcStencilArray; +// binding = 2 used as an image in the colour copy compute shaders + uniform ivec4 mscopy; #define numMultiSamples (mscopy.x) diff --git a/renderdoc/data/glsl/depthms2arr.frag b/renderdoc/data/glsl/depthms2arr.frag index afbd24a09..1a75cec30 100644 --- a/renderdoc/data/glsl/depthms2arr.frag +++ b/renderdoc/data/glsl/depthms2arr.frag @@ -22,16 +22,14 @@ * THE SOFTWARE. ******************************************************************************/ -#extension GL_ARB_shading_language_420pack : require - #include "glsl_globals.h" +#ifdef VULKAN + layout(binding = 0) uniform PRECISION sampler2DMSArray srcDepthMS; layout(binding = 1) uniform PRECISION usampler2DMSArray srcStencilMS; // binding = 2 used as an image in the colour copy compute shaders -#ifdef VULKAN - layout(push_constant) uniform multisamplePush { int numMultiSamples; @@ -48,6 +46,10 @@ mscopy; #else +uniform PRECISION sampler2DMSArray srcDepthMS; +uniform PRECISION usampler2DMSArray srcStencilMS; +// binding = 2 used as an image in the colour copy compute shaders + uniform ivec4 mscopy; #define numMultiSamples (mscopy.x) diff --git a/renderdoc/data/glsl/gl_texsample.h b/renderdoc/data/glsl/gl_texsample.h index adea8013b..cb7eed538 100644 --- a/renderdoc/data/glsl/gl_texsample.h +++ b/renderdoc/data/glsl/gl_texsample.h @@ -33,17 +33,17 @@ // these bindings are defined based on the RESTYPE_ defines in glsl_ubos.h -layout(binding = 1) uniform usampler1D texUInt1D; -layout(binding = 2) uniform usampler2D texUInt2D; -layout(binding = 3) uniform usampler3D texUInt3D; +uniform usampler1D texUInt1D; +uniform usampler2D texUInt2D; +uniform usampler3D texUInt3D; // cube = 4 -layout(binding = 5) uniform usampler1DArray texUInt1DArray; -layout(binding = 6) uniform usampler2DArray texUInt2DArray; +uniform usampler1DArray texUInt1DArray; +uniform usampler2DArray texUInt2DArray; // cube array = 7 -layout(binding = 8) uniform usampler2DRect texUInt2DRect; -layout(binding = 9) uniform usamplerBuffer texUIntBuffer; +uniform usampler2DRect texUInt2DRect; +uniform usamplerBuffer texUIntBuffer; #ifdef TEXSAMPLE_MULTISAMPLE -layout(binding = 10) uniform usampler2DMS texUInt2DMS; +uniform usampler2DMS texUInt2DMS; #endif vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes, @@ -107,17 +107,17 @@ ivec4 SampleTextureSInt4(int type, vec2 pos, float slice, int mipLevel, int samp // these bindings are defined based on the RESTYPE_ defines in glsl_ubos.h -layout(binding = 1) uniform isampler1D texSInt1D; -layout(binding = 2) uniform isampler2D texSInt2D; -layout(binding = 3) uniform isampler3D texSInt3D; +uniform isampler1D texSInt1D; +uniform isampler2D texSInt2D; +uniform isampler3D texSInt3D; // cube = 4 -layout(binding = 5) uniform isampler1DArray texSInt1DArray; -layout(binding = 6) uniform isampler2DArray texSInt2DArray; +uniform isampler1DArray texSInt1DArray; +uniform isampler2DArray texSInt2DArray; // cube array = 7 -layout(binding = 8) uniform isampler2DRect texSInt2DRect; -layout(binding = 9) uniform isamplerBuffer texSIntBuffer; +uniform isampler2DRect texSInt2DRect; +uniform isamplerBuffer texSIntBuffer; #ifdef TEXSAMPLE_MULTISAMPLE -layout(binding = 10) uniform isampler2DMS texSInt2DMS; +uniform isampler2DMS texSInt2DMS; #endif vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes, @@ -181,19 +181,19 @@ ivec4 SampleTextureSInt4(int type, vec2 pos, float slice, int mipLevel, int samp // these bindings are defined based on the RESTYPE_ defines in glsl_ubos.h -layout(binding = 1) uniform sampler1D tex1D; -layout(binding = 2) uniform sampler2D tex2D; -layout(binding = 3) uniform sampler3D tex3D; -layout(binding = 4) uniform samplerCube texCube; -layout(binding = 5) uniform sampler1DArray tex1DArray; -layout(binding = 6) uniform sampler2DArray tex2DArray; +uniform sampler1D tex1D; +uniform sampler2D tex2D; +uniform sampler3D tex3D; +uniform samplerCube texCube; +uniform sampler1DArray tex1DArray; +uniform sampler2DArray tex2DArray; #ifdef TEXSAMPLE_CUBE_ARRAY -layout(binding = 7) uniform samplerCubeArray texCubeArray; +uniform samplerCubeArray texCubeArray; #endif -layout(binding = 8) uniform sampler2DRect tex2DRect; -layout(binding = 9) uniform samplerBuffer texBuffer; +uniform sampler2DRect tex2DRect; +uniform samplerBuffer texBuffer; #ifdef TEXSAMPLE_MULTISAMPLE -layout(binding = 10) uniform sampler2DMS tex2DMS; +uniform sampler2DMS tex2DMS; #endif vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes, diff --git a/renderdoc/data/glsl/gles_texsample.h b/renderdoc/data/glsl/gles_texsample.h index f7b49ca3c..a86548810 100644 --- a/renderdoc/data/glsl/gles_texsample.h +++ b/renderdoc/data/glsl/gles_texsample.h @@ -39,18 +39,18 @@ // these bindings are defined based on the RESTYPE_ defines in glsl_ubos.h // 1d = 1 -layout(binding = 2) uniform PRECISION usampler2D texUInt2D; -layout(binding = 3) uniform PRECISION usampler3D texUInt3D; +uniform PRECISION usampler2D texUInt2D; +uniform PRECISION usampler3D texUInt3D; // cube = 4 // 1d array = 5 -layout(binding = 6) uniform PRECISION usampler2DArray texUInt2DArray; +uniform PRECISION usampler2DArray texUInt2DArray; // cube array = 7 // 2d rect = 8 #ifdef TEXSAMPLE_BUFFER -layout(binding = 9) uniform PRECISION usamplerBuffer texUIntBuffer; +uniform PRECISION usamplerBuffer texUIntBuffer; #endif #ifdef TEXSAMPLE_MULTISAMPLE -layout(binding = 10) uniform PRECISION usampler2DMS texUInt2DMS; +uniform PRECISION usampler2DMS texUInt2DMS; #endif vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes, @@ -107,18 +107,18 @@ ivec4 SampleTextureSInt4(int type, vec2 pos, float slice, int mipLevel, int samp // these bindings are defined based on the RESTYPE_ defines in glsl_ubos.h // 1d = 1 -layout(binding = 2) uniform PRECISION isampler2D texSInt2D; -layout(binding = 3) uniform PRECISION isampler3D texSInt3D; +uniform PRECISION isampler2D texSInt2D; +uniform PRECISION isampler3D texSInt3D; // cube = 4 // 1d array = 5 -layout(binding = 6) uniform PRECISION isampler2DArray texSInt2DArray; +uniform PRECISION isampler2DArray texSInt2DArray; // cube array = 7 // 2d rect = 8 #ifdef TEXSAMPLE_BUFFER -layout(binding = 9) uniform PRECISION isamplerBuffer texSIntBuffer; +uniform PRECISION isamplerBuffer texSIntBuffer; #endif #ifdef TEXSAMPLE_MULTISAMPLE -layout(binding = 10) uniform PRECISION isampler2DMS texSInt2DMS; +uniform PRECISION isampler2DMS texSInt2DMS; #endif vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes, @@ -175,20 +175,20 @@ ivec4 SampleTextureSInt4(int type, vec2 pos, float slice, int mipLevel, int samp // these bindings are defined based on the RESTYPE_ defines in glsl_ubos.h // 1d = 1 -layout(binding = 2) uniform PRECISION sampler2D tex2D; -layout(binding = 3) uniform PRECISION sampler3D tex3D; -layout(binding = 4) uniform PRECISION samplerCube texCube; +uniform PRECISION sampler2D tex2D; +uniform PRECISION sampler3D tex3D; +uniform PRECISION samplerCube texCube; // 1d array = 5 -layout(binding = 6) uniform PRECISION sampler2DArray tex2DArray; +uniform PRECISION sampler2DArray tex2DArray; #ifdef TEXSAMPLE_CUBE_ARRAY -layout(binding = 7) uniform PRECISION samplerCubeArray texCubeArray; +uniform PRECISION samplerCubeArray texCubeArray; #endif // 2d rect = 8 #ifdef TEXSAMPLE_BUFFER -layout(binding = 9) uniform PRECISION samplerBuffer texBuffer; +uniform PRECISION samplerBuffer texBuffer; #endif #ifdef TEXSAMPLE_MULTISAMPLE -layout(binding = 10) uniform PRECISION sampler2DMS tex2DMS; +uniform PRECISION sampler2DMS tex2DMS; #endif vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes, diff --git a/renderdoc/data/glsl/glsl_globals.h b/renderdoc/data/glsl/glsl_globals.h index 9aae9dffd..2af835f89 100644 --- a/renderdoc/data/glsl/glsl_globals.h +++ b/renderdoc/data/glsl/glsl_globals.h @@ -38,8 +38,10 @@ #else // ifdef VULKAN -// drop I/O location specifiers on GL, we don't use separate programs so it can be matched by name. -#define BINDING(b) layout(binding = b, std140) +// drop I/O location specifiers and bindings on GL, we don't use separate programs so I/O variables +// can be matched by name, and we don't want to require GL_ARB_shading_language_420pack so we can't +// specify bindings in shaders. +#define BINDING(b) layout(std140) #define IO_LOCATION(l) #define VERTEX_ID gl_VertexID #define INSTANCE_ID gl_InstanceID diff --git a/renderdoc/data/glsl/glsl_ubos.h b/renderdoc/data/glsl/glsl_ubos.h index 1599898aa..da52e76be 100644 --- a/renderdoc/data/glsl/glsl_ubos.h +++ b/renderdoc/data/glsl/glsl_ubos.h @@ -22,11 +22,6 @@ * THE SOFTWARE. ******************************************************************************/ -#if !defined(OPENGL_ES) && !defined(__cplusplus) -// we require this extensions to be able to set explicit layout bindings on buffers/images -#extension GL_ARB_shading_language_420pack : require -#endif - #include "glsl_globals.h" // the ARM driver is buggy and crashes if we declare UBOs that don't correspond to descriptors, diff --git a/renderdoc/data/glsl/histogram.comp b/renderdoc/data/glsl/histogram.comp index 6120dc8dd..c58102ff4 100644 --- a/renderdoc/data/glsl/histogram.comp +++ b/renderdoc/data/glsl/histogram.comp @@ -25,6 +25,9 @@ #if defined(OPENGL_CORE) #extension GL_ARB_compute_shader : require #extension GL_ARB_shader_storage_buffer_object : require + +// safe to assume this extension in compute shaders as it pre-dates compute shaders +#extension GL_ARB_shading_language_420pack : require #endif #define HISTOGRAM_UBO diff --git a/renderdoc/data/glsl/mesh.comp b/renderdoc/data/glsl/mesh.comp index 0a4048a9d..61d2ca75f 100644 --- a/renderdoc/data/glsl/mesh.comp +++ b/renderdoc/data/glsl/mesh.comp @@ -25,6 +25,9 @@ #if defined(OPENGL_CORE) #extension GL_ARB_compute_shader : require #extension GL_ARB_shader_storage_buffer_object : require + +// safe to assume this extension in compute shaders as it pre-dates compute shaders +#extension GL_ARB_shading_language_420pack : require #endif #define MESH_PICK_UBO diff --git a/renderdoc/data/glsl/mesh.frag b/renderdoc/data/glsl/mesh.frag index 364ce360d..1b2fed0ae 100644 --- a/renderdoc/data/glsl/mesh.frag +++ b/renderdoc/data/glsl/mesh.frag @@ -26,8 +26,19 @@ #include "glsl_ubos.h" -IO_LOCATION(0) in vec4 secondary; -IO_LOCATION(1) in vec4 norm; +// this allows overrides from outside on GL where we use name-interface matching. On vulkan we can +// default to whatever name we like + +#ifndef SECONDARY_NAME +#define SECONDARY_NAME fragin_secondary +#endif + +#ifndef NORM_NAME +#define NORM_NAME fragin_norm +#endif + +IO_LOCATION(0) in vec4 SECONDARY_NAME; +IO_LOCATION(1) in vec4 NORM_NAME; IO_LOCATION(0) out vec4 color_out; @@ -37,17 +48,17 @@ void main(void) if(type == MESHDISPLAY_SECONDARY) { - color_out = vec4(secondary.xyz, 1); + color_out = vec4(SECONDARY_NAME.xyz, 1); } else if(type == MESHDISPLAY_SECONDARY_ALPHA) { - color_out = vec4(secondary.www, 1); + color_out = vec4(SECONDARY_NAME.www, 1); } else if(type == MESHDISPLAY_FACELIT) { vec3 lightDir = normalize(vec3(0, -0.3f, -1)); - color_out = vec4(Mesh.color.xyz * abs(dot(lightDir, norm.xyz)), 1); + color_out = vec4(Mesh.color.xyz * abs(dot(lightDir, NORM_NAME.xyz)), 1); } else // if(type == MESHDISPLAY_SOLID) { diff --git a/renderdoc/data/glsl/mesh.geom b/renderdoc/data/glsl/mesh.geom index 364038beb..57b55209e 100644 --- a/renderdoc/data/glsl/mesh.geom +++ b/renderdoc/data/glsl/mesh.geom @@ -38,8 +38,8 @@ layout(triangle_strip, max_vertices = 3) out; IO_LOCATION(0) in vec4 vsout_secondary[3]; IO_LOCATION(1) in vec4 vsout_norm[3]; -IO_LOCATION(0) out vec4 secondary; -IO_LOCATION(1) out vec4 norm; +IO_LOCATION(0) out vec4 gsout_secondary; +IO_LOCATION(1) out vec4 gsout_norm; void main() { @@ -50,8 +50,8 @@ void main() for(int i = 0; i < 3; i++) { gl_Position = gl_in[i].gl_Position; - secondary = vsout_secondary[i]; - norm = vec4(faceNormal.xyz, 1); + gsout_secondary = vsout_secondary[i]; + gsout_norm = vec4(faceNormal.xyz, 1); EmitVertex(); } EndPrimitive(); diff --git a/renderdoc/data/glsl/mesh.vert b/renderdoc/data/glsl/mesh.vert index 8d9993ff4..931941a4d 100644 --- a/renderdoc/data/glsl/mesh.vert +++ b/renderdoc/data/glsl/mesh.vert @@ -26,10 +26,6 @@ #include "glsl_ubos.h" -#if !defined(OPENGL_ES) -#extension GL_ARB_explicit_attrib_location : require -#endif - // this allows overrides from outside to change to e.g. dvec4 #ifndef POSITION_TYPE @@ -40,8 +36,8 @@ #define SECONDARY_TYPE vec4 #endif -layout(location = 0) in POSITION_TYPE position; -layout(location = 1) in SECONDARY_TYPE IN_secondary; +IO_LOCATION(0) in POSITION_TYPE vsin_position; +IO_LOCATION(1) in SECONDARY_TYPE vsin_secondary; IO_LOCATION(0) out vec4 vsout_secondary; IO_LOCATION(1) out vec4 vsout_norm; @@ -51,7 +47,7 @@ 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 = vec4(position); + vec4 pos = vec4(vsin_position); if(Mesh.homogenousInput == 0u) { pos = vec4(pos.xyz, 1); @@ -65,7 +61,7 @@ void main(void) gl_Position = Mesh.mvp * pos; gl_Position.xy += Mesh.pointSpriteSize.xy * 0.01f * psprite[VERTEX_ID % 4] * gl_Position.w; - vsout_secondary = vec4(IN_secondary); + vsout_secondary = vec4(vsin_secondary); vsout_norm = vec4(0, 0, 1, 1); #ifdef VULKAN diff --git a/renderdoc/data/glsl/minmaxresult.comp b/renderdoc/data/glsl/minmaxresult.comp index bb7800ff9..2d8730f26 100644 --- a/renderdoc/data/glsl/minmaxresult.comp +++ b/renderdoc/data/glsl/minmaxresult.comp @@ -25,6 +25,9 @@ #if defined(OPENGL_CORE) #extension GL_ARB_compute_shader : require #extension GL_ARB_shader_storage_buffer_object : require + +// safe to assume this extension in compute shaders as it pre-dates compute shaders +#extension GL_ARB_shading_language_420pack : require #endif #define HISTOGRAM_UBO diff --git a/renderdoc/data/glsl/minmaxtile.comp b/renderdoc/data/glsl/minmaxtile.comp index 19477bd76..97eb9947d 100644 --- a/renderdoc/data/glsl/minmaxtile.comp +++ b/renderdoc/data/glsl/minmaxtile.comp @@ -25,6 +25,9 @@ #if defined(OPENGL_CORE) #extension GL_ARB_compute_shader : require #extension GL_ARB_shader_storage_buffer_object : require + +// safe to assume this extension in compute shaders as it pre-dates compute shaders +#extension GL_ARB_shading_language_420pack : require #endif #define HISTOGRAM_UBO diff --git a/renderdoc/data/glsl/ms2array.comp b/renderdoc/data/glsl/ms2array.comp index f6957658a..61fd5238f 100644 --- a/renderdoc/data/glsl/ms2array.comp +++ b/renderdoc/data/glsl/ms2array.comp @@ -24,6 +24,9 @@ #if defined(OPENGL_CORE) #extension GL_ARB_compute_shader : require + +// safe to assume this extension in compute shaders as it pre-dates compute shaders +#extension GL_ARB_shading_language_420pack : require #endif #include "glsl_globals.h" diff --git a/renderdoc/data/glsl/quadresolve.frag b/renderdoc/data/glsl/quadresolve.frag index fb8a92d26..d1da47581 100644 --- a/renderdoc/data/glsl/quadresolve.frag +++ b/renderdoc/data/glsl/quadresolve.frag @@ -24,7 +24,6 @@ #if !defined(OPENGL_ES) #extension GL_ARB_shader_image_load_store : require -#extension GL_ARB_shading_language_420pack : require #endif #include "glsl_globals.h" @@ -36,7 +35,11 @@ // https://github.com/selfshadow/demos/blob/master/QuadShading/QuadShading.fx //////////////////////////////////////////////////////////////////////////////////////////// -layout(binding = 0, r32ui) uniform PRECISION coherent uimage2DArray overdrawImage; +#if defined(VULKAN) +layout(binding = 0) +#endif + + layout(r32ui) uniform PRECISION coherent uimage2DArray overdrawImage; IO_LOCATION(0) out vec4 color_out; diff --git a/renderdoc/data/glsl/trisize.geom b/renderdoc/data/glsl/trisize.geom index 7ed350561..45512a178 100644 --- a/renderdoc/data/glsl/trisize.geom +++ b/renderdoc/data/glsl/trisize.geom @@ -29,8 +29,6 @@ #extension GL_OES_geometry_shader : enable #endif -#extension GL_ARB_shading_language_420pack : require - layout(triangles) in; layout(triangle_strip, max_vertices = 3) out; @@ -39,7 +37,7 @@ IO_LOCATION(1) in vec4 vsout_norm[3]; IO_LOCATION(0) out float pixarea; -layout(binding = 2) uniform ViewportSizeUBO +BINDING(2) uniform ViewportSizeUBO { vec4 size; } diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index 83bbd45a3..4ca794574 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -123,17 +123,10 @@ bool CheckReplayContext() // for program introspection, needed for shader reflection. // Possible to remove by compiling shaders to SPIR-V and reflecting ourselves. REQUIRE_EXTENSION(ARB_program_interface_query); - // strangely, this is the extension needed for layout(binding = X) on uniforms, textures, etc. - // Possible to remove by #defining out the layout specifiers and manually setting the uniform - // values. - REQUIRE_EXTENSION(ARB_shading_language_420pack); // needed for program pipelines, glProgramUniform*, and reflecting shaders on their own // Possible to remove this with self-compiled SPIR-V for reflection - see above. Likewise // convenience for our own pipelines when replacing single shaders or such. REQUIRE_EXTENSION(ARB_separate_shader_objects); - // needed for layout(location = X) on fragment shader outputs - // similar to ARB_shading_language_420pack we could do without this by assigning locations in code - REQUIRE_EXTENSION(ARB_explicit_attrib_location); // adds sampler objects so we can swap sampling behaviour when sampling from the capture's // textures // Possible to remove by manually pushing and popping all of the sampler state that we're diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 4639366a8..31a018ff9 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -93,9 +93,27 @@ GLuint GLReplay::CreateCShaderProgram(const std::string &src) return ret; } -GLuint GLReplay::CreateShaderProgram(const std::string &vs, const std::string &fs) +GLuint GLReplay::CreateShaderProgram(GLuint vs, GLuint fs, GLuint gs) { - return CreateShaderProgram(vs, fs, ""); + GLuint ret = GL.glCreateProgram(); + + GL.glAttachShader(ret, vs); + GL.glAttachShader(ret, fs); + if(gs) + GL.glAttachShader(ret, gs); + + GL.glLinkProgram(ret); + + char buffer[1024] = {}; + GLint status = 0; + GL.glGetProgramiv(ret, eGL_LINK_STATUS, &status); + if(status == 0) + { + GL.glGetProgramInfoLog(ret, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + + return ret; } GLuint GLReplay::CreateShaderProgram(const std::string &vsSrc, const std::string &fsSrc, @@ -137,23 +155,7 @@ GLuint GLReplay::CreateShaderProgram(const std::string &vsSrc, const std::string return 0; } - GLuint ret = GL.glCreateProgram(); - - GL.glAttachShader(ret, vs); - GL.glAttachShader(ret, fs); - if(gs) - GL.glAttachShader(ret, gs); - - GL.glLinkProgram(ret); - - char buffer[1024] = {}; - GLint status = 0; - GL.glGetProgramiv(ret, eGL_LINK_STATUS, &status); - if(status == 0) - { - GL.glGetProgramInfoLog(ret, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } + GLuint ret = CreateShaderProgram(vs, fs, gs); GL.glDetachShader(ret, vs); GL.glDetachShader(ret, fs); @@ -197,6 +199,90 @@ void GLReplay::CheckGLSLVersion(const char *sl, int &glslVersion) } } +GLuint GLReplay::CreateMeshProgram(GLuint vs, GLuint fs, GLuint gs) +{ + GLuint program = CreateShaderProgram(vs, fs, gs); + + // set attrib locations + GL.glBindAttribLocation(program, 0, "position"); + GL.glBindAttribLocation(program, 1, "IN_secondary"); + + // relink + GL.glLinkProgram(program); + + // check that the relink succeeded + char buffer[1024] = {}; + GLint status = 0; + GL.glGetProgramiv(program, eGL_LINK_STATUS, &status); + if(status == 0) + { + GL.glGetProgramInfoLog(program, 1024, NULL, buffer); + RDCERR("Link error: %s", buffer); + } + + // detach the shaders + GL.glDetachShader(program, vs); + GL.glDetachShader(program, fs); + if(gs) + GL.glDetachShader(program, gs); + + // bind the UBO + BindUBO(program, "MeshUBOData", 0); + + return program; +} + +void GLReplay::ConfigureTexDisplayProgramBindings(GLuint program) +{ + GLint location = -1; + + GL.glUseProgram(program); + +// since we split the shader up by type, not all texture slots are always available. Also on GLES +// some texture slots might be missing due to lack of extensions. So we need to check for a location +// of -1 +#define SET_TEX_BINDING(name, bind) \ + location = GL.glGetUniformLocation(program, name); \ + if(location >= 0) \ + GL.glUniform1i(location, bind); + + SET_TEX_BINDING("texUInt1D", 1); + SET_TEX_BINDING("texUInt2D", 2); + SET_TEX_BINDING("texUInt3D", 3); + SET_TEX_BINDING("texUInt1DArray", 5); + SET_TEX_BINDING("texUInt2DArray", 6); + SET_TEX_BINDING("texUInt2DRect", 8); + SET_TEX_BINDING("texUIntBuffer", 9); + SET_TEX_BINDING("texUInt2DMS", 10); + + SET_TEX_BINDING("texSInt1D", 1); + SET_TEX_BINDING("texSInt2D", 2); + SET_TEX_BINDING("texSInt3D", 3); + SET_TEX_BINDING("texSInt1DArray", 5); + SET_TEX_BINDING("texSInt2DArray", 6); + SET_TEX_BINDING("texSInt2DRect", 8); + SET_TEX_BINDING("texSIntBuffer", 9); + SET_TEX_BINDING("texSInt2DMS", 10); + + SET_TEX_BINDING("tex1D", 1); + SET_TEX_BINDING("tex2D", 2); + SET_TEX_BINDING("tex3D", 3); + SET_TEX_BINDING("texCube", 4); + SET_TEX_BINDING("tex1DArray", 5); + SET_TEX_BINDING("tex2DArray", 6); + SET_TEX_BINDING("texCubeArray", 7); + SET_TEX_BINDING("tex2DRect", 8); + SET_TEX_BINDING("texBuffer", 9); + SET_TEX_BINDING("tex2DMS", 10); + +#undef SET_TEX_BINDING +} + +void GLReplay::BindUBO(GLuint program, const char *name, GLuint binding) +{ + GL.glUniformBlockBinding(program, GL.glGetUniformBlockIndex(program, name), binding); +} + void GLReplay::InitDebugData() { if(m_pDriver == NULL) @@ -288,6 +374,10 @@ void GLReplay::InitDebugData() defines + texSampleDefines); DebugData.texDisplayProg[i] = CreateShaderProgram(vs, fs); + + BindUBO(DebugData.texDisplayProg[i], "TexDisplayUBOData", 0); + BindUBO(DebugData.texDisplayProg[i], "HeatmapData", 1); + ConfigureTexDisplayProgramBindings(DebugData.texDisplayProg[i]); } RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.2f); @@ -336,6 +426,10 @@ void GLReplay::InitDebugData() fs = GenerateGLSLShader(GetEmbeddedResource(glsl_quadresolve_frag), shaderType, glslBaseVer); DebugData.quadoverdrawResolveProg = CreateShaderProgram(vs, fs); + + GL.glUseProgram(DebugData.quadoverdrawResolveProg); + + GL.glUniform1i(GL.glGetUniformLocation(DebugData.quadoverdrawResolveProg, "overdrawImage"), 0); } else { @@ -351,19 +445,46 @@ void GLReplay::InitDebugData() fs = GenerateGLSLShader(GetEmbeddedResource(glsl_checkerboard_frag), shaderType, glslBaseVer); DebugData.checkerProg = CreateShaderProgram(vs, fs); + BindUBO(DebugData.checkerProg, "CheckerboardUBOData", 0); + if(HasExt[ARB_geometry_shader4]) { vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer); fs = GenerateGLSLShader(GetEmbeddedResource(glsl_trisize_frag), shaderType, glslBaseVer); gs = GenerateGLSLShader(GetEmbeddedResource(glsl_trisize_geom), shaderType, glslBaseVer); - DebugData.trisizeProg = CreateShaderProgram(vs, fs, gs); + // create the shaders + GLuint vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + GLuint trifsShad = CreateShader(eGL_FRAGMENT_SHADER, fs); + GLuint gsShad = CreateShader(eGL_GEOMETRY_SHADER, gs); - fs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_frag), shaderType, glslBaseVer); + DebugData.trisizeProg = CreateMeshProgram(vsShad, trifsShad, gsShad); + + // bind trisize-unique viewport size UBO + BindUBO(DebugData.trisizeProg, "ViewportSizeUBO", 2); + + GL.glDeleteShader(trifsShad); + GL.glDeleteShader(gsShad); + + // we have two fragment shaders, one that reads from the vs outputs and one that reads from the + // gs outputs + std::string vsfs = + GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_frag), shaderType, glslBaseVer, + "#define SECONDARY_NAME vsout_secondary\n" + "#define NORM_NAME vsout_norm\n"); + std::string gsfs = + GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_frag), shaderType, glslBaseVer, + "#define SECONDARY_NAME gsout_secondary\n" + "#define NORM_NAME gsout_norm\n"); gs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_geom), shaderType, glslBaseVer); - DebugData.meshProg[0] = CreateShaderProgram(vs, fs); - DebugData.meshgsProg[0] = CreateShaderProgram(vs, fs, gs); + // recreate the shaders + GLuint vsfsShad = CreateShader(eGL_FRAGMENT_SHADER, vsfs); + GLuint gsfsShad = CreateShader(eGL_FRAGMENT_SHADER, gsfs); + gsShad = CreateShader(eGL_GEOMETRY_SHADER, gs); + + DebugData.meshProg[0] = CreateMeshProgram(vsShad, vsfsShad); + DebugData.meshgsProg[0] = CreateMeshProgram(vsShad, gsfsShad, gsShad); if(HasExt[ARB_gpu_shader_fp64] && HasExt[ARB_vertex_attrib_64bit]) { @@ -375,15 +496,23 @@ void GLReplay::InitDebugData() vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer, extensions + "#define POSITION_TYPE dvec4\n"); - DebugData.meshProg[1] = CreateShaderProgram(vs, fs); - DebugData.meshgsProg[1] = CreateShaderProgram(vs, fs, gs); + // delete old shader and recreate with new source + GL.glDeleteShader(vsShad); + vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + + DebugData.meshProg[1] = CreateMeshProgram(vsShad, vsfsShad); + DebugData.meshgsProg[1] = CreateMeshProgram(vsShad, gsfsShad, gsShad); // secondary only dvec4 vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer, extensions + "#define SECONDARY_TYPE dvec4\n"); - DebugData.meshProg[2] = CreateShaderProgram(vs, fs); - DebugData.meshgsProg[2] = CreateShaderProgram(vs, fs, gs); + // delete old shader and recreate with new source + GL.glDeleteShader(vsShad); + vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + + DebugData.meshProg[2] = CreateMeshProgram(vsShad, vsfsShad); + DebugData.meshgsProg[2] = CreateMeshProgram(vsShad, gsfsShad, gsShad); // both dvec4 vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer, @@ -391,8 +520,12 @@ void GLReplay::InitDebugData() "#define POSITION_TYPE dvec4\n" "#define SECONDARY_TYPE dvec4\n"); - DebugData.meshProg[3] = CreateShaderProgram(vs, fs); - DebugData.meshgsProg[3] = CreateShaderProgram(vs, fs, gs); + // delete old shader and recreate with new source + GL.glDeleteShader(vsShad); + vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + + DebugData.meshProg[3] = CreateMeshProgram(vsShad, vsfsShad); + DebugData.meshgsProg[3] = CreateMeshProgram(vsShad, gsfsShad, gsShad); } else { @@ -401,13 +534,26 @@ void GLReplay::InitDebugData() DebugData.meshProg[1] = DebugData.meshProg[2] = DebugData.meshProg[3] = 0; DebugData.meshgsProg[1] = DebugData.meshgsProg[2] = DebugData.meshgsProg[3] = 0; } + + GL.glDeleteShader(vsShad); + GL.glDeleteShader(vsfsShad); + GL.glDeleteShader(gsfsShad); + GL.glDeleteShader(gsShad); } else { vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer); - fs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_frag), shaderType, glslBaseVer); - DebugData.meshProg[0] = CreateShaderProgram(vs, fs); + // without a geometry shader, the fragment shader always reads from vs outputs + fs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_frag), shaderType, glslBaseVer, + "#define SECONDARY_NAME vsout_secondary\n" + "#define NORM_NAME vsout_norm\n"); + + // create the shaders + GLuint vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + GLuint fsShad = CreateShader(eGL_FRAGMENT_SHADER, fs); + + DebugData.meshProg[0] = CreateMeshProgram(vsShad, fsShad); RDCEraseEl(DebugData.meshgsProg); DebugData.trisizeProg = 0; @@ -428,13 +574,21 @@ void GLReplay::InitDebugData() vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer, extensions + "#define POSITION_TYPE dvec4"); - DebugData.meshProg[1] = CreateShaderProgram(vs, fs); + // delete old shader and recreate with new source + GL.glDeleteShader(vsShad); + vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + + DebugData.meshProg[1] = CreateMeshProgram(vsShad, fsShad); // secondary only dvec4 vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer, extensions + "#define SECONDARY_TYPE dvec4"); - DebugData.meshProg[2] = CreateShaderProgram(vs, fs); + // delete old shader and recreate with new source + GL.glDeleteShader(vsShad); + vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + + DebugData.meshProg[2] = CreateMeshProgram(vsShad, fsShad); // both dvec4 vs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_vert), shaderType, glslBaseVer, @@ -442,7 +596,11 @@ void GLReplay::InitDebugData() "#define POSITION_TYPE dvec4\n" "#define SECONDARY_TYPE dvec4"); - DebugData.meshProg[3] = CreateShaderProgram(vs, fs); + // delete old shader and recreate with new source + GL.glDeleteShader(vsShad); + vsShad = CreateShader(eGL_VERTEX_SHADER, vs); + + DebugData.meshProg[3] = CreateMeshProgram(vsShad, fsShad); } else { @@ -450,6 +608,9 @@ void GLReplay::InitDebugData() // it then it's highly unlikely that the capture uses it. DebugData.meshProg[1] = DebugData.meshProg[2] = DebugData.meshProg[3] = 0; } + + GL.glDeleteShader(vsShad); + GL.glDeleteShader(fsShad); } RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.4f); @@ -512,6 +673,13 @@ void GLReplay::InitDebugData() RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.6f); + if(HasExt[ARB_compute_shader] && !HasExt[ARB_shading_language_420pack]) + { + RDCERR( + "GL implementation has ARB_compute_shader but not ARB_shading_language_420pack! " + "Compute shaders won't compile successfully."); + } + // histogram/minmax data { RDCEraseEl(DebugData.minmaxTileProgram); @@ -546,6 +714,9 @@ void GLReplay::InitDebugData() glslCSVer, defines); DebugData.minmaxTileProgram[idx] = CreateCShaderProgram(cs); + + BindUBO(DebugData.minmaxTileProgram[idx], "HistogramUBOData", 2); + ConfigureTexDisplayProgramBindings(DebugData.minmaxTileProgram[idx]); } { @@ -559,6 +730,9 @@ void GLReplay::InitDebugData() defines); DebugData.histogramProgram[idx] = CreateCShaderProgram(cs); + + BindUBO(DebugData.histogramProgram[idx], "HistogramUBOData", 2); + ConfigureTexDisplayProgramBindings(DebugData.histogramProgram[idx]); } if(t == 1) @@ -572,6 +746,9 @@ void GLReplay::InitDebugData() glslCSVer, defines); DebugData.minmaxResultProgram[i] = CreateCShaderProgram(cs); + + BindUBO(DebugData.minmaxResultProgram[i], "HistogramUBOData", 2); + ConfigureTexDisplayProgramBindings(DebugData.minmaxResultProgram[i]); } } } @@ -639,8 +816,18 @@ void GLReplay::InitDebugData() fs = GenerateGLSLShader(GetEmbeddedResource(glsl_depthms2arr_frag), shaderType, glslBaseVer); DebugData.DepthMS2Array = CreateShaderProgram(vs, fs); + GL.glUseProgram(DebugData.DepthMS2Array); + + GL.glUniform1i(GL.glGetUniformLocation(DebugData.DepthMS2Array, "srcDepthMS"), 0); + GL.glUniform1i(GL.glGetUniformLocation(DebugData.DepthMS2Array, "srcStencilMS"), 1); + fs = GenerateGLSLShader(GetEmbeddedResource(glsl_deptharr2ms_frag), shaderType, glslBaseVer); DebugData.DepthArray2MS = CreateShaderProgram(vs, fs); + + GL.glUseProgram(DebugData.DepthArray2MS); + + GL.glUniform1i(GL.glGetUniformLocation(DebugData.DepthArray2MS, "srcDepthArray"), 0); + GL.glUniform1i(GL.glGetUniformLocation(DebugData.DepthArray2MS, "srcStencilArray"), 1); } else { @@ -656,6 +843,8 @@ void GLReplay::InitDebugData() { cs = GenerateGLSLShader(GetEmbeddedResource(glsl_mesh_comp), shaderType, glslCSVer); DebugData.meshPickProgram = CreateCShaderProgram(cs); + + BindUBO(DebugData.meshPickProgram, "MeshPickUBOData", 0); } else { diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 21135700d..0a1c3dd07 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -385,6 +385,10 @@ private: ResourceId m_GetTexturePrevID; byte *m_GetTexturePrevData[16]; + GLuint CreateMeshProgram(GLuint vs, GLuint fs, GLuint gs = 0); + void ConfigureTexDisplayProgramBindings(GLuint program); + void BindUBO(GLuint program, const char *name, GLuint binding); + void InitDebugData(); void DeleteDebugData(); @@ -394,8 +398,9 @@ private: const vector &counters); GLuint CreateShader(GLenum shaderType, const std::string &src); - GLuint CreateShaderProgram(const std::string &vs, const std::string &fs, const std::string &gs); - GLuint CreateShaderProgram(const std::string &vs, const std::string &fs); + GLuint CreateShaderProgram(const std::string &vs, const std::string &fs, + const std::string &gs = ""); + GLuint CreateShaderProgram(GLuint vs, GLuint fs, GLuint gs = 0); GLuint CreateCShaderProgram(const std::string &cs); void InitOutputWindow(OutputWindow &outwin);