Mesa (main): spirv: handle phis decorated with RelaxedPrecision

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 19 22:37:02 UTC 2022


Module: Mesa
Branch: main
Commit: 6f25d45877a1e1a7ac6250a7d051d33485e0cba7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6f25d45877a1e1a7ac6250a7d051d33485e0cba7

Author: Daniel Schürmann <daniel at schuermann.dev>
Date:   Fri Jun  3 14:00:11 2022 +0200

spirv: handle phis decorated with RelaxedPrecision

If the driver can do 16-bit ALU ops, then store RelaxedPrecision phi
values into 16-bit NIR variables with downconverts/upconverts on the way
in/out.

This has no impact on shader-db on freedreno (not that we have a ton of
GLES content there), but it does cause an ANGLE-translated CTS shader on
vulkan to get consistent conversions between two copies of a value, and
avoid a test bug.

Reviewed-by: Emma Anholt <emma at anholt.net>
Closes: #6585
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14018>

---

 src/compiler/spirv/vtn_cfg.c | 39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c
index e0f88322f6a..9f1853befbe 100644
--- a/src/compiler/spirv/vtn_cfg.c
+++ b/src/compiler/spirv/vtn_cfg.c
@@ -921,13 +921,34 @@ vtn_handle_phis_first_pass(struct vtn_builder *b, SpvOp opcode,
     * algorithm all over again.  It's easier if we just let
     * lower_vars_to_ssa do that for us instead of repeating it here.
     */
-   struct vtn_type *type = vtn_get_type(b, w[1]);
-   nir_variable *phi_var =
-      nir_local_variable_create(b->nb.impl, type->type, "phi");
+   bool relaxed_precision = false;
+   if (b->options->mediump_16bit_alu) {
+      struct vtn_value *phi_val = vtn_untyped_value(b, w[2]);
+      relaxed_precision = vtn_value_is_relaxed_precision(b, phi_val);
+   }
+
+   const struct glsl_type *dest_type = vtn_get_type(b, w[1])->type;
+   const struct glsl_type *type = dest_type;
+   if (relaxed_precision) {
+      if (glsl_get_base_type(type) == GLSL_TYPE_FLOAT)
+         type = glsl_float16_type(type);
+      else if (glsl_get_base_type(type) == GLSL_TYPE_INT)
+         type = glsl_int16_type(type);
+      else if (glsl_get_base_type(type) == GLSL_TYPE_UINT)
+         type = glsl_uint16_type(type);
+   }
+
+   nir_variable *phi_var = nir_local_variable_create(b->nb.impl, type, "phi");
    _mesa_hash_table_insert(b->phi_table, w, phi_var);
 
-   vtn_push_ssa_value(b, w[2],
-      vtn_local_load(b, nir_build_deref_var(&b->nb, phi_var), 0));
+   struct vtn_ssa_value *dest =
+      vtn_local_load(b, nir_build_deref_var(&b->nb, phi_var), 0);
+
+   if (relaxed_precision) {
+      dest->type = dest_type;
+      vtn_mediump_upconvert_value(b, dest);
+   }
+   vtn_push_ssa_value(b, w[2], dest);
 
    return true;
 }
@@ -948,6 +969,12 @@ vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
    if (phi_entry == NULL)
       return true;
 
+   bool relaxed_precision = false;
+   if (b->options->mediump_16bit_alu) {
+      struct vtn_value *phi_val = vtn_untyped_value(b, w[2]);
+      relaxed_precision = vtn_value_is_relaxed_precision(b, phi_val);
+   }
+
    nir_variable *phi_var = phi_entry->data;
 
    for (unsigned i = 3; i < count; i += 2) {
@@ -961,6 +988,8 @@ vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
       b->nb.cursor = nir_after_instr(&pred->end_nop->instr);
 
       struct vtn_ssa_value *src = vtn_ssa_value(b, w[i]);
+      if (relaxed_precision)
+         src = vtn_mediump_downconvert_value(b, src);
 
       vtn_local_store(b, src, nir_build_deref_var(&b->nb, phi_var), 0);
    }



More information about the mesa-commit mailing list