zink: abstract descriptor functionality and make descriptor structs private

the first step to adding modular descriptor managers is to isolate the existing one
so that it can be easily swapped out

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10849>
This commit is contained in:
Mike Blumenkrantz 2021-04-01 15:18:51 -04:00
parent d54c21d279
commit 425642bec1
9 changed files with 196 additions and 104 deletions

View file

@ -54,16 +54,7 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs)
util_dynarray_clear(&bs->zombie_samplers);
util_dynarray_clear(&bs->persistent_resources);
set_foreach(bs->desc_sets, entry) {
struct zink_descriptor_set *zds = (void*)entry->key;
zink_batch_usage_unset(&zds->batch_uses, bs->fence.batch_id);
/* reset descriptor pools when no bs is using this program to avoid
* having some inactive program hogging a billion descriptors
*/
pipe_reference(&zds->reference, NULL);
zink_descriptor_set_recycle(zds);
_mesa_set_remove(bs->desc_sets, entry);
}
screen->batch_descriptor_reset(screen, bs);
set_foreach_remove(bs->programs, entry) {
struct zink_program *pg = (struct zink_program*)entry->key;
@ -146,8 +137,8 @@ zink_batch_state_destroy(struct zink_screen *screen, struct zink_batch_state *bs
_mesa_set_destroy(bs->surfaces, NULL);
_mesa_set_destroy(bs->bufferviews, NULL);
_mesa_set_destroy(bs->programs, NULL);
_mesa_set_destroy(bs->desc_sets, NULL);
_mesa_set_destroy(bs->active_queries, NULL);
screen->batch_descriptor_deinit(screen, bs);
simple_mtx_destroy(&bs->fence.resource_mtx);
ralloc_free(bs);
}
@ -190,11 +181,13 @@ create_batch_state(struct zink_context *ctx)
SET_CREATE_OR_FAIL(bs->surfaces);
SET_CREATE_OR_FAIL(bs->bufferviews);
SET_CREATE_OR_FAIL(bs->programs);
SET_CREATE_OR_FAIL(bs->desc_sets);
SET_CREATE_OR_FAIL(bs->active_queries);
util_dynarray_init(&bs->zombie_samplers, NULL);
util_dynarray_init(&bs->persistent_resources, NULL);
if (!screen->batch_descriptor_init(screen, bs))
goto fail;
VkFenceCreateInfo fci = {};
fci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
@ -649,15 +642,6 @@ zink_batch_reference_program(struct zink_batch *batch,
batch->has_work = true;
}
bool
zink_batch_add_desc_set(struct zink_batch *batch, struct zink_descriptor_set *zds)
{
if (!batch_ptr_add_usage(batch, batch->state->desc_sets, zds, &zds->batch_uses))
return false;
pipe_reference(NULL, &zds->reference);
return true;
}
void
zink_batch_reference_image_view(struct zink_batch *batch,
struct zink_image_view *image_view)

View file

@ -76,13 +76,14 @@ struct zink_batch_state {
struct set *surfaces;
struct set *bufferviews;
struct set *desc_sets;
struct util_dynarray persistent_resources;
struct util_dynarray zombie_samplers;
struct set *active_queries; /* zink_query objects which were active at some point in this batch */
struct zink_batch_descriptor_data *dd;
VkDeviceSize resource_size;
bool is_device_lost;
@ -173,9 +174,6 @@ zink_batch_state_reference(struct zink_screen *screen,
if (dst) *dst = src;
}
bool
zink_batch_add_desc_set(struct zink_batch *batch, struct zink_descriptor_set *zds);
void
zink_batch_usage_set(struct zink_batch_usage *u, uint32_t batch_id);
bool

View file

@ -134,7 +134,7 @@ zink_context_destroy(struct pipe_context *pctx)
_mesa_hash_table_destroy(ctx->render_pass_cache, NULL);
slab_destroy_child(&ctx->transfer_pool_unsync);
zink_descriptors_deinit(ctx);
screen->descriptors_deinit(ctx);
zink_descriptor_layouts_deinit(ctx);
@ -512,7 +512,7 @@ zink_bind_sampler_states(struct pipe_context *pctx,
for (unsigned i = 0; i < num_samplers; ++i) {
VkSampler *sampler = samplers[i];
if (ctx->sampler_states[shader][start_slot + i] != samplers[i])
zink_context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, 1);
zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, 1);
ctx->sampler_states[shader][start_slot + i] = sampler;
ctx->di.textures[shader][start_slot + i].sampler = sampler ? *sampler : VK_NULL_HANDLE;
}
@ -933,7 +933,7 @@ zink_set_constant_buffer(struct pipe_context *pctx,
update_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, index);
if (update)
zink_context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, index, 1);
zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, index, 1);
}
static void
@ -986,7 +986,7 @@ zink_set_shader_buffers(struct pipe_context *pctx,
if (start_slot + count >= ctx->di.num_ssbos[p_stage])
ctx->di.num_ssbos[p_stage] = max_slot + 1;
if (update)
zink_context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_SSBO, start_slot, count);
zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_SSBO, start_slot, count);
}
static void
@ -995,13 +995,13 @@ update_binds_for_samplerviews(struct zink_context *ctx, struct zink_resource *re
if (is_compute) {
u_foreach_bit(slot, res->sampler_binds[PIPE_SHADER_COMPUTE]) {
update_descriptor_state(ctx, PIPE_SHADER_COMPUTE, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot);
zink_context_invalidate_descriptor_state(ctx, PIPE_SHADER_COMPUTE, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, PIPE_SHADER_COMPUTE, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
}
} else {
for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
u_foreach_bit(slot, res->sampler_binds[i]) {
update_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot);
zink_context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
}
}
}
@ -1099,7 +1099,7 @@ zink_set_shader_images(struct pipe_context *pctx,
}
ctx->di.num_images[p_stage] = start_slot + count;
if (update)
zink_context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_IMAGE, start_slot, count);
zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_IMAGE, start_slot, count);
}
static void
@ -1183,7 +1183,7 @@ zink_set_sampler_views(struct pipe_context *pctx,
}
ctx->di.num_sampler_views[shader_type] = start_slot + num_views;
if (update)
zink_context_invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
}
static void
@ -2729,7 +2729,7 @@ rebind_buffer(struct zink_context *ctx, struct zink_resource *res)
break;
}
zink_context_invalidate_descriptor_state(ctx, shader, type, i, 1);
zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, type, i, 1);
update_descriptor_state(ctx, shader, type, i);
}
}
@ -2797,7 +2797,7 @@ rebind_image(struct zink_context *ctx, struct zink_resource *res)
struct pipe_surface *psurf = &sv->image_view->base;
zink_rebind_surface(ctx, &psurf);
sv->image_view = zink_surface(psurf);
zink_context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
update_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j);
}
}
@ -2806,7 +2806,7 @@ rebind_image(struct zink_context *ctx, struct zink_resource *res)
continue;
for (unsigned j = 0; j < ctx->di.num_images[i]; j++) {
if (zink_resource(ctx->image_views[i][j].base.resource) == res) {
zink_context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
update_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j);
}
}
@ -2938,19 +2938,6 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
if (!ctx->blitter)
goto fail;
vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &ctx->batch.queue);
if (screen->threaded && screen->max_queues > 1)
vkGetDeviceQueue(screen->dev, screen->gfx_queue, 1, &ctx->batch.thread_queue);
else
ctx->batch.thread_queue = ctx->batch.queue;
ctx->have_timelines = screen->info.have_KHR_timeline_semaphore;
simple_mtx_init(&ctx->batch_mtx, mtx_plain);
incr_curr_batch(ctx);
zink_start_batch(ctx, &ctx->batch);
if (!ctx->batch.state)
goto fail;
ctx->program_cache = _mesa_hash_table_create(NULL,
hash_gfx_program,
equals_gfx_program);
@ -2976,9 +2963,23 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
if (!zink_descriptor_layouts_init(ctx))
goto fail;
if (!zink_descriptors_init(ctx))
goto fail;
if (!screen->descriptors_init(ctx)) {
zink_screen_init_descriptor_funcs(screen, true);
if (!screen->descriptors_init(ctx))
goto fail;
}
vkGetDeviceQueue(screen->dev, screen->gfx_queue, 0, &ctx->batch.queue);
if (screen->threaded && screen->max_queues > 1)
vkGetDeviceQueue(screen->dev, screen->gfx_queue, 1, &ctx->batch.thread_queue);
else
ctx->batch.thread_queue = ctx->batch.queue;
ctx->have_timelines = screen->info.have_KHR_timeline_semaphore;
simple_mtx_init(&ctx->batch_mtx, mtx_plain);
incr_curr_batch(ctx);
zink_start_batch(ctx, &ctx->batch);
if (!ctx->batch.state)
goto fail;
if (!(flags & PIPE_CONTEXT_PREFER_THREADED) || flags & PIPE_CONTEXT_COMPUTE_ONLY) {
return &ctx->base;
}

