diff --git a/src/imagination/rogue/rogue_compile.c b/src/imagination/rogue/rogue_compile.c index b4b2f11499d..f6bdf5c4f39 100644 --- a/src/imagination/rogue/rogue_compile.c +++ b/src/imagination/rogue/rogue_compile.c @@ -311,6 +311,11 @@ mesa_stage_to_pvr(gl_shader_stage mesa_stage) unreachable("Unsupported gl_shader_stage."); } +static bool descriptor_is_dynamic(VkDescriptorType type) +{ + return (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || + type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC); +} static void trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b, @@ -325,12 +330,9 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b, struct pvr_pipeline_layout *pipeline_layout = b->shader->ctx->pipeline_layout; - /* Defaults for offline compiler. */ - /* TODO: Load these from an offline pipeline description - * if using the offline compiler. - */ - unsigned desc_set_table_sh_reg = 0; - unsigned flat_desc_idx = binding; + unsigned desc_set_table_sh_reg; + unsigned desc_set_offset; + unsigned desc_offset; if (pipeline_layout) { /* Fetch shared registers containing descriptor set table address. */ @@ -341,26 +343,45 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b, pipeline_layout->sh_reg_layout_per_stage[pvr_stage] .descriptor_set_addrs_table.offset; - /* Lookup offsets for descriptor set and descriptor. */ + /* Calculate offset for the descriptor set. */ assert(desc_set < pipeline_layout->set_count); + desc_set_offset = desc_set * sizeof(pvr_dev_addr_t); /* Table is an array + of addresses. */ - unsigned binding_count = - pipeline_layout->set_layout[desc_set]->binding_count; - assert(binding < binding_count); + const struct pvr_descriptor_set_layout *set_layout = + pipeline_layout->set_layout[desc_set]; + const struct pvr_descriptor_set_layout_mem_layout *mem_layout = + &set_layout->memory_layout_in_dwords_per_stage[pvr_stage]; - flat_desc_idx = ~0U; - for (unsigned u = 0; u < binding_count; ++u) { - unsigned binding_number = - pipeline_layout->set_layout[desc_set]->bindings[u].binding_number; + /* Calculate offset for the descriptor/binding. */ + assert(binding < set_layout->binding_count); - if (binding_number == binding) { - flat_desc_idx = pipeline_layout->set_layout[desc_set] - ->bindings[u] - .descriptor_index; - break; - } - } - assert(flat_desc_idx != ~0U); + const struct pvr_descriptor_set_layout_binding *binding_layout = + pvr_get_descriptor_binding(set_layout, binding); + assert(binding_layout); + + /* TODO: Handle secondaries. */ + /* TODO: Handle bindings having multiple descriptors + * (VkDescriptorSetLayoutBinding->descriptorCount). + */ + + if (descriptor_is_dynamic(binding_layout->type)) + desc_offset = set_layout->total_size_in_dwords; + else + desc_offset = mem_layout->primary_offset; + + desc_offset += + binding_layout->per_stage_offset_in_dwords[pvr_stage].primary; + + desc_offset *= sizeof(uint32_t); /* DWORDs to bytes. */ + } else { + /* Dummy defaults for offline compiler. */ + /* TODO: Load these from an offline pipeline description + * if using the offline compiler. + */ + desc_set_table_sh_reg = 0; + desc_set_offset = desc_set * sizeof(pvr_dev_addr_t); + desc_offset = binding * sizeof(pvr_dev_addr_t); } unsigned desc_set_table_addr_idx = b->shader->ctx->next_ssa_idx++; @@ -384,8 +405,6 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b, ->instr; rogue_add_instr_comment(instr, "desc_set_table_addr_hi"); - /* TODO: Don't add offsets if the descriptor set/flat descriptor is 0. */ - /* Offset the descriptor set table address to access the descriptor set. */ unsigned desc_set_table_addr_offset_idx = b->shader->ctx->next_ssa_idx++; rogue_regarray *desc_set_table_addr_offset_64 = @@ -395,14 +414,27 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b, rogue_ssa_vec_regarray(b->shader, 1, desc_set_table_addr_offset_idx, 1), }; + unsigned desc_set_table_addr_offset_lo_idx = b->shader->ctx->next_ssa_idx++; + unsigned desc_set_table_addr_offset_hi_idx = b->shader->ctx->next_ssa_idx++; + + rogue_reg *desc_set_table_addr_offset_lo = + rogue_ssa_reg(b->shader, desc_set_table_addr_offset_lo_idx); + rogue_reg *desc_set_table_addr_offset_hi = + rogue_ssa_reg(b->shader, desc_set_table_addr_offset_hi_idx); + + rogue_MOV(b, + rogue_ref_reg(desc_set_table_addr_offset_lo), + rogue_ref_imm(desc_set_offset)); + rogue_MOV(b, rogue_ref_reg(desc_set_table_addr_offset_hi), rogue_ref_imm(0)); + rogue_ADD64(b, rogue_ref_regarray(desc_set_table_addr_offset_2x32[0]), rogue_ref_regarray(desc_set_table_addr_offset_2x32[1]), rogue_ref_io(ROGUE_IO_NONE), rogue_ref_regarray(desc_set_table_addr_2x32[0]), rogue_ref_regarray(desc_set_table_addr_2x32[1]), - rogue_ref_imm(desc_set * 4), /* TODO: use UMADD64 instead */ - rogue_ref_imm(0), + rogue_ref_reg(desc_set_table_addr_offset_lo), + rogue_ref_reg(desc_set_table_addr_offset_hi), rogue_ref_io(ROGUE_IO_NONE)); unsigned desc_set_addr_idx = b->shader->ctx->next_ssa_idx++; @@ -429,14 +461,27 @@ trans_nir_intrinsic_load_vulkan_descriptor(rogue_builder *b, rogue_ssa_vec_regarray(b->shader, 1, desc_addr_offset_idx, 1), }; + unsigned desc_addr_offset_lo_idx = b->shader->ctx->next_ssa_idx++; + unsigned desc_addr_offset_hi_idx = b->shader->ctx->next_ssa_idx++; + + rogue_reg *desc_addr_offset_val_lo = + rogue_ssa_reg(b->shader, desc_addr_offset_lo_idx); + rogue_reg *desc_addr_offset_val_hi = + rogue_ssa_reg(b->shader, desc_addr_offset_hi_idx); + + rogue_MOV(b, + rogue_ref_reg(desc_addr_offset_val_lo), + rogue_ref_imm(desc_offset)); + rogue_MOV(b, rogue_ref_reg(desc_addr_offset_val_hi), rogue_ref_imm(0)); + rogue_ADD64(b, rogue_ref_regarray(desc_addr_offset_2x32[0]), rogue_ref_regarray(desc_addr_offset_2x32[1]), rogue_ref_io(ROGUE_IO_NONE), rogue_ref_regarray(desc_set_addr_2x32[0]), rogue_ref_regarray(desc_set_addr_2x32[1]), - rogue_ref_imm(flat_desc_idx * 4), /* TODO: use UMADD64 instead */ - rogue_ref_imm(0), + rogue_ref_reg(desc_addr_offset_val_lo), + rogue_ref_reg(desc_addr_offset_val_hi), rogue_ref_io(ROGUE_IO_NONE)); unsigned desc_addr_idx = intr->dest.ssa.index; diff --git a/src/imagination/vulkan/pvr_common.h b/src/imagination/vulkan/pvr_common.h index 19bb76dca60..5976123dbe7 100644 --- a/src/imagination/vulkan/pvr_common.h +++ b/src/imagination/vulkan/pvr_common.h @@ -407,4 +407,38 @@ struct pvr_pipeline_layout { } per_stage_reg_info[PVR_STAGE_ALLOCATION_COUNT]; }; +static int pvr_compare_layout_binding(const void *a, const void *b) +{ + uint32_t binding_a; + uint32_t binding_b; + + binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number; + binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number; + + if (binding_a < binding_b) + return -1; + + if (binding_a > binding_b) + return 1; + + return 0; +} + +/* This function does not assume that the binding will always exist for a + * particular binding_num. Caller should check before using the return pointer. + */ +static struct pvr_descriptor_set_layout_binding * +pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout, + const uint32_t binding_num) +{ + struct pvr_descriptor_set_layout_binding binding; + binding.binding_number = binding_num; + + return bsearch(&binding, + layout->bindings, + layout->binding_count, + sizeof(binding), + pvr_compare_layout_binding); +} + #endif /* PVR_COMMON_H */ diff --git a/src/imagination/vulkan/pvr_descriptor_set.c b/src/imagination/vulkan/pvr_descriptor_set.c index 9d5c0e8fac0..2c0737be86b 100644 --- a/src/imagination/vulkan/pvr_descriptor_set.c +++ b/src/imagination/vulkan/pvr_descriptor_set.c @@ -1339,40 +1339,6 @@ VkResult pvr_FreeDescriptorSets(VkDevice _device, return VK_SUCCESS; } -static int pvr_compare_layout_binding(const void *a, const void *b) -{ - uint32_t binding_a; - uint32_t binding_b; - - binding_a = ((struct pvr_descriptor_set_layout_binding *)a)->binding_number; - binding_b = ((struct pvr_descriptor_set_layout_binding *)b)->binding_number; - - if (binding_a < binding_b) - return -1; - - if (binding_a > binding_b) - return 1; - - return 0; -} - -/* This function does not assume that the binding will always exist for a - * particular binding_num. Caller should check before using the return pointer. - */ -static struct pvr_descriptor_set_layout_binding * -pvr_get_descriptor_binding(const struct pvr_descriptor_set_layout *layout, - const uint32_t binding_num) -{ - struct pvr_descriptor_set_layout_binding binding; - binding.binding_number = binding_num; - - return bsearch(&binding, - layout->bindings, - layout->binding_count, - sizeof(binding), - pvr_compare_layout_binding); -} - static void pvr_descriptor_update_buffer_info( const struct pvr_device *device, const VkWriteDescriptorSet *write_set,