summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/nir/nir.c2
-rw-r--r--src/compiler/nir/nir_intrinsics.py1
-rw-r--r--src/compiler/nir/nir_lower_system_values.c49
-rw-r--r--src/compiler/shader_enums.h1
-rw-r--r--src/compiler/spirv/vtn_variables.c4
5 files changed, 45 insertions, 12 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index d759dfdce21..4a7c757db3a 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -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:
diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py
index d53b26c88d6..1ae453f757d 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -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.
#
diff --git a/src/compiler/nir/nir_lower_system_values.c b/src/compiler/nir/nir_lower_system_values.c
index de5ccab0f38..4436799fa52 100644
--- a/src/compiler/nir/nir_lower_system_values.c
+++ b/src/compiler/nir/nir_lower_system_values.c
@@ -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;
}
diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h
index 1dff01484b5..fe26d03a920 100644
--- a/src/compiler/shader_enums.h
+++ b/src/compiler/shader_enums.h
@@ -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,
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index 69dd72941ba..b155681ca1f 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -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).