View file

@ -37,6 +37,46 @@
#define XXH_INLINE_ALL
#include "util/xxhash.h"
struct zink_descriptor_pool {
struct pipe_reference reference;
enum zink_descriptor_type type;
struct hash_table *desc_sets;
struct hash_table *free_desc_sets;
struct util_dynarray alloc_desc_sets;
VkDescriptorPool descpool;
struct zink_descriptor_pool_key key;
unsigned num_resources;
unsigned num_sets_allocated;
simple_mtx_t mtx;
};
struct zink_descriptor_set {
struct zink_descriptor_pool *pool;
struct pipe_reference reference; //incremented for batch usage
VkDescriptorSet desc_set;
uint32_t hash;
bool invalid;
bool punted;
bool recycled;
struct zink_descriptor_state_key key;
struct util_dynarray barriers;
struct zink_batch_usage batch_uses;
#ifndef NDEBUG
/* for extra debug asserts */
unsigned num_resources;
#endif
union {
struct zink_resource_object **res_objs;
struct zink_image_view **image_views;
struct {
struct zink_sampler_view **sampler_views;
struct zink_sampler_state **sampler_states;
};
};
};
struct zink_descriptor_data {
struct zink_descriptor_state gfx_descriptor_states[ZINK_SHADER_COUNT]; // keep incremental hashes here
struct zink_descriptor_state descriptor_states[2]; // gfx, compute
@ -48,6 +88,19 @@ struct zink_program_descriptor_data {
struct zink_descriptor_set *last_set[ZINK_DESCRIPTOR_TYPES];
};
struct zink_batch_descriptor_data {
struct set *desc_sets;
};
static bool
batch_add_desc_set(struct zink_batch *batch, struct zink_descriptor_set *zds)
{
if (!batch_ptr_add_usage(batch, batch->state->dd->desc_sets, zds, &zds->batch_uses))
return false;
pipe_reference(NULL, &zds->reference);
return true;
}
static void
debug_describe_zink_descriptor_pool(char *buf, const struct zink_descriptor_pool *ptr)
{
@ -590,7 +643,7 @@ quick_out:
util_dynarray_clear(&zds->barriers);
zds->punted = zds->invalid = false;
*need_resource_refs = false;
if (zink_batch_add_desc_set(batch, zds)) {
if (batch_add_desc_set(batch, zds)) {
batch->state->descs_used += pool->key.layout->num_descriptors;
*need_resource_refs = true;
}
@ -1429,6 +1482,40 @@ zink_descriptors_update(struct zink_context *ctx, bool is_compute)
}
}
void
zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state *bs)
{
if (!bs->dd)
return;
_mesa_set_destroy(bs->dd->desc_sets, NULL);
ralloc_free(bs->dd);
}
void
zink_batch_descriptor_reset(struct zink_screen *screen, struct zink_batch_state *bs)
{
set_foreach(bs->dd->desc_sets, entry) {
struct zink_descriptor_set *zds = (void*)entry->key;
zink_batch_usage_unset(&zds->batch_uses, bs->fence.batch_id);
/* reset descriptor pools when no bs is using this program to avoid
* having some inactive program hogging a billion descriptors
*/
pipe_reference(&zds->reference, NULL);
zink_descriptor_set_recycle(zds);
_mesa_set_remove(bs->dd->desc_sets, entry);
}
}
bool
zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *bs)
{
bs->dd = rzalloc(bs, struct zink_batch_descriptor_data);
if (!bs->dd)
return false;
bs->dd->desc_sets = _mesa_pointer_set_create(bs);
return !!bs->dd->desc_sets;
}
struct zink_resource *
zink_get_resource_for_descriptor(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type shader, int idx)
{

View file

@ -92,54 +92,11 @@ struct zink_descriptor_pool_key {
VkDescriptorPoolSize *sizes;
};
struct zink_descriptor_pool {
struct pipe_reference reference;
enum zink_descriptor_type type;
struct hash_table *desc_sets;
struct hash_table *free_desc_sets;
struct util_dynarray alloc_desc_sets;
VkDescriptorPool descpool;
struct zink_descriptor_pool_key key;
unsigned num_resources;
unsigned num_sets_allocated;
simple_mtx_t mtx;
};
struct zink_descriptor_set {
struct zink_descriptor_pool *pool;
struct pipe_reference reference; //incremented for batch usage
VkDescriptorSet desc_set;
uint32_t hash;
bool invalid;
bool punted;
bool recycled;
struct zink_descriptor_state_key key;
struct util_dynarray barriers;
struct zink_batch_usage batch_uses;
#ifndef NDEBUG
/* for extra debug asserts */
unsigned num_resources;
#endif
union {
struct zink_resource_object **res_objs;
struct zink_image_view **image_views;
struct {
struct zink_sampler_view **sampler_views;
struct zink_sampler_state **sampler_states;
};
};
};
struct zink_descriptor_reference {
void **ref;
bool *invalid;
};
void
zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr);
void
zink_descriptor_set_recycle(struct zink_descriptor_set *zds);
bool
zink_descriptor_layouts_init(struct zink_context *ctx);
@ -147,15 +104,31 @@ zink_descriptor_layouts_init(struct zink_context *ctx);
void
zink_descriptor_layouts_deinit(struct zink_context *ctx);
uint32_t
zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer);
uint32_t
zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer);
bool
zink_descriptor_util_alloc_sets(struct zink_screen *screen, VkDescriptorSetLayout dsl, VkDescriptorPool pool, VkDescriptorSet *sets, unsigned num_sets);
bool
zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg);
VkDescriptorSetLayout
zink_descriptor_util_layout_get(struct zink_context *ctx, enum zink_descriptor_type type,
VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings,
struct zink_descriptor_layout_key **layout_key);
struct zink_resource *
zink_get_resource_for_descriptor(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type shader, int idx);
/* these two can't be called in lazy mode */
void
zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr);
void
zink_descriptor_set_recycle(struct zink_descriptor_set *zds);
bool
zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg);
void
zink_descriptor_program_deinit(struct zink_screen *screen, struct zink_program *pg);
@ -174,6 +147,13 @@ zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image
struct zink_resource *
zink_get_resource_for_descriptor(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type shader, int idx);
void
zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state *bs);
void
zink_batch_descriptor_reset(struct zink_screen *screen, struct zink_batch_state *bs);
bool
zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *bs);
bool
zink_descriptors_init(struct zink_context *ctx);

