shaderc: If GLSL version is above 4.00 shaderc will just pass preprocessed code without invoking glsl-optimizer.

This commit is contained in:
Branimir Karadžić
2017-06-05 17:37:26 -07:00
parent ed99f83093
commit e19a6738c7
6 changed files with 318 additions and 234 deletions

View File

@@ -6974,8 +6974,8 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, const TStr
// Deal with initializer
TIntermNode* initNode = nullptr;
if (symbol && initializer) {
if (flattenVar)
error(loc, "flattened array with initializer list unsupported", identifier.c_str(), "");
// if (flattenVar)
// error(loc, "flattened array with initializer list unsupported", identifier.c_str(), "");
TVariable* variable = symbol->getAsVariable();
if (! variable) {

View File

@@ -5431,7 +5431,8 @@ namespace bgfx { namespace gl
if (0 != m_id)
{
if (GL_COMPUTE_SHADER != m_type)
if (GL_COMPUTE_SHADER != m_type
&& 0 != bx::strCmp(code, "#version 430", 12) )
{
int32_t codeLen = (int32_t)bx::strLen(code);
int32_t tempLen = codeLen + (4<<10);
@@ -5859,7 +5860,24 @@ namespace bgfx { namespace gl
if (0 == compiled)
{
BX_TRACE("\n####\n%s\n####", code);
LineReader lineReader(code);
bx::Error err;
for (int32_t line = 1; err.isOk(); ++line)
{
char str[4096];
int32_t len = bx::read(&lineReader, str, BX_COUNTOF(str)-1, &err);
if (err.isOk() )
{
str[len] = '\0';
const char* eol = bx::streol(str);
if (eol != str)
{
*const_cast<char*>(eol) = '\0';
}
BX_TRACE("%3d %s", line, str);
}
}
GLsizei len;
char log[1024];

View File

@@ -1515,6 +1515,45 @@ namespace bgfx { namespace gl
bx::RingBufferControl m_control;
};
class LineReader : public bx::ReaderI
{
public:
LineReader(const void* _str)
: m_str( (const char*)_str)
, m_pos(0)
, m_size(bx::strLen( (const char*)_str) )
{
}
virtual int32_t read(void* _data, int32_t _size, bx::Error* _err) BX_OVERRIDE
{
if (m_str[m_pos] == '\0'
|| m_pos == m_size)
{
BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "LineReader: EOF.");
return 0;
}
uint32_t pos = m_pos;
const char* str = &m_str[pos];
const char* nl = bx::strnl(str);
pos += (uint32_t)(nl - str);
const char* eol = &m_str[pos];
uint32_t size = bx::uint32_min(uint32_t(eol - str), _size);
bx::memCopy(_data, str, size);
m_pos += size;
return size;
}
const char* m_str;
uint32_t m_pos;
uint32_t m_size;
};
} /* namespace gl */ } // namespace bgfx
#endif // BGFX_RENDERER_GL_H_HEADER_GUARD

View File

@@ -408,15 +408,22 @@ namespace bgfx
{
fprintf(stderr, "Code:\n---\n");
LineReader lr(_code);
for (int32_t line = 1; !lr.isEof() && line < _end; ++line)
bx::Error err;
LineReader reader(_code);
for (int32_t line = 1; err.isOk() && line < _end; ++line)
{
if (line >= _start)
char str[4096];
int32_t len = bx::read(&reader, str, BX_COUNTOF(str), &err);
if (err.isOk()
&& line >= _start)
{
std::string strLine(str, len);
if (_line == line)
{
fprintf(stderr, "\n");
fprintf(stderr, ">>> %3d: %s", line, lr.getLine().c_str() );
fprintf(stderr, ">>> %3d: %s", line, strLine.c_str() );
if (-1 != _column)
{
fprintf(stderr, ">>> %3d: %*s\n", _column, _column, "^");
@@ -425,13 +432,9 @@ namespace bgfx
}
else
{
fprintf(stderr, " %3d: %s", line, lr.getLine().c_str() );
fprintf(stderr, " %3d: %s", line, strLine.c_str() );
}
}
else
{
lr.skipLine();
}
}
fprintf(stderr, "---\n");
@@ -1914,210 +1917,227 @@ namespace bgfx
{
std::string code;
const bool usesTextureLod = false
|| !!bx::findIdentifierMatch(input, s_ARB_shader_texture_lod)
|| !!bx::findIdentifierMatch(input, s_EXT_shader_texture_lod)
;
const bool usesInstanceID = !!bx::strFind(input, "gl_InstanceID");
const bool usesGpuShader4 = !!bx::findIdentifierMatch(input, s_EXT_gpu_shader4);
const bool usesGpuShader5 = !!bx::findIdentifierMatch(input, s_ARB_gpu_shader5);
const bool usesTexelFetch = !!bx::findIdentifierMatch(input, s_texelFetch);
const bool usesTextureMS = !!bx::findIdentifierMatch(input, s_ARB_texture_multisample);
const bool usesTextureArray = !!bx::findIdentifierMatch(input, s_textureArray);
const bool usesPacking = !!bx::findIdentifierMatch(input, s_ARB_shading_language_packing);
if (0 == essl)
if (glsl < 400)
{
const bool need130 = 120 == glsl && (false
|| bx::findIdentifierMatch(input, s_130)
|| usesTexelFetch
);
const bool usesTextureLod = false
|| !!bx::findIdentifierMatch(input, s_ARB_shader_texture_lod)
|| !!bx::findIdentifierMatch(input, s_EXT_shader_texture_lod)
;
const bool usesInstanceID = !!bx::strFind(input, "gl_InstanceID");
const bool usesGpuShader4 = !!bx::findIdentifierMatch(input, s_EXT_gpu_shader4);
const bool usesGpuShader5 = !!bx::findIdentifierMatch(input, s_ARB_gpu_shader5);
const bool usesTexelFetch = !!bx::findIdentifierMatch(input, s_texelFetch);
const bool usesTextureMS = !!bx::findIdentifierMatch(input, s_ARB_texture_multisample);
const bool usesTextureArray = !!bx::findIdentifierMatch(input, s_textureArray);
const bool usesPacking = !!bx::findIdentifierMatch(input, s_ARB_shading_language_packing);
if (0 != metal)
if (0 == essl)
{
bx::stringPrintf(code, "#version 120\n");
}
else
{
bx::stringPrintf(code, "#version %s\n", need130 ? "130" : profile);
glsl = 130;
}
if (usesInstanceID)
{
bx::stringPrintf(code
, "#extension GL_ARB_draw_instanced : enable\n"
const bool need130 = 120 == glsl && (false
|| bx::findIdentifierMatch(input, s_130)
|| usesTexelFetch
);
}
if (usesGpuShader4)
{
bx::stringPrintf(code
, "#extension GL_EXT_gpu_shader4 : enable\n"
);
}
if (usesGpuShader5)
{
bx::stringPrintf(code
, "#extension GL_ARB_gpu_shader5 : enable\n"
);
}
if (usesPacking)
{
bx::stringPrintf(code
, "#extension GL_ARB_shading_language_packing : enable\n"
);
}
bool ARB_shader_texture_lod = false;
bool EXT_shader_texture_lod = false;
if (usesTextureLod)
{
if ('f' == shaderType)
if (0 != metal)
{
ARB_shader_texture_lod = true;
bx::stringPrintf(code
, "#extension GL_ARB_shader_texture_lod : enable\n"
);
bx::stringPrintf(code, "#version 120\n");
}
else
{
EXT_shader_texture_lod = true;
bx::stringPrintf(code, "#version %s\n", need130 ? "130" : profile);
glsl = 130;
}
if (usesInstanceID)
{
bx::stringPrintf(code
, "#extension GL_EXT_shader_texture_lod : enable\n"
, "#extension GL_ARB_draw_instanced : enable\n"
);
}
if (usesGpuShader4)
{
bx::stringPrintf(code
, "#extension GL_EXT_gpu_shader4 : enable\n"
);
}
if (usesGpuShader5)
{
bx::stringPrintf(code
, "#extension GL_ARB_gpu_shader5 : enable\n"
);
}
if (usesPacking)
{
bx::stringPrintf(code
, "#extension GL_ARB_shading_language_packing : enable\n"
);
}
bool ARB_shader_texture_lod = false;
bool EXT_shader_texture_lod = false;
if (usesTextureLod)
{
if ('f' == shaderType)
{
ARB_shader_texture_lod = true;
bx::stringPrintf(code
, "#extension GL_ARB_shader_texture_lod : enable\n"
);
}
else
{
EXT_shader_texture_lod = true;
bx::stringPrintf(code
, "#extension GL_EXT_shader_texture_lod : enable\n"
);
}
}
if (usesTextureMS)
{
bx::stringPrintf(code
, "#extension GL_ARB_texture_multisample : enable\n"
);
}
if (usesTextureArray)
{
bx::stringPrintf(code
, "#extension GL_EXT_texture_array : enable\n"
);
}
if (130 > glsl)
{
bx::stringPrintf(code,
"#define ivec2 vec2\n"
"#define ivec3 vec3\n"
"#define ivec4 vec4\n"
);
}
if (ARB_shader_texture_lod)
{
bx::stringPrintf(code,
"#define texture2DProjLod texture2DProjLodARB\n"
"#define texture2DGrad texture2DGradARB\n"
"#define texture2DProjGrad texture2DProjGradARB\n"
"#define textureCubeGrad textureCubeGradARB\n"
);
}
else if (EXT_shader_texture_lod)
{
bx::stringPrintf(code,
"#define texture2DProjLod texture2DProjLodEXT\n"
"#define texture2DGrad texture2DGradEXT\n"
"#define texture2DProjGrad texture2DProjGradEXT\n"
"#define textureCubeGrad textureCubeGradEXT\n"
);
}
}
if (usesTextureMS)
{
bx::stringPrintf(code
, "#extension GL_ARB_texture_multisample : enable\n"
, "#define bgfxShadow2D shadow2D\n"
"#define bgfxShadow2DProj shadow2DProj\n"
);
}
if (usesTextureArray)
else
{
bx::stringPrintf(code
, "#extension GL_EXT_texture_array : enable\n"
);
}
// Pretend that all extensions are available.
// This will be stripped later.
if (usesTextureLod)
{
bx::stringPrintf(code
, "#extension GL_EXT_shader_texture_lod : enable\n"
"#define texture2DLod texture2DLodEXT\n"
"#define texture2DGrad texture2DGradEXT\n"
"#define texture2DProjLod texture2DProjLodEXT\n"
"#define texture2DProjGrad texture2DProjGradEXT\n"
"#define textureCubeLod textureCubeLodEXT\n"
"#define textureCubeGrad textureCubeGradEXT\n"
);
}
if (NULL != bx::findIdentifierMatch(input, s_OES_standard_derivatives) )
{
bx::stringPrintf(code, "#extension GL_OES_standard_derivatives : enable\n");
}
if (NULL != bx::findIdentifierMatch(input, s_OES_texture_3D) )
{
bx::stringPrintf(code, "#extension GL_OES_texture_3D : enable\n");
}
if (NULL != bx::findIdentifierMatch(input, s_EXT_shadow_samplers) )
{
bx::stringPrintf(code
, "#extension GL_EXT_shadow_samplers : enable\n"
"#define shadow2D shadow2DEXT\n"
"#define shadow2DProj shadow2DProjEXT\n"
);
}
if (usesGpuShader5)
{
bx::stringPrintf(code
, "#extension GL_ARB_gpu_shader5 : enable\n"
);
}
if (usesPacking)
{
bx::stringPrintf(code
, "#extension GL_ARB_shading_language_packing : enable\n"
);
}
if (NULL != bx::findIdentifierMatch(input, "gl_FragDepth") )
{
bx::stringPrintf(code
, "#extension GL_EXT_frag_depth : enable\n"
"#define gl_FragDepth gl_FragDepthEXT\n"
);
}
if (usesTextureArray)
{
bx::stringPrintf(code
, "#extension GL_EXT_texture_array : enable\n"
);
}
if (130 > glsl)
{
bx::stringPrintf(code,
"#define ivec2 vec2\n"
"#define ivec3 vec3\n"
"#define ivec4 vec4\n"
);
"#define ivec2 vec2\n"
"#define ivec3 vec3\n"
"#define ivec4 vec4\n"
);
}
if (ARB_shader_texture_lod)
{
bx::stringPrintf(code,
"#define texture2DProjLod texture2DProjLodARB\n"
"#define texture2DGrad texture2DGradARB\n"
"#define texture2DProjGrad texture2DProjGradARB\n"
"#define textureCubeGrad textureCubeGradARB\n"
);
}
else if (EXT_shader_texture_lod)
{
bx::stringPrintf(code,
"#define texture2DProjLod texture2DProjLodEXT\n"
"#define texture2DGrad texture2DGradEXT\n"
"#define texture2DProjGrad texture2DProjGradEXT\n"
"#define textureCubeGrad textureCubeGradEXT\n"
);
}
bx::stringPrintf(code
, "#define bgfxShadow2D shadow2D\n"
"#define bgfxShadow2DProj shadow2DProj\n"
);
}
else
{
// Pretend that all extensions are available.
// This will be stripped later.
if (usesTextureLod)
{
bx::stringPrintf(code
, "#extension GL_EXT_shader_texture_lod : enable\n"
"#define texture2DLod texture2DLodEXT\n"
"#define texture2DGrad texture2DGradEXT\n"
"#define texture2DProjLod texture2DProjLodEXT\n"
"#define texture2DProjGrad texture2DProjGradEXT\n"
"#define textureCubeLod textureCubeLodEXT\n"
"#define textureCubeGrad textureCubeGradEXT\n"
);
}
if (NULL != bx::findIdentifierMatch(input, s_OES_standard_derivatives) )
{
bx::stringPrintf(code, "#extension GL_OES_standard_derivatives : enable\n");
}
if (NULL != bx::findIdentifierMatch(input, s_OES_texture_3D) )
{
bx::stringPrintf(code, "#extension GL_OES_texture_3D : enable\n");
}
if (NULL != bx::findIdentifierMatch(input, s_EXT_shadow_samplers) )
{
bx::stringPrintf(code
, "#extension GL_EXT_shadow_samplers : enable\n"
"#define shadow2D shadow2DEXT\n"
"#define shadow2DProj shadow2DProjEXT\n"
);
}
if (usesGpuShader5)
{
bx::stringPrintf(code
, "#extension GL_ARB_gpu_shader5 : enable\n"
);
}
if (usesPacking)
{
bx::stringPrintf(code
, "#extension GL_ARB_shading_language_packing : enable\n"
);
}
if (NULL != bx::findIdentifierMatch(input, "gl_FragDepth") )
{
bx::stringPrintf(code
, "#extension GL_EXT_frag_depth : enable\n"
"#define gl_FragDepth gl_FragDepthEXT\n"
);
}
if (usesTextureArray)
{
bx::stringPrintf(code
, "#extension GL_EXT_texture_array : enable\n"
);
}
bx::stringPrintf(code,
"#define ivec2 vec2\n"
"#define ivec3 vec3\n"
"#define ivec4 vec4\n"
);
}
code += preprocessor.m_preprocessed;
compiled = compileGLSLShader(cmdLine
, metal ? BX_MAKEFOURCC('M', 'T', 'L', 0) : essl
, code
, writer
);
if (glsl > 400)
{
bx::write(writer, uint16_t(0) );
uint32_t shaderSize = (uint32_t)code.size();
bx::write(writer, shaderSize);
bx::write(writer, code.c_str(), shaderSize);
bx::write(writer, uint8_t(0) );
compiled = true;
}
else
{
compiled = compileGLSLShader(cmdLine
, metal ? BX_MAKEFOURCC('M', 'T', 'L', 0) : essl
, code
, writer
);
}
}
else if (0 != spirv)
{

View File

@@ -68,38 +68,38 @@ namespace bgfx
{
extern bool g_verbose;
class LineReader
class LineReader : public bx::ReaderI
{
public:
LineReader(const char* _str)
: m_str(_str)
, m_pos(0)
, m_size((uint32_t)bx::strLen(_str))
, m_size(bx::strLen(_str) )
{
}
std::string getLine()
virtual int32_t read(void* _data, int32_t _size, bx::Error* _err) BX_OVERRIDE
{
const char* str = &m_str[m_pos];
skipLine();
if (m_str[m_pos] == '\0'
|| m_pos == m_size)
{
BX_ERROR_SET(_err, BX_ERROR_READERWRITER_EOF, "LineReader: EOF.");
return 0;
}
const char* eol = &m_str[m_pos];
std::string tmp;
tmp.assign(str, eol - str);
return tmp;
}
bool isEof() const
{
return m_str[m_pos] == '\0';
}
void skipLine()
{
const char* str = &m_str[m_pos];
uint32_t pos = m_pos;
const char* str = &m_str[pos];
const char* nl = bx::strnl(str);
m_pos += (uint32_t)(nl - str);
pos += (uint32_t)(nl - str);
const char* eol = &m_str[pos];
uint32_t size = bx::uint32_min(uint32_t(eol - str), _size);
bx::memCopy(_data, str, size);
m_pos += size;
return size;
}
const char* m_str;

View File

@@ -624,7 +624,7 @@ namespace bgfx { namespace hlsl
int32_t end = INT32_MAX;
bool found = false
|| 2 == sscanf(log, "(%u,%u):", &line, &column)
|| 2 == sscanf(log, "(%u,%u):", &line, &column)
|| 2 == sscanf(log, " :%u:%u: ", &line, &column)
;
@@ -670,32 +670,39 @@ namespace bgfx { namespace hlsl
// first time through, we just find unused uniforms and get rid of them
std::string output;
bx::Error err;
LineReader reader(_code.c_str() );
while (!reader.isEof() )
while (err.isOk() )
{
std::string line = reader.getLine();
for (UniformNameList::iterator it = unusedUniforms.begin(), itEnd = unusedUniforms.end(); it != itEnd; ++it)
char str[4096];
int32_t len = bx::read(&reader, str, BX_COUNTOF(str), &err);
if (err.isOk() )
{
size_t index = line.find("uniform ");
if (index == std::string::npos)
std::string strLine(str, len);
for (UniformNameList::iterator it = unusedUniforms.begin(), itEnd = unusedUniforms.end(); it != itEnd; ++it)
{
continue;
size_t index = strLine.find("uniform ");
if (index == std::string::npos)
{
continue;
}
// matching lines like: uniform u_name;
// we want to replace "uniform" with "static" so that it's no longer
// included in the uniform blob that the application must upload
// we can't just remove them, because unused functions might still reference
// them and cause a compile error when they're gone
if (!!bx::findIdentifierMatch(strLine.c_str(), it->c_str() ) )
{
strLine = strLine.replace(index, strLength, "static");
unusedUniforms.erase(it);
break;
}
}
// matching lines like: uniform u_name;
// we want to replace "uniform" with "static" so that it's no longer
// included in the uniform blob that the application must upload
// we can't just remove them, because unused functions might still reference
// them and cause a compile error when they're gone
if (!!bx::findIdentifierMatch(line.c_str(), it->c_str() ) )
{
line = line.replace(index, strLength, "static");
unusedUniforms.erase(it);
break;
}
output += strLine;
}
output += line;
}
// recompile with the unused uniforms converted to statics