From 8afde5ec199989a65c1785852942466ab1fbbb4b Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Sun, 2 Feb 2025 17:23:21 +0000 Subject: [PATCH] pvr, pco: add input attachment sampler and initial support Signed-off-by: Simon Perretta Acked-by: Erik Faye-Lund Part-of: --- src/imagination/pco/pco_data.h | 9 +++ src/imagination/pco/pco_internal.h | 4 +- src/imagination/pco/pco_nir.c | 7 ++- src/imagination/pco/pco_nir_pvfio.c | 11 +++- src/imagination/pco/pco_nir_tex.c | 43 ++++++++++--- src/imagination/pco/pco_nir_vk.c | 50 +++++++++++---- src/imagination/pco/pco_trans_nir.c | 36 ++++++++--- src/imagination/vulkan/pds/pvr_pds.h | 1 + src/imagination/vulkan/pds/pvr_pipeline_pds.c | 3 +- src/imagination/vulkan/pvr_cmd_buffer.c | 36 +++++++++++ src/imagination/vulkan/pvr_descriptor_set.c | 27 ++++++++ src/imagination/vulkan/pvr_pipeline.c | 61 ++++++++++++++++--- 12 files changed, 243 insertions(+), 45 deletions(-) diff --git a/src/imagination/pco/pco_data.h b/src/imagination/pco/pco_data.h index ac304d6f94d..cb77e3d7407 100644 --- a/src/imagination/pco/pco_data.h +++ b/src/imagination/pco/pco_data.h @@ -21,6 +21,7 @@ #include #define PCO_POINT_SAMPLER 0xffff +#define PCO_IA_SAMPLER 0xfffe /* Compiler-specific forward-declarations. */ typedef struct _pco_shader pco_shader; @@ -67,6 +68,12 @@ typedef struct _pco_fs_data { /** Fragment output formats. */ enum pipe_format output_formats[FRAG_RESULT_MAX]; + /** On-chip input attachment mappings. */ + pco_range ias_onchip[4]; + + /** On-chip input attachment formats. */ + enum pipe_format ia_formats[4]; + /* Blend options. */ nir_lower_blend_options blend_opts; pco_range blend_consts; @@ -149,6 +156,7 @@ typedef struct _pco_common_data { pco_push_const_data push_consts; pco_range point_sampler; + pco_range ia_sampler; unsigned temps; /** Number of allocated temp registers. */ unsigned vtxins; /** Number of allocated vertex input registers. */ @@ -165,6 +173,7 @@ typedef struct _pco_common_data { bool side_effects; /** Whether the shader has side effects. */ bool empty; /** Whether the shader is empty. */ bool point_sampler; /** Whether the shader uses a point sampler. */ + bool ia_sampler; /** Does the shader use an input attachment sampler? */ } uses; } pco_common_data; diff --git a/src/imagination/pco/pco_internal.h b/src/imagination/pco/pco_internal.h index 485f80ff49b..59514fe27cc 100644 --- a/src/imagination/pco/pco_internal.h +++ b/src/imagination/pco/pco_internal.h @@ -1649,10 +1649,10 @@ bool pco_nir_lower_algebraic(nir_shader *shader); bool pco_nir_lower_algebraic_late(nir_shader *shader); bool pco_nir_lower_atomics(nir_shader *shader, bool *uses_usclib); bool pco_nir_lower_barriers(nir_shader *shader, bool *uses_usclib); -bool pco_nir_lower_images(nir_shader *shader); +bool pco_nir_lower_images(nir_shader *shader, pco_data *data); bool pco_nir_lower_io(nir_shader *shader); bool pco_nir_lower_tex(nir_shader *shader); -bool pco_nir_lower_vk(nir_shader *shader, pco_common_data *common); +bool pco_nir_lower_vk(nir_shader *shader, pco_data *data); bool pco_nir_pfo(nir_shader *shader, pco_fs_data *fs); bool pco_nir_point_size(nir_shader *shader); bool pco_nir_pvi(nir_shader *shader, pco_vs_data *vs); diff --git a/src/imagination/pco/pco_nir.c b/src/imagination/pco/pco_nir.c index 38493ca9e31..79cb45ea29a 100644 --- a/src/imagination/pco/pco_nir.c +++ b/src/imagination/pco/pco_nir.c @@ -512,6 +512,9 @@ void pco_preprocess_nir(pco_ctx *ctx, nir_shader *nir) NIR_PASS(_, nir, nir_lower_flrp, 32, true); NIR_PASS(_, nir, nir_remove_dead_derefs); + NIR_PASS(_, nir, nir_opt_undef); + NIR_PASS(_, nir, nir_lower_undef_to_zero); + NIR_PASS(_, nir, nir_opt_cse); NIR_PASS(_, nir, nir_opt_dce); NIR_PASS(_, nir, @@ -685,7 +688,7 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data) nir_address_format_32bit_offset); NIR_PASS(_, nir, nir_lower_io_to_scalar, nir_var_mem_shared, NULL, NULL); - NIR_PASS(_, nir, pco_nir_lower_vk, &data->common); + NIR_PASS(_, nir, pco_nir_lower_vk, data); NIR_PASS(_, nir, pco_nir_lower_io); NIR_PASS(_, nir, pco_nir_lower_atomics, &uses_usclib); @@ -711,7 +714,7 @@ void pco_lower_nir(pco_ctx *ctx, nir_shader *nir, pco_data *data) nir_io_add_const_offset_to_base, nir_var_shader_in | nir_var_shader_out); - NIR_PASS(_, nir, pco_nir_lower_images); + NIR_PASS(_, nir, pco_nir_lower_images, data); NIR_PASS(_, nir, nir_lower_tex, &(nir_lower_tex_options){}); NIR_PASS(_, nir, pco_nir_lower_tex); diff --git a/src/imagination/pco/pco_nir_pvfio.c b/src/imagination/pco/pco_nir_pvfio.c index 96460a3a48b..b02242eb58d 100644 --- a/src/imagination/pco/pco_nir_pvfio.c +++ b/src/imagination/pco/pco_nir_pvfio.c @@ -819,7 +819,16 @@ static nir_def *lower_pfo_load(nir_builder *b, struct nir_io_semantics io_semantics = nir_intrinsic_io_semantics(intr); gl_frag_result location = io_semantics.location; - enum pipe_format format = state->fs->output_formats[location]; + enum pipe_format format; + /* Special case for input attachments. */ + if (location == FRAG_RESULT_COLOR) { + format = state->fs->ia_formats[base]; + } else { + assert(location >= FRAG_RESULT_DATA0); + assert(!base); + format = state->fs->output_formats[location]; + } + if (format == PIPE_FORMAT_NONE) return nir_undef(b, intr->def.num_components, intr->def.bit_size); diff --git a/src/imagination/pco/pco_nir_tex.c b/src/imagination/pco/pco_nir_tex.c index 438c76db22e..3e175365552 100644 --- a/src/imagination/pco/pco_nir_tex.c +++ b/src/imagination/pco/pco_nir_tex.c @@ -763,13 +763,15 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data) ? nir_intrinsic_dest_type(intr) : nir_intrinsic_src_type(intr); + bool msaa = image_dim == GLSL_SAMPLER_DIM_MS || + image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS; + unsigned desc_set = nir_src_comp_as_uint(intr->src[0], 0); unsigned binding = nir_src_comp_as_uint(intr->src[0], 1); nir_def *elem = nir_channel(b, intr->src[0].ssa, 2); - nir_def *coords = !nir_src_is_undef(intr->src[1]) ? intr->src[1].ssa : NULL; - nir_def *sample_index = !nir_src_is_undef(intr->src[2]) ? intr->src[2].ssa - : NULL; + nir_def *coords = intr->src[1].ssa; + nir_def *sample_index = msaa ? intr->src[2].ssa : NULL; nir_def *write_data = intr->intrinsic == nir_intrinsic_image_deref_store ? intr->src[3].ssa @@ -780,9 +782,30 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data) assert(write_data->num_components == 4); } - ASSERTED bool msaa = image_dim == GLSL_SAMPLER_DIM_MS || - image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS; - assert(!!sample_index == msaa); + bool ia = image_dim == GLSL_SAMPLER_DIM_SUBPASS || + image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS; + + if (ia) { + nir_load_const_instr *load = + nir_instr_as_load_const(intr->src[0].ssa->parent_instr); + bool onchip = load->def.num_components == 4; + + if (onchip) { + unsigned ia_idx = nir_src_comp_as_uint(intr->src[0], 3); + return nir_load_output(b, + intr->def.num_components, + intr->def.bit_size, + nir_imm_int(b, 0), + .base = ia_idx, + .component = 0, + .dest_type = nir_intrinsic_dest_type(intr), + .io_semantics.location = FRAG_RESULT_COLOR, + .io_semantics.num_slots = 1/*, + .io_semantics.fb_fetch_output = true*/); + } + } + + unsigned smp_desc = ia ? PCO_IA_SAMPLER : PCO_POINT_SAMPLER; nir_def *tex_state = nir_load_tex_state_pco(b, ROGUE_NUM_TEXSTATE_DWORDS, @@ -793,8 +816,8 @@ static nir_def *lower_image(nir_builder *b, nir_instr *instr, void *cb_data) nir_def *smp_state = nir_load_smp_state_pco(b, ROGUE_NUM_TEXSTATE_DWORDS, nir_imm_int(b, 0), - .desc_set = PCO_POINT_SAMPLER, - .binding = PCO_POINT_SAMPLER); + .desc_set = smp_desc, + .binding = smp_desc); unsigned num_coord_comps = nir_image_intrinsic_coord_components(intr); if (coords) @@ -859,7 +882,7 @@ static bool is_image(const nir_instr *instr, UNUSED const void *cb_data) return false; } -bool pco_nir_lower_images(nir_shader *shader) +bool pco_nir_lower_images(nir_shader *shader, pco_data *data) { - return nir_shader_lower_instructions(shader, is_image, lower_image, NULL); + return nir_shader_lower_instructions(shader, is_image, lower_image, data); } diff --git a/src/imagination/pco/pco_nir_vk.c b/src/imagination/pco/pco_nir_vk.c index ea472e83706..ac053ca561e 100644 --- a/src/imagination/pco/pco_nir_vk.c +++ b/src/imagination/pco/pco_nir_vk.c @@ -122,9 +122,8 @@ lower_tex_derefs(nir_builder *b, nir_tex_instr *tex, pco_common_data *common) lower_tex_deref_to_binding(b, tex, deref_index, common); } -static nir_def *lower_image_derefs(nir_builder *b, - nir_intrinsic_instr *intr, - pco_common_data *common) +static nir_def * +lower_image_derefs(nir_builder *b, nir_intrinsic_instr *intr, pco_data *data) { nir_src *deref_src = &intr->src[0]; nir_deref_instr *deref = nir_src_as_deref(*deref_src); @@ -132,16 +131,42 @@ static nir_def *lower_image_derefs(nir_builder *b, nir_variable *var = nir_deref_instr_get_variable(deref); assert(var); + unsigned desc_set = var->data.descriptor_set; unsigned binding = var->data.binding; - nir_def *elem = array_elem_from_deref(b, deref); - - set_resource_used(common, desc_set, binding); - common->uses.point_sampler = true; + set_resource_used(&data->common, desc_set, binding); if (nir_intrinsic_format(intr) == PIPE_FORMAT_NONE) nir_intrinsic_set_format(intr, var->data.image.format); + enum glsl_sampler_dim image_dim = nir_intrinsic_image_dim(intr); + bool ia = image_dim == GLSL_SAMPLER_DIM_SUBPASS || + image_dim == GLSL_SAMPLER_DIM_SUBPASS_MS; + + if (ia) { + unsigned ia_idx = var->data.index; + bool onchip = data->fs.ias_onchip[ia_idx].count > 0; + + if (onchip) { + nir_def *elem = array_elem_from_deref(b, deref); + nir_def *index = nir_vec4(b, + nir_imm_int(b, desc_set), + nir_imm_int(b, binding), + elem, + nir_imm_int(b, ia_idx)); + + nir_src_rewrite(deref_src, index); + + return NIR_LOWER_INSTR_PROGRESS; + } + + /* Sampler not needed for on-chip input attachments. */ + data->common.uses.ia_sampler = true; + } else { + data->common.uses.point_sampler = true; + } + + nir_def *elem = array_elem_from_deref(b, deref); nir_def *index = nir_vec3(b, nir_imm_int(b, desc_set), nir_imm_int(b, binding), elem); @@ -160,7 +185,8 @@ static nir_def *lower_image_derefs(nir_builder *b, */ static nir_def *lower_vk(nir_builder *b, nir_instr *instr, void *cb_data) { - pco_common_data *common = cb_data; + pco_data *data = cb_data; + pco_common_data *common = &data->common; switch (instr->type) { case nir_instr_type_intrinsic: { @@ -171,7 +197,7 @@ static nir_def *lower_vk(nir_builder *b, nir_instr *instr, void *cb_data) case nir_intrinsic_image_deref_load: case nir_intrinsic_image_deref_store: - return lower_image_derefs(b, intr, common); + return lower_image_derefs(b, intr, data); default: break; @@ -239,14 +265,14 @@ static bool is_vk(const nir_instr *instr, UNUSED const void *cb_data) * \brief Vulkan lowering pass. * * \param[in,out] shader NIR shader. - * \param[in,out] common Common shader data. + * \param[in,out] data Shader data. * \return True if the pass made progress. */ -bool pco_nir_lower_vk(nir_shader *shader, pco_common_data *common) +bool pco_nir_lower_vk(nir_shader *shader, pco_data *data) { bool progress = false; - progress |= nir_shader_lower_instructions(shader, is_vk, lower_vk, common); + progress |= nir_shader_lower_instructions(shader, is_vk, lower_vk, data); return progress; } diff --git a/src/imagination/pco/pco_trans_nir.c b/src/imagination/pco/pco_trans_nir.c index d5679c1b93e..055e957cc81 100644 --- a/src/imagination/pco/pco_trans_nir.c +++ b/src/imagination/pco/pco_trans_nir.c @@ -406,7 +406,7 @@ trans_store_output_fs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref src) ASSERTED const nir_src offset = intr->src[1]; assert(nir_src_as_uint(offset) == 0); - gl_varying_slot location = nir_intrinsic_io_semantics(intr).location; + gl_frag_result location = nir_intrinsic_io_semantics(intr).location; const pco_range *range = &tctx->shader->data.fs.outputs[location]; assert(component < range->count); @@ -430,6 +430,12 @@ static unsigned fetch_resource_base_reg(const pco_common_data *common, assert(common->uses.point_sampler); range = &common->point_sampler; + if (is_img_smp) + *is_img_smp = false; + } else if (desc_set == PCO_IA_SAMPLER && binding == PCO_IA_SAMPLER) { + assert(common->uses.ia_sampler); + range = &common->ia_sampler; + if (is_img_smp) *is_img_smp = false; } else { @@ -477,23 +483,33 @@ static unsigned fetch_resource_base_reg_packed(const pco_common_data *common, static pco_instr * trans_load_output_fs(trans_ctx *tctx, nir_intrinsic_instr *intr, pco_ref dest) { - ASSERTED unsigned base = nir_intrinsic_base(intr); - assert(!base); - + unsigned base = nir_intrinsic_base(intr); unsigned component = nir_intrinsic_component(intr); ASSERTED const nir_src offset = intr->src[0]; assert(nir_src_as_uint(offset) == 0); - gl_varying_slot location = nir_intrinsic_io_semantics(intr).location; + gl_frag_result location = nir_intrinsic_io_semantics(intr).location; + + const pco_range *range; + if (location >= FRAG_RESULT_DATA0) { + assert(!base); + + range = &tctx->shader->data.fs.outputs[location]; + + ASSERTED bool output_reg = tctx->shader->data.fs.output_reg[location]; + assert(output_reg); + /* TODO: tile buffer support. */ + } else if (location == FRAG_RESULT_COLOR) { + /* Special case for on-chip input attachments. */ + assert(base < ARRAY_SIZE(tctx->shader->data.fs.ias_onchip)); + range = &tctx->shader->data.fs.ias_onchip[base]; + } else { + UNREACHABLE(""); + } - const pco_range *range = &tctx->shader->data.fs.outputs[location]; assert(component < range->count); - ASSERTED bool output_reg = tctx->shader->data.fs.output_reg[location]; - assert(output_reg); - /* TODO: tile buffer support. */ - pco_ref src = pco_ref_hwreg(range->start + component, PCO_REG_CLASS_PIXOUT); return pco_mov(&tctx->b, dest, src, .olchk = true); } diff --git a/src/imagination/vulkan/pds/pvr_pds.h b/src/imagination/vulkan/pds/pvr_pds.h index 47174a00137..0b923028544 100644 --- a/src/imagination/vulkan/pds/pvr_pds.h +++ b/src/imagination/vulkan/pds/pvr_pds.h @@ -893,6 +893,7 @@ struct pvr_pds_descriptor_set { #define PVR_BUFFER_TYPE_DYNAMIC (5) #define PVR_BUFFER_TYPE_UBO_ZEROING (6) #define PVR_BUFFER_TYPE_POINT_SAMPLER (7) +#define PVR_BUFFER_TYPE_IA_SAMPLER (8) #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 153b59f666d..01763d7dfa4 100644 --- a/src/imagination/vulkan/pds/pvr_pipeline_pds.c +++ b/src/imagination/vulkan/pds/pvr_pipeline_pds.c @@ -1576,7 +1576,8 @@ void pvr_pds_generate_descriptor_upload_program( switch (buffer->type) { case PVR_BUFFER_TYPE_PUSH_CONSTS: case PVR_BUFFER_TYPE_BLEND_CONSTS: - case PVR_BUFFER_TYPE_POINT_SAMPLER: { + case PVR_BUFFER_TYPE_POINT_SAMPLER: + case PVR_BUFFER_TYPE_IA_SAMPLER: { 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 1d8de9fc908..5e9b2786bf3 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_cmd_buffer.c @@ -3686,6 +3686,42 @@ static VkResult pvr_setup_descriptor_mappings( break; } + case PVR_BUFFER_TYPE_IA_SAMPLER: { + uint64_t ia_sampler_words[ROGUE_NUM_TEXSTATE_SAMPLER_WORDS]; + pvr_csb_pack (&ia_sampler_words[0], + TEXSTATE_SAMPLER_WORD0, + sampler) { + sampler.addrmode_u = ROGUE_TEXSTATE_ADDRMODE_CLAMP_TO_EDGE; + sampler.addrmode_v = ROGUE_TEXSTATE_ADDRMODE_CLAMP_TO_EDGE; + sampler.addrmode_w = ROGUE_TEXSTATE_ADDRMODE_CLAMP_TO_EDGE; + sampler.dadjust = ROGUE_TEXSTATE_DADJUST_ZERO_UINT; + sampler.magfilter = ROGUE_TEXSTATE_FILTER_POINT; + sampler.minfilter = ROGUE_TEXSTATE_FILTER_POINT; + sampler.anisoctl = ROGUE_TEXSTATE_ANISOCTL_DISABLED; + sampler.non_normalized_coords = true; + } + + pvr_csb_pack (&ia_sampler_words[1], + TEXSTATE_SAMPLER_WORD1, + sampler) { + } + + struct pvr_suballoc_bo *ia_sampler_bo; + result = pvr_cmd_buffer_upload_general(cmd_buffer, + ia_sampler_words, + sizeof(ia_sampler_words), + &ia_sampler_bo); + + if (result != VK_SUCCESS) + return result; + + PVR_WRITE(qword_buffer, + ia_sampler_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_descriptor_set.c b/src/imagination/vulkan/pvr_descriptor_set.c index 0019c63cd83..de5dccdbdfa 100644 --- a/src/imagination/vulkan/pvr_descriptor_set.c +++ b/src/imagination/vulkan/pvr_descriptor_set.c @@ -85,6 +85,7 @@ static unsigned pvr_descriptor_size(VkDescriptorType type) case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return sizeof(struct pvr_image_descriptor); default: @@ -514,6 +515,23 @@ write_image_sampler(const struct pvr_descriptor_set *set, memcpy(desc_mapping, &image_sampler_desc, sizeof(image_sampler_desc)); } +static void +write_input_attachment(const struct pvr_descriptor_set *set, + const VkDescriptorImageInfo *image_info, + const struct pvr_descriptor_set_layout_binding *binding, + uint32_t elem) +{ + PVR_FROM_HANDLE(pvr_image_view, image_view, image_info->imageView); + + const unsigned desc_offset = binding->offset + (elem * binding->stride); + void *desc_mapping = (uint8_t *)set->mapping + desc_offset; + + struct pvr_image_descriptor image_desc = + image_view->image_state[PVR_TEXTURE_STATE_ATTACHMENT]; + + memcpy(desc_mapping, &image_desc, sizeof(image_desc)); +} + static void write_storage_image(const struct pvr_descriptor_set *set, const VkDescriptorImageInfo *image_info, @@ -643,6 +661,15 @@ void pvr_UpdateDescriptorSets(VkDevice _device, } break; + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + for (uint32_t j = 0; j < write->descriptorCount; j++) { + write_input_attachment(set, + &write->pImageInfo[j], + binding, + write->dstArrayElement + j); + } + break; + default: UNREACHABLE(""); } diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c index 583d104caa2..ab638a83483 100644 --- a/src/imagination/vulkan/pvr_pipeline.c +++ b/src/imagination/vulkan/pvr_pipeline.c @@ -606,6 +606,14 @@ static VkResult pvr_pds_descriptor_program_create_and_upload( }; } + if (data->common.ia_sampler.count > 0) { + program.buffers[program.buffer_count++] = (struct pvr_pds_buffer){ + .type = PVR_BUFFER_TYPE_IA_SAMPLER, + .size_in_dwords = data->common.ia_sampler.count, + .destination = data->common.ia_sampler.start, + }; + } + pds_info->entries_size_in_bytes = const_entries_size_in_bytes; pvr_pds_generate_descriptor_upload_program(&program, NULL, pds_info); @@ -1799,11 +1807,7 @@ pvr_setup_fs_outputs(pco_data *data, const struct pvr_render_subpass *const subpass, const struct pvr_renderpass_hwsetup_subpass *hw_subpass) { - ASSERTED unsigned num_outputs = hw_subpass->setup.num_render_targets; - assert(num_outputs == subpass->color_count); - uint64_t outputs_written = nir->info.outputs_written; - assert(util_bitcount64(outputs_written) == num_outputs); for (unsigned u = 0; u < subpass->color_count; ++u) { gl_frag_result location = FRAG_RESULT_DATA0 + u; @@ -1846,10 +1850,44 @@ pvr_setup_fs_outputs(pco_data *data, static void pvr_init_fs_input_attachments( pco_data *data, + const struct pvr_render_pass *pass, const struct pvr_render_subpass *const subpass, const struct pvr_renderpass_hwsetup_subpass *hw_subpass) { - pvr_finishme("pvr_init_fs_input_attachments"); + for (unsigned u = 0; u < subpass->input_count; ++u) { + unsigned idx = subpass->input_attachments[u]; + if (idx == VK_ATTACHMENT_UNUSED) + continue; + + bool onchip = hw_subpass->input_access[u].type != + PVR_RENDERPASS_HWSETUP_INPUT_ACCESS_OFFCHIP; + if (!onchip) + continue; + + /* TODO: z-replicate. */ + assert(hw_subpass->input_access[u].type != + PVR_RENDERPASS_HWSETUP_INPUT_ACCESS_ONCHIP_ZREPLICATE); + + VkFormat vk_format = pass->attachments[idx].vk_format; + data->fs.ia_formats[u] = vk_format_to_pipe_format(vk_format); + + unsigned mrt_idx = hw_subpass->input_access[u].on_chip_rt; + const struct usc_mrt_resource *mrt_resource = + &hw_subpass->setup.mrt_resources[mrt_idx]; + + ASSERTED bool output_reg = mrt_resource->type == + USC_MRT_RESOURCE_TYPE_OUTPUT_REG; + assert(output_reg); + /* TODO: tile buffer support. */ + + unsigned format_bits = + util_format_get_blocksizebits(data->fs.ia_formats[u]); + + data->fs.ias_onchip[u] = (pco_range){ + .start = mrt_resource->reg.output_reg, + .count = DIV_ROUND_UP(format_bits, 32), + }; + } } static void pvr_init_fs_blend(pco_data *data, @@ -1903,7 +1941,7 @@ static void pvr_setup_fs_input_attachments( const struct pvr_render_subpass *const subpass, const struct pvr_renderpass_hwsetup_subpass *hw_subpass) { - pvr_finishme("pvr_setup_fs_input_attachments"); + /* pvr_finishme("pvr_setup_fs_input_attachments"); */ } static void pvr_setup_fs_blend(pco_data *data) @@ -2088,6 +2126,15 @@ static void pvr_setup_descriptors(pco_data *data, data->common.shareds += ROGUE_NUM_TEXSTATE_DWORDS; } + if (data->common.uses.ia_sampler) { + data->common.ia_sampler = (pco_range){ + .start = data->common.shareds, + .count = ROGUE_NUM_TEXSTATE_DWORDS, + }; + + data->common.shareds += ROGUE_NUM_TEXSTATE_DWORDS; + } + assert(data->common.shareds < 256); } @@ -2120,7 +2167,7 @@ pvr_preprocess_shader_data(pco_data *data, .subpasses[subpass_map->subpass]; pvr_init_fs_outputs(data, pass, subpass, hw_subpass); - pvr_init_fs_input_attachments(data, subpass, hw_subpass); + pvr_init_fs_input_attachments(data, pass, subpass, hw_subpass); pvr_init_fs_blend(data, state->cb); /* TODO: push consts, dynamic state, etc. */