zink: move barrier jit to zink_context.c
this gives access to all the good descriptor functions and enshrinkens the c++ file size Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20891>
This commit is contained in:
@@ -5138,3 +5138,82 @@ zink_tc_context_unwrap(struct pipe_context *pctx, bool threaded)
|
||||
pctx = trace_get_possibly_threaded_context(pctx);
|
||||
return zink_context(pctx);
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
add_implicit_color_feedback_loop(struct zink_context *ctx, struct zink_resource *res)
|
||||
{
|
||||
if (!res->fb_bind_count || !res->sampler_bind_count[0] || ctx->feedback_loops & res->fb_binds)
|
||||
return false;
|
||||
bool is_feedback = false;
|
||||
/* avoid false positives when a texture is bound but not used */
|
||||
u_foreach_bit(vkstage, res->gfx_barrier) {
|
||||
VkPipelineStageFlags vkstagebit = BITFIELD_BIT(vkstage);
|
||||
if (vkstagebit < VK_PIPELINE_STAGE_VERTEX_SHADER_BIT || vkstagebit > VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
|
||||
continue;
|
||||
/* in-range VkPipelineStageFlagBits can be converted to VkShaderStageFlags with a bitshift */
|
||||
gl_shader_stage stage = vk_to_mesa_shader_stage((VkShaderStageFlagBits)(vkstagebit >> 3));
|
||||
/* check shader texture usage against resource's sampler binds */
|
||||
if ((ctx->gfx_stages[stage] && (res->sampler_binds[stage] & ctx->gfx_stages[stage]->nir->info.textures_used[0])))
|
||||
is_feedback = true;
|
||||
}
|
||||
if (!is_feedback)
|
||||
return false;
|
||||
/* new feedback loop detected */
|
||||
if (res->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||
if (!ctx->gfx_pipeline_state.feedback_loop)
|
||||
ctx->gfx_pipeline_state.dirty = true;
|
||||
ctx->gfx_pipeline_state.feedback_loop = true;
|
||||
} else {
|
||||
if (!ctx->gfx_pipeline_state.feedback_loop_zs)
|
||||
ctx->gfx_pipeline_state.dirty = true;
|
||||
ctx->gfx_pipeline_state.feedback_loop_zs = true;
|
||||
}
|
||||
ctx->rp_layout_changed = true;
|
||||
ctx->feedback_loops |= res->fb_binds;
|
||||
u_foreach_bit(idx, res->fb_binds) {
|
||||
if (zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout)
|
||||
ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
|
||||
else
|
||||
ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
zink_update_barriers(struct zink_context *ctx, bool is_compute,
|
||||
struct pipe_resource *index, struct pipe_resource *indirect, struct pipe_resource *indirect_draw_count)
|
||||
{
|
||||
if (!ctx->need_barriers[is_compute]->entries)
|
||||
return;
|
||||
struct set *need_barriers = ctx->need_barriers[is_compute];
|
||||
ctx->barrier_set_idx[is_compute] = !ctx->barrier_set_idx[is_compute];
|
||||
ctx->need_barriers[is_compute] = &ctx->update_barriers[is_compute][ctx->barrier_set_idx[is_compute]];
|
||||
set_foreach(need_barriers, he) {
|
||||
struct zink_resource *res = (struct zink_resource *)he->key;
|
||||
if (res->bind_count[is_compute]) {
|
||||
VkPipelineStageFlagBits pipeline = is_compute ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT : res->gfx_barrier;
|
||||
if (res->base.b.target == PIPE_BUFFER)
|
||||
zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, res->barrier_access[is_compute], pipeline);
|
||||
else {
|
||||
bool is_feedback = is_compute ? false : add_implicit_color_feedback_loop(ctx, res);
|
||||
VkImageLayout layout = zink_descriptor_util_image_layout_eval(ctx, res, is_compute);
|
||||
/* GENERAL is only used for feedback loops and storage image binds */
|
||||
if (is_feedback || layout != VK_IMAGE_LAYOUT_GENERAL || res->image_bind_count[is_compute])
|
||||
zink_screen(ctx->base.screen)->image_barrier(ctx, res, layout, res->barrier_access[is_compute], pipeline);
|
||||
}
|
||||
if (zink_resource_access_is_write(res->barrier_access[is_compute]))
|
||||
res->obj->unordered_read = res->obj->unordered_write = false;
|
||||
else
|
||||
res->obj->unordered_read = false;
|
||||
/* always barrier on draw if this resource has either multiple image write binds or
|
||||
* image write binds and image read binds
|
||||
*/
|
||||
if (res->write_bind_count[is_compute] && res->bind_count[is_compute] > 1)
|
||||
_mesa_set_add_pre_hashed(ctx->need_barriers[is_compute], he->hash, res);
|
||||
}
|
||||
_mesa_set_remove(need_barriers, he);
|
||||
if (!need_barriers->entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,11 @@ void
|
||||
zink_init_grid_functions(struct zink_context *ctx);
|
||||
struct zink_context *
|
||||
zink_tc_context_unwrap(struct pipe_context *pctx, bool threaded);
|
||||
|
||||
void
|
||||
zink_update_barriers(struct zink_context *ctx, bool is_compute,
|
||||
struct pipe_resource *index, struct pipe_resource *indirect, struct pipe_resource *indirect_draw_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -280,84 +280,6 @@ draw(struct zink_context *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
add_implicit_color_feedback_loop(struct zink_context *ctx, struct zink_resource *res)
|
||||
{
|
||||
if (!res->fb_bind_count || !res->sampler_bind_count[0] || ctx->feedback_loops & res->fb_binds)
|
||||
return false;
|
||||
bool is_feedback = false;
|
||||
/* avoid false positives when a texture is bound but not used */
|
||||
u_foreach_bit(vkstage, res->gfx_barrier) {
|
||||
VkPipelineStageFlags vkstagebit = BITFIELD_BIT(vkstage);
|
||||
if (vkstagebit < VK_PIPELINE_STAGE_VERTEX_SHADER_BIT || vkstagebit > VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
|
||||
continue;
|
||||
/* in-range VkPipelineStageFlagBits can be converted to VkShaderStageFlags with a bitshift */
|
||||
gl_shader_stage stage = vk_to_mesa_shader_stage((VkShaderStageFlagBits)(vkstagebit >> 3));
|
||||
/* check shader texture usage against resource's sampler binds */
|
||||
if ((ctx->gfx_stages[stage] && (res->sampler_binds[stage] & ctx->gfx_stages[stage]->nir->info.textures_used[0])))
|
||||
is_feedback = true;
|
||||
}
|
||||
if (!is_feedback)
|
||||
return false;
|
||||
/* new feedback loop detected */
|
||||
if (res->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||
if (!ctx->gfx_pipeline_state.feedback_loop)
|
||||
ctx->gfx_pipeline_state.dirty = true;
|
||||
ctx->gfx_pipeline_state.feedback_loop = true;
|
||||
} else {
|
||||
if (!ctx->gfx_pipeline_state.feedback_loop_zs)
|
||||
ctx->gfx_pipeline_state.dirty = true;
|
||||
ctx->gfx_pipeline_state.feedback_loop_zs = true;
|
||||
}
|
||||
ctx->rp_layout_changed = true;
|
||||
ctx->feedback_loops |= res->fb_binds;
|
||||
u_foreach_bit(idx, res->fb_binds) {
|
||||
if (zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout)
|
||||
ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
|
||||
else
|
||||
ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
update_barriers(struct zink_context *ctx, bool is_compute,
|
||||
struct pipe_resource *index, struct pipe_resource *indirect, struct pipe_resource *indirect_draw_count)
|
||||
{
|
||||
if (!ctx->need_barriers[is_compute]->entries)
|
||||
return;
|
||||
struct set *need_barriers = ctx->need_barriers[is_compute];
|
||||
ctx->barrier_set_idx[is_compute] = !ctx->barrier_set_idx[is_compute];
|
||||
ctx->need_barriers[is_compute] = &ctx->update_barriers[is_compute][ctx->barrier_set_idx[is_compute]];
|
||||
set_foreach(need_barriers, he) {
|
||||
struct zink_resource *res = (struct zink_resource *)he->key;
|
||||
if (res->bind_count[is_compute]) {
|
||||
VkPipelineStageFlagBits pipeline = is_compute ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT : res->gfx_barrier;
|
||||
if (res->base.b.target == PIPE_BUFFER)
|
||||
zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, res->barrier_access[is_compute], pipeline);
|
||||
else {
|
||||
bool is_feedback = is_compute ? false : add_implicit_color_feedback_loop(ctx, res);
|
||||
VkImageLayout layout = zink_descriptor_util_image_layout_eval(ctx, res, is_compute);
|
||||
/* GENERAL is only used for feedback loops and storage image binds */
|
||||
if (is_feedback || layout != VK_IMAGE_LAYOUT_GENERAL || res->image_bind_count[is_compute])
|
||||
zink_screen(ctx->base.screen)->image_barrier(ctx, res, layout, res->barrier_access[is_compute], pipeline);
|
||||
}
|
||||
if (zink_resource_access_is_write(res->barrier_access[is_compute]))
|
||||
res->obj->unordered_read = res->obj->unordered_write = false;
|
||||
else
|
||||
res->obj->unordered_read = false;
|
||||
/* always barrier on draw if this resource has either multiple image write binds or
|
||||
* image write binds and image read binds
|
||||
*/
|
||||
if (res->write_bind_count[is_compute] && res->bind_count[is_compute] > 1)
|
||||
_mesa_set_add_pre_hashed(ctx->need_barriers[is_compute], he->hash, res);
|
||||
}
|
||||
_mesa_set_remove(need_barriers, he);
|
||||
if (!need_barriers->entries)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template <zink_dynamic_state DYNAMIC_STATE, bool BATCH_CHANGED>
|
||||
static bool
|
||||
update_gfx_pipeline(struct zink_context *ctx, struct zink_batch_state *bs, enum pipe_prim_type mode)
|
||||
@@ -499,7 +421,7 @@ zink_draw(struct pipe_context *pctx,
|
||||
|
||||
barrier_draw_buffers(ctx, dinfo, dindirect, index_buffer);
|
||||
/* this may re-emit draw buffer barriers, but such synchronization is harmless */
|
||||
update_barriers(ctx, false, index_buffer, dindirect ? dindirect->buffer : NULL, dindirect ? dindirect->indirect_draw_count : NULL);
|
||||
zink_update_barriers(ctx, false, index_buffer, dindirect ? dindirect->buffer : NULL, dindirect ? dindirect->indirect_draw_count : NULL);
|
||||
|
||||
/* ensure synchronization between doing streamout with counter buffer
|
||||
* and using counter buffer for indirect draw
|
||||
@@ -1022,7 +944,7 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
|
||||
check_buffer_barrier(ctx, info->indirect, VK_ACCESS_INDIRECT_COMMAND_READ_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
|
||||
}
|
||||
|
||||
update_barriers(ctx, true, NULL, info->indirect, NULL);
|
||||
zink_update_barriers(ctx, true, NULL, info->indirect, NULL);
|
||||
if (ctx->memory_barrier)
|
||||
zink_flush_memory_barrier(ctx, true);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user