mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-09 13:50:05 +00:00
GLSL: Fix row-major workaround wrapper for ES.
By default, the matrix would be declared as mediump, causing precision issues. Need to dispatch to two separate functions since GLSL does not support overload based on precision.
This commit is contained in:
parent
3c997e12eb
commit
03b1f66ef1
@ -11,7 +11,8 @@ uniform Buffer _13;
|
||||
|
||||
attribute vec4 Position;
|
||||
|
||||
mat4 spvWorkaroundRowMajor(mat4 wrap) { return wrap; }
|
||||
highp mat4 spvWorkaroundRowMajor(highp mat4 wrap) { return wrap; }
|
||||
mediump mat4 spvWorkaroundRowMajorMP(mediump mat4 wrap) { return wrap; }
|
||||
|
||||
mat4 spvTranspose(mat4 m)
|
||||
{
|
||||
|
@ -8,7 +8,8 @@ layout(binding = 0, std140) uniform Block
|
||||
layout(location = 0) in vec4 a_position;
|
||||
layout(location = 0) out mediump float v_vtxResult;
|
||||
|
||||
mat2x3 spvWorkaroundRowMajor(mat2x3 wrap) { return wrap; }
|
||||
highp mat2x3 spvWorkaroundRowMajor(highp mat2x3 wrap) { return wrap; }
|
||||
mediump mat2x3 spvWorkaroundRowMajorMP(mediump mat2x3 wrap) { return wrap; }
|
||||
|
||||
void main()
|
||||
{
|
||||
|
30
reference/opt/shaders/vert/row-major-workaround.vert
Normal file
30
reference/opt/shaders/vert/row-major-workaround.vert
Normal file
@ -0,0 +1,30 @@
|
||||
#version 310 es
|
||||
|
||||
layout(binding = 0, std140) uniform Buffer
|
||||
{
|
||||
layout(row_major) mat4 HP;
|
||||
layout(row_major) mediump mat4 MP;
|
||||
} _21;
|
||||
|
||||
layout(binding = 1, std140) uniform Buffer2
|
||||
{
|
||||
layout(row_major) mediump mat4 MP2;
|
||||
} _39;
|
||||
|
||||
layout(location = 0) out vec4 H;
|
||||
layout(location = 0) in vec4 Hin;
|
||||
layout(location = 1) out mediump vec4 M;
|
||||
layout(location = 1) in mediump vec4 Min;
|
||||
layout(location = 2) out mediump vec4 M2;
|
||||
|
||||
highp mat4 spvWorkaroundRowMajor(highp mat4 wrap) { return wrap; }
|
||||
mediump mat4 spvWorkaroundRowMajorMP(mediump mat4 wrap) { return wrap; }
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(1.0);
|
||||
H = spvWorkaroundRowMajor(_21.HP) * Hin;
|
||||
M = spvWorkaroundRowMajor(_21.MP) * Min;
|
||||
M2 = spvWorkaroundRowMajorMP(_39.MP2) * Min;
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ uniform Buffer _13;
|
||||
|
||||
attribute vec4 Position;
|
||||
|
||||
mat4 spvWorkaroundRowMajor(mat4 wrap) { return wrap; }
|
||||
highp mat4 spvWorkaroundRowMajor(highp mat4 wrap) { return wrap; }
|
||||
mediump mat4 spvWorkaroundRowMajorMP(mediump mat4 wrap) { return wrap; }
|
||||
|
||||
mat4 spvTranspose(mat4 m)
|
||||
{
|
||||
|
@ -8,7 +8,8 @@ layout(binding = 0, std140) uniform Block
|
||||
layout(location = 0) in vec4 a_position;
|
||||
layout(location = 0) out mediump float v_vtxResult;
|
||||
|
||||
mat2x3 spvWorkaroundRowMajor(mat2x3 wrap) { return wrap; }
|
||||
highp mat2x3 spvWorkaroundRowMajor(highp mat2x3 wrap) { return wrap; }
|
||||
mediump mat2x3 spvWorkaroundRowMajorMP(mediump mat2x3 wrap) { return wrap; }
|
||||
|
||||
mediump float compare_float(float a, float b)
|
||||
{
|
||||
|
30
reference/shaders/vert/row-major-workaround.vert
Normal file
30
reference/shaders/vert/row-major-workaround.vert
Normal file
@ -0,0 +1,30 @@
|
||||
#version 310 es
|
||||
|
||||
layout(binding = 0, std140) uniform Buffer
|
||||
{
|
||||
layout(row_major) mat4 HP;
|
||||
layout(row_major) mediump mat4 MP;
|
||||
} _21;
|
||||
|
||||
layout(binding = 1, std140) uniform Buffer2
|
||||
{
|
||||
layout(row_major) mediump mat4 MP2;
|
||||
} _39;
|
||||
|
||||
layout(location = 0) out vec4 H;
|
||||
layout(location = 0) in vec4 Hin;
|
||||
layout(location = 1) out mediump vec4 M;
|
||||
layout(location = 1) in mediump vec4 Min;
|
||||
layout(location = 2) out mediump vec4 M2;
|
||||
|
||||
highp mat4 spvWorkaroundRowMajor(highp mat4 wrap) { return wrap; }
|
||||
mediump mat4 spvWorkaroundRowMajorMP(mediump mat4 wrap) { return wrap; }
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(1.0);
|
||||
H = spvWorkaroundRowMajor(_21.HP) * Hin;
|
||||
M = spvWorkaroundRowMajor(_21.MP) * Min;
|
||||
M2 = spvWorkaroundRowMajorMP(_39.MP2) * Min;
|
||||
}
|
||||
|
28
shaders/vert/row-major-workaround.vert
Normal file
28
shaders/vert/row-major-workaround.vert
Normal file
@ -0,0 +1,28 @@
|
||||
#version 310 es
|
||||
|
||||
layout(binding = 0) uniform Buffer
|
||||
{
|
||||
layout(row_major) highp mat4 HP;
|
||||
layout(row_major) mediump mat4 MP;
|
||||
};
|
||||
|
||||
layout(binding = 1) uniform Buffer2
|
||||
{
|
||||
layout(row_major) mediump mat4 MP2;
|
||||
};
|
||||
|
||||
|
||||
layout(location = 0) in vec4 Hin;
|
||||
layout(location = 1) in mediump vec4 Min;
|
||||
layout(location = 0) out vec4 H;
|
||||
layout(location = 1) out mediump vec4 M;
|
||||
layout(location = 2) out mediump vec4 M2;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(1.0);
|
||||
H = HP * Hin;
|
||||
M = MP * Min;
|
||||
M2 = MP2 * Min;
|
||||
}
|
||||
|
@ -4362,8 +4362,18 @@ void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
|
||||
for (auto &type_id : workaround_ubo_load_overload_types)
|
||||
{
|
||||
auto &type = get<SPIRType>(type_id);
|
||||
statement(type_to_glsl(type), " spvWorkaroundRowMajor(", type_to_glsl(type),
|
||||
" wrap) { return wrap; }");
|
||||
|
||||
if (options.es && is_matrix(type))
|
||||
{
|
||||
// Need both variants.
|
||||
// GLSL cannot overload on precision, so need to dispatch appropriately.
|
||||
statement("highp ", type_to_glsl(type), " spvWorkaroundRowMajor(highp ", type_to_glsl(type), " wrap) { return wrap; }");
|
||||
statement("mediump ", type_to_glsl(type), " spvWorkaroundRowMajorMP(mediump ", type_to_glsl(type), " wrap) { return wrap; }");
|
||||
}
|
||||
else
|
||||
{
|
||||
statement(type_to_glsl(type), " spvWorkaroundRowMajor(", type_to_glsl(type), " wrap) { return wrap; }");
|
||||
}
|
||||
}
|
||||
statement("");
|
||||
}
|
||||
@ -17335,6 +17345,7 @@ void CompilerGLSL::rewrite_load_for_wrapped_row_major(std::string &expr, TypeID
|
||||
|
||||
auto *type = &get<SPIRType>(loaded_type);
|
||||
bool rewrite = false;
|
||||
bool relaxed = options.es;
|
||||
|
||||
if (is_matrix(*type))
|
||||
{
|
||||
@ -17345,24 +17356,31 @@ void CompilerGLSL::rewrite_load_for_wrapped_row_major(std::string &expr, TypeID
|
||||
// If an access chain occurred, the workaround is not required, so loading vectors or scalars don't need workaround.
|
||||
type = &backing_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're loading a composite, we don't have overloads like these.
|
||||
relaxed = false;
|
||||
}
|
||||
|
||||
if (type->basetype == SPIRType::Struct)
|
||||
{
|
||||
// If we're loading a struct where any member is a row-major matrix, apply the workaround.
|
||||
for (uint32_t i = 0; i < uint32_t(type->member_types.size()); i++)
|
||||
{
|
||||
if (combined_decoration_for_member(*type, i).get(DecorationRowMajor))
|
||||
{
|
||||
auto decorations = combined_decoration_for_member(*type, i);
|
||||
if (decorations.get(DecorationRowMajor))
|
||||
rewrite = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Since we decide on a per-struct basis, only use mediump wrapper if all candidates are mediump.
|
||||
if (!decorations.get(DecorationRelaxedPrecision))
|
||||
relaxed = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (rewrite)
|
||||
{
|
||||
request_workaround_wrapper_overload(loaded_type);
|
||||
expr = join("spvWorkaroundRowMajor(", expr, ")");
|
||||
expr = join("spvWorkaroundRowMajor", (relaxed ? "MP" : ""), "(", expr, ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user