nir/vtn: add support for SpvBuiltInGlobalLinearId

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>
This commit is contained in:
Karol Herbst
2019-01-14 18:36:37 +01:00
parent f48c672965
commit d0b47ec4df
5 changed files with 45 additions and 12 deletions

View File

@@ -1860,6 +1860,8 @@ nir_intrinsic_from_system_value(gl_system_value val)
return nir_intrinsic_load_local_group_size; return nir_intrinsic_load_local_group_size;
case SYSTEM_VALUE_GLOBAL_INVOCATION_ID: case SYSTEM_VALUE_GLOBAL_INVOCATION_ID:
return nir_intrinsic_load_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: case SYSTEM_VALUE_WORK_DIM:
return nir_intrinsic_load_work_dim; return nir_intrinsic_load_work_dim;
default: default:

View File

@@ -533,6 +533,7 @@ system_value("num_subgroups", 1)
system_value("subgroup_id", 1) system_value("subgroup_id", 1)
system_value("local_group_size", 3) system_value("local_group_size", 3)
system_value("global_invocation_id", 3, bit_sizes=[32, 64]) 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) system_value("work_dim", 1)
# Driver-specific viewport scale/offset parameters. # Driver-specific viewport scale/offset parameters.
# #

View 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 static bool
convert_block(nir_block *block, nir_builder *b) 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; nir_ssa_def *sysval = NULL;
switch (var->data.location) { switch (var->data.location) {
case SYSTEM_VALUE_GLOBAL_INVOCATION_ID: { case SYSTEM_VALUE_GLOBAL_INVOCATION_ID: {
/* From the GLSL man page for gl_GlobalInvocationID: sysval = build_global_invocation_id(b, bit_size);
* break;
* "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 = nir_iadd(b, nir_imul(b, group_id, group_size), local_id); 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);
/* 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; break;
} }
@@ -259,9 +286,7 @@ convert_block(nir_block *block, nir_builder *b)
break; break;
case SYSTEM_VALUE_GLOBAL_GROUP_SIZE: { case SYSTEM_VALUE_GLOBAL_GROUP_SIZE: {
nir_ssa_def *group_size = build_local_group_size(b, bit_size); sysval = build_global_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);
break; break;
} }

View File

@@ -600,6 +600,7 @@ typedef enum
SYSTEM_VALUE_LOCAL_INVOCATION_ID, SYSTEM_VALUE_LOCAL_INVOCATION_ID,
SYSTEM_VALUE_LOCAL_INVOCATION_INDEX, SYSTEM_VALUE_LOCAL_INVOCATION_INDEX,
SYSTEM_VALUE_GLOBAL_INVOCATION_ID, SYSTEM_VALUE_GLOBAL_INVOCATION_ID,
SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX,
SYSTEM_VALUE_WORK_GROUP_ID, SYSTEM_VALUE_WORK_GROUP_ID,
SYSTEM_VALUE_NUM_WORK_GROUPS, SYSTEM_VALUE_NUM_WORK_GROUPS,
SYSTEM_VALUE_LOCAL_GROUP_SIZE, SYSTEM_VALUE_LOCAL_GROUP_SIZE,

View File

@@ -1337,6 +1337,10 @@ vtn_get_builtin_location(struct vtn_builder *b,
*location = SYSTEM_VALUE_GLOBAL_INVOCATION_ID; *location = SYSTEM_VALUE_GLOBAL_INVOCATION_ID;
set_mode_system_value(b, mode); set_mode_system_value(b, mode);
break; break;
case SpvBuiltInGlobalLinearId:
*location = SYSTEM_VALUE_GLOBAL_INVOCATION_INDEX;
set_mode_system_value(b, mode);
break;
case SpvBuiltInBaseVertex: case SpvBuiltInBaseVertex:
/* OpenGL gl_BaseVertex (SYSTEM_VALUE_BASE_VERTEX) is not the same /* OpenGL gl_BaseVertex (SYSTEM_VALUE_BASE_VERTEX) is not the same
* semantic as SPIR-V BaseVertex (SYSTEM_VALUE_FIRST_VERTEX). * semantic as SPIR-V BaseVertex (SYSTEM_VALUE_FIRST_VERTEX).