zink: handle scissor+viewport states dynamically if extension is available
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Wed, 16 Sep 2020 18:10:00 +0000 (14:10 -0400)
committerMarge Bot <eric+marge@anholt.net>
Mon, 22 Feb 2021 14:04:29 +0000 (14:04 +0000)
this is a huge perf win since it means we don't have to create a new pipeline
every time this state changes

also we can now move the viewport state back to zink_context since that's the
real value we're using and the pipeline state value is just for the hash

ref mesa/mesa#3359

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9153>

src/gallium/drivers/zink/zink_blit.c
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_context.h
src/gallium/drivers/zink/zink_draw.c
src/gallium/drivers/zink/zink_pipeline.c

index 1de31d2..ffe2ae6 100644 (file)
@@ -220,7 +220,7 @@ void
 zink_blit_begin(struct zink_context *ctx, enum zink_blit_flags flags)
 {
    util_blitter_save_vertex_elements(ctx->blitter, ctx->element_state);
-   util_blitter_save_viewport(ctx->blitter, ctx->viewport_states);
+   util_blitter_save_viewport(ctx->blitter, ctx->vp_state.viewport_states);
 
    util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->buffers);
    util_blitter_save_vertex_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_VERTEX]);
@@ -236,7 +236,7 @@ zink_blit_begin(struct zink_context *ctx, enum zink_blit_flags flags)
       util_blitter_save_depth_stencil_alpha(ctx->blitter, ctx->dsa_state);
       util_blitter_save_stencil_ref(ctx->blitter, &ctx->stencil_ref);
       util_blitter_save_sample_mask(ctx->blitter, ctx->gfx_pipeline_state.sample_mask);
-      util_blitter_save_scissor(ctx->blitter, ctx->scissor_states);
+      util_blitter_save_scissor(ctx->blitter, ctx->vp_state.scissor_states);
       /* also util_blitter_save_window_rectangles when we have that? */
 
       util_blitter_save_fragment_shader(ctx->blitter, ctx->gfx_stages[PIPE_SHADER_FRAGMENT]);
index ae76e62..28a98f4 100644 (file)
@@ -515,10 +515,14 @@ zink_set_viewport_states(struct pipe_context *pctx,
    struct zink_context *ctx = zink_context(pctx);
 
    for (unsigned i = 0; i < num_viewports; ++i)
-      ctx->viewport_states[start_slot + i] = state[i];
-   if (ctx->gfx_pipeline_state.num_viewports != start_slot + num_viewports)
-      ctx->gfx_pipeline_state.dirty = true;
-   ctx->gfx_pipeline_state.num_viewports = start_slot + num_viewports;
+      ctx->vp_state.viewport_states[start_slot + i] = state[i];
+   ctx->vp_state.num_viewports = start_slot + num_viewports;
+
+   if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state) {
+      if (ctx->gfx_pipeline_state.num_viewports != ctx->vp_state.num_viewports)
+         ctx->gfx_pipeline_state.dirty = true;
+      ctx->gfx_pipeline_state.num_viewports = ctx->vp_state.num_viewports;
+   }
 }
 
 static void
@@ -535,8 +539,8 @@ zink_set_scissor_states(struct pipe_context *pctx,
       scissor.offset.y = states[i].miny;
       scissor.extent.width = states[i].maxx - states[i].minx;
       scissor.extent.height = states[i].maxy - states[i].miny;
-      ctx->scissor_states[start_slot + i] = states[i];
-      ctx->scissors[start_slot + i] = scissor;
+      ctx->vp_state.scissor_states[start_slot + i] = states[i];
+      ctx->vp_state.scissors[start_slot + i] = scissor;
    }
 }
 
index d8d8d86..10b95d2 100644 (file)
@@ -90,6 +90,13 @@ zink_so_target(struct pipe_stream_output_target *so_target)
    return (struct zink_so_target *)so_target;
 }
 
+struct zink_viewport_state {
+   struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS];
+   struct pipe_scissor_state scissor_states[PIPE_MAX_VIEWPORTS];
+   VkRect2D scissors[PIPE_MAX_VIEWPORTS];
+   uint8_t num_viewports;
+};
+
 #define ZINK_SHADER_COUNT (PIPE_SHADER_TYPES - 1)
 #define ZINK_NUM_GFX_BATCHES 4
 #define ZINK_COMPUTE_BATCH_ID ZINK_NUM_GFX_BATCHES
@@ -140,9 +147,6 @@ struct zink_context {
 
    struct zink_framebuffer *framebuffer;
 
-   struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS];
-   struct pipe_scissor_state scissor_states[PIPE_MAX_VIEWPORTS];
-   VkRect2D scissors[PIPE_MAX_VIEWPORTS];
    struct pipe_vertex_buffer buffers[PIPE_MAX_ATTRIBS];
    uint32_t buffers_enabled_mask;
 
