Suppress listing gl_PointSize or gl_ClipDistance if they weren't used

This commit is contained in:
baldurk
2015-01-25 21:38:40 +00:00
parent 9bd5fabe1a
commit 6155d6d925
3 changed files with 85 additions and 5 deletions
+71 -1
View File
@@ -96,6 +96,69 @@ void copy(rdctype::array<ShaderConstant> &outvars, const vector<DynShaderConstan
}
}
void CheckVertexOutputUses(vector<string> sources, bool &pointSizeUsed, bool &clipDistanceUsed)
{
pointSizeUsed = false;
clipDistanceUsed = false;
for(size_t i=0; i < sources.size(); i++)
{
string &s = sources[i];
size_t offs = 0;
while(true)
{
offs = s.find("gl_PointSize", offs);
if(offs == string::npos)
break;
// consider gl_PointSize used if we encounter a '=' before a ';' or the end of the string
while(offs < s.length())
{
if(s[offs] == '=')
{
pointSizeUsed = true;
break;
}
if(s[offs] == ';')
break;
offs++;
}
}
offs = 0;
while(true)
{
offs = s.find("gl_ClipDistance", offs);
if(offs == string::npos)
break;
// consider gl_ClipDistance used if we encounter a '=' before a ';' or the end of the string
while(offs < s.length())
{
if(s[offs] == '=')
{
clipDistanceUsed = true;
break;
}
if(s[offs] == ';')
break;
offs++;
}
}
}
}
// little utility function that if necessary emulates glCreateShaderProgramv functionality but using glCompileShaderIncludeARB
static GLuint CreateSepProgram(const GLHookSet &gl, GLenum type, GLsizei numSources, const char **sources, GLsizei numPaths, const char **paths)
{
@@ -578,7 +641,7 @@ void ReconstructVarTree(const GLHookSet &gl, GLenum query, GLuint sepProg, GLuin
}
}
void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, ShaderReflection &refl)
void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, ShaderReflection &refl, bool pointSizeUsed, bool clipDistanceUsed)
{
refl.DebugInfo.entryFunc = "main";
refl.DebugInfo.compileFlags = 0;
@@ -1424,6 +1487,13 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
#define IS_BUILTIN(builtin) !strncmp(nm, builtin, sizeof(builtin)-1)
// if these weren't used, they were probably added just to make a separable program
// (either by us or the program originally). Skip them from the output signature
if(IS_BUILTIN("gl_PointSize") && !pointSizeUsed)
continue;
if(IS_BUILTIN("gl_ClipDistance") && !clipDistanceUsed)
continue;
// VS built-in inputs
if(IS_BUILTIN("gl_VertexID")) sig.systemValue = eAttr_VertexIndex;
if(IS_BUILTIN("gl_InstanceID")) sig.systemValue = eAttr_InstanceIndex;
+2 -1
View File
@@ -26,5 +26,6 @@
#include "replay/replay_driver.h"
void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, ShaderReflection &refl);
void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, ShaderReflection &refl, bool pointSizeUsed, bool clipDistanceUsed);
GLuint MakeSeparableShaderProgram(const GLHookSet &gl, GLenum type, std::vector<std::string> sources, vector<string> *includepaths);
void CheckVertexOutputUses(std::vector<std::string> sources, bool &pointSizeUsed, bool &clipDistanceUsed);
@@ -152,6 +152,9 @@ bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader)
auto &shadDetails = m_Shaders[liveId];
bool pointSizeUsed = false, clipDistanceUsed = false;
if(shadDetails.type == eGL_VERTEX_SHADER) CheckVertexOutputUses(shadDetails.sources, pointSizeUsed, clipDistanceUsed);
GLuint sepProg = MakeSeparableShaderProgram(m_Real, shadDetails.type, shadDetails.sources, NULL);
if(sepProg == 0)
@@ -161,7 +164,7 @@ bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader)
else
{
shadDetails.prog = sepProg;
MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection);
MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);
create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
for(size_t i=0; i < shadDetails.sources.size(); i++)
@@ -341,10 +344,13 @@ bool WrappedOpenGL::Serialise_glCreateShaderProgramv(GLuint program, GLenum type
auto &shadDetails = m_Shaders[liveId];
bool pointSizeUsed = false, clipDistanceUsed = false;
if(Type == eGL_VERTEX_SHADER) CheckVertexOutputUses(src, pointSizeUsed, clipDistanceUsed);
shadDetails.type = Type;
shadDetails.sources.swap(src);
shadDetails.prog = real;
MakeShaderReflection(m_Real, Type, real, shadDetails.reflection);
MakeShaderReflection(m_Real, Type, real, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);
create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
for(size_t i=0; i < shadDetails.sources.size(); i++)
@@ -1063,6 +1069,9 @@ bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(GLuint shader, GLsizei c
for(int32_t i=0; i < Count; i++)
shadDetails.includepaths.push_back(pathstrings[i]);
bool pointSizeUsed = false, clipDistanceUsed = false;
if(shadDetails.type == eGL_VERTEX_SHADER) CheckVertexOutputUses(shadDetails.sources, pointSizeUsed, clipDistanceUsed);
GLuint sepProg = MakeSeparableShaderProgram(m_Real, shadDetails.type, shadDetails.sources, &paths);
if(sepProg == 0)
@@ -1072,7 +1081,7 @@ bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(GLuint shader, GLsizei c
else
{
shadDetails.prog = sepProg;
MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection);
MakeShaderReflection(m_Real, shadDetails.type, sepProg, shadDetails.reflection, pointSizeUsed, clipDistanceUsed);
create_array_uninit(shadDetails.reflection.DebugInfo.files, shadDetails.sources.size());
for(size_t i=0; i < shadDetails.sources.size(); i++)