zink: add context-based descriptor info tracking infrastructure
this maintains the exact structs needed to update descriptor states it's incomplete at this moment due to lacking shader image rebinds, but it's also not yet being used Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10699>
This commit is contained in:
parent
a8e80b3344
commit
42634824f8
|
@ -370,6 +370,137 @@ zink_create_sampler_state(struct pipe_context *pctx,
|
|||
return sampler;
|
||||
}
|
||||
|
||||
static VkImageLayout
|
||||
get_layout_for_binding(struct zink_resource *res, enum zink_descriptor_type type)
|
||||
{
|
||||
if (res->obj->is_buffer)
|
||||
return 0;
|
||||
switch (type) {
|
||||
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
|
||||
return res->bind_history & BITFIELD64_BIT(ZINK_DESCRIPTOR_TYPE_IMAGE) ?
|
||||
VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case ZINK_DESCRIPTOR_TYPE_IMAGE:
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct zink_surface *
|
||||
get_imageview_for_binding(struct zink_context *ctx, enum pipe_shader_type stage, enum zink_descriptor_type type, unsigned idx)
|
||||
{
|
||||
switch (type) {
|
||||
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
|
||||
struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[stage][idx]);
|
||||
return sampler_view->base.texture ? sampler_view->image_view : NULL;
|
||||
}
|
||||
case ZINK_DESCRIPTOR_TYPE_IMAGE: {
|
||||
struct zink_image_view *image_view = &ctx->image_views[stage][idx];
|
||||
return image_view->base.resource ? image_view->surface : NULL;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
unreachable("ACK");
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
static struct zink_buffer_view *
|
||||
get_bufferview_for_binding(struct zink_context *ctx, enum pipe_shader_type stage, enum zink_descriptor_type type, unsigned idx)
|
||||
{
|
||||
switch (type) {
|
||||
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
|
||||
struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[stage][idx]);
|
||||
return sampler_view->base.texture ? sampler_view->buffer_view : NULL;
|
||||
}
|
||||
case ZINK_DESCRIPTOR_TYPE_IMAGE: {
|
||||
struct zink_image_view *image_view = &ctx->image_views[stage][idx];
|
||||
return image_view->base.resource ? image_view->buffer_view : NULL;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
unreachable("ACK");
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_descriptor_state(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned slot)
|
||||
{
|
||||
bool have_null_descriptors = zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor;
|
||||
VkBuffer null_buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
|
||||
struct zink_resource *res = zink_get_resource_for_descriptor(ctx, type, shader, slot);
|
||||
ctx->di.descriptor_res[type][shader][slot] = res;
|
||||
switch (type) {
|
||||
case ZINK_DESCRIPTOR_TYPE_UBO:
|
||||
ctx->di.ubos[shader][slot].offset = ctx->ubos[shader][slot].buffer_offset;
|
||||
if (res) {
|
||||
ctx->di.ubos[shader][slot].buffer = res->obj->buffer;
|
||||
ctx->di.ubos[shader][slot].range = ctx->ubos[shader][slot].buffer_size;
|
||||
} else {
|
||||
ctx->di.ubos[shader][slot].buffer = have_null_descriptors ? VK_NULL_HANDLE : null_buffer;
|
||||
ctx->di.ubos[shader][slot].range = VK_WHOLE_SIZE;
|
||||
}
|
||||
if (!slot) {
|
||||
if (res)
|
||||
ctx->di.push_valid |= BITFIELD64_BIT(shader);
|
||||
else
|
||||
ctx->di.push_valid &= ~BITFIELD64_BIT(shader);
|
||||
}
|
||||
break;
|
||||
case ZINK_DESCRIPTOR_TYPE_SSBO:
|
||||
ctx->di.ssbos[shader][slot].offset = ctx->ssbos[shader][slot].buffer_offset;
|
||||
if (res) {
|
||||
ctx->di.ssbos[shader][slot].buffer = res->obj->buffer;
|
||||
ctx->di.ssbos[shader][slot].range = ctx->ssbos[shader][slot].buffer_size;
|
||||
} else {
|
||||
ctx->di.ssbos[shader][slot].buffer = have_null_descriptors ? VK_NULL_HANDLE : null_buffer;
|
||||
ctx->di.ssbos[shader][slot].range = VK_WHOLE_SIZE;
|
||||
}
|
||||
break;
|
||||
case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
|
||||
if (res) {
|
||||
if (res->obj->is_buffer) {
|
||||
struct zink_buffer_view *bv = get_bufferview_for_binding(ctx, shader, type, slot);
|
||||
ctx->di.tbos[shader][slot] = bv->buffer_view;
|
||||
ctx->di.sampler_surfaces[shader][slot].bufferview = bv;
|
||||
} else {
|
||||
struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
|
||||
ctx->di.textures[shader][slot].imageLayout = get_layout_for_binding(res, type);
|
||||
ctx->di.textures[shader][slot].imageView = surface->image_view;
|
||||
ctx->di.sampler_surfaces[shader][slot].surface = surface;
|
||||
}
|
||||
} else {
|
||||
ctx->di.textures[shader][slot].imageView = VK_NULL_HANDLE;
|
||||
ctx->di.textures[shader][slot].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
ctx->di.tbos[shader][slot] = VK_NULL_HANDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZINK_DESCRIPTOR_TYPE_IMAGE: {
|
||||
if (res) {
|
||||
if (res->obj->is_buffer) {
|
||||
struct zink_buffer_view *bv = get_bufferview_for_binding(ctx, shader, type, slot);
|
||||
ctx->di.texel_images[shader][slot] = bv->buffer_view;
|
||||
ctx->di.image_surfaces[shader][slot].bufferview = bv;
|
||||
} else {
|
||||
struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
|
||||
ctx->di.images[shader][slot].imageLayout = get_layout_for_binding(res, type);
|
||||
ctx->di.images[shader][slot].imageView = surface->image_view;
|
||||
ctx->di.image_surfaces[shader][slot].surface = surface;
|
||||
}
|
||||
} else {
|
||||
memset(&ctx->di.images[shader][slot], 0, sizeof(ctx->di.images[shader][slot]));
|
||||
ctx->di.texel_images[shader][slot] = VK_NULL_HANDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
zink_bind_sampler_states(struct pipe_context *pctx,
|
||||
enum pipe_shader_type shader,
|
||||
|
@ -383,7 +514,7 @@ zink_bind_sampler_states(struct pipe_context *pctx,
|
|||
VkSampler *sampler = samplers[i];
|
||||
update |= ctx->sampler_states[shader][start_slot + i] != samplers[i];
|
||||
ctx->sampler_states[shader][start_slot + i] = sampler;
|
||||
ctx->samplers[shader][start_slot + i] = sampler ? *sampler : VK_NULL_HANDLE;
|
||||
ctx->di.textures[shader][start_slot + i].sampler = sampler ? *sampler : VK_NULL_HANDLE;
|
||||
}
|
||||
ctx->num_samplers[shader] = start_slot + num_samplers;
|
||||
if (update)
|
||||
|
@ -793,6 +924,7 @@ zink_set_constant_buffer(struct pipe_context *pctx,
|
|||
/* Invalidate current inlinable uniforms. */
|
||||
ctx->inlinable_uniforms_valid_mask &= ~(1 << shader);
|
||||
}
|
||||
update_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, index);
|
||||
|
||||
if (update)
|
||||
zink_context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO);
|
||||
|
@ -831,6 +963,7 @@ zink_set_shader_buffers(struct pipe_context *pctx,
|
|||
ssbo->buffer_offset = 0;
|
||||
ssbo->buffer_size = 0;
|
||||
}
|
||||
update_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_SSBO, start_slot + i);
|
||||
}
|
||||
if (update)
|
||||
zink_context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_SSBO);
|
||||
|
@ -862,6 +995,7 @@ zink_set_shader_images(struct pipe_context *pctx,
|
|||
{
|
||||
struct zink_context *ctx = zink_context(pctx);
|
||||
bool update = false;
|
||||
unsigned max_slot = 0;
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
struct zink_image_view *image_view = &ctx->image_views[p_stage][start_slot + i];
|
||||
if (images && images[i].resource) {
|
||||
|
@ -895,11 +1029,17 @@ zink_set_shader_images(struct pipe_context *pctx,
|
|||
|
||||
unbind_shader_image(ctx, p_stage, start_slot + i);
|
||||
}
|
||||
if (image_view->base.resource)
|
||||
max_slot = MAX2(max_slot, start_slot + i);
|
||||
update_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_IMAGE, start_slot + i);
|
||||
}
|
||||
for (unsigned i = 0; i < unbind_num_trailing_slots; i++) {
|
||||
update |= !!ctx->image_views[p_stage][start_slot + count + i].base.resource;
|
||||
unbind_shader_image(ctx, p_stage, start_slot + count + i);
|
||||
update_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_IMAGE, start_slot + count + i);
|
||||
}
|
||||
if (start_slot + count - 1 >= ctx->di.num_images[p_stage])
|
||||
ctx->di.num_images[p_stage] = max_slot;
|
||||
if (update)
|
||||
zink_context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_IMAGE);
|
||||
}
|
||||
|
@ -957,12 +1097,14 @@ zink_set_sampler_views(struct pipe_context *pctx,
|
|||
uint32_t hash_b = zink_get_sampler_view_hash(ctx, b, is_buffer);
|
||||
update |= !!a != !!b || hash_a != hash_b;
|
||||
pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], pview);
|
||||
update_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i);
|
||||
}
|
||||
for (; i < num_views + unbind_num_trailing_slots; ++i) {
|
||||
update |= !!ctx->sampler_views[shader_type][start_slot + i];
|
||||
pipe_sampler_view_reference(
|
||||
&ctx->sampler_views[shader_type][start_slot + i],
|
||||
NULL);
|
||||
update_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i);
|
||||
}
|
||||
ctx->num_sampler_views[shader_type] = start_slot + num_views;
|
||||
if (update)
|
||||
|
@ -2441,6 +2583,7 @@ zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res)
|
|||
}
|
||||
|
||||
zink_context_invalidate_descriptor_state(ctx, shader, type);
|
||||
update_descriptor_state(ctx, shader, type, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,6 +124,12 @@ struct zink_viewport_state {
|
|||
uint8_t num_viewports;
|
||||
};
|
||||
|
||||
|
||||
union zink_descriptor_surface {
|
||||
struct zink_surface *surface;
|
||||
struct zink_buffer_view *bufferview;
|
||||
};
|
||||
|
||||
struct zink_context {
|
||||
struct pipe_context base;
|
||||
struct threaded_context *tc;
|
||||
|
@ -189,7 +195,6 @@ struct zink_context {
|
|||
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
|
||||
|
||||
void *sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
VkSampler samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
unsigned num_samplers[PIPE_SHADER_TYPES];
|
||||
struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
unsigned num_sampler_views[PIPE_SHADER_TYPES];
|
||||
|
@ -223,6 +228,25 @@ struct zink_context {
|
|||
struct pipe_resource *dummy_xfb_buffer;
|
||||
struct pipe_resource *null_buffers[5]; /* used to create zink_framebuffer->null_surface, one buffer per samplecount */
|
||||
|
||||
struct {
|
||||
/* descriptor info */
|
||||
VkDescriptorBufferInfo ubos[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
|
||||
uint32_t push_valid;
|
||||
|
||||
VkDescriptorBufferInfo ssbos[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
|
||||
|
||||
VkDescriptorImageInfo textures[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
VkBufferView tbos[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
|
||||
VkDescriptorImageInfo images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
|
||||
VkBufferView texel_images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
|
||||
unsigned num_images[PIPE_SHADER_TYPES];
|
||||
|
||||
struct zink_resource *descriptor_res[ZINK_DESCRIPTOR_TYPES][PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
union zink_descriptor_surface sampler_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
union zink_descriptor_surface image_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
|
||||
} di;
|
||||
|
||||
uint32_t num_so_targets;
|
||||
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_OUTPUTS];
|
||||
bool dirty_so_targets;
|
||||
|
|
Loading…
Reference in New Issue