View file

@ -479,7 +479,7 @@ zink_draw_vbo(struct pipe_context *pctx,
}
if (zink_program_has_descriptors(&gfx_program->base))
zink_descriptors_update(ctx, false);
screen->descriptors_update(ctx, false);
struct zink_batch *batch = zink_batch_rp(ctx);
VkViewport viewports[PIPE_MAX_VIEWPORTS];
@ -731,7 +731,7 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
&ctx->compute_pipeline_state);
if (zink_program_has_descriptors(&comp_program->base))
zink_descriptors_update(ctx, true);
screen->descriptors_update(ctx, true);
vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);

View file

@ -564,7 +564,7 @@ zink_create_gfx_program(struct zink_context *ctx,
}
p_atomic_dec(&prog->base.reference.count);
if (!zink_descriptor_program_init(ctx, &prog->base))
if (!screen->descriptor_program_init(ctx, &prog->base))
goto fail;
return prog;
@ -658,7 +658,7 @@ zink_create_compute_program(struct zink_context *ctx, struct zink_shader *shader
_mesa_set_add(shader->programs, comp);
comp->shader = shader;
if (!zink_descriptor_program_init(ctx, &comp->base))
if (!screen->descriptor_program_init(ctx, &comp->base))
goto fail;
return comp;
@ -796,7 +796,7 @@ zink_destroy_gfx_program(struct zink_screen *screen,
_mesa_hash_table_destroy(prog->pipelines[i], NULL);
}
zink_shader_cache_reference(screen, &prog->shader_cache, NULL);
zink_descriptor_program_deinit(screen, &prog->base);
screen->descriptor_program_deinit(screen, &prog->base);
ralloc_free(prog);
}
@ -821,7 +821,7 @@ zink_destroy_compute_program(struct zink_screen *screen,
}
_mesa_hash_table_destroy(comp->pipelines, NULL);
zink_shader_cache_reference(screen, &comp->shader_cache, NULL);
zink_descriptor_program_deinit(screen, &comp->base);
screen->descriptor_program_deinit(screen, &comp->base);
ralloc_free(comp);
}