@@ -152,6 +156,8 @@ struct zink_context {
    struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
    unsigned num_sampler_views[PIPE_SHADER_TYPES];
 
+   struct zink_viewport_state vp_state;
+
    float line_width;
    float blend_constants[4];
 
index 80418dd..ab15bb9 100644 (file)
@@ -743,31 +743,36 @@ zink_draw_vbo(struct pipe_context *pctx,
 
    struct zink_batch *batch = zink_batch_rp(ctx);
    VkViewport viewports[PIPE_MAX_VIEWPORTS] = {};
-   for (unsigned i = 0; i < ctx->gfx_pipeline_state.num_viewports; i++) {
+   for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) {
       VkViewport viewport = {
-         ctx->viewport_states[i].translate[0] - ctx->viewport_states[i].scale[0],
-         ctx->viewport_states[i].translate[1] - ctx->viewport_states[i].scale[1],
-         ctx->viewport_states[i].scale[0] * 2,
-         ctx->viewport_states[i].scale[1] * 2,
+         ctx->vp_state.viewport_states[i].translate[0] - ctx->vp_state.viewport_states[i].scale[0],
+         ctx->vp_state.viewport_states[i].translate[1] - ctx->vp_state.viewport_states[i].scale[1],
+         ctx->vp_state.viewport_states[i].scale[0] * 2,
+         ctx->vp_state.viewport_states[i].scale[1] * 2,
          ctx->rast_state->base.clip_halfz ?
-            ctx->viewport_states[i].translate[2] :
-            ctx->viewport_states[i].translate[2] - ctx->viewport_states[i].scale[2],
-         ctx->viewport_states[i].translate[2] + ctx->viewport_states[i].scale[2]
+            ctx->vp_state.viewport_states[i].translate[2] :
+            ctx->vp_state.viewport_states[i].translate[2] - ctx->vp_state.viewport_states[i].scale[2],
+         ctx->vp_state.viewport_states[i].translate[2] + ctx->vp_state.viewport_states[i].scale[2]
       };
       viewports[i] = viewport;
    }
-   vkCmdSetViewport(batch->cmdbuf, 0, ctx->gfx_pipeline_state.num_viewports, viewports);
+   if (screen->info.have_EXT_extended_dynamic_state)
+      screen->vk_CmdSetViewportWithCountEXT(batch->cmdbuf, ctx->vp_state.num_viewports, viewports);
+   else
+      vkCmdSetViewport(batch->cmdbuf, 0, ctx->vp_state.num_viewports, viewports);
+   VkRect2D scissors[PIPE_MAX_VIEWPORTS] = {};
    if (ctx->rast_state->base.scissor)
-      vkCmdSetScissor(batch->cmdbuf, 0, ctx->gfx_pipeline_state.num_viewports, ctx->scissors);
+      memcpy(scissors, ctx->vp_state.scissors, sizeof(scissors));
    else if (ctx->fb_state.width && ctx->fb_state.height) {
-      VkRect2D fb_scissor[ctx->gfx_pipeline_state.num_viewports];
-      for (unsigned i = 0; i < ctx->gfx_pipeline_state.num_viewports; i++) {
-         fb_scissor[i].offset.x = fb_scissor[i].offset.y = 0;
-         fb_scissor[i].extent.width = ctx->fb_state.width;
-         fb_scissor[i].extent.height = ctx->fb_state.height;
+      for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) {
+         scissors[i].extent.width = ctx->fb_state.width;
+         scissors[i].extent.height = ctx->fb_state.height;
       }
-      vkCmdSetScissor(batch->cmdbuf, 0, ctx->gfx_pipeline_state.num_viewports, fb_scissor);
    }
+   if (screen->info.have_EXT_extended_dynamic_state)
+      screen->vk_CmdSetScissorWithCountEXT(batch->cmdbuf, ctx->vp_state.num_viewports, scissors);
+   else
+      vkCmdSetScissor(batch->cmdbuf, 0, ctx->vp_state.num_viewports, scissors);
 
    if (line_width_needed(reduced_prim, rast_state->hw_state.polygon_mode)) {
       if (screen->info.feats.features.wideLines || ctx->line_width == 1.0f)
index c95def4..92d4229 100644 (file)
@@ -125,8 +125,8 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
    depth_stencil_state.depthWriteEnable = state->depth_stencil_alpha_state->depth_write;
 
    VkDynamicState dynamicStateEnables[] = {
-      VK_DYNAMIC_STATE_VIEWPORT,
-      VK_DYNAMIC_STATE_SCISSOR,
+      screen->info.have_EXT_extended_dynamic_state ? VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT : VK_DYNAMIC_STATE_VIEWPORT,
+      screen->info.have_EXT_extended_dynamic_state ? VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT : VK_DYNAMIC_STATE_SCISSOR,
       VK_DYNAMIC_STATE_LINE_WIDTH,
       VK_DYNAMIC_STATE_DEPTH_BIAS,
       VK_DYNAMIC_STATE_BLEND_CONSTANTS,