- Assigning locations to in/out between stages when type is larger than 4 floats (mat2, mat3, mat4)
Example:
Vertex shader:
out (location=0) highp mat3 vMatrix;
out (location=3) highp float vNumber; // Location must be 3 not 1!
Fragment shader:
in (location=0) highp mat3 vMatrix;
in (location=3) highp float vNumber; // Location must be 3 not 1!
This patch doesn't deal with arrays and doesn't deal with input attributes in
vertex shader. It only resolves problem of default PBR shader.
- SPIRVGenerator::Generate() sates 'valid' flag correctly now (false on error)
Change-Id: I19ee9ac639baf30ef988a43c06ad6295f042c424
--- /dev/null
+//@version 100
+
+// Some amazing uniform block
+UNIFORM_BLOCK FragBlock// another breaking comment
+{
+ UNIFORM lowp vec4 uColor;// This is color (used to cause a parsing error!)
+};
+
+// Input coords
+INPUT mediump vec2 vTexCoord;
+INPUT mediump vec2 vTexCoord2;
+INPUT highp mat3 vMatrix;
+
+UNIFORM sampler2D sTexture;// Sampler two-dimensional
+UNIFORM samplerCube sTextureCube;// Cube sampler for fun
+
+void main()
+{
+
+ // Using GLSL100 semantics
+ vec4 skyboxColor = textureCube(sTextureCube, vec3(0,0,0));
+
+ // Using modern semantics
+ vec4 skyboxColor2 = TEXTURE_CUBE(sTextureCube, vec3(0,0,0));
+
+ gl_FragColor = TEXTURE(sTexture, vTexCoord) * uColor;
+}
--- /dev/null
+#version 430
+//@version 100
+#define TEXTURE texture
+#define TEXTURE_CUBE texture
+#define TEXTURE_LOD textureLod
+#define TEXTURE_CUBE_LOD textureLod
+#define textureCube texture
+#define texture2D texture
+#define texture2DLod textureLod
+#define textureCubeLod textureLod
+
+// Some amazing uniform block
+layout(set=0, binding=1, std140) uniform FragBlock// another breaking comment
+{
+ lowp vec4 uColor;// This is color (used to cause a parsing error!)
+};
+
+// Input coords
+layout(location = 0) in mediump vec2 vTexCoord;
+layout(location = 4) in mediump vec2 vTexCoord2;
+layout(location = 1) in highp mat3 vMatrix;
+
+layout(binding = 2) uniform sampler2D sTexture;// Sampler two-dimensional
+layout(binding = 3) uniform samplerCube sTextureCube;// Cube sampler for fun
+
+#define gl_FragColor _glFragColor
+layout(location=0) out mediump vec4 _glFragColor;
+void main()
+{
+
+ // Using GLSL100 semantics
+ vec4 skyboxColor = textureCube(sTextureCube, vec3(0,0,0));
+
+ // Using modern semantics
+ vec4 skyboxColor2 = TEXTURE_CUBE(sTextureCube, vec3(0,0,0));
+
+ gl_FragColor = TEXTURE(sTexture, vTexCoord) * uColor;
+}
--- /dev/null
+//@version 100
+
+INPUT mediump vec2 aPosition;// This is postion
+INPUT mediump vec2 aTexCoord;/// This is texcort
+OUTPUT mediump vec2 vTexCoord;// some output
+OUTPUT highp mat3 vMatrix;
+OUTPUT medium vec2 vTexCoord2;// other output
+
+// Some vertex block
+UNIFORM_BLOCK VertBlock//block comment
+{
+ UNIFORM highp mat4 uMvpMatrix;//comment0
+ UNIFORM highp vec3 uSize;//comment1
+};
+
+// Main function
+void main()
+{
+
+ // Compute position
+ gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);
+
+ vTexCoord = aPosition + vec2(0.5);// and set up tex coord
+}
--- /dev/null
+#version 430
+//@version 100
+#define TEXTURE texture
+#define TEXTURE_CUBE texture
+#define TEXTURE_LOD textureLod
+#define TEXTURE_CUBE_LOD textureLod
+#define textureCube texture
+#define texture2D texture
+#define texture2DLod textureLod
+#define textureCubeLod textureLod
+
+layout(location = 0) in mediump vec2 aPosition;// This is postion
+layout(location = 1) in mediump vec2 aTexCoord;/// This is texcort
+layout(location=0) out mediump vec2 vTexCoord;// some output
+layout(location=1) out highp mat3 vMatrix;
+layout(location=4) out medium vec2 vTexCoord2;// other output
+
+// Some vertex block
+layout(set=0, binding=0, std140) uniform VertBlock//block comment
+{
+ highp mat4 uMvpMatrix;//comment0
+ highp vec3 uSize;//comment1
+};
+
+// Main function
+void main()
+{
+
+ // Compute position
+ gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);
+
+ vTexCoord = aPosition + vec2(0.5);// and set up tex coord
+}
DALI_TEST_EQUALS(cmp, true, TEST_LOCATION);
}
END_TEST;
+}
+
+int UtcParserInOutLocation0(void)
+{
+ tet_infoline("UtcParserInOutLocation0 - Tests In/Out locations for longer types");
+
+ auto vertexShader = LoadTextFile(TEST_RESOURCE_DIR "/shaders/inout-locations.vert");
+ auto fragmentShader = LoadTextFile(TEST_RESOURCE_DIR "/shaders/inout-locations.frag");
+
+ std::vector<std::string> outStrings;
+
+ Internal::ShaderParser::ShaderParserInfo parseInfo{};
+ parseInfo.vertexShaderCode = &vertexShader;
+ parseInfo.fragmentShaderCode = &fragmentShader;
+ parseInfo.vertexShaderLegacyVersion = 0;
+ parseInfo.fragmentShaderLegacyVersion = 0;
+ parseInfo.language = Internal::ShaderParser::OutputLanguage::SPIRV_GLSL;
+ parseInfo.outputVersion = 0;
+ Parse(parseInfo, outStrings);
+
+ auto& outVertexShader = outStrings[0];
+ auto& outFragmentShader = outStrings[1];
+ {
+ bool cmp = CompareFileWithString(TEST_RESOURCE_DIR "/shaders/inout-locations.vert.processed", outVertexShader);
+ DALI_TEST_EQUALS(cmp, true, TEST_LOCATION);
+ }
+ {
+ bool cmp = CompareFileWithString(TEST_RESOURCE_DIR "/shaders/inout-locations.frag.processed", outFragmentShader);
+ DALI_TEST_EQUALS(cmp, true, TEST_LOCATION);
+ }
+ END_TEST;
}
\ No newline at end of file
namespace
{
+const std::vector<std::string> MATRIX_DATA_TYPE_TOKENS{"mat3", "mat4", "mat2"};
+
inline bool IsWordChar(const char c)
{
return ('A' <= c && c <= 'Z') ||
return std::string_view(&line.line[line.tokens[i].first], line.tokens[i].second);
}
+/**
+ * Function is looking for any token from the given list.
+ *
+ * @return return -1 if no token found, or index of token that has been found first
+ */
+int HasAnyToken(CodeLine& line, const std::vector<std::string>& tokens)
+{
+ for(const auto& token : line.tokens)
+ {
+ uint32_t i = 0;
+ auto str = std::string_view(&line.line[token.first], token.second);
+ for(const auto& token2 : tokens)
+ {
+ if(str == token2)
+ {
+ return i;
+ }
+ ++i;
+ }
+ }
+ return -1;
+}
+
+bool HasToken(CodeLine& line, std::string_view tokenToFind)
+{
+ for(const auto& token : line.tokens)
+ {
+ auto str = std::string_view(&line.line[token.first], token.second);
+ if(str == tokenToFind)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
void TokenizeSource(Program& program, ShaderStage stage, std::istream& ss)
{
Shader* output{nullptr};
if(isOutputToken)
{
- auto varname = GetToken(line, -1);
- program.varyings[varname] = location++;
+ auto varname = GetToken(line, -1);
+
+ // The location depends on type, anything larger than vec4 (4 floats)
+ // will require adjusting the location, otherwise the location override error
+ // will occur.
+ auto locationsUsed = 1;
+ auto tokenIndex = HasAnyToken(line, MATRIX_DATA_TYPE_TOKENS);
+ if(tokenIndex >= 0)
+ {
+ // get last character which indicates how many vec4-sizes the type uses
+ locationsUsed = int(std::string_view(MATRIX_DATA_TYPE_TOKENS[tokenIndex]).back()) - '0';
+ }
+
+ program.varyings[varname] = location;
+ location += locationsUsed;
}
}
// Verify
// Using new to inject internal data visible only within implementation
mGeneratorInfo.extraInfo = new SPIRVGeneratorExtraInfo;
- mGeneratorInfo.extraInfo->valid = true;
+ mGeneratorInfo.extraInfo->valid = false;
switch(mGeneratorInfo.pipelineStage)
{
mBinary.resize(size);
glslang_program_SPIRV_get(program, mBinary.data());
+ mGeneratorInfo.extraInfo->valid = true;
+
const char* spirv_messages = glslang_program_SPIRV_get_messages(program);
if(spirv_messages)
+ {
DALI_LOG_ERROR("%s\b", spirv_messages);
+ mGeneratorInfo.extraInfo->valid = false;
+ }
glslang_program_delete(program);
glslang_finalize_process();