From b37a2c6ef2a1aec00a48bea8d3442b7f98f4c5e0 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 13 Jul 2021 10:37:24 -0400 Subject: [PATCH] zink: add template for starting new cmdbuf this avoids reading/updating context changed flags Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_context.c | 13 +++---- src/gallium/drivers/zink/zink_context.h | 8 +++-- src/gallium/drivers/zink/zink_draw.cpp | 62 +++++++++++++++++++++++++++++---- src/gallium/drivers/zink/zink_inlines.h | 10 +++++- src/gallium/drivers/zink/zink_program.c | 8 +++-- 5 files changed, 79 insertions(+), 22 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index f9b0485..7b87a14 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1878,13 +1878,8 @@ flush_batch(struct zink_context *ctx, bool sync) ctx->dirty_so_targets = true; ctx->descriptor_refs_dirty[0] = ctx->descriptor_refs_dirty[1] = true; ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true; - ctx->sample_locations_changed |= ctx->gfx_pipeline_state.sample_locations_enabled; - ctx->vertex_buffers_dirty = true; - ctx->vp_state_changed = true; - ctx->scissor_changed = true; - ctx->rast_state_changed = true; - ctx->stencil_ref_changed = true; - ctx->dsa_state_changed = true; + zink_select_draw_vbo(ctx); + zink_select_launch_grid(ctx); } } @@ -3418,11 +3413,13 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->have_timelines = screen->info.have_KHR_timeline_semaphore; ctx->dynamic_state = screen->info.have_EXT_extended_dynamic_state; + ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true; ctx->gfx_pipeline_state.dirty = true; ctx->compute_pipeline_state.dirty = true; ctx->fb_changed = ctx->rp_changed = true; zink_init_draw_functions(ctx); + zink_init_grid_functions(ctx); ctx->base.screen = pscreen; ctx->base.priv = priv; @@ -3467,7 +3464,6 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->base.clear_render_target = zink_clear_render_target; ctx->base.clear_depth_stencil = zink_clear_depth_stencil; - ctx->base.launch_grid = zink_launch_grid; ctx->base.fence_server_sync = zink_fence_server_sync; ctx->base.flush = zink_flush; ctx->base.memory_barrier = zink_memory_barrier; @@ -3571,6 +3567,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) p_atomic_inc(&screen->base.num_contexts); zink_select_draw_vbo(ctx); + zink_select_launch_grid(ctx); if (!(flags & PIPE_CONTEXT_PREFER_THREADED) || flags & PIPE_CONTEXT_COMPUTE_ONLY) { return &ctx->base; diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 0a11a62..bff7f1a 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -143,6 +143,7 @@ typedef void (*pipe_draw_vbo_func)(struct pipe_context *pipe, const struct pipe_draw_start_count_bias *draws, unsigned num_draws); +typedef void (*pipe_launch_grid_func)(struct pipe_context *pipe, const struct pipe_grid_info *info); typedef enum { ZINK_NO_MULTIDRAW, @@ -163,7 +164,8 @@ struct zink_context { zink_multidraw multidraw : 1; zink_dynamic_state dynamic_state : 1; - pipe_draw_vbo_func draw_vbo[2][2]; //multidraw, dynamic state + pipe_draw_vbo_func draw_vbo[2][2][2]; //multidraw, dynamic state, batch changed + pipe_launch_grid_func launch_grid[2]; //batch changed struct pipe_device_reset_callback reset; @@ -386,9 +388,9 @@ zink_pipeline_flags_from_pipe_stage(enum pipe_shader_type pstage) void zink_init_draw_functions(struct zink_context *ctx); - void -zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info); +zink_init_grid_functions(struct zink_context *ctx); + #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 47ace7c..49c5c54 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -6,6 +6,7 @@ #include "zink_screen.h" #include "zink_state.h" #include "zink_surface.h" +#include "zink_inlines.h" #include "tgsi/tgsi_from_mesa.h" #include "util/hash_table.h" @@ -395,7 +396,7 @@ update_barriers(struct zink_context *ctx, bool is_compute) } } -template +template void zink_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *dinfo, @@ -442,6 +443,7 @@ zink_draw_vbo(struct pipe_context *pctx, if (zink_program_has_descriptors(&ctx->curr_program->base)) { if (screen->descriptors_update(ctx, false)) { /* descriptors have flushed the batch */ + zink_select_draw_vbo(ctx); pctx->draw_vbo(pctx, dinfo, drawid_offset, dindirect, draws, num_draws); return; } @@ -498,7 +500,7 @@ zink_draw_vbo(struct pipe_context *pctx, VkPipeline pipeline = zink_get_gfx_pipeline(ctx, ctx->curr_program, &ctx->gfx_pipeline_state, dinfo->mode); - bool pipeline_changed = prev_pipeline != pipeline || ctx->pipeline_changed[0]; + bool pipeline_changed = prev_pipeline != pipeline || BATCH_CHANGED; if (pipeline_changed) vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); @@ -675,7 +677,10 @@ zink_draw_vbo(struct pipe_context *pctx, screen->vk.CmdBeginTransformFeedbackEXT(batch->state->cmdbuf, 0, ctx->num_so_targets, counter_buffers, counter_buffer_offsets); } - ctx->pipeline_changed[0] = false; + if (BATCH_CHANGED) { + ctx->pipeline_changed[0] = false; + zink_select_draw_vbo(ctx); + } unsigned draw_id = drawid_offset; bool needs_drawid = ctx->drawid_broken; @@ -745,7 +750,8 @@ zink_draw_vbo(struct pipe_context *pctx, zink_maybe_flush_or_stall(ctx); } -void +template +static void zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info) { struct zink_context *ctx = zink_context(pctx); @@ -759,6 +765,7 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info) if (zink_program_has_descriptors(&ctx->curr_compute->base)) { if (screen->descriptors_update(ctx, true)) { /* descriptors have flushed the batch */ + zink_select_launch_grid(ctx); pctx->launch_grid(pctx, info); return; } @@ -772,9 +779,12 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info) if (ctx->descriptor_refs_dirty[1]) zink_update_descriptor_refs(ctx, true); - if (prev_pipeline != pipeline || ctx->pipeline_changed[1]) + if (prev_pipeline != pipeline || BATCH_CHANGED) vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); - ctx->pipeline_changed[1] = false; + if (BATCH_CHANGED) { + ctx->pipeline_changed[1] = false; + zink_select_launch_grid(ctx); + } if (BITSET_TEST(ctx->compute_stage->nir->info.system_values_read, SYSTEM_VALUE_WORK_DIM)) vkCmdPushConstants(batch->state->cmdbuf, ctx->curr_compute->base.layout, VK_SHADER_STAGE_COMPUTE_BIT, @@ -792,11 +802,19 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info) zink_maybe_flush_or_stall(ctx); } +template +static void +init_batch_changed_functions(struct zink_context *ctx) +{ + ctx->draw_vbo[HAS_MULTIDRAW][HAS_DYNAMIC_STATE][BATCH_CHANGED] = zink_draw_vbo; +} + template static void init_dynamic_state_functions(struct zink_context *ctx) { - ctx->draw_vbo[HAS_MULTIDRAW][HAS_DYNAMIC_STATE] = zink_draw_vbo; + init_batch_changed_functions(ctx); + init_batch_changed_functions(ctx); } template @@ -814,6 +832,20 @@ init_all_draw_functions(struct zink_context *ctx) init_multidraw_functions(ctx); } +template +static void +init_grid_batch_changed_functions(struct zink_context *ctx) +{ + ctx->launch_grid[BATCH_CHANGED] = zink_launch_grid; +} + +static void +init_all_grid_functions(struct zink_context *ctx) +{ + init_grid_batch_changed_functions(ctx); + init_grid_batch_changed_functions(ctx); +} + static void zink_invalid_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *dinfo, @@ -825,6 +857,12 @@ zink_invalid_draw_vbo(struct pipe_context *pipe, unreachable("vertex shader not bound"); } +static void +zink_invalid_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info) +{ + unreachable("compute shader not bound"); +} + extern "C" void zink_init_draw_functions(struct zink_context *ctx) @@ -835,3 +873,13 @@ zink_init_draw_functions(struct zink_context *ctx) */ ctx->base.draw_vbo = zink_invalid_draw_vbo; } + +void +zink_init_grid_functions(struct zink_context *ctx) +{ + init_all_grid_functions(ctx); + /* Bind a fake launch_grid, so that draw_vbo isn't NULL, which would skip + * initialization of callbacks in upper layers (such as u_threaded_context). + */ + ctx->base.launch_grid = zink_invalid_launch_grid; +} diff --git a/src/gallium/drivers/zink/zink_inlines.h b/src/gallium/drivers/zink/zink_inlines.h index 7fe4c8b..66939bc 100644 --- a/src/gallium/drivers/zink/zink_inlines.h +++ b/src/gallium/drivers/zink/zink_inlines.h @@ -5,8 +5,16 @@ static inline void zink_select_draw_vbo(struct zink_context *ctx) { - ctx->base.draw_vbo = ctx->draw_vbo[ctx->multidraw][ctx->dynamic_state]; + ctx->base.draw_vbo = ctx->draw_vbo[ctx->multidraw][ctx->dynamic_state] + [ctx->pipeline_changed[0]]; assert(ctx->base.draw_vbo); } +static inline void +zink_select_launch_grid(struct zink_context *ctx) +{ + ctx->base.launch_grid = ctx->launch_grid[ctx->pipeline_changed[1]]; + assert(ctx->base.launch_grid); +} + #endif diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index f9fbaaa..ca67dd1 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -26,6 +26,7 @@ #include "zink_compiler.h" #include "zink_context.h" #include "zink_descriptors.h" +#include "zink_helpers.h" #include "zink_render_pass.h" #include "zink_resource.h" #include "zink_screen.h" @@ -862,14 +863,15 @@ zink_get_compute_pipeline(struct zink_screen *screen, return state->pipeline; } - static inline void bind_stage(struct zink_context *ctx, enum pipe_shader_type stage, struct zink_shader *shader) { - if (stage == PIPE_SHADER_COMPUTE) + if (stage == PIPE_SHADER_COMPUTE) { ctx->compute_stage = shader; - else + if (shader) + zink_select_launch_grid(ctx); + } else ctx->gfx_stages[stage] = shader; ctx->dirty_shader_stages |= 1 << stage; if (shader && shader->nir->info.num_inlinable_uniforms) -- 2.7.4