diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index 1de31d25221..ffe2ae6db43 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -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]); diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index ae76e62dd1b..28a98f43faf 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -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; } } diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index d8d8d8691c3..10b95d2bfd5 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -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]; diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 80418dd2df6..ab15bb9c15f 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -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) diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c index c95def406a8..92d422942e5 100644 --- a/src/gallium/drivers/zink/zink_pipeline.c +++ b/src/gallium/drivers/zink/zink_pipeline.c @@ -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,