diff --git a/3rdparty/glslang/hlsl/hlslParseHelper.cpp b/3rdparty/glslang/hlsl/hlslParseHelper.cpp index ff0c7771e..16a82c41f 100755 --- a/3rdparty/glslang/hlsl/hlslParseHelper.cpp +++ b/3rdparty/glslang/hlsl/hlslParseHelper.cpp @@ -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) { diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 0bac66a02..e74181095 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -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(eol) = '\0'; + } + BX_TRACE("%3d %s", line, str); + } + } GLsizei len; char log[1024]; diff --git a/src/renderer_gl.h b/src/renderer_gl.h index b59e04753..91301be0e 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -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 diff --git a/tools/shaderc/shaderc.cpp b/tools/shaderc/shaderc.cpp index 9ad11e5af..cf9ff58b0 100644 --- a/tools/shaderc/shaderc.cpp +++ b/tools/shaderc/shaderc.cpp @@ -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) { diff --git a/tools/shaderc/shaderc.h b/tools/shaderc/shaderc.h index b7e0fb71e..7ddfba635 100644 --- a/tools/shaderc/shaderc.h +++ b/tools/shaderc/shaderc.h @@ -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; diff --git a/tools/shaderc/shaderc_hlsl.cpp b/tools/shaderc/shaderc_hlsl.cpp index 85eb74220..c9f7d13e5 100644 --- a/tools/shaderc/shaderc_hlsl.cpp +++ b/tools/shaderc/shaderc_hlsl.cpp @@ -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