View file

@ -26,6 +26,7 @@
#include "zink_compiler.h"
#include "zink_context.h"
#include "zink_device_info.h"
#include "zink_descriptors.h"
#include "zink_fence.h"
#include "zink_format.h"
#include "zink_framebuffer.h"
@ -1160,6 +1161,24 @@ zink_get_format(struct zink_screen *screen, enum pipe_format format)
return ret;
}
void
zink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback)
{
{
#define DEFAULT(FUNC) screen->FUNC = zink_##FUNC
DEFAULT(descriptor_program_init);
DEFAULT(descriptor_program_deinit);
DEFAULT(context_invalidate_descriptor_state);
DEFAULT(batch_descriptor_init);
DEFAULT(batch_descriptor_reset);
DEFAULT(batch_descriptor_deinit);
DEFAULT(descriptors_init);
DEFAULT(descriptors_deinit);
DEFAULT(descriptors_update);
#undef DEFAULT
}
}
static bool
load_device_extensions(struct zink_screen *screen)
{
@ -1643,6 +1662,8 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
_mesa_hash_table_init(&screen->surface_cache, screen, NULL, equals_ivci);
_mesa_hash_table_init(&screen->bufferview_cache, screen, NULL, equals_bvci);
zink_screen_init_descriptor_funcs(screen, false);
return screen;
fail:

View file

@ -44,6 +44,13 @@
extern uint32_t zink_debug;
struct hash_table;
struct zink_batch_state;
struct zink_context;
struct zink_descriptor_layout_key;
struct zink_program;
struct zink_shader;
enum zink_descriptor_type;
#define ZINK_DEBUG_NIR 0x1
#define ZINK_DEBUG_SPIRV 0x2
#define ZINK_DEBUG_TGSI 0x4
@ -117,6 +124,18 @@ struct zink_screen {
PFN_vkWaitSemaphores vk_WaitSemaphores;
PFN_vkGetDescriptorSetLayoutSupport vk_GetDescriptorSetLayoutSupport;
bool (*descriptor_program_init)(struct zink_context *ctx, struct zink_program *pg);
void (*descriptor_program_deinit)(struct zink_screen *screen, struct zink_program *pg);
void (*descriptors_update)(struct zink_context *ctx, bool is_compute);
void (*context_update_descriptor_states)(struct zink_context *ctx, bool is_compute);
void (*context_invalidate_descriptor_state)(struct zink_context *ctx, enum pipe_shader_type shader,
enum zink_descriptor_type type,
unsigned start, unsigned count);
bool (*batch_descriptor_init)(struct zink_screen *screen, struct zink_batch_state *bs);
void (*batch_descriptor_reset)(struct zink_screen *screen, struct zink_batch_state *bs);
void (*batch_descriptor_deinit)(struct zink_screen *screen, struct zink_batch_state *bs);
bool (*descriptors_init)(struct zink_context *ctx);
void (*descriptors_deinit)(struct zink_context *ctx);
PFN_vkGetMemoryFdKHR vk_GetMemoryFdKHR;
PFN_vkCmdBeginConditionalRenderingEXT vk_CmdBeginConditionalRenderingEXT;
@ -279,4 +298,6 @@ zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format);
void
zink_screen_update_pipeline_cache(struct zink_screen *screen);
void
zink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback);
#endif