diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c index 2975a371a7b..ee804f97255 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_cmd_buffer.c @@ -89,28 +89,17 @@ panvk_CmdBindIndexBuffer(VkCommandBuffer commandBuffer, } static void -panvk_set_ssbo_pointers(struct panvk_descriptor_state *desc_state, - unsigned ssbo_offset, - unsigned dyn_ssbo_offset, - struct panvk_descriptor_set *set) +panvk_set_dyn_ssbo_pointers(struct panvk_descriptor_state *desc_state, + unsigned dyn_ssbo_offset, + struct panvk_descriptor_set *set) { struct panvk_sysvals *sysvals = &desc_state->sysvals; - unsigned ssbo_idx = ssbo_offset; - for (unsigned i = 0; i < set->layout->num_ssbos; i++) { - const struct panvk_buffer_desc *ssbo = &set->ssbos[i]; - - sysvals->ssbos[ssbo_idx++] = (struct panvk_ssbo_addr) { - .base_addr = panvk_buffer_gpu_ptr(ssbo->buffer, ssbo->offset), - .size = panvk_buffer_range(ssbo->buffer, ssbo->offset, ssbo->size), - }; - } - for (unsigned i = 0; i < set->layout->num_dyn_ssbos; i++) { const struct panvk_buffer_desc *ssbo = &desc_state->dyn.ssbos[dyn_ssbo_offset + i]; - sysvals->ssbos[ssbo_idx++] = (struct panvk_ssbo_addr) { + sysvals->dyn_ssbos[dyn_ssbo_offset + i] = (struct panvk_ssbo_addr) { .base_addr = panvk_buffer_gpu_ptr(ssbo->buffer, ssbo->offset), .size = panvk_buffer_range(ssbo->buffer, ssbo->offset, ssbo->size), }; @@ -165,18 +154,17 @@ panvk_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, } } - if (set->layout->num_ssbos || set->layout->num_dyn_ssbos) { - panvk_set_ssbo_pointers(descriptors_state, - playout->sets[idx].ssbo_offset, - playout->sets[idx].dyn_ssbo_offset, - set); + if (set->layout->num_dyn_ssbos) { + panvk_set_dyn_ssbo_pointers(descriptors_state, + playout->sets[idx].dyn_ssbo_offset, + set); } - if (set->layout->num_ssbos || set->layout->num_dyn_ssbos) + if (set->layout->num_dyn_ssbos) descriptors_state->dirty |= PANVK_DYNAMIC_SSBO; if (set->layout->num_ubos || set->layout->num_dyn_ubos || - set->layout->num_ssbos || set->layout->num_dyn_ssbos) + set->layout->num_dyn_ssbos || set->layout->desc_ubo_size) descriptors_state->ubos = 0; if (set->layout->num_textures) diff --git a/src/panfrost/vulkan/panvk_descriptor_set.c b/src/panfrost/vulkan/panvk_descriptor_set.c index 4537096d5ab..8e296781d6a 100644 --- a/src/panfrost/vulkan/panvk_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_descriptor_set.c @@ -85,7 +85,7 @@ panvk_GetDescriptorSetLayoutSupport(VkDevice _device, } unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0; - unsigned ssbo_idx = 0, dynoffset_idx = 0, img_idx = 0; + unsigned dynoffset_idx = 0, img_idx = 0; for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) { const VkDescriptorSetLayoutBinding *binding = &bindings[i]; @@ -113,7 +113,6 @@ panvk_GetDescriptorSetLayoutSupport(VkDevice _device, dynoffset_idx += binding->descriptorCount; FALLTHROUGH; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - ssbo_idx += binding->descriptorCount; break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: @@ -159,7 +158,7 @@ panvk_CreatePipelineLayout(VkDevice _device, layout->num_sets = pCreateInfo->setLayoutCount; _mesa_sha1_init(&ctx); - unsigned sampler_idx = 0, tex_idx = 0, ssbo_idx = 0, ubo_idx = 0; + unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0; unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, img_idx = 0; for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) { VK_FROM_HANDLE(panvk_descriptor_set_layout, set_layout, @@ -170,14 +169,12 @@ panvk_CreatePipelineLayout(VkDevice _device, layout->sets[set].tex_offset = tex_idx; layout->sets[set].ubo_offset = ubo_idx; layout->sets[set].dyn_ubo_offset = dyn_ubo_idx; - layout->sets[set].ssbo_offset = ssbo_idx; layout->sets[set].dyn_ssbo_offset = dyn_ssbo_idx; layout->sets[set].img_offset = img_idx; sampler_idx += set_layout->num_samplers; tex_idx += set_layout->num_textures; ubo_idx += set_layout->num_ubos; dyn_ubo_idx += set_layout->num_dyn_ubos; - ssbo_idx += set_layout->num_ssbos; dyn_ssbo_idx += set_layout->num_dyn_ssbos; img_idx += set_layout->num_imgs; @@ -210,7 +207,6 @@ panvk_CreatePipelineLayout(VkDevice _device, layout->num_textures = tex_idx; layout->num_ubos = ubo_idx; layout->num_dyn_ubos = dyn_ubo_idx; - layout->num_ssbos = ssbo_idx; layout->num_dyn_ssbos = dyn_ssbo_idx; layout->num_imgs = img_idx; @@ -349,7 +345,6 @@ panvk_descriptor_set_destroy(struct panvk_device *device, vk_free(&device->vk.alloc, set->samplers); vk_free(&device->vk.alloc, set->ubos); vk_free(&device->vk.alloc, set->dyn_ubos); - vk_free(&device->vk.alloc, set->ssbos); vk_free(&device->vk.alloc, set->dyn_ssbos); vk_free(&device->vk.alloc, set->img_fmts); vk_free(&device->vk.alloc, set->img_attrib_bufs); diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h index 6a2393b954d..34fb66ada85 100644 --- a/src/panfrost/vulkan/panvk_private.h +++ b/src/panfrost/vulkan/panvk_private.h @@ -345,7 +345,6 @@ struct panvk_descriptor_set { struct panvk_descriptor_pool *pool; const struct panvk_descriptor_set_layout *layout; struct panvk_descriptor *descs; - struct panvk_buffer_desc *ssbos; struct panvk_buffer_desc *dyn_ssbos; void *ubos; struct panvk_buffer_desc *dyn_ubos; @@ -375,7 +374,6 @@ struct panvk_descriptor_set_binding_layout { }; unsigned tex_idx; }; - unsigned ssbo_idx; unsigned dyn_ssbo_idx; unsigned ubo_idx; unsigned dyn_ubo_idx; @@ -408,7 +406,6 @@ struct panvk_descriptor_set_layout { unsigned num_textures; unsigned num_ubos; unsigned num_dyn_ubos; - unsigned num_ssbos; unsigned num_dyn_ssbos; unsigned num_imgs; @@ -455,7 +452,6 @@ struct panvk_pipeline_layout { unsigned num_textures; unsigned num_ubos; unsigned num_dyn_ubos; - unsigned num_ssbos; unsigned num_dyn_ssbos; uint32_t num_imgs; uint32_t num_sets; @@ -470,7 +466,6 @@ struct panvk_pipeline_layout { unsigned tex_offset; unsigned ubo_offset; unsigned dyn_ubo_offset; - unsigned ssbo_offset; unsigned dyn_ssbo_offset; unsigned img_offset; } sets[MAX_SETS]; @@ -639,10 +634,9 @@ struct panvk_sysvals { }; }; -/* This will be gone in the next commit */ -#define MAX_SSBOS 28 + /* The back-end compiler doesn't know about any sysvals after this point */ - struct panvk_ssbo_addr ssbos[MAX_SSBOS]; + struct panvk_ssbo_addr dyn_ssbos[MAX_DYNAMIC_STORAGE_BUFFERS]; }; struct panvk_descriptor_state { diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set.c b/src/panfrost/vulkan/panvk_vX_descriptor_set.c index fa8d50bf5fa..0bc267f009b 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set.c @@ -90,7 +90,7 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device, set_layout->flags = pCreateInfo->flags; set_layout->binding_count = num_bindings; - unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0, ssbo_idx = 0; + unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0; unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, desc_idx = 0, img_idx = 0; uint32_t desc_ubo_size = 0; @@ -147,8 +147,7 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device, dyn_ssbo_idx += binding_layout->array_size; break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - binding_layout->ssbo_idx = ssbo_idx; - ssbo_idx += binding_layout->array_size; + binding_layout->desc_ubo_stride = sizeof(struct panvk_ssbo_addr); break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: binding_layout->img_idx = img_idx; @@ -176,7 +175,6 @@ panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device, set_layout->num_textures = tex_idx; set_layout->num_ubos = ubo_idx; set_layout->num_dyn_ubos = dyn_ubo_idx; - set_layout->num_ssbos = ssbo_idx; set_layout->num_dyn_ssbos = dyn_ssbo_idx; set_layout->num_imgs = img_idx; p_atomic_set(&set_layout->refcount, 1); @@ -228,14 +226,6 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device, goto err_free_set; } - if (layout->num_ssbos) { - set->ssbos = vk_zalloc(&device->vk.alloc, - sizeof(*set->ssbos) * layout->num_ssbos, 8, - VK_OBJECT_TYPE_DESCRIPTOR_SET); - if (!set->ssbos) - goto err_free_set; - } - if (layout->num_dyn_ssbos) { set->dyn_ssbos = vk_zalloc(&device->vk.alloc, sizeof(*set->dyn_ssbos) * layout->num_dyn_ssbos, 8, @@ -308,10 +298,9 @@ panvk_per_arch(descriptor_set_create)(struct panvk_device *device, err_free_set: vk_free(&device->vk.alloc, set->textures); vk_free(&device->vk.alloc, set->samplers); - vk_free(&device->vk.alloc, set->ssbos); - vk_free(&device->vk.alloc, set->dyn_ssbos); vk_free(&device->vk.alloc, set->ubos); vk_free(&device->vk.alloc, set->dyn_ubos); + vk_free(&device->vk.alloc, set->dyn_ssbos); vk_free(&device->vk.alloc, set->img_fmts); vk_free(&device->vk.alloc, set->img_attrib_bufs); vk_free(&device->vk.alloc, set->descs); @@ -375,6 +364,24 @@ panvk_per_arch(set_ubo_desc)(void *ubo, panvk_per_arch(emit_ubo)(ptr, size, ubo); } +static void +panvk_set_ssbo_desc(struct panvk_descriptor_set *set, + const struct panvk_descriptor_set_binding_layout *binding_layout, + uint32_t idx, const VkDescriptorBufferInfo *pBufferInfo) +{ + VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer); + + void *desc = (char *)set->desc_bo->ptr.cpu + + binding_layout->desc_ubo_offset + + binding_layout->desc_ubo_stride * idx; + + *(struct panvk_ssbo_addr *)desc = (struct panvk_ssbo_addr) { + .base_addr = panvk_buffer_gpu_ptr(buffer, pBufferInfo->offset), + .size = panvk_buffer_range(buffer, pBufferInfo->offset, + pBufferInfo->range), + }; +} + static void panvk_set_sampler_desc(void *desc, const VkDescriptorImageInfo *pImageInfo) @@ -537,8 +544,8 @@ panvk_per_arch(write_descriptor_set)(struct panvk_device *dev, break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: for (unsigned i = 0; i < ndescs; i++) { - unsigned ssbo = binding_layout->ssbo_idx + dest_offset + i; - panvk_set_buffer_desc(&set->ssbos[ssbo], &pDescriptorWrite->pBufferInfo[src_offset + i]); + panvk_set_ssbo_desc(set, binding_layout, i, + &pDescriptorWrite->pBufferInfo[src_offset + i]); } break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: diff --git a/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c b/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c index 11f66a17e85..1a2785dbdf0 100644 --- a/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c +++ b/src/panfrost/vulkan/panvk_vX_nir_lower_descriptors.c @@ -34,9 +34,284 @@ struct apply_descriptors_ctx { const struct panvk_pipeline_layout *layout; + bool add_bounds_checks; bool has_img_access; + nir_address_format desc_addr_format; + nir_address_format ubo_addr_format; + nir_address_format ssbo_addr_format; }; +static nir_address_format +addr_format_for_desc_type(VkDescriptorType desc_type, + const struct apply_descriptors_ctx *ctx) +{ + switch (desc_type) { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + return ctx->ubo_addr_format; + + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + return ctx->ssbo_addr_format; + + default: + unreachable("Unsupported descriptor type"); + } +} + +/** Build a Vulkan resource index + * + * A "resource index" is the term used by our SPIR-V parser and the relevant + * NIR intrinsics for a reference into a descriptor set. It acts much like a + * deref in NIR except that it accesses opaque descriptors instead of memory. + * + * Coming out of SPIR-V, both the resource indices (in the form of + * vulkan_resource_[re]index intrinsics) and the memory derefs (in the form + * of nir_deref_instr) use the same vector component/bit size. The meaning + * of those values for memory derefs (nir_deref_instr) is given by the + * nir_address_format associated with the descriptor type. For resource + * indices, it's an entirely internal to panvk encoding which describes, in + * some sense, the address of the descriptor. Thanks to the NIR/SPIR-V rules, + * it must be packed into the same size SSA values as a memory address. For + * this reason, the actual encoding may depend both on the address format for + * memory derefs and the descriptor address format. + * + * The load_vulkan_descriptor intrinsic exists to provide a transition point + * between these two forms of derefs: descriptor and memory. + */ +static nir_ssa_def * +build_res_index(nir_builder *b, uint32_t set, uint32_t binding, + nir_ssa_def *array_index, nir_address_format addr_format, + const struct apply_descriptors_ctx *ctx) +{ + const struct panvk_descriptor_set_layout *set_layout = + ctx->layout->sets[set].layout; + const struct panvk_descriptor_set_binding_layout *bind_layout = + &set_layout->bindings[binding]; + + uint32_t array_size = bind_layout->array_size; + + switch (bind_layout->type) { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: { + assert(addr_format == nir_address_format_32bit_index_offset); + + const unsigned ubo_idx = + panvk_pipeline_layout_ubo_index(ctx->layout, set, binding, 0); + + const uint32_t packed = (array_size - 1) << 16 | ubo_idx; + + return nir_vec2(b, nir_imm_int(b, packed), array_index); + } + + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { + assert(addr_format == nir_address_format_64bit_bounded_global || + addr_format == nir_address_format_64bit_global_32bit_offset); + + const unsigned set_ubo_idx = + panvk_pipeline_layout_ubo_start(ctx->layout, set, false) + + set_layout->desc_ubo_index; + + const uint32_t packed = (bind_layout->desc_ubo_stride << 16 ) | + set_ubo_idx; + + return nir_vec4(b, nir_imm_int(b, packed), + nir_imm_int(b, bind_layout->desc_ubo_offset), + nir_imm_int(b, array_size - 1), + array_index); + } + + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { + assert(addr_format == nir_address_format_64bit_bounded_global || + addr_format == nir_address_format_64bit_global_32bit_offset); + + const unsigned dyn_ssbo_idx = ctx->layout->sets[set].dyn_ssbo_offset + + bind_layout->dyn_ssbo_idx; + + const unsigned ubo_idx = PANVK_SYSVAL_UBO_INDEX; + const unsigned desc_stride = sizeof(struct panvk_ssbo_addr); + const uint32_t ubo_offset = offsetof(struct panvk_sysvals, dyn_ssbos) + + dyn_ssbo_idx * desc_stride; + + const uint32_t packed = (desc_stride << 16) | ubo_idx; + + return nir_vec4(b, nir_imm_int(b, packed), + nir_imm_int(b, ubo_offset), + nir_imm_int(b, array_size - 1), + array_index); + } + + default: + unreachable("Unsupported descriptor type"); + } +} + +/** Adjust a Vulkan resource index + * + * This is the equivalent of nir_deref_type_ptr_as_array for resource indices. + * For array descriptors, it allows us to adjust the array index. Thanks to + * variable pointers, we cannot always fold this re-index operation into the + * vulkan_resource_index intrinsic and we have to do it based on nothing but + * the address format. + */ +static nir_ssa_def * +build_res_reindex(nir_builder *b, nir_ssa_def *orig, nir_ssa_def *delta, + nir_address_format addr_format) +{ + switch (addr_format) { + case nir_address_format_32bit_index_offset: + return nir_vec2(b, nir_channel(b, orig, 0), + nir_iadd(b, nir_channel(b, orig, 1), delta)); + + case nir_address_format_64bit_bounded_global: + case nir_address_format_64bit_global_32bit_offset: + return nir_vec4(b, nir_channel(b, orig, 0), + nir_channel(b, orig, 1), + nir_channel(b, orig, 2), + nir_iadd(b, nir_channel(b, orig, 3), delta)); + + default: + unreachable("Unhandled address format"); + } +} + +/** Convert a Vulkan resource index into a buffer address + * + * In some cases, this does a memory load from the descriptor set and, in + * others, it simply converts from one form to another. + * + * See build_res_index for details about each resource index format. + */ +static nir_ssa_def * +build_buffer_addr_for_res_index(nir_builder *b, + nir_ssa_def *res_index, + nir_address_format addr_format, + const struct apply_descriptors_ctx *ctx) +{ + switch (addr_format) { + case nir_address_format_32bit_index_offset: { + nir_ssa_def *packed = nir_channel(b, res_index, 0); + nir_ssa_def *array_index = nir_channel(b, res_index, 1); + nir_ssa_def *surface_index = nir_extract_u16(b, packed, nir_imm_int(b, 0)); + nir_ssa_def *array_max = nir_extract_u16(b, packed, nir_imm_int(b, 1)); + + if (ctx->add_bounds_checks) + array_index = nir_umin(b, array_index, array_max); + + return nir_vec2(b, nir_iadd(b, surface_index, array_index), + nir_imm_int(b, 0)); + } + + case nir_address_format_64bit_bounded_global: + case nir_address_format_64bit_global_32bit_offset: { + nir_ssa_def *packed = nir_channel(b, res_index, 0); + nir_ssa_def *desc_ubo_offset = nir_channel(b, res_index, 1); + nir_ssa_def *array_max = nir_channel(b, res_index, 2); + nir_ssa_def *array_index = nir_channel(b, res_index, 3); + + nir_ssa_def *desc_ubo_idx = nir_extract_u16(b, packed, nir_imm_int(b, 0)); + nir_ssa_def *desc_ubo_stride = nir_extract_u16(b, packed, nir_imm_int(b, 1)); + + if (ctx->add_bounds_checks) + array_index = nir_umin(b, array_index, array_max); + + desc_ubo_offset = nir_iadd(b, desc_ubo_offset, + nir_imul(b, array_index, desc_ubo_stride)); + + nir_ssa_def *desc = nir_load_ubo(b, 4, 32, desc_ubo_idx, + desc_ubo_offset, + .align_mul=16, .range=~0); + + /* The offset in the descriptor is guaranteed to be zero when it's + * written into the descriptor set. This lets us avoid some unnecessary + * adds. + */ + return nir_vec4(b, nir_channel(b, desc, 0), + nir_channel(b, desc, 1), + nir_channel(b, desc, 2), + nir_imm_int(b, 0)); + } + + default: + unreachable("Unhandled address format"); + } +} + + +static bool +lower_res_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin, + const struct apply_descriptors_ctx *ctx) +{ + b->cursor = nir_before_instr(&intrin->instr); + + const VkDescriptorType desc_type = nir_intrinsic_desc_type(intrin); + nir_address_format addr_format = addr_format_for_desc_type(desc_type, ctx); + + nir_ssa_def *res; + switch (intrin->intrinsic) { + case nir_intrinsic_vulkan_resource_index: + assert(intrin->src[0].is_ssa); + res = build_res_index(b, nir_intrinsic_desc_set(intrin), + nir_intrinsic_binding(intrin), + intrin->src[0].ssa, + addr_format, ctx); + break; + + case nir_intrinsic_vulkan_resource_reindex: + assert(intrin->src[0].is_ssa && intrin->src[1].is_ssa); + res = build_res_reindex(b, intrin->src[0].ssa, + intrin->src[1].ssa, + addr_format); + break; + + case nir_intrinsic_load_vulkan_descriptor: + assert(intrin->src[0].is_ssa); + res = build_buffer_addr_for_res_index(b, intrin->src[0].ssa, + addr_format, ctx); + break; + + default: + unreachable("Unhandled resource intrinsic"); + } + + assert(intrin->dest.is_ssa); + assert(intrin->dest.ssa.bit_size == res->bit_size); + assert(intrin->dest.ssa.num_components == res->num_components); + nir_ssa_def_rewrite_uses(&intrin->dest.ssa, res); + nir_instr_remove(&intrin->instr); + + return true; +} + +static bool +lower_get_ssbo_size(nir_builder *b, nir_intrinsic_instr *intrin, + const struct apply_descriptors_ctx *ctx) +{ + b->cursor = nir_before_instr(&intrin->instr); + + nir_address_format addr_format = + addr_format_for_desc_type(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ctx); + + assert(intrin->src[0].is_ssa); + nir_ssa_def *desc = build_buffer_addr_for_res_index(b, intrin->src[0].ssa, + addr_format, ctx); + + switch (addr_format) { + case nir_address_format_64bit_bounded_global: + case nir_address_format_64bit_global_32bit_offset: { + nir_ssa_def *size = nir_channel(b, desc, 2); + nir_ssa_def_rewrite_uses(&intrin->dest.ssa, size); + nir_instr_remove(&intrin->instr); + break; + } + + default: + unreachable("Unsupported address format"); + } + + return true; +} + static void get_resource_deref_binding(nir_deref_instr *deref, uint32_t *set, uint32_t *binding, @@ -120,54 +395,6 @@ lower_tex(nir_builder *b, nir_tex_instr *tex, return progress; } -static void -lower_vulkan_resource_index(nir_builder *b, nir_intrinsic_instr *intr, - const struct apply_descriptors_ctx *ctx) -{ - nir_ssa_def *vulkan_idx = intr->src[0].ssa; - - unsigned set = nir_intrinsic_desc_set(intr); - unsigned binding = nir_intrinsic_binding(intr); - struct panvk_descriptor_set_layout *set_layout = ctx->layout->sets[set].layout; - struct panvk_descriptor_set_binding_layout *binding_layout = - &set_layout->bindings[binding]; - unsigned base; - - switch (binding_layout->type) { - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - base = panvk_pipeline_layout_ubo_index(ctx->layout, set, binding, 0); - break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - base = binding_layout->ssbo_idx + ctx->layout->sets[set].ssbo_offset; - break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - base = binding_layout->dyn_ssbo_idx + ctx->layout->num_ssbos + - ctx->layout->sets[set].dyn_ssbo_offset; - break; - default: - unreachable("Invalid descriptor type"); - break; - } - - b->cursor = nir_before_instr(&intr->instr); - nir_ssa_def *idx = nir_iadd(b, nir_imm_int(b, base), vulkan_idx); - nir_ssa_def_rewrite_uses(&intr->dest.ssa, idx); - nir_instr_remove(&intr->instr); -} - -static void -lower_load_vulkan_descriptor(nir_builder *b, nir_intrinsic_instr *intrin) -{ - /* Loading the descriptor happens as part of the load/store instruction so - * this is a no-op. - */ - b->cursor = nir_before_instr(&intrin->instr); - nir_ssa_def *val = nir_vec2(b, intrin->src[0].ssa, nir_imm_int(b, 0)); - nir_ssa_def_rewrite_uses(&intrin->dest.ssa, val); - nir_instr_remove(&intrin->instr); -} - static nir_ssa_def * get_img_index(nir_builder *b, nir_deref_instr *deref, const struct apply_descriptors_ctx *ctx) @@ -199,11 +426,11 @@ lower_intrinsic(nir_builder *b, nir_intrinsic_instr *intr, { switch (intr->intrinsic) { case nir_intrinsic_vulkan_resource_index: - lower_vulkan_resource_index(b, intr, ctx); - return true; + case nir_intrinsic_vulkan_resource_reindex: case nir_intrinsic_load_vulkan_descriptor: - lower_load_vulkan_descriptor(b, intr); - return true; + return lower_res_intrinsic(b, intr, ctx); + case nir_intrinsic_get_ssbo_size: + return lower_get_ssbo_size(b, intr, ctx); case nir_intrinsic_image_deref_store: case nir_intrinsic_image_deref_load: case nir_intrinsic_image_deref_atomic_add: @@ -257,6 +484,9 @@ panvk_per_arch(nir_lower_descriptors)(nir_shader *nir, { struct apply_descriptors_ctx ctx = { .layout = layout, + .desc_addr_format = nir_address_format_32bit_index_offset, + .ubo_addr_format = nir_address_format_32bit_index_offset, + .ssbo_addr_format = nir_address_format_64bit_global_32bit_offset, }; bool progress = nir_shader_instructions_pass(nir, lower_descriptors_instr, diff --git a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c index 4994582fa8c..f78bf6e655f 100644 --- a/src/panfrost/vulkan/panvk_vX_shader.c +++ b/src/panfrost/vulkan/panvk_vX_shader.c @@ -66,15 +66,10 @@ panvk_init_sysvals(struct panfrost_sysvals *sysvals, INIT_SYSVAL(vertex_instance_offsets, VERTEX_INSTANCE_OFFSETS); INIT_SYSVAL(blend_constants, BLEND_CONSTANTS); } - - int ssbo0_slot = SYSVAL_SLOT(ssbos); - for (unsigned i = 0; i < MAX_SSBOS; i++) - sysvals->sysvals[ssbo0_slot + i] = PAN_SYSVAL(SSBO, i); + sysvals->sysval_count = SYSVAL_SLOT(dyn_ssbos); #undef SYSVAL_SLOT #undef INIT_SYSVAL - - sysvals->sysval_count = sizeof(struct panvk_sysvals) / 16; } static bool @@ -347,7 +342,7 @@ panvk_per_arch(shader_create)(struct panvk_device *dev, const struct spirv_to_nir_options spirv_options = { .caps = { false }, .ubo_addr_format = nir_address_format_32bit_index_offset, - .ssbo_addr_format = nir_address_format_32bit_index_offset, + .ssbo_addr_format = nir_address_format_64bit_global_32bit_offset, }; nir_shader *nir; @@ -397,9 +392,13 @@ panvk_per_arch(shader_create)(struct panvk_device *dev, panvk_lower_blend(pdev, nir, &inputs, blend_state, static_blend_constants); } - NIR_PASS_V(nir, nir_lower_explicit_io, - nir_var_mem_ubo | nir_var_mem_ssbo, + NIR_PASS_V(nir, panvk_per_arch(nir_lower_descriptors), + dev, layout, &shader->has_img_access); + + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ubo, nir_address_format_32bit_index_offset); + NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ssbo, + spirv_options.ssbo_addr_format); NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const, nir_address_format_32bit_offset); @@ -436,9 +435,6 @@ panvk_per_arch(shader_create)(struct panvk_device *dev, */ NIR_PASS_V(nir, nir_lower_global_vars_to_local); - NIR_PASS_V(nir, panvk_per_arch(nir_lower_descriptors), - dev, layout, &shader->has_img_access); - nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); if (unlikely(dev->physical_device->instance->debug_flags & PANVK_DEBUG_NIR)) { fprintf(stderr, "translated nir:\n");