diff options
-rw-r--r-- | src/compiler/nir/nir.c | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_intrinsics.py | 1 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_system_values.c | 49 | ||||
-rw-r--r-- | src/compiler/shader_enums.h | 1 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_variables.c | 4 |
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). |