diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-12-13 15:38:58 +0100 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-12-13 15:44:03 +0100 |
commit | 03b1f66ef11c53f8b471df18e84b9fb94a13343f (patch) | |
tree | 1c21f35e7d495c16cc9006c0fa0a1a21eeb6abf4 | |
parent | 3c997e12eb06cd36c3befe82dbc5d745a4849443 (diff) | |
download | SPIRV-Cross-03b1f66ef11c53f8b471df18e84b9fb94a13343f.tar.gz SPIRV-Cross-03b1f66ef11c53f8b471df18e84b9fb94a13343f.tar.bz2 SPIRV-Cross-03b1f66ef11c53f8b471df18e84b9fb94a13343f.zip |
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.
-rw-r--r-- | reference/opt/shaders/legacy/vert/transpose.legacy.vert | 3 | ||||
-rw-r--r-- | reference/opt/shaders/vert/read-from-row-major-array.vert | 3 | ||||
-rw-r--r-- | reference/opt/shaders/vert/row-major-workaround.vert | 30 | ||||
-rw-r--r-- | reference/shaders/legacy/vert/transpose.legacy.vert | 3 | ||||
-rw-r--r-- | reference/shaders/vert/read-from-row-major-array.vert | 3 | ||||
-rw-r--r-- | reference/shaders/vert/row-major-workaround.vert | 30 | ||||
-rw-r--r-- | shaders/vert/row-major-workaround.vert | 28 | ||||
-rw-r--r-- | spirv_glsl.cpp | 32 |
8 files changed, 121 insertions, 11 deletions
diff --git a/reference/opt/shaders/legacy/vert/transpose.legacy.vert b/reference/opt/shaders/legacy/vert/transpose.legacy.vert index 9c7f465a..d725bfbb 100644 --- a/reference/opt/shaders/legacy/vert/transpose.legacy.vert +++ b/reference/opt/shaders/legacy/vert/transpose.legacy.vert @@ -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) { diff --git a/reference/opt/shaders/vert/read-from-row-major-array.vert b/reference/opt/shaders/vert/read-from-row-major-array.vert index c491b547..d5d9681d 100644 --- a/reference/opt/shaders/vert/read-from-row-major-array.vert +++ b/reference/opt/shaders/vert/read-from-row-major-array.vert @@ -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() { diff --git a/reference/opt/shaders/vert/row-major-workaround.vert b/reference/opt/shaders/vert/row-major-workaround.vert new file mode 100644 index 00000000..4fe6885d --- /dev/null +++ b/reference/opt/shaders/vert/row-major-workaround.vert @@ -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; +} + diff --git a/reference/shaders/legacy/vert/transpose.legacy.vert b/reference/shaders/legacy/vert/transpose.legacy.vert index 8d6ee7c1..ce5cf8b1 100644 --- a/reference/shaders/legacy/vert/transpose.legacy.vert +++ b/reference/shaders/legacy/vert/transpose.legacy.vert @@ -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) { diff --git a/reference/shaders/vert/read-from-row-major-array.vert b/reference/shaders/vert/read-from-row-major-array.vert index b7e66c54..8b5ec967 100644 --- a/reference/shaders/vert/read-from-row-major-array.vert +++ b/reference/shaders/vert/read-from-row-major-array.vert @@ -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) { diff --git a/reference/shaders/vert/row-major-workaround.vert b/reference/shaders/vert/row-major-workaround.vert new file mode 100644 index 00000000..4fe6885d --- /dev/null +++ b/reference/shaders/vert/row-major-workaround.vert @@ -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; +} + diff --git a/shaders/vert/row-major-workaround.vert b/shaders/vert/row-major-workaround.vert new file mode 100644 index 00000000..edb8a842 --- /dev/null +++ b/shaders/vert/row-major-workaround.vert @@ -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; +} + diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 07956247..2f9276e1 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -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, ")"); } } |