diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index dfea8e96b65..18ac691dd70 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -2738,3 +2738,5 @@ intrinsic("wop_pco") system_value("face_ccw_pco", 1, bit_sizes=[32]) system_value("front_face_op_pco", 1, bit_sizes=[32]) + +system_value("fs_meta_pco", 1, bit_sizes=[32]) diff --git a/src/imagination/pco/pco_data.h b/src/imagination/pco/pco_data.h index e0c07ddb1a5..a51a3a53fc4 100644 --- a/src/imagination/pco/pco_data.h +++ b/src/imagination/pco/pco_data.h @@ -83,6 +83,8 @@ typedef struct _pco_fs_data { /** On-chip input attachment formats. */ enum pipe_format ia_formats[4]; + pco_range meta; + gl_frag_result z_replicate; /* Blend options. */ @@ -101,6 +103,9 @@ typedef struct _pco_fs_data { bool early_frag; bool sample_shading; } uses; + + struct { + } meta_present; } pco_fs_data; /** PCO compute shader-specific data. */ diff --git a/src/imagination/pco/pco_trans_nir.c b/src/imagination/pco/pco_trans_nir.c index c2315c1d581..914454c773a 100644 --- a/src/imagination/pco/pco_trans_nir.c +++ b/src/imagination/pco/pco_trans_nir.c @@ -1381,6 +1381,13 @@ static pco_instr *trans_intr(trans_ctx *tctx, nir_intrinsic_instr *intr) instr = trans_load_sysval(tctx, intr, dest); break; + case nir_intrinsic_load_fs_meta_pco: + return pco_mov(&tctx->b, + dest, + pco_ref_hwreg(tctx->shader->data.fs.meta.start, + PCO_REG_CLASS_SHARED)); + break; + case nir_intrinsic_ddx: case nir_intrinsic_ddx_fine: case nir_intrinsic_ddx_coarse: diff --git a/src/imagination/vulkan/pds/pvr_pds.h b/src/imagination/vulkan/pds/pvr_pds.h index 0daf9489320..f92c9b4dbaa 100644 --- a/src/imagination/vulkan/pds/pvr_pds.h +++ b/src/imagination/vulkan/pds/pvr_pds.h @@ -899,6 +899,7 @@ struct pvr_pds_descriptor_set { #define PVR_BUFFER_TYPE_POINT_SAMPLER (7) #define PVR_BUFFER_TYPE_IA_SAMPLER (8) #define PVR_BUFFER_TYPE_FRONT_FACE_OP (9) +#define PVR_BUFFER_TYPE_FS_META (10) #define PVR_BUFFER_TYPE_INVALID (~0) struct pvr_pds_buffer { diff --git a/src/imagination/vulkan/pds/pvr_pipeline_pds.c b/src/imagination/vulkan/pds/pvr_pipeline_pds.c index a57143912c6..758d77b34a4 100644 --- a/src/imagination/vulkan/pds/pvr_pipeline_pds.c +++ b/src/imagination/vulkan/pds/pvr_pipeline_pds.c @@ -1579,7 +1579,8 @@ void pvr_pds_generate_descriptor_upload_program( case PVR_BUFFER_TYPE_BLEND_CONSTS: case PVR_BUFFER_TYPE_POINT_SAMPLER: case PVR_BUFFER_TYPE_IA_SAMPLER: - case PVR_BUFFER_TYPE_FRONT_FACE_OP: { + case PVR_BUFFER_TYPE_FRONT_FACE_OP: + case PVR_BUFFER_TYPE_FS_META: { struct pvr_const_map_entry_special_buffer *special_buffer_entry; special_buffer_entry = diff --git a/src/imagination/vulkan/pvr_cmd_buffer.c b/src/imagination/vulkan/pvr_cmd_buffer.c index 4dd39fdebd5..d16c62c6903 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_cmd_buffer.c @@ -3848,6 +3848,25 @@ static VkResult pvr_setup_descriptor_mappings( break; } + case PVR_BUFFER_TYPE_FS_META: { + uint32_t fs_meta = 0; + + struct pvr_suballoc_bo *fs_meta_bo; + result = pvr_cmd_buffer_upload_general(cmd_buffer, + &fs_meta, + sizeof(fs_meta), + &fs_meta_bo); + + if (result != VK_SUCCESS) + return result; + + PVR_WRITE(qword_buffer, + fs_meta_bo->dev_addr.addr, + special_buff_entry->const_offset, + pds_info->data_size_in_dwords); + break; + } + default: UNREACHABLE("Unsupported special buffer type."); } diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c index d32d9d476d2..d003698b611 100644 --- a/src/imagination/vulkan/pvr_pipeline.c +++ b/src/imagination/vulkan/pvr_pipeline.c @@ -613,6 +613,14 @@ static VkResult pvr_pds_descriptor_program_create_and_upload( }; } + if (stage == MESA_SHADER_FRAGMENT && data->fs.meta.count > 0) { + program.buffers[program.buffer_count++] = (struct pvr_pds_buffer){ + .type = PVR_BUFFER_TYPE_FS_META, + .size_in_dwords = data->fs.meta.count, + .destination = data->fs.meta.start, + }; + } + pds_info->entries_size_in_bytes = const_entries_size_in_bytes; pvr_pds_generate_descriptor_upload_program(&program, NULL, pds_info); @@ -1738,6 +1746,8 @@ static void pvr_alloc_vs_varyings(pco_data *data, nir_shader *nir) static void pvr_alloc_fs_sysvals(pco_data *data, nir_shader *nir) { BITSET_DECLARE(system_values_read, SYSTEM_VALUE_MAX); + bool has_meta = false; + BITSET_COPY(system_values_read, nir->info.system_values_read); gl_system_value sys_vals[] = { @@ -1769,6 +1779,16 @@ static void pvr_alloc_fs_sysvals(pco_data *data, nir_shader *nir) BITSET_CLEAR(system_values_read, builtin_sys_vals[u]); assert(BITSET_IS_EMPTY(system_values_read)); + + if (!has_meta) + return; + + data->fs.meta = (pco_range){ + .start = data->common.shareds, + .count = 1, + }; + + ++data->common.shareds; } static void pvr_alloc_fs_varyings(pco_data *data, nir_shader *nir)