From c749da61356d98b6a9c20ca3fd81cebf18b01979 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Tue, 16 Nov 2021 16:27:26 +0200 Subject: [PATCH] ir3,turnip: Add support for GL_KHR_shader_subgroup_quad Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/ir3/ir3.h | 4 ++++ src/freedreno/ir3/ir3_compiler_nir.c | 35 ++++++++++++++++++++++++++++ src/freedreno/vulkan/tu_device.c | 1 + src/freedreno/vulkan/tu_shader.c | 1 + 4 files changed, 41 insertions(+) diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 042715b319c..3fec81d85b7 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -2196,6 +2196,10 @@ INSTR2(ATOMIC_AND) INSTR2(ATOMIC_OR) INSTR2(ATOMIC_XOR) INSTR2(LDC) +INSTR2(QUAD_SHUFFLE_BRCST) +INSTR1(QUAD_SHUFFLE_HORIZ) +INSTR1(QUAD_SHUFFLE_VERT) +INSTR1(QUAD_SHUFFLE_DIAG) #if GPU >= 600 INSTR3NODST(STIB); INSTR2(LDIB); diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index b6ba7b90d5d..b0572e67c9b 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -2247,6 +2247,41 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr) break; } + case nir_intrinsic_quad_broadcast: { + struct ir3_instruction *src = ir3_get_src(ctx, &intr->src[0])[0]; + struct ir3_instruction *idx = ir3_get_src(ctx, &intr->src[1])[0]; + + type_t dst_type = type_uint_size(nir_dest_bit_size(intr->dest)); + + if (dst_type != TYPE_U32) + idx = ir3_COV(ctx->block, idx, TYPE_U32, dst_type); + + dst[0] = ir3_QUAD_SHUFFLE_BRCST(ctx->block, src, 0, idx, 0); + dst[0]->cat5.type = dst_type; + break; + } + + case nir_intrinsic_quad_swap_horizontal: { + struct ir3_instruction *src = ir3_get_src(ctx, &intr->src[0])[0]; + dst[0] = ir3_QUAD_SHUFFLE_HORIZ(ctx->block, src, 0); + dst[0]->cat5.type = type_uint_size(nir_dest_bit_size(intr->dest)); + break; + } + + case nir_intrinsic_quad_swap_vertical: { + struct ir3_instruction *src = ir3_get_src(ctx, &intr->src[0])[0]; + dst[0] = ir3_QUAD_SHUFFLE_VERT(ctx->block, src, 0); + dst[0]->cat5.type = type_uint_size(nir_dest_bit_size(intr->dest)); + break; + } + + case nir_intrinsic_quad_swap_diagonal: { + struct ir3_instruction *src = ir3_get_src(ctx, &intr->src[0])[0]; + dst[0] = ir3_QUAD_SHUFFLE_DIAG(ctx->block, src, 0); + dst[0]->cat5.type = type_uint_size(nir_dest_bit_size(intr->dest)); + break; + } + case nir_intrinsic_load_shared_ir3: emit_intrinsic_load_shared_ir3(ctx, intr, dst); break; diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index a894dc68ff2..90a8a0cef98 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -809,6 +809,7 @@ tu_get_physical_device_properties_1_1(struct tu_physical_device *pdevice, VK_SUBGROUP_FEATURE_BALLOT_BIT; if (pdevice->info->a6xx.has_getfiberid) { p->subgroupSupportedStages |= VK_SHADER_STAGE_ALL_GRAPHICS; + p->subgroupSupportedOperations |= VK_SUBGROUP_FEATURE_QUAD_BIT; } p->subgroupQuadOperationsInAllStages = false; diff --git a/src/freedreno/vulkan/tu_shader.c b/src/freedreno/vulkan/tu_shader.c index ea5838a518f..a6c23304841 100644 --- a/src/freedreno/vulkan/tu_shader.c +++ b/src/freedreno/vulkan/tu_shader.c @@ -81,6 +81,7 @@ tu_spirv_to_nir(struct tu_device *dev, .subgroup_basic = true, .subgroup_ballot = true, .subgroup_vote = true, + .subgroup_quad = true, .physical_storage_buffer_address = true, }, };