diff --git a/renderdoc/data/glsl/blit.vert b/renderdoc/data/glsl/blit.vert index a6283fa73..eb5423f55 100644 --- a/renderdoc/data/glsl/blit.vert +++ b/renderdoc/data/glsl/blit.vert @@ -24,6 +24,13 @@ #version 420 core +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[]; +}; + void main(void) { const vec4 verts[4] = vec4[4](vec4(-1.0, -1.0, 0.5, 1.0), diff --git a/renderdoc/data/glsl/generic.vert b/renderdoc/data/glsl/generic.vert index 317764829..51905514b 100644 --- a/renderdoc/data/glsl/generic.vert +++ b/renderdoc/data/glsl/generic.vert @@ -29,6 +29,13 @@ layout (location = 0) in vec4 position; uniform vec4 RENDERDOC_GenericVS_Offset; uniform vec4 RENDERDOC_GenericVS_Scale; +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[]; +}; + void main(void) { gl_Position = position*RENDERDOC_GenericVS_Scale + RENDERDOC_GenericVS_Offset; diff --git a/renderdoc/data/glsl/mesh.vert b/renderdoc/data/glsl/mesh.vert index e604fcc16..c535223e1 100644 --- a/renderdoc/data/glsl/mesh.vert +++ b/renderdoc/data/glsl/mesh.vert @@ -31,6 +31,13 @@ uniform mat4 ModelViewProj; uniform vec2 PointSpriteSize; uniform uint HomogenousInput; +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[]; +}; + out v2f { vec4 secondary; diff --git a/renderdoc/data/glsl/text.vert b/renderdoc/data/glsl/text.vert index 073c16151..57554f319 100644 --- a/renderdoc/data/glsl/text.vert +++ b/renderdoc/data/glsl/text.vert @@ -44,6 +44,13 @@ out v2f vec2 glyphuv; } OUT; +out gl_PerVertex +{ + vec4 gl_Position; + float gl_PointSize; + float gl_ClipDistance[]; +}; + void main(void) { const vec3 verts[4] = vec3[4](vec3( 0.0, 0.0, 0.5), diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index de451e070..4778825ae 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -79,7 +79,7 @@ GLuint GLReplay::CreateCShaderProgram(const char *csSrc) return ret; } -GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc, const char *gsSrc) +GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *fsSrc, const char *gsSrc) { if(m_pDriver == NULL) return 0; @@ -87,45 +87,50 @@ GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc, const WrappedOpenGL &gl = *m_pDriver; - GLuint vs = gl.glCreateShader(eGL_VERTEX_SHADER); - GLuint fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); + GLuint vs = 0; + GLuint fs = 0; GLuint gs = 0; - const char *src = vsSrc; - gl.glShaderSource(vs, 1, &src, NULL); - src = psSrc; - gl.glShaderSource(fs, 1, &src, NULL); - - if(gsSrc) - { - gs = gl.glCreateShader(eGL_GEOMETRY_SHADER); - src = gsSrc; - gl.glShaderSource(gs, 1, &src, NULL); - } - - gl.glCompileShader(vs); - gl.glCompileShader(fs); - if(gs) gl.glCompileShader(gs); - char buffer[1024]; GLint status = 0; - gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); - if(status == 0) + if(vsSrc) { - gl.glGetShaderInfoLog(vs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); + vs = gl.glCreateShader(eGL_VERTEX_SHADER); + gl.glShaderSource(vs, 1, &vsSrc, NULL); + + gl.glCompileShader(vs); + + gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(vs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } } - gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); - if(status == 0) + if(fsSrc) { - gl.glGetShaderInfoLog(fs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); + fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); + gl.glShaderSource(fs, 1, &fsSrc, NULL); + + gl.glCompileShader(fs); + + gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(fs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } } - if(gs) + if(gsSrc) { + gs = gl.glCreateShader(eGL_GEOMETRY_SHADER); + gl.glShaderSource(gs, 1, &gsSrc, NULL); + + gl.glCompileShader(gs); + gl.glGetShaderiv(gs, eGL_COMPILE_STATUS, &status); if(status == 0) { @@ -136,18 +141,27 @@ GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc, const GLuint ret = gl.glCreateProgram(); - gl.glAttachShader(ret, vs); - gl.glAttachShader(ret, fs); + if(vs) gl.glAttachShader(ret, vs); + if(fs) gl.glAttachShader(ret, fs); if(gs) gl.glAttachShader(ret, gs); + + gl.glProgramParameteri(ret, eGL_PROGRAM_SEPARABLE, GL_TRUE); gl.glLinkProgram(ret); - gl.glDetachShader(ret, vs); - gl.glDetachShader(ret, fs); + gl.glGetShaderiv(ret, eGL_LINK_STATUS, &status); + if(status == 0) + { + gl.glGetProgramInfoLog(ret, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + + if(vs) gl.glDetachShader(ret, vs); + if(fs) gl.glDetachShader(ret, fs); if(gs) gl.glDetachShader(ret, gs); - gl.glDeleteShader(vs); - gl.glDeleteShader(fs); + if(vs) gl.glDeleteShader(vs); + if(fs) gl.glDeleteShader(fs); if(gs) gl.glDeleteShader(gs); return ret; @@ -179,6 +193,8 @@ void GLReplay::InitDebugData() string texfs = GetEmbeddedResource(texsample_h); texfs += GetEmbeddedResource(texdisplay_frag); + DebugData.texDisplayVSProg = CreateShaderProgram(DebugData.blitvsSource.c_str(), NULL); + for(int i=0; i < 3; i++) { string glsl = glslheader; @@ -186,7 +202,7 @@ void GLReplay::InitDebugData() glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; glsl += texfs; - DebugData.texDisplayProg[i] = CreateShaderProgram(DebugData.blitvsSource.c_str(), glsl.c_str()); + DebugData.texDisplayProg[i] = CreateShaderProgram(NULL, glsl.c_str()); } string checkerfs = GetEmbeddedResource(checkerboard_frag); @@ -207,6 +223,9 @@ void GLReplay::InitDebugData() DebugData.meshgsProg = CreateShaderProgram(meshvs.c_str(), meshfs.c_str(), meshgs.c_str()); WrappedOpenGL &gl = *m_pDriver; + + void *ctx = gl.GetCtx(); + gl.glGenProgramPipelines(1, &DebugData.texDisplayPipe); { float data[] = { @@ -258,6 +277,10 @@ void GLReplay::InitDebugData() DebugData.overlayTexWidth = DebugData.overlayTexHeight = 0; DebugData.overlayTex = DebugData.overlayFBO = 0; + gl.glGenFramebuffers(1, &DebugData.customFBO); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.customFBO); + DebugData.customTex = 0; + gl.glGenFramebuffers(1, &DebugData.pickPixelFBO); gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.pickPixelFBO); @@ -455,9 +478,12 @@ void GLReplay::DeleteDebugData() gl.glDeleteProgram(DebugData.blitProg); + gl.glDeleteProgram(DebugData.texDisplayVSProg); for(int i=0; i < 3; i++) gl.glDeleteProgram(DebugData.texDisplayProg[i]); + gl.glDeleteProgramPipelines(1, &DebugData.texDisplayPipe); + gl.glDeleteProgram(DebugData.checkerProg); gl.glDeleteProgram(DebugData.genericProg); gl.glDeleteProgram(DebugData.meshProg); @@ -472,6 +498,10 @@ void GLReplay::DeleteDebugData() gl.glDeleteBuffers(ARRAY_COUNT(DebugData.UBOs), DebugData.UBOs); gl.glDeleteFramebuffers(1, &DebugData.pickPixelFBO); gl.glDeleteTextures(1, &DebugData.pickPixelTex); + + gl.glDeleteFramebuffers(1, &DebugData.customFBO); + if(DebugData.customTex != 0) + gl.glDeleteTextures(1, &DebugData.customTex); gl.glDeleteVertexArrays(1, &DebugData.emptyVAO); @@ -1053,7 +1083,16 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) intIdx = 2; } - gl.glUseProgram(DebugData.texDisplayProg[intIdx]); + gl.glUseProgram(0); + gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_VERTEX_SHADER_BIT, DebugData.texDisplayVSProg); + gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_FRAGMENT_SHADER_BIT, DebugData.texDisplayProg[intIdx]); + + if(cfg.CustomShader != ResourceId() && gl.GetResourceManager()->HasCurrentResource(cfg.CustomShader)) + { + GLuint customProg = gl.GetResourceManager()->GetCurrentResource(cfg.CustomShader).name; + gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_FRAGMENT_SHADER_BIT, customProg); + } + gl.glBindProgramPipeline(DebugData.texDisplayPipe); gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + resType)); gl.glBindTexture(target, texname); @@ -1067,7 +1106,9 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) int maxlevel = -1; - int clampmaxlevel = m_CachedTextures[cfg.texid].mips - 1; + int clampmaxlevel = 0; + if(cfg.texid != DebugData.CustomShaderTexID) + clampmaxlevel = m_CachedTextures[cfg.texid].mips - 1; gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 7124d5860..188ee0591 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2475,79 +2475,136 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, return ret; } -#pragma endregion - -vector GLReplay::GetUsage(ResourceId id) -{ - GLNOTIMP("GetUsage"); - return vector(); -} - -void GLReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) -{ - RDCUNIMPLEMENTED("SetContextFilter"); -} - -void GLReplay::FreeTargetResource(ResourceId id) -{ - RDCUNIMPLEMENTED("FreeTargetResource"); -} - -void GLReplay::FreeCustomShader(ResourceId id) -{ - RDCUNIMPLEMENTED("FreeCustomShader"); -} - -void GLReplay::ReplaceResource(ResourceId from, ResourceId to) -{ - RDCUNIMPLEMENTED("ReplaceResource"); -} - -void GLReplay::RemoveReplacement(ResourceId id) -{ - RDCUNIMPLEMENTED("RemoveReplacement"); -} - -void GLReplay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) -{ - RDCUNIMPLEMENTED("BuildTargetShader"); -} - void GLReplay::BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) { - RDCUNIMPLEMENTED("BuildCustomShader"); -} + if(id == NULL || errors == NULL) + { + if(id) *id = ResourceId(); + return; + } -vector GLReplay::PixelHistory(uint32_t frameID, vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t sampleIdx) -{ - RDCUNIMPLEMENTED("GLReplay::PixelHistory"); - return vector(); -} + WrappedOpenGL &gl = *m_pDriver; + + MakeCurrentReplayContext(m_DebugCtx); -ShaderDebugTrace GLReplay::DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) -{ - RDCUNIMPLEMENTED("DebugVertex"); - return ShaderDebugTrace(); -} + GLenum shtype = eGL_VERTEX_SHADER; + switch(type) + { + default: RDCWARN("Unknown shader type %u", type); + case eShaderStage_Vertex: shtype = eGL_VERTEX_SHADER; break; + case eShaderStage_Tess_Control: shtype = eGL_TESS_CONTROL_SHADER; break; + case eShaderStage_Tess_Eval: shtype = eGL_TESS_EVALUATION_SHADER; break; + case eShaderStage_Geometry: shtype = eGL_GEOMETRY_SHADER; break; + case eShaderStage_Fragment: shtype = eGL_FRAGMENT_SHADER; break; + case eShaderStage_Compute: shtype = eGL_COMPUTE_SHADER; break; + } + + const char *src = source.c_str(); + GLuint shaderprog = gl.glCreateShaderProgramv(shtype, 1, &src); + + GLint status = 0; + gl.glGetProgramiv(shaderprog, eGL_LINK_STATUS, &status); -ShaderDebugTrace GLReplay::DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) -{ - RDCUNIMPLEMENTED("DebugPixel"); - return ShaderDebugTrace(); -} + if(errors) + { + GLint len = 1024; + gl.glGetProgramiv(shaderprog, eGL_INFO_LOG_LENGTH, &len); + char *buffer = new char[len+1]; + gl.glGetProgramInfoLog(shaderprog, len, NULL, buffer); buffer[len] = 0; + *errors = buffer; + delete[] buffer; + } -ShaderDebugTrace GLReplay::DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) -{ - RDCUNIMPLEMENTED("DebugThread"); - return ShaderDebugTrace(); + if(status == 0) + *id = ResourceId(); + else + *id = m_pDriver->GetResourceManager()->GetID(ProgramRes(m_pDriver->GetCtx(), shaderprog)); } ResourceId GLReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) { - RDCUNIMPLEMENTED("ApplyCustomShader"); - return ResourceId(); + if(shader == ResourceId() || texid == ResourceId()) return ResourceId(); + + auto &texDetails = m_pDriver->m_Textures[texid]; + + MakeCurrentReplayContext(m_DebugCtx); + + CreateCustomShaderTex(texDetails.width, texDetails.height); + + m_pDriver->glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.customFBO); + m_pDriver->glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D, DebugData.customTex, 0); + + m_pDriver->glViewport(0, 0, texDetails.width, texDetails.height); + + DebugData.outWidth = float(texDetails.width); DebugData.outHeight = float(texDetails.height); + + float clr[] = { 0.0f, 0.8f, 0.0f, 0.0f }; + m_pDriver->glClearBufferfv(eGL_COLOR, 0, clr); + + TextureDisplay disp; + disp.Red = disp.Green = disp.Blue = disp.Alpha = true; + disp.FlipY = false; + disp.offx = 0.0f; + disp.offy = 0.0f; + disp.CustomShader = shader; + disp.texid = texid; + disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0,0,0,0); + disp.HDRMul = -1.0f; + disp.linearDisplayAsGamma = true; + disp.mip = mip; + disp.sampleIdx = 0; + disp.overlay = eTexOverlay_None; + disp.rangemin = 0.0f; + disp.rangemax = 1.0f; + disp.rawoutput = false; + disp.scale = 1.0f; + disp.sliceFace = 0; + + RenderTextureInternal(disp, false); + + return DebugData.CustomShaderTexID; } +void GLReplay::CreateCustomShaderTex(uint32_t w, uint32_t h) +{ + if(DebugData.customTex) + { + uint32_t oldw = 0, oldh = 0; + m_pDriver->glGetTextureLevelParameterivEXT(DebugData.customTex, eGL_TEXTURE_2D, 0, eGL_TEXTURE_WIDTH, (GLint *)&oldw); + m_pDriver->glGetTextureLevelParameterivEXT(DebugData.customTex, eGL_TEXTURE_2D, 0, eGL_TEXTURE_HEIGHT, (GLint *)&oldh); + + if(oldw == w && oldh == h) + return; + + m_pDriver->glDeleteTextures(1, &DebugData.customTex); + DebugData.customTex = 0; + } + + m_pDriver->glGenTextures(1, &DebugData.customTex); + m_pDriver->glBindTexture(eGL_TEXTURE_2D, DebugData.customTex); + m_pDriver->glTexStorage2D(eGL_TEXTURE_2D, 1, eGL_RGBA16F, (GLsizei)w, (GLsizei)h); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_BASE_LEVEL, 0); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + + DebugData.CustomShaderTexID = m_pDriver->GetResourceManager()->GetID(TextureRes(m_pDriver->GetCtx(), DebugData.customTex)); +} + +void GLReplay::FreeCustomShader(ResourceId id) +{ + if(id == ResourceId()) return; + + m_pDriver->glDeleteProgram(m_pDriver->GetResourceManager()->GetCurrentResource(id).name); +} + +#pragma endregion + + + + ResourceId GLReplay::CreateProxyTexture( FetchTexture templateTex ) { RDCUNIMPLEMENTED("CreateProxyTexture"); @@ -2570,6 +2627,72 @@ void GLReplay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) RDCUNIMPLEMENTED("SetProxyBufferData"); } + + + +vector GLReplay::GetUsage(ResourceId id) +{ + GLNOTIMP("GetUsage"); + return vector(); +} + +void GLReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) +{ + RDCUNIMPLEMENTED("SetContextFilter"); +} + + + +void GLReplay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +{ + RDCUNIMPLEMENTED("BuildTargetShader"); +} + +void GLReplay::ReplaceResource(ResourceId from, ResourceId to) +{ + RDCUNIMPLEMENTED("ReplaceResource"); +} + +void GLReplay::RemoveReplacement(ResourceId id) +{ + RDCUNIMPLEMENTED("RemoveReplacement"); +} + +void GLReplay::FreeTargetResource(ResourceId id) +{ + RDCUNIMPLEMENTED("FreeTargetResource"); +} + + + + +vector GLReplay::PixelHistory(uint32_t frameID, vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t sampleIdx) +{ + RDCUNIMPLEMENTED("GLReplay::PixelHistory"); + return vector(); +} + + + + +ShaderDebugTrace GLReplay::DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) +{ + RDCUNIMPLEMENTED("DebugVertex"); + return ShaderDebugTrace(); +} + +ShaderDebugTrace GLReplay::DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) +{ + RDCUNIMPLEMENTED("DebugPixel"); + return ShaderDebugTrace(); +} + +ShaderDebugTrace GLReplay::DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) +{ + RDCUNIMPLEMENTED("DebugThread"); + return ShaderDebugTrace(); +} + const GLHookSet &GetRealFunctions(); // defined in gl_replay_.cpp diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 83c5f84eb..50169911d 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -194,6 +194,8 @@ class GLReplay : public IReplayDriver const rdctype::array &variables, vector &outvars, const vector &data); + void CreateCustomShaderTex(uint32_t w, uint32_t h); + void GetMapping(WrappedOpenGL &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping); void CopyArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height, GLint arraySize, GLint samples, GLenum intFormat); @@ -252,8 +254,14 @@ class GLReplay : public IReplayDriver // no transformation or scaling GLuint blitProg; + GLuint texDisplayPipe; + GLuint texDisplayVSProg; GLuint texDisplayProg[3]; // float/uint/sint + GLuint customFBO; + GLuint customTex; + ResourceId CustomShaderTexID; + GLuint MS2Array, Array2MS; GLuint pointSampler; @@ -325,7 +333,7 @@ class GLReplay : public IReplayDriver void FillTimers(CounterContext &ctx, const DrawcallTreeNode &drawnode); - GLuint CreateShaderProgram(const char *vs, const char *ps, const char *gs = NULL); + GLuint CreateShaderProgram(const char *vs, const char *fs, const char *gs = NULL); GLuint CreateCShaderProgram(const char *cs); void InitOutputWindow(OutputWindow &outwin); diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index 2001b002a..780a3a9b1 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -503,6 +503,7 @@ void ReplayOutput::DisplayTex() texDisplay.CustomShader = ResourceId(); texDisplay.sliceFace = 0; texDisplay.mip = 0; + texDisplay.linearDisplayAsGamma = false; } float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; diff --git a/renderdocui/Windows/TextureViewer.cs b/renderdocui/Windows/TextureViewer.cs index 611476260..bfa15cfd4 100644 --- a/renderdocui/Windows/TextureViewer.cs +++ b/renderdocui/Windows/TextureViewer.cs @@ -611,6 +611,7 @@ namespace renderdocui.Windows private void customEdit_Click(object sender, EventArgs e) { var filename = customShader.Text; + var key = filename.ToUpperInvariant(); var files = new Dictionary(); files.Add(filename, File.ReadAllText(Path.Combine(Core.ConfigDirectory, filename + m_Core.APIProps.ShaderExtension))); @@ -629,10 +630,10 @@ namespace renderdocui.Windows // Close Callback () => { - m_CustomShaderEditor.Remove(filename); + m_CustomShaderEditor.Remove(key); }); - m_CustomShaderEditor[customShader.Text] = s; + m_CustomShaderEditor[key] = s; s.Show(this.DockPanel); }