panvk: Put SSBO addresses in the descriptor buffer

Instead of storing SSBO pointers in the very limited sysval space, store
them in the UBO we've attached to the descriptor set.  This gives us a
virtually unlimited number of SSBOs.  Dynamic SSBOs still live in the
sysval space so we can update them as part of vkCmdBindDescriptorSets().
Also, the new code (based on the code in ANV) loads those SSBO addresses
in a way that never chases the deref chain back to the variable so we
should now be able to handle all of variable pointers.  The code as
written in this patch is a bit overly generic because it switches on
address modes a bit more than panvk needs but we ended up needing all
that flexibility in ANV so we may as well leave hooks for it in panvk.

Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16276>
This commit is contained in:
Jason Ekstrand
2022-04-27 17:58:03 -05:00
committed by Marge Bot
parent e265583ee1
commit a463c58e22
6 changed files with 327 additions and 117 deletions
+10 -22
View File
@@ -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)
+2 -7
View File
@@ -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);
+2 -8
View File
@@ -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 {
+23 -16
View File
@@ -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:
@@ -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,
+8 -12
View File
@@ -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");