mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 22:10:10 +01:00
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:
parent
6b49dec675
commit
99ba529fee
5 changed files with 231 additions and 65 deletions
|
|
@ -414,13 +414,20 @@ zink_batch_bind_db(struct zink_context *ctx)
|
||||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||||
struct zink_batch *batch = &ctx->batch;
|
struct zink_batch *batch = &ctx->batch;
|
||||||
unsigned count = screen->compact_descriptors ? 3 : 5;
|
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++) {
|
for (unsigned i = 0; i < count; i++) {
|
||||||
infos[i].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT;
|
infos[i].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT;
|
||||||
infos[i].address = batch->state->dd.db[i]->obj->bda;
|
infos[i].address = batch->state->dd.db[i]->obj->bda;
|
||||||
infos[i].usage = batch->state->dd.db[i]->obj->vkusage;
|
infos[i].usage = batch->state->dd.db[i]->obj->vkusage;
|
||||||
assert(infos[i].usage);
|
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);
|
VKSCR(CmdBindDescriptorBuffersEXT)(batch->state->cmdbuf, count, infos);
|
||||||
batch->state->db_bound = true;
|
batch->state->db_bound = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,9 @@ zink_context_destroy(struct pipe_context *pctx)
|
||||||
for (unsigned i = 0; i < 2; i++) {
|
for (unsigned i = 0; i < 2; i++) {
|
||||||
util_idalloc_fini(&ctx->di.bindless[i].tex_slots);
|
util_idalloc_fini(&ctx->di.bindless[i].tex_slots);
|
||||||
util_idalloc_fini(&ctx->di.bindless[i].img_slots);
|
util_idalloc_fini(&ctx->di.bindless[i].img_slots);
|
||||||
|
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].t.buffer_infos);
|
||||||
free(ctx->di.bindless[i].img_infos);
|
free(ctx->di.bindless[i].img_infos);
|
||||||
util_dynarray_fini(&ctx->di.bindless[i].updates);
|
util_dynarray_fini(&ctx->di.bindless[i].updates);
|
||||||
|
|
@ -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;
|
bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
|
||||||
if (res->base.b.target == PIPE_BUFFER)
|
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);
|
zink_buffer_view_reference(zink_screen(pctx->screen), &bd->ds.bufferview, sv->buffer_view);
|
||||||
else
|
}
|
||||||
|
} else {
|
||||||
zink_surface_reference(zink_screen(pctx->screen), &bd->ds.surface, sv->image_view);
|
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);
|
uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].tex_slots);
|
||||||
if (bd->ds.is_buffer)
|
if (bd->ds.is_buffer)
|
||||||
handle += ZINK_MAX_BINDLESS_HANDLES;
|
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);
|
util_dynarray_append(&ctx->batch.state->bindless_releases[0], uint32_t, h);
|
||||||
|
|
||||||
if (ds->is_buffer) {
|
if (ds->is_buffer) {
|
||||||
|
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);
|
zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
|
zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
|
||||||
pctx->delete_sampler_state(pctx, bd->sampler);
|
pctx->delete_sampler_state(pctx, bd->sampler);
|
||||||
|
|
@ -2064,6 +2079,9 @@ zink_delete_texture_handle(struct pipe_context *pctx, uint64_t handle)
|
||||||
static void
|
static void
|
||||||
rebind_bindless_bufferview(struct zink_context *ctx, struct zink_resource *res, struct zink_descriptor_surface *ds)
|
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,
|
/* if this resource has been rebound while it wasn't set here,
|
||||||
* its backing resource will have changed and thus we need to update
|
* its backing resource will have changed and thus we need to update
|
||||||
* the bufferview
|
* 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 (likely(zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor)) {
|
||||||
if (is_buffer) {
|
if (is_buffer) {
|
||||||
|
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];
|
VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
|
||||||
*bv = VK_NULL_HANDLE;
|
*bv = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
|
VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
|
||||||
memset(ii, 0, sizeof(*ii));
|
memset(ii, 0, sizeof(*ii));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_buffer) {
|
if (is_buffer) {
|
||||||
|
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];
|
VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
|
||||||
struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
|
struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
|
||||||
*bv = null_bufferview->buffer_view;
|
*bv = null_bufferview->buffer_view;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
struct zink_surface *null_surface = zink_get_dummy_surface(ctx, 0);
|
struct zink_surface *null_surface = zink_get_dummy_surface(ctx, 0);
|
||||||
VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
|
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);
|
update_res_bind_count(ctx, res, true, false);
|
||||||
res->bindless[0]++;
|
res->bindless[0]++;
|
||||||
if (is_buffer) {
|
if (is_buffer) {
|
||||||
|
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)
|
if (ds->bufferview->bvci.buffer != res->obj->buffer)
|
||||||
rebind_bindless_bufferview(ctx, res, ds);
|
rebind_bindless_bufferview(ctx, res, ds);
|
||||||
VkBufferView *bv = &ctx->di.bindless[0].t.buffer_infos[handle];
|
VkBufferView *bv = &ctx->di.bindless[0].t.buffer_infos[handle];
|
||||||
*bv = ds->bufferview->buffer_view;
|
*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_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);
|
zink_batch_resource_usage_set(&ctx->batch, res, false, true);
|
||||||
} else {
|
} 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;
|
bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
|
||||||
if (res->base.b.target == PIPE_BUFFER)
|
if (res->base.b.target == PIPE_BUFFER)
|
||||||
|
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);
|
bd->ds.bufferview = create_image_bufferview(ctx, view);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
bd->ds.surface = create_image_surface(ctx, view, false);
|
bd->ds.surface = create_image_surface(ctx, view, false);
|
||||||
uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].img_slots);
|
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);
|
util_dynarray_append(&ctx->batch.state->bindless_releases[1], uint32_t, h);
|
||||||
|
|
||||||
if (ds->is_buffer) {
|
if (ds->is_buffer) {
|
||||||
|
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);
|
zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
|
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->image_bind_count[1]++;
|
||||||
res->bindless[1]++;
|
res->bindless[1]++;
|
||||||
if (is_buffer) {
|
if (is_buffer) {
|
||||||
|
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)
|
if (ds->bufferview->bvci.buffer != res->obj->buffer)
|
||||||
rebind_bindless_bufferview(ctx, res, ds);
|
rebind_bindless_bufferview(ctx, res, ds);
|
||||||
VkBufferView *bv = &ctx->di.bindless[1].t.buffer_infos[handle];
|
VkBufferView *bv = &ctx->di.bindless[1].t.buffer_infos[handle];
|
||||||
*bv = ds->bufferview->buffer_view;
|
*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_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);
|
zink_batch_resource_usage_set(&ctx->batch, res, zink_resource_access_is_write(access), true);
|
||||||
} else {
|
} 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_alloc(&ctx->di.bindless[i].tex_slots);
|
||||||
util_idalloc_init(&ctx->di.bindless[i].img_slots, ZINK_MAX_BINDLESS_HANDLES);
|
util_idalloc_init(&ctx->di.bindless[i].img_slots, ZINK_MAX_BINDLESS_HANDLES);
|
||||||
util_idalloc_alloc(&ctx->di.bindless[i].img_slots);
|
util_idalloc_alloc(&ctx->di.bindless[i].img_slots);
|
||||||
|
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].t.buffer_infos = malloc(sizeof(VkBufferView) * ZINK_MAX_BINDLESS_HANDLES);
|
||||||
|
}
|
||||||
ctx->di.bindless[i].img_infos = malloc(sizeof(VkDescriptorImageInfo) * 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].updates, NULL);
|
||||||
util_dynarray_init(&ctx->di.bindless[i].resident, NULL);
|
util_dynarray_init(&ctx->di.bindless[i].resident, NULL);
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,9 @@ struct zink_vertex_elements_state;
|
||||||
static inline struct zink_resource *
|
static inline struct zink_resource *
|
||||||
zink_descriptor_surface_resource(struct zink_descriptor_surface *ds)
|
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
|
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;
|
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 (pg->dd.push_usage && (ctx->dd.push_state_changed[is_compute] || bind_sets)) {
|
||||||
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||||
uint32_t index = ZINK_DESCRIPTOR_TYPE_UNIFORMS;
|
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);
|
zink_descriptors_update_masked(ctx, is_compute, changed_sets, bind_sets);
|
||||||
/* bindless descriptors are context-based and get updated elsewhere */
|
/* bindless descriptors are context-based and get updated elsewhere */
|
||||||
if (pg->dd.bindless && unlikely(!ctx->dd.bindless_bound)) {
|
if (pg->dd.bindless && unlikely(!ctx->dd.bindless_bound)) {
|
||||||
|
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,
|
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,
|
pg->layout, ZINK_DESCRIPTOR_BINDLESS, 1, &ctx->dd.t.bindless_set,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
|
}
|
||||||
ctx->dd.bindless_bound = true;
|
ctx->dd.bindless_bound = true;
|
||||||
}
|
}
|
||||||
bs->dd.pg[is_compute] = pg;
|
bs->dd.pg[is_compute] = pg;
|
||||||
|
|
@ -1473,7 +1487,7 @@ type_from_bindless_index(unsigned idx)
|
||||||
void
|
void
|
||||||
zink_descriptors_init_bindless(struct zink_context *ctx)
|
zink_descriptors_init_bindless(struct zink_context *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->dd.bindless_set)
|
if (ctx->dd.bindless_layout)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||||
|
|
@ -1485,12 +1499,17 @@ zink_descriptors_init_bindless(struct zink_context *ctx)
|
||||||
VkDescriptorSetLayoutBindingFlagsCreateInfo fci = {0};
|
VkDescriptorSetLayoutBindingFlagsCreateInfo fci = {0};
|
||||||
VkDescriptorBindingFlags flags[4];
|
VkDescriptorBindingFlags flags[4];
|
||||||
dcslci.pNext = &fci;
|
dcslci.pNext = &fci;
|
||||||
|
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;
|
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.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
|
||||||
fci.bindingCount = num_bindings;
|
fci.bindingCount = num_bindings;
|
||||||
fci.pBindingFlags = flags;
|
fci.pBindingFlags = flags;
|
||||||
for (unsigned i = 0; i < num_bindings; i++) {
|
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 */
|
/* 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++) {
|
for (unsigned i = 0; i < num_bindings; i++) {
|
||||||
|
|
@ -1509,6 +1528,20 @@ zink_descriptors_init_bindless(struct zink_context *ctx)
|
||||||
return;
|
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};
|
VkDescriptorPoolCreateInfo dpci = {0};
|
||||||
VkDescriptorPoolSize sizes[4];
|
VkDescriptorPoolSize sizes[4];
|
||||||
for (unsigned i = 0; i < 4; i++) {
|
for (unsigned i = 0; i < 4; i++) {
|
||||||
|
|
@ -1520,13 +1553,14 @@ zink_descriptors_init_bindless(struct zink_context *ctx)
|
||||||
dpci.poolSizeCount = 4;
|
dpci.poolSizeCount = 4;
|
||||||
dpci.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
|
dpci.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
|
||||||
dpci.maxSets = 1;
|
dpci.maxSets = 1;
|
||||||
result = VKSCR(CreateDescriptorPool)(screen->dev, &dpci, 0, &ctx->dd.bindless_pool);
|
result = VKSCR(CreateDescriptorPool)(screen->dev, &dpci, 0, &ctx->dd.t.bindless_pool);
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) {
|
||||||
mesa_loge("ZINK: vkCreateDescriptorPool failed (%s)", vk_Result_to_str(result));
|
mesa_loge("ZINK: vkCreateDescriptorPool failed (%s)", vk_Result_to_str(result));
|
||||||
return;
|
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 */
|
/* 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);
|
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||||
if (ctx->dd.bindless_layout)
|
if (ctx->dd.bindless_layout)
|
||||||
VKSCR(DestroyDescriptorSetLayout)(screen->dev, ctx->dd.bindless_layout, NULL);
|
VKSCR(DestroyDescriptorSetLayout)(screen->dev, ctx->dd.bindless_layout, NULL);
|
||||||
if (ctx->dd.bindless_pool)
|
if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
|
||||||
VKSCR(DestroyDescriptorPool)(screen->dev, ctx->dd.bindless_pool, NULL);
|
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 */
|
/* entrypoint for updating bindless descriptors: called from draw/dispatch */
|
||||||
|
|
@ -1545,6 +1588,9 @@ void
|
||||||
zink_descriptors_update_bindless(struct zink_context *ctx)
|
zink_descriptors_update_bindless(struct zink_context *ctx)
|
||||||
{
|
{
|
||||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
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 */
|
/* bindless descriptors are split between images and buffers */
|
||||||
for (unsigned i = 0; i < 2; i++) {
|
for (unsigned i = 0; i < 2; i++) {
|
||||||
if (!ctx->di.bindless_dirty[i])
|
if (!ctx->di.bindless_dirty[i])
|
||||||
|
|
@ -1553,11 +1599,42 @@ zink_descriptors_update_bindless(struct zink_context *ctx)
|
||||||
/* updates are tracked by handle */
|
/* updates are tracked by handle */
|
||||||
uint32_t handle = util_dynarray_pop(&ctx->di.bindless[i].updates, uint32_t);
|
uint32_t handle = util_dynarray_pop(&ctx->di.bindless[i].updates, uint32_t);
|
||||||
bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
|
bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
|
||||||
|
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;
|
VkWriteDescriptorSet wd;
|
||||||
wd.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
wd.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
wd.pNext = NULL;
|
wd.pNext = NULL;
|
||||||
wd.dstSet = ctx->dd.bindless_set;
|
wd.dstSet = ctx->dd.t.bindless_set;
|
||||||
wd.dstBinding = is_buffer ? i * 2 + 1: i * 2;
|
wd.dstBinding = binding;
|
||||||
/* buffer handle ids are offset by ZINK_MAX_BINDLESS_HANDLES for internal tracking */
|
/* buffer handle ids are offset by ZINK_MAX_BINDLESS_HANDLES for internal tracking */
|
||||||
wd.dstArrayElement = is_buffer ? handle - ZINK_MAX_BINDLESS_HANDLES : handle;
|
wd.dstArrayElement = is_buffer ? handle - ZINK_MAX_BINDLESS_HANDLES : handle;
|
||||||
wd.descriptorCount = 1;
|
wd.descriptorCount = 1;
|
||||||
|
|
@ -1570,5 +1647,6 @@ zink_descriptors_update_bindless(struct zink_context *ctx)
|
||||||
VKSCR(UpdateDescriptorSets)(screen->dev, 1, &wd, 0, NULL);
|
VKSCR(UpdateDescriptorSets)(screen->dev, 1, &wd, 0, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ctx->di.any_bindless_dirty = 0;
|
ctx->di.any_bindless_dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -394,8 +394,18 @@ struct zink_descriptor_data {
|
||||||
struct zink_descriptor_layout *dummy_dsl;
|
struct zink_descriptor_layout *dummy_dsl;
|
||||||
|
|
||||||
VkDescriptorSetLayout bindless_layout;
|
VkDescriptorSetLayout bindless_layout;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
VkDescriptorPool bindless_pool;
|
VkDescriptorPool bindless_pool;
|
||||||
VkDescriptorSet bindless_set;
|
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
|
struct zink_program *pg[2]; //gfx, compute
|
||||||
|
|
||||||
|
|
@ -1510,11 +1520,18 @@ struct zink_viewport_state {
|
||||||
uint8_t num_viewports;
|
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 {
|
struct zink_descriptor_surface {
|
||||||
union {
|
union {
|
||||||
struct zink_surface *surface;
|
struct zink_surface *surface;
|
||||||
struct zink_buffer_view *bufferview;
|
struct zink_buffer_view *bufferview;
|
||||||
|
struct zink_descriptor_db_info db;
|
||||||
};
|
};
|
||||||
bool is_buffer;
|
bool is_buffer;
|
||||||
};
|
};
|
||||||
|
|
@ -1735,6 +1752,9 @@ struct zink_context {
|
||||||
struct {
|
struct {
|
||||||
VkBufferView *buffer_infos; //tex, img
|
VkBufferView *buffer_infos; //tex, img
|
||||||
} t;
|
} t;
|
||||||
|
struct {
|
||||||
|
VkDescriptorAddressInfoEXT *buffer_infos;
|
||||||
|
} db;
|
||||||
};
|
};
|
||||||
VkDescriptorImageInfo *img_infos; //tex, img
|
VkDescriptorImageInfo *img_infos; //tex, img
|
||||||
struct util_dynarray updates; //texture, img
|
struct util_dynarray updates; //texture, img
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue