nir/vtn: add support for SpvBuiltInGlobalLinearId
authorKarol Herbst <kherbst@redhat.com>
Mon, 14 Jan 2019 17:36:37 +0000 (18:36 +0100)
committerKarol Herbst <kherbst@redhat.com>
Tue, 5 Mar 2019 21:28:29 +0000 (22:28 +0100)
v2: use formula with fewer operations

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/compiler/nir/nir.c
src/compiler/nir/nir_intrinsics.py
src/compiler/nir/nir_lower_system_values.c
src/compiler/shader_enums.h
src/compiler/spirv/vtn_variables.c

index d759dfdce2101df9fe54b38606b453204f29e539..4a7c757db3a4f8190097087f625ea7ac6334d155 100644 (file)
@@ -1860,6 +1860,8 @@ nir_intrinsic_from_system_value(gl_system_value val)
       return nir_intrinsic_load_local_group_size;
    case SYSTEM_VALUE_GLOBAL_INVOCATION_ID:
       return nir_intrinsic_load_global_invocation_id;
+   case SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX:
+      return nir_intrinsic_load_global_invocation_index;
    case SYSTEM_VALUE_WORK_DIM:
       return nir_intrinsic_load_work_dim;
    default:
index d53b26c88d605b44c28abcd0344a36c96479f268..1ae453f757d8d15003736978ce68085a344ef271 100644 (file)
@@ -533,6 +533,7 @@ system_value("num_subgroups", 1)
 system_value("subgroup_id", 1)
 system_value("local_group_size", 3)
 system_value("global_invocation_id", 3, bit_sizes=[32, 64])
+system_value("global_invocation_index", 1, bit_sizes=[32, 64])
 system_value("work_dim", 1)
 # Driver-specific viewport scale/offset parameters.
 #
index de5ccab0f38823aaff3c0fa1730a3bdf4c93076a..4436799fa527893c5b963b59b4c226517ef73b24 100644 (file)
@@ -99,6 +99,29 @@ build_local_invocation_id(nir_builder *b, unsigned bit_size)
    }
 }
 
+static nir_ssa_def*
+build_global_group_size(nir_builder *b, unsigned bit_size)
+{
+   nir_ssa_def *group_size = build_local_group_size(b, bit_size);
+   nir_ssa_def *num_work_groups = nir_u2u(b, nir_load_num_work_groups(b), bit_size);
+   return nir_imul(b, group_size, num_work_groups);
+}
+
+static nir_ssa_def*
+build_global_invocation_id(nir_builder *b, unsigned bit_size)
+{
+   /* From the GLSL man page for gl_GlobalInvocationID:
+    *
+    *    "The value of gl_GlobalInvocationID is equal to
+    *    gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID"
+    */
+   nir_ssa_def *group_size = build_local_group_size(b, bit_size);
+   nir_ssa_def *group_id = nir_u2u(b, nir_load_work_group_id(b), bit_size);
+   nir_ssa_def *local_id = build_local_invocation_id(b, bit_size);
+
+   return nir_iadd(b, nir_imul(b, group_id, group_size), local_id);
+}
+
 static bool
 convert_block(nir_block *block, nir_builder *b)
 {
@@ -133,16 +156,20 @@ convert_block(nir_block *block, nir_builder *b)
       nir_ssa_def *sysval = NULL;
       switch (var->data.location) {
       case SYSTEM_VALUE_GLOBAL_INVOCATION_ID: {
-         /* From the GLSL man page for gl_GlobalInvocationID:
-          *
-          *    "The value of gl_GlobalInvocationID is equal to
-          *    gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID"
-          */
-         nir_ssa_def *group_size = build_local_group_size(b, bit_size);
-         nir_ssa_def *group_id = nir_u2u(b, nir_load_work_group_id(b), bit_size);
-         nir_ssa_def *local_id = build_local_invocation_id(b, bit_size);
+         sysval = build_global_invocation_id(b, bit_size);
+         break;
+      }
+
+      case SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX: {
+         nir_ssa_def *global_id = build_global_invocation_id(b, bit_size);
+         nir_ssa_def *global_size = build_global_group_size(b, bit_size);
 
-         sysval = nir_iadd(b, nir_imul(b, group_id, group_size), local_id);
+         /* index = id.x + ((id.y + (id.z * size.y)) * size.x) */
+         sysval = nir_imul(b, nir_channel(b, global_id, 2),
+                              nir_channel(b, global_size, 1));
+         sysval = nir_iadd(b, nir_channel(b, global_id, 1), sysval);
+         sysval = nir_imul(b, nir_channel(b, global_size, 0), sysval);
+         sysval = nir_iadd(b, nir_channel(b, global_id, 0), sysval);
          break;
       }
 
@@ -259,9 +286,7 @@ convert_block(nir_block *block, nir_builder *b)
          break;
 
       case SYSTEM_VALUE_GLOBAL_GROUP_SIZE: {
-         nir_ssa_def *group_size = build_local_group_size(b, bit_size);
-         nir_ssa_def *num_work_groups = nir_u2u(b, nir_load_num_work_groups(b), bit_size);
-         sysval = nir_imul(b, group_size, num_work_groups);
+         sysval = build_global_group_size(b, bit_size);
          break;
       }
 
index 1dff01484b5b0f1730d133b05fd44961a6ab8a4b..fe26d03a920ab30241aef2cea3c7eceb9dd5f3cd 100644 (file)
@@ -600,6 +600,7 @@ typedef enum
    SYSTEM_VALUE_LOCAL_INVOCATION_ID,
    SYSTEM_VALUE_LOCAL_INVOCATION_INDEX,
    SYSTEM_VALUE_GLOBAL_INVOCATION_ID,
+   SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX,
    SYSTEM_VALUE_WORK_GROUP_ID,
    SYSTEM_VALUE_NUM_WORK_GROUPS,
    SYSTEM_VALUE_LOCAL_GROUP_SIZE,
index 69dd72941baed28de9d51ccfdb8cd60195093b5d..b155681ca1fa8f88835580cb08a9f60702491e75 100644 (file)
@@ -1337,6 +1337,10 @@ vtn_get_builtin_location(struct vtn_builder *b,
       *location = SYSTEM_VALUE_GLOBAL_INVOCATION_ID;
       set_mode_system_value(b, mode);
       break;
+   case SpvBuiltInGlobalLinearId:
+      *location = SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX;
+      set_mode_system_value(b, mode);
+      break;
    case SpvBuiltInBaseVertex:
       /* OpenGL gl_BaseVertex (SYSTEM_VALUE_BASE_VERTEX) is not the same
        * semantic as SPIR-V BaseVertex (SYSTEM_VALUE_FIRST_VERTEX).