summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-12-13 15:38:58 +0100
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-12-13 15:44:03 +0100
commit03b1f66ef11c53f8b471df18e84b9fb94a13343f (patch)
tree1c21f35e7d495c16cc9006c0fa0a1a21eeb6abf4
parent3c997e12eb06cd36c3befe82dbc5d745a4849443 (diff)
downloadSPIRV-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.vert3
-rw-r--r--reference/opt/shaders/vert/read-from-row-major-array.vert3
-rw-r--r--reference/opt/shaders/vert/row-major-workaround.vert30
-rw-r--r--reference/shaders/legacy/vert/transpose.legacy.vert3
-rw-r--r--reference/shaders/vert/read-from-row-major-array.vert3
-rw-r--r--reference/shaders/vert/row-major-workaround.vert30
-rw-r--r--shaders/vert/row-major-workaround.vert28
-rw-r--r--spirv_glsl.cpp32
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, ")");
}
}