Hi,
some versions of the PVR Series6+ OpenGL GLSL driver (e.g. on Xiaomi Redmi 6A) seem to have a compiler bug/issues with code like:
vec3 view_dir = normalize(pos.xyz - _50.viewMatrix[3].xyz);
Results in “compile failed”.
Rewriting the line by wrapping the row in vec4(…)
vec3 view_dir = normalize(pos.xyz - vec4(_50.viewMatrix[3]).xyz);
Results in “compile success”.
This is reproducible with PVRShaderEditor by selecting “PVR Series6+” profile with the shader below.
#version 300 es
struct RSInput
{
vec3 position;
vec3 normal;
};
struct RSOutput
{
vec4 position;
vec3 normal;
vec3 view_dir;
vec3 wsposition;
};
layout(std140) uniform RHI_ParamBlock3_VS_C3
{
layout(row_major) mat4 localTransform;
vec4 clipPlane;
} _32;
layout(std140) uniform RHI_ParamBlock1_VS_C1
{
layout(row_major) mat4 viewMatrix;
layout(row_major) mat4 projectionMatrix;
layout(row_major) mat4 viewProjectionMatrix;
vec4 viewportParams;
vec4 cameraPosition;
} _50;
layout(std140) uniform RHI_ParamBlock2_VS_C2
{
vec3 materialColorDiffuse;
float materialOpacity;
vec3 materialColorSpecular;
float materialShininess;
float materialShininessStrength;
float materialReflectivity;
float materialRefractIndex;
float padding;
} _111;
layout(location = 0) in vec3 input_position;
layout(location = 1) in vec3 input_normal;
out vec3 vs_output_0;
out vec3 vs_output_1;
out vec3 vs_output_2;
mat4 spvWorkaroundRowMajor(mat4 wrap) { return wrap; }
RSOutput _main(RSInput _input)
{
vec4 pos = vec4(_input.position, 1.0);
pos *= spvWorkaroundRowMajor(_32.localTransform);
vec4 local_pos = pos;
RSOutput _output;
_output.wsposition = pos.xyz;
// this fails with plain "compile fail"
vec3 view_dir = normalize(pos.xyz - _50.viewMatrix[3].xyz);
// wrapping mat4 _50.viewMatrix[3] row in vec4 leads to successfull compile:
// -> vec3 view_dir = normalize(pos.xyz - vec4(_50.viewMatrix[3]).xyz);
pos *= spvWorkaroundRowMajor(_50.viewProjectionMatrix);
_output.position = pos;
_output.normal = normalize((vec4(_input.normal, 0.0) * spvWorkaroundRowMajor(_32.localTransform)).xyz);
_output.view_dir = view_dir;
return _output;
}
void main()
{
RSInput _input;
_input.position = input_position;
_input.normal = input_normal;
RSInput param = _input;
RSOutput flattenTemp = _main(param);
gl_Position = flattenTemp.position;
vs_output_0 = flattenTemp.normal;
vs_output_1 = flattenTemp.view_dir;
vs_output_2 = flattenTemp.wsposition;
gl_Position.z = 2.0 * gl_Position.z - gl_Position.w;
gl_Position.y = -gl_Position.y;
}