zink: implement descriptor buffer handling of bindless texture
pretty straightforward, just lazily allocating the context-based db and then writing updates to it on-demand Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21085>
This commit is contained in:

committed by
Marge Bot

parent
6b49dec675
commit
99ba529fee
@@ -414,13 +414,20 @@ zink_batch_bind_db(struct zink_context *ctx)
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
struct zink_batch *batch = &ctx->batch;
|
||||
unsigned count = screen->compact_descriptors ? 3 : 5;
|
||||
VkDescriptorBufferBindingInfoEXT infos[ZINK_DESCRIPTOR_NON_BINDLESS_TYPES] = {0};
|
||||
VkDescriptorBufferBindingInfoEXT infos[ZINK_DESCRIPTOR_ALL_TYPES] = {0};
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
infos[i].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT;
|
||||
infos[i].address = batch->state->dd.db[i]->obj->bda;
|
||||
infos[i].usage = batch->state->dd.db[i]->obj->vkusage;
|
||||
assert(infos[i].usage);
|
||||
}
|
||||
if (ctx->dd.bindless_layout) {
|
||||
infos[ZINK_DESCRIPTOR_BINDLESS].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT;
|
||||
infos[ZINK_DESCRIPTOR_BINDLESS].address = ctx->dd.db.bindless_db->obj->bda;
|
||||
infos[ZINK_DESCRIPTOR_BINDLESS].usage = ctx->dd.db.bindless_db->obj->vkusage;
|
||||
assert(infos[ZINK_DESCRIPTOR_BINDLESS].usage);
|
||||
count++;
|
||||
}
|
||||
VKSCR(CmdBindDescriptorBuffersEXT)(batch->state->cmdbuf, count, infos);
|
||||
batch->state->db_bound = true;
|
||||
}
|
||||
|
@@ -154,7 +154,10 @@ zink_context_destroy(struct pipe_context *pctx)
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
util_idalloc_fini(&ctx->di.bindless[i].tex_slots);
|
||||
util_idalloc_fini(&ctx->di.bindless[i].img_slots);
|
||||
free(ctx->di.bindless[i].t.buffer_infos);
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
|
||||
free(ctx->di.bindless[i].db.buffer_infos);
|
||||
else
|
||||
free(ctx->di.bindless[i].t.buffer_infos);
|
||||
free(ctx->di.bindless[i].img_infos);
|
||||
util_dynarray_fini(&ctx->di.bindless[i].updates);
|
||||
util_dynarray_fini(&ctx->di.bindless[i].resident);
|
||||
@@ -2027,10 +2030,18 @@ zink_create_texture_handle(struct pipe_context *pctx, struct pipe_sampler_view *
|
||||
}
|
||||
|
||||
bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
|
||||
if (res->base.b.target == PIPE_BUFFER)
|
||||
zink_buffer_view_reference(zink_screen(pctx->screen), &bd->ds.bufferview, sv->buffer_view);
|
||||
else
|
||||
if (res->base.b.target == PIPE_BUFFER) {
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
pipe_resource_reference(&bd->ds.db.pres, view->texture);
|
||||
bd->ds.db.format = view->format;
|
||||
bd->ds.db.offset = view->u.buf.offset;
|
||||
bd->ds.db.size = view->u.buf.size;
|
||||
} else {
|
||||
zink_buffer_view_reference(zink_screen(pctx->screen), &bd->ds.bufferview, sv->buffer_view);
|
||||
}
|
||||
} else {
|
||||
zink_surface_reference(zink_screen(pctx->screen), &bd->ds.surface, sv->image_view);
|
||||
}
|
||||
uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].tex_slots);
|
||||
if (bd->ds.is_buffer)
|
||||
handle += ZINK_MAX_BINDLESS_HANDLES;
|
||||
@@ -2053,7 +2064,11 @@ zink_delete_texture_handle(struct pipe_context *pctx, uint64_t handle)
|
||||
util_dynarray_append(&ctx->batch.state->bindless_releases[0], uint32_t, h);
|
||||
|
||||
if (ds->is_buffer) {
|
||||
zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
pipe_resource_reference(&ds->db.pres, NULL);
|
||||
} else {
|
||||
zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
|
||||
}
|
||||
} else {
|
||||
zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
|
||||
pctx->delete_sampler_state(pctx, bd->sampler);
|
||||
@@ -2064,6 +2079,9 @@ zink_delete_texture_handle(struct pipe_context *pctx, uint64_t handle)
|
||||
static void
|
||||
rebind_bindless_bufferview(struct zink_context *ctx, struct zink_resource *res, struct zink_descriptor_surface *ds)
|
||||
{
|
||||
/* descriptor buffer is unaffected by this */
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
|
||||
return;
|
||||
/* if this resource has been rebound while it wasn't set here,
|
||||
* its backing resource will have changed and thus we need to update
|
||||
* the bufferview
|
||||
@@ -2081,17 +2099,27 @@ zero_bindless_descriptor(struct zink_context *ctx, uint32_t handle, bool is_buff
|
||||
{
|
||||
if (likely(zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor)) {
|
||||
if (is_buffer) {
|
||||
VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
|
||||
*bv = VK_NULL_HANDLE;
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
ctx->di.bindless[is_image].db.buffer_infos[handle].address = 0;
|
||||
ctx->di.bindless[is_image].db.buffer_infos[handle].range = 0;
|
||||
} else {
|
||||
VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
|
||||
*bv = VK_NULL_HANDLE;
|
||||
}
|
||||
} else {
|
||||
VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
|
||||
memset(ii, 0, sizeof(*ii));
|
||||
}
|
||||
} else {
|
||||
if (is_buffer) {
|
||||
VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
|
||||
struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
|
||||
*bv = null_bufferview->buffer_view;
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
ctx->di.bindless[is_image].db.buffer_infos[handle].address = zink_resource(ctx->dummy_bufferview->pres)->obj->bda;
|
||||
ctx->di.bindless[is_image].db.buffer_infos[handle].range = 1;
|
||||
} else {
|
||||
VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
|
||||
struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
|
||||
*bv = null_bufferview->buffer_view;
|
||||
}
|
||||
} else {
|
||||
struct zink_surface *null_surface = zink_get_dummy_surface(ctx, 0);
|
||||
VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
|
||||
@@ -2119,10 +2147,16 @@ zink_make_texture_handle_resident(struct pipe_context *pctx, uint64_t handle, bo
|
||||
update_res_bind_count(ctx, res, true, false);
|
||||
res->bindless[0]++;
|
||||
if (is_buffer) {
|
||||
if (ds->bufferview->bvci.buffer != res->obj->buffer)
|
||||
rebind_bindless_bufferview(ctx, res, ds);
|
||||
VkBufferView *bv = &ctx->di.bindless[0].t.buffer_infos[handle];
|
||||
*bv = ds->bufferview->buffer_view;
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
ctx->di.bindless[0].db.buffer_infos[handle].address = res->obj->bda + ds->db.offset;
|
||||
ctx->di.bindless[0].db.buffer_infos[handle].range = ds->db.size;
|
||||
ctx->di.bindless[0].db.buffer_infos[handle].format = ds->db.format;
|
||||
} else {
|
||||
if (ds->bufferview->bvci.buffer != res->obj->buffer)
|
||||
rebind_bindless_bufferview(ctx, res, ds);
|
||||
VkBufferView *bv = &ctx->di.bindless[0].t.buffer_infos[handle];
|
||||
*bv = ds->bufferview->buffer_view;
|
||||
}
|
||||
zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
zink_batch_resource_usage_set(&ctx->batch, res, false, true);
|
||||
} else {
|
||||
@@ -2171,7 +2205,14 @@ zink_create_image_handle(struct pipe_context *pctx, const struct pipe_image_view
|
||||
|
||||
bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
|
||||
if (res->base.b.target == PIPE_BUFFER)
|
||||
bd->ds.bufferview = create_image_bufferview(ctx, view);
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
pipe_resource_reference(&bd->ds.db.pres, view->resource);
|
||||
bd->ds.db.format = view->format;
|
||||
bd->ds.db.offset = view->u.buf.offset;
|
||||
bd->ds.db.size = view->u.buf.size;
|
||||
} else {
|
||||
bd->ds.bufferview = create_image_bufferview(ctx, view);
|
||||
}
|
||||
else
|
||||
bd->ds.surface = create_image_surface(ctx, view, false);
|
||||
uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].img_slots);
|
||||
@@ -2195,7 +2236,11 @@ zink_delete_image_handle(struct pipe_context *pctx, uint64_t handle)
|
||||
util_dynarray_append(&ctx->batch.state->bindless_releases[1], uint32_t, h);
|
||||
|
||||
if (ds->is_buffer) {
|
||||
zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
pipe_resource_reference(&ds->db.pres, NULL);
|
||||
} else {
|
||||
zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
|
||||
}
|
||||
} else {
|
||||
zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
|
||||
}
|
||||
@@ -2236,10 +2281,16 @@ zink_make_image_handle_resident(struct pipe_context *pctx, uint64_t handle, unsi
|
||||
res->image_bind_count[1]++;
|
||||
res->bindless[1]++;
|
||||
if (is_buffer) {
|
||||
if (ds->bufferview->bvci.buffer != res->obj->buffer)
|
||||
rebind_bindless_bufferview(ctx, res, ds);
|
||||
VkBufferView *bv = &ctx->di.bindless[1].t.buffer_infos[handle];
|
||||
*bv = ds->bufferview->buffer_view;
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
ctx->di.bindless[0].db.buffer_infos[handle].address = res->obj->bda + ds->db.offset;
|
||||
ctx->di.bindless[0].db.buffer_infos[handle].range = ds->db.size;
|
||||
ctx->di.bindless[0].db.buffer_infos[handle].format = ds->db.format;
|
||||
} else {
|
||||
if (ds->bufferview->bvci.buffer != res->obj->buffer)
|
||||
rebind_bindless_bufferview(ctx, res, ds);
|
||||
VkBufferView *bv = &ctx->di.bindless[1].t.buffer_infos[handle];
|
||||
*bv = ds->bufferview->buffer_view;
|
||||
}
|
||||
zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, access, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
zink_batch_resource_usage_set(&ctx->batch, res, zink_resource_access_is_write(access), true);
|
||||
} else {
|
||||
@@ -5044,7 +5095,15 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||
util_idalloc_alloc(&ctx->di.bindless[i].tex_slots);
|
||||
util_idalloc_init(&ctx->di.bindless[i].img_slots, ZINK_MAX_BINDLESS_HANDLES);
|
||||
util_idalloc_alloc(&ctx->di.bindless[i].img_slots);
|
||||
ctx->di.bindless[i].t.buffer_infos = malloc(sizeof(VkBufferView) * ZINK_MAX_BINDLESS_HANDLES);
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
ctx->di.bindless[i].db.buffer_infos = malloc(sizeof(VkDescriptorAddressInfoEXT) * ZINK_MAX_BINDLESS_HANDLES);
|
||||
for (unsigned j = 0; j < ZINK_MAX_BINDLESS_HANDLES; j++) {
|
||||
ctx->di.bindless[i].db.buffer_infos[j].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT;
|
||||
ctx->di.bindless[i].db.buffer_infos[j].pNext = NULL;
|
||||
}
|
||||
} else {
|
||||
ctx->di.bindless[i].t.buffer_infos = malloc(sizeof(VkBufferView) * ZINK_MAX_BINDLESS_HANDLES);
|
||||
}
|
||||
ctx->di.bindless[i].img_infos = malloc(sizeof(VkDescriptorImageInfo) * ZINK_MAX_BINDLESS_HANDLES);
|
||||
util_dynarray_init(&ctx->di.bindless[i].updates, NULL);
|
||||
util_dynarray_init(&ctx->di.bindless[i].resident, NULL);
|
||||
|
@@ -53,7 +53,9 @@ struct zink_vertex_elements_state;
|
||||
static inline struct zink_resource *
|
||||
zink_descriptor_surface_resource(struct zink_descriptor_surface *ds)
|
||||
{
|
||||
return ds->is_buffer ? (struct zink_resource*)ds->bufferview->pres : (struct zink_resource*)ds->surface->base.texture;
|
||||
return ds->is_buffer ?
|
||||
zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB ? (struct zink_resource*)ds->bufferview->pres : zink_resource(ds->db.pres) :
|
||||
(struct zink_resource*)ds->surface->base.texture;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
@@ -1118,6 +1118,9 @@ zink_descriptors_update(struct zink_context *ctx, bool is_compute)
|
||||
*/
|
||||
uint8_t bind_sets = bs->dd.pg[is_compute] && bs->dd.compat_id[is_compute] == pg->compat_id ? 0 : pg->dd.binding_usage;
|
||||
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB && !bs->db_bound)
|
||||
zink_batch_bind_db(ctx);
|
||||
|
||||
if (pg->dd.push_usage && (ctx->dd.push_state_changed[is_compute] || bind_sets)) {
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
uint32_t index = ZINK_DESCRIPTOR_TYPE_UNIFORMS;
|
||||
@@ -1184,9 +1187,20 @@ zink_descriptors_update(struct zink_context *ctx, bool is_compute)
|
||||
zink_descriptors_update_masked(ctx, is_compute, changed_sets, bind_sets);
|
||||
/* bindless descriptors are context-based and get updated elsewhere */
|
||||
if (pg->dd.bindless && unlikely(!ctx->dd.bindless_bound)) {
|
||||
VKCTX(CmdBindDescriptorSets)(ctx->batch.state->cmdbuf, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pg->layout, ZINK_DESCRIPTOR_BINDLESS, 1, &ctx->dd.bindless_set,
|
||||
0, NULL);
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
unsigned index = ZINK_DESCRIPTOR_BINDLESS;
|
||||
VkDeviceSize offset = 0;
|
||||
VKCTX(CmdSetDescriptorBufferOffsetsEXT)(bs->cmdbuf,
|
||||
is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pg->layout,
|
||||
ZINK_DESCRIPTOR_BINDLESS, 1,
|
||||
&index,
|
||||
&offset);
|
||||
} else {
|
||||
VKCTX(CmdBindDescriptorSets)(ctx->batch.state->cmdbuf, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pg->layout, ZINK_DESCRIPTOR_BINDLESS, 1, &ctx->dd.t.bindless_set,
|
||||
0, NULL);
|
||||
}
|
||||
ctx->dd.bindless_bound = true;
|
||||
}
|
||||
bs->dd.pg[is_compute] = pg;
|
||||
@@ -1473,7 +1487,7 @@ type_from_bindless_index(unsigned idx)
|
||||
void
|
||||
zink_descriptors_init_bindless(struct zink_context *ctx)
|
||||
{
|
||||
if (ctx->dd.bindless_set)
|
||||
if (ctx->dd.bindless_layout)
|
||||
return;
|
||||
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
@@ -1485,12 +1499,17 @@ zink_descriptors_init_bindless(struct zink_context *ctx)
|
||||
VkDescriptorSetLayoutBindingFlagsCreateInfo fci = {0};
|
||||
VkDescriptorBindingFlags flags[4];
|
||||
dcslci.pNext = &fci;
|
||||
dcslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
|
||||
dcslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
|
||||
else
|
||||
dcslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
|
||||
fci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
|
||||
fci.bindingCount = num_bindings;
|
||||
fci.pBindingFlags = flags;
|
||||
for (unsigned i = 0; i < num_bindings; i++) {
|
||||
flags[i] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT;
|
||||
flags[i] = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT;
|
||||
if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB)
|
||||
flags[i] |= VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT;
|
||||
}
|
||||
/* there is exactly 1 bindless descriptor set per context, and it has 4 bindings, 1 for each descriptor type */
|
||||
for (unsigned i = 0; i < num_bindings; i++) {
|
||||
@@ -1509,24 +1528,39 @@ zink_descriptors_init_bindless(struct zink_context *ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
VkDescriptorPoolCreateInfo dpci = {0};
|
||||
VkDescriptorPoolSize sizes[4];
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
sizes[i].type = type_from_bindless_index(i);
|
||||
sizes[i].descriptorCount = ZINK_MAX_BINDLESS_HANDLES;
|
||||
}
|
||||
dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
dpci.pPoolSizes = sizes;
|
||||
dpci.poolSizeCount = 4;
|
||||
dpci.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
|
||||
dpci.maxSets = 1;
|
||||
result = VKSCR(CreateDescriptorPool)(screen->dev, &dpci, 0, &ctx->dd.bindless_pool);
|
||||
if (result != VK_SUCCESS) {
|
||||
mesa_loge("ZINK: vkCreateDescriptorPool failed (%s)", vk_Result_to_str(result));
|
||||
return;
|
||||
}
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
unsigned bind = ZINK_BIND_RESOURCE_DESCRIPTOR | ZINK_BIND_SAMPLER_DESCRIPTOR;
|
||||
VkDeviceSize size;
|
||||
VKSCR(GetDescriptorSetLayoutSizeEXT)(screen->dev, ctx->dd.bindless_layout, &size);
|
||||
struct pipe_resource *pres = pipe_buffer_create(&screen->base, bind, 0, size);
|
||||
ctx->dd.db.bindless_db = zink_resource(pres);
|
||||
ctx->dd.db.bindless_db_map = pipe_buffer_map(&ctx->base, pres, PIPE_MAP_READ | PIPE_MAP_WRITE, &ctx->dd.db.bindless_db_xfer);
|
||||
zink_batch_bind_db(ctx);
|
||||
for (unsigned i = 0; i < num_bindings; i++) {
|
||||
VkDeviceSize offset;
|
||||
VKSCR(GetDescriptorSetLayoutBindingOffsetEXT)(screen->dev, ctx->dd.bindless_layout, i, &offset);
|
||||
ctx->dd.db.db_offsets[i] = offset;
|
||||
}
|
||||
} else {
|
||||
VkDescriptorPoolCreateInfo dpci = {0};
|
||||
VkDescriptorPoolSize sizes[4];
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
sizes[i].type = type_from_bindless_index(i);
|
||||
sizes[i].descriptorCount = ZINK_MAX_BINDLESS_HANDLES;
|
||||
}
|
||||
dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
dpci.pPoolSizes = sizes;
|
||||
dpci.poolSizeCount = 4;
|
||||
dpci.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
|
||||
dpci.maxSets = 1;
|
||||
result = VKSCR(CreateDescriptorPool)(screen->dev, &dpci, 0, &ctx->dd.t.bindless_pool);
|
||||
if (result != VK_SUCCESS) {
|
||||
mesa_loge("ZINK: vkCreateDescriptorPool failed (%s)", vk_Result_to_str(result));
|
||||
return;
|
||||
}
|
||||
|
||||
zink_descriptor_util_alloc_sets(screen, ctx->dd.bindless_layout, ctx->dd.bindless_pool, &ctx->dd.bindless_set, 1);
|
||||
zink_descriptor_util_alloc_sets(screen, ctx->dd.bindless_layout, ctx->dd.t.bindless_pool, &ctx->dd.t.bindless_set, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* called on context destroy */
|
||||
@@ -1536,8 +1570,17 @@ zink_descriptors_deinit_bindless(struct zink_context *ctx)
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
if (ctx->dd.bindless_layout)
|
||||
VKSCR(DestroyDescriptorSetLayout)(screen->dev, ctx->dd.bindless_layout, NULL);
|
||||
if (ctx->dd.bindless_pool)
|
||||
VKSCR(DestroyDescriptorPool)(screen->dev, ctx->dd.bindless_pool, NULL);
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
if (ctx->dd.db.bindless_db_xfer)
|
||||
pipe_buffer_unmap(&ctx->base, ctx->dd.db.bindless_db_xfer);
|
||||
if (ctx->dd.db.bindless_db) {
|
||||
struct pipe_resource *pres = &ctx->dd.db.bindless_db->base.b;
|
||||
pipe_resource_reference(&pres, NULL);
|
||||
}
|
||||
} else {
|
||||
if (ctx->dd.t.bindless_pool)
|
||||
VKSCR(DestroyDescriptorPool)(screen->dev, ctx->dd.t.bindless_pool, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* entrypoint for updating bindless descriptors: called from draw/dispatch */
|
||||
@@ -1545,6 +1588,9 @@ void
|
||||
zink_descriptors_update_bindless(struct zink_context *ctx)
|
||||
{
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
VkDescriptorGetInfoEXT info;
|
||||
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT;
|
||||
info.pNext = NULL;
|
||||
/* bindless descriptors are split between images and buffers */
|
||||
for (unsigned i = 0; i < 2; i++) {
|
||||
if (!ctx->di.bindless_dirty[i])
|
||||
@@ -1553,21 +1599,53 @@ zink_descriptors_update_bindless(struct zink_context *ctx)
|
||||
/* updates are tracked by handle */
|
||||
uint32_t handle = util_dynarray_pop(&ctx->di.bindless[i].updates, uint32_t);
|
||||
bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
|
||||
VkWriteDescriptorSet wd;
|
||||
wd.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
wd.pNext = NULL;
|
||||
wd.dstSet = ctx->dd.bindless_set;
|
||||
wd.dstBinding = is_buffer ? i * 2 + 1: i * 2;
|
||||
/* buffer handle ids are offset by ZINK_MAX_BINDLESS_HANDLES for internal tracking */
|
||||
wd.dstArrayElement = is_buffer ? handle - ZINK_MAX_BINDLESS_HANDLES : handle;
|
||||
wd.descriptorCount = 1;
|
||||
wd.descriptorType = type_from_bindless_index(wd.dstBinding);
|
||||
if (is_buffer)
|
||||
wd.pTexelBufferView = &ctx->di.bindless[i].t.buffer_infos[wd.dstArrayElement];
|
||||
else
|
||||
wd.pImageInfo = &ctx->di.bindless[i].img_infos[handle];
|
||||
/* this sucks, but sets must be singly updated to be handled correctly */
|
||||
VKSCR(UpdateDescriptorSets)(screen->dev, 1, &wd, 0, NULL);
|
||||
unsigned binding = i * 2 + !!is_buffer;
|
||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||
if (is_buffer) {
|
||||
size_t size = i ? screen->info.db_props.robustStorageTexelBufferDescriptorSize : screen->info.db_props.robustUniformTexelBufferDescriptorSize;
|
||||
info.type = i ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
|
||||
info.data.pSampler = (void*)&ctx->di.bindless[i].db.buffer_infos[handle];
|
||||
VKSCR(GetDescriptorEXT)(screen->dev, &info, size, ctx->dd.db.bindless_db_map + ctx->dd.db.db_offsets[binding] + handle * size);
|
||||
} else {
|
||||
info.type = i ? VK_DESCRIPTOR_TYPE_STORAGE_IMAGE : VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
if (screen->info.db_props.combinedImageSamplerDescriptorSingleArray || i) {
|
||||
size_t size = i ? screen->info.db_props.storageImageDescriptorSize : screen->info.db_props.combinedImageSamplerDescriptorSize;
|
||||
info.data.pSampler = (void*)&ctx->di.bindless[i].img_infos[handle];
|
||||
VKSCR(GetDescriptorEXT)(screen->dev, &info, size, ctx->dd.db.bindless_db_map + ctx->dd.db.db_offsets[binding] + handle * size);
|
||||
} else {
|
||||
/* drivers that don't support combinedImageSamplerDescriptorSingleArray must have sampler arrays written in memory as
|
||||
*
|
||||
* | array_of_samplers[] | array_of_sampled_images[] |
|
||||
*
|
||||
* which means each descriptor's data must be split
|
||||
*/
|
||||
uint8_t buf[1024];
|
||||
size_t size = screen->info.db_props.combinedImageSamplerDescriptorSize;
|
||||
info.data.pSampler = (void*)&ctx->di.bindless[i].img_infos[handle];
|
||||
VKSCR(GetDescriptorEXT)(screen->dev, &info, size, buf);
|
||||
memcpy(ctx->dd.db.bindless_db_map + ctx->dd.db.db_offsets[binding] + handle * screen->info.db_props.samplerDescriptorSize, buf, screen->info.db_props.samplerDescriptorSize);
|
||||
size_t offset = screen->info.db_props.samplerDescriptorSize * ZINK_MAX_BINDLESS_HANDLES;
|
||||
offset += handle * screen->info.db_props.sampledImageDescriptorSize;
|
||||
memcpy(ctx->dd.db.bindless_db_map + ctx->dd.db.db_offsets[binding] + offset, &buf[screen->info.db_props.samplerDescriptorSize], screen->info.db_props.sampledImageDescriptorSize);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
VkWriteDescriptorSet wd;
|
||||
wd.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
wd.pNext = NULL;
|
||||
wd.dstSet = ctx->dd.t.bindless_set;
|
||||
wd.dstBinding = binding;
|
||||
/* buffer handle ids are offset by ZINK_MAX_BINDLESS_HANDLES for internal tracking */
|
||||
wd.dstArrayElement = is_buffer ? handle - ZINK_MAX_BINDLESS_HANDLES : handle;
|
||||
wd.descriptorCount = 1;
|
||||
wd.descriptorType = type_from_bindless_index(wd.dstBinding);
|
||||
if (is_buffer)
|
||||
wd.pTexelBufferView = &ctx->di.bindless[i].t.buffer_infos[wd.dstArrayElement];
|
||||
else
|
||||
wd.pImageInfo = &ctx->di.bindless[i].img_infos[handle];
|
||||
/* this sucks, but sets must be singly updated to be handled correctly */
|
||||
VKSCR(UpdateDescriptorSets)(screen->dev, 1, &wd, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->di.any_bindless_dirty = 0;
|
||||
|
@@ -394,8 +394,18 @@ struct zink_descriptor_data {
|
||||
struct zink_descriptor_layout *dummy_dsl;
|
||||
|
||||
VkDescriptorSetLayout bindless_layout;
|
||||
VkDescriptorPool bindless_pool;
|
||||
VkDescriptorSet bindless_set;
|
||||
union {
|
||||
struct {
|
||||
VkDescriptorPool bindless_pool;
|
||||
VkDescriptorSet bindless_set;
|
||||
} t;
|
||||
struct {
|
||||
struct zink_resource *bindless_db;
|
||||
uint8_t *bindless_db_map;
|
||||
struct pipe_transfer *bindless_db_xfer;
|
||||
uint32_t db_offsets[4];
|
||||
} db;
|
||||
};
|
||||
|
||||
struct zink_program *pg[2]; //gfx, compute
|
||||
|
||||
@@ -1510,11 +1520,18 @@ struct zink_viewport_state {
|
||||
uint8_t num_viewports;
|
||||
};
|
||||
|
||||
struct zink_descriptor_db_info {
|
||||
unsigned offset;
|
||||
unsigned size;
|
||||
enum pipe_format format;
|
||||
struct pipe_resource *pres;
|
||||
};
|
||||
|
||||
struct zink_descriptor_surface {
|
||||
union {
|
||||
struct zink_surface *surface;
|
||||
struct zink_buffer_view *bufferview;
|
||||
struct zink_descriptor_db_info db;
|
||||
};
|
||||
bool is_buffer;
|
||||
};
|
||||
@@ -1735,6 +1752,9 @@ struct zink_context {
|
||||
struct {
|
||||
VkBufferView *buffer_infos; //tex, img
|
||||
} t;
|
||||
struct {
|
||||
VkDescriptorAddressInfoEXT *buffer_infos;
|
||||
} db;
|
||||
};
|
||||
VkDescriptorImageInfo *img_infos; //tex, img
|
||||
struct util_dynarray updates; //texture, img
|
||||
|
Reference in New Issue
Block a user