Implement custom display shaders for OpenGL logs, no parameters yet

* glsl and hlsl custom display shaders are kept separate, and only shown
  for the appropriate log type.
* The little snippets added in the shader editor aren't updated yet, and
  none of the pre-defined shader constants are filled out.
This commit is contained in:
baldurk
2015-02-09 22:19:13 +00:00
parent 72cfee5c0f
commit 86d0b8a952
9 changed files with 303 additions and 101 deletions
+7
View File
@@ -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),
+7
View File
@@ -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;
+7
View File
@@ -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;
+7
View File
@@ -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),
+78 -37
View File
@@ -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);
+184 -61
View File
@@ -2475,79 +2475,136 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip,
return ret;
}
#pragma endregion
vector<EventUsage> GLReplay::GetUsage(ResourceId id)
{
GLNOTIMP("GetUsage");
return vector<EventUsage>();
}
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<PixelModification> GLReplay::PixelHistory(uint32_t frameID, vector<EventUsage> events, ResourceId target, uint32_t x, uint32_t y, uint32_t sampleIdx)
{
RDCUNIMPLEMENTED("GLReplay::PixelHistory");
return vector<PixelModification>();
}
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<EventUsage> GLReplay::GetUsage(ResourceId id)
{
GLNOTIMP("GetUsage");
return vector<EventUsage>();
}
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<PixelModification> GLReplay::PixelHistory(uint32_t frameID, vector<EventUsage> events, ResourceId target, uint32_t x, uint32_t y, uint32_t sampleIdx)
{
RDCUNIMPLEMENTED("GLReplay::PixelHistory");
return vector<PixelModification>();
}
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_<platform>.cpp
+9 -1
View File
@@ -194,6 +194,8 @@ class GLReplay : public IReplayDriver
const rdctype::array<ShaderConstant> &variables, vector<ShaderVariable> &outvars,
const vector<byte> &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);
+1
View File
@@ -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};
+3 -2
View File
@@ -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<string, string>();
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);
}