spirv: Move OpSelect handling to a function
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 3 Jun 2019 22:30:33 +0000 (15:30 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 4 Jun 2019 00:20:54 +0000 (17:20 -0700)
This will make a later change easier to review.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/spirv/spirv_to_nir.c

index 42fbc68023088b1917117dd868dae7529701f142..8032a7b79c643b8f0e8f92feb31fb728926739ea 100644 (file)
@@ -4084,6 +4084,70 @@ vtn_handle_variable_or_type_instruction(struct vtn_builder *b, SpvOp opcode,
    return true;
 }
 
+static void
+vtn_handle_select(struct vtn_builder *b, SpvOp opcode,
+                  const uint32_t *w, unsigned count)
+{
+   /* Handle OpSelect up-front here because it needs to be able to handle
+    * pointers and not just regular vectors and scalars.
+    */
+   struct vtn_value *res_val = vtn_untyped_value(b, w[2]);
+   struct vtn_value *sel_val = vtn_untyped_value(b, w[3]);
+   struct vtn_value *obj1_val = vtn_untyped_value(b, w[4]);
+   struct vtn_value *obj2_val = vtn_untyped_value(b, w[5]);
+
+   const struct glsl_type *sel_type;
+   switch (res_val->type->base_type) {
+   case vtn_base_type_scalar:
+      sel_type = glsl_bool_type();
+      break;
+   case vtn_base_type_vector:
+      sel_type = glsl_vector_type(GLSL_TYPE_BOOL, res_val->type->length);
+      break;
+   case vtn_base_type_pointer:
+      /* We need to have actual storage for pointer types */
+      vtn_fail_if(res_val->type->type == NULL,
+                  "Invalid pointer result type for OpSelect");
+      sel_type = glsl_bool_type();
+      break;
+   default:
+      vtn_fail("Result type of OpSelect must be a scalar, vector, or pointer");
+   }
+
+   if (unlikely(sel_val->type->type != sel_type)) {
+      if (sel_val->type->type == glsl_bool_type()) {
+         /* This case is illegal but some older versions of GLSLang produce
+          * it.  The GLSLang issue was fixed on March 30, 2017:
+          *
+          * https://github.com/KhronosGroup/glslang/issues/809
+          *
+          * Unfortunately, there are applications in the wild which are
+          * shipping with this bug so it isn't nice to fail on them so we
+          * throw a warning instead.  It's not actually a problem for us as
+          * nir_builder will just splat the condition out which is most
+          * likely what the client wanted anyway.
+          */
+         vtn_warn("Condition type of OpSelect must have the same number "
+                  "of components as Result Type");
+      } else {
+         vtn_fail("Condition type of OpSelect must be a scalar or vector "
+                  "of Boolean type. It must have the same number of "
+                  "components as Result Type");
+      }
+   }
+
+   vtn_fail_if(obj1_val->type != res_val->type ||
+               obj2_val->type != res_val->type,
+               "Object types must match the result type in OpSelect");
+
+   struct vtn_type *res_type = vtn_value(b, w[1], vtn_value_type_type)->type;
+   struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, res_type->type);
+   ssa->def = nir_bcsel(&b->nb, vtn_ssa_value(b, w[3])->def,
+                        vtn_ssa_value(b, w[4])->def,
+                        vtn_ssa_value(b, w[5])->def);
+   vtn_push_ssa(b, w[2], res_type, ssa);
+}
+
 static void
 vtn_handle_ptr(struct vtn_builder *b, SpvOp opcode,
                const uint32_t *w, unsigned count)
@@ -4258,67 +4322,9 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
       break;
    }
 
-   case SpvOpSelect: {
-      /* Handle OpSelect up-front here because it needs to be able to handle
-       * pointers and not just regular vectors and scalars.
-       */
-      struct vtn_value *res_val = vtn_untyped_value(b, w[2]);
-      struct vtn_value *sel_val = vtn_untyped_value(b, w[3]);
-      struct vtn_value *obj1_val = vtn_untyped_value(b, w[4]);
-      struct vtn_value *obj2_val = vtn_untyped_value(b, w[5]);
-
-      const struct glsl_type *sel_type;
-      switch (res_val->type->base_type) {
-      case vtn_base_type_scalar:
-         sel_type = glsl_bool_type();
-         break;
-      case vtn_base_type_vector:
-         sel_type = glsl_vector_type(GLSL_TYPE_BOOL, res_val->type->length);
-         break;
-      case vtn_base_type_pointer:
-         /* We need to have actual storage for pointer types */
-         vtn_fail_if(res_val->type->type == NULL,
-                     "Invalid pointer result type for OpSelect");
-         sel_type = glsl_bool_type();
-         break;
-      default:
-         vtn_fail("Result type of OpSelect must be a scalar, vector, or pointer");
-      }
-
-      if (unlikely(sel_val->type->type != sel_type)) {
-         if (sel_val->type->type == glsl_bool_type()) {
-            /* This case is illegal but some older versions of GLSLang produce
-             * it.  The GLSLang issue was fixed on March 30, 2017:
-             *
-             * https://github.com/KhronosGroup/glslang/issues/809
-             *
-             * Unfortunately, there are applications in the wild which are
-             * shipping with this bug so it isn't nice to fail on them so we
-             * throw a warning instead.  It's not actually a problem for us as
-             * nir_builder will just splat the condition out which is most
-             * likely what the client wanted anyway.
-             */
-            vtn_warn("Condition type of OpSelect must have the same number "
-                     "of components as Result Type");
-         } else {
-            vtn_fail("Condition type of OpSelect must be a scalar or vector "
-                     "of Boolean type. It must have the same number of "
-                     "components as Result Type");
-         }
-      }
-
-      vtn_fail_if(obj1_val->type != res_val->type ||
-                  obj2_val->type != res_val->type,
-                  "Object types must match the result type in OpSelect");
-
-      struct vtn_type *res_type = vtn_value(b, w[1], vtn_value_type_type)->type;
-      struct vtn_ssa_value *ssa = vtn_create_ssa_value(b, res_type->type);
-      ssa->def = nir_bcsel(&b->nb, vtn_ssa_value(b, w[3])->def,
-                                   vtn_ssa_value(b, w[4])->def,
-                                   vtn_ssa_value(b, w[5])->def);
-      vtn_push_ssa(b, w[2], res_type, ssa);
+   case SpvOpSelect:
+      vtn_handle_select(b, opcode, w, count);
       break;
-   }
 
    case SpvOpSNegate:
    case SpvOpFNegate: