From: Tapani Pälli Date: Wed, 10 Jun 2020 07:52:29 +0000 (+0300) Subject: anv: handle dynamic viewport count X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c34d8ac26e0a21c9036b4cfaf9e42c1e4298794f;p=mesa.git anv: handle dynamic viewport count Emit 3DSTATE_CLIP during cmd_buffer_flush_state so that we can change the max viewport count dynamically. v2: use one common clip state as size is the same for all gens (Lionel) Signed-off-by: Tapani Pälli Reviewed-by: Lionel Landwerlin Part-of: --- diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index eeb95ff823b..662daa0dd63 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -62,6 +62,8 @@ void genX(flush_pipeline_select_gpgpu)(struct anv_cmd_buffer *cmd_buffer); void genX(cmd_buffer_config_l3)(struct anv_cmd_buffer *cmd_buffer, const struct gen_l3_config *cfg); +void genX(cmd_buffer_emit_clip)(struct anv_cmd_buffer *cmd_buffer); + void genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer); void genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index d6b0f105799..957fa3d7b4a 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -3385,6 +3385,7 @@ struct anv_graphics_pipeline { struct { uint32_t sf[7]; uint32_t depth_stencil_state[3]; + uint32_t clip[4]; } gen7; struct { diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 34afcf7a505..773aa3b63c5 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3263,6 +3263,28 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer, cmd_buffer->state.push_constants_dirty &= ~flushed; } +void +genX(cmd_buffer_emit_clip)(struct anv_cmd_buffer *cmd_buffer) +{ + struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; + + if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE | + ANV_CMD_DIRTY_DYNAMIC_VIEWPORT)) { + uint32_t dwords[GENX(3DSTATE_CLIP_length)]; + int32_t count = + cmd_buffer->state.gfx.dynamic.viewport.count > 0 ? + cmd_buffer->state.gfx.dynamic.viewport.count - 1 : 0; + + struct GENX(3DSTATE_CLIP) clip = { + GENX(3DSTATE_CLIP_header), + .MaximumVPIndex = count, + }; + GENX(3DSTATE_CLIP_pack)(NULL, dwords, &clip); + anv_batch_emit_merge(&cmd_buffer->batch, dwords, + pipeline->gen7.clip); + } +} + void genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) { @@ -3434,8 +3456,10 @@ genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer) if (dirty) cmd_buffer_emit_descriptor_pointers(cmd_buffer, dirty); - if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) + if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) { + genX(cmd_buffer_emit_clip)(cmd_buffer); gen8_cmd_buffer_emit_viewport(cmd_buffer); + } if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_DYNAMIC_VIEWPORT | ANV_CMD_DIRTY_PIPELINE)) { diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index 80750eb2236..e76dd870d35 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -1277,74 +1277,80 @@ static void emit_3dstate_clip(struct anv_graphics_pipeline *pipeline, const VkPipelineInputAssemblyStateCreateInfo *ia_info, const VkPipelineViewportStateCreateInfo *vp_info, - const VkPipelineRasterizationStateCreateInfo *rs_info) + const VkPipelineRasterizationStateCreateInfo *rs_info, + const uint32_t dynamic_states) { const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline); (void) wm_prog_data; - anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_CLIP), clip) { - clip.ClipEnable = true; - clip.StatisticsEnable = true; - clip.EarlyCullEnable = true; - clip.APIMode = APIMODE_D3D; - clip.GuardbandClipTestEnable = true; - - /* Only enable the XY clip test when the final polygon rasterization - * mode is VK_POLYGON_MODE_FILL. We want to leave it disabled for - * points and lines so we get "pop-free" clipping. - */ - VkPolygonMode raster_mode = - anv_raster_polygon_mode(pipeline, ia_info, rs_info); - clip.ViewportXYClipTestEnable = (raster_mode == VK_POLYGON_MODE_FILL); + + struct GENX(3DSTATE_CLIP) clip = { + GENX(3DSTATE_CLIP_header), + }; + + clip.ClipEnable = true; + clip.StatisticsEnable = true; + clip.EarlyCullEnable = true; + clip.APIMode = APIMODE_D3D; + clip.GuardbandClipTestEnable = true; + + /* Only enable the XY clip test when the final polygon rasterization + * mode is VK_POLYGON_MODE_FILL. We want to leave it disabled for + * points and lines so we get "pop-free" clipping. + */ + VkPolygonMode raster_mode = + anv_raster_polygon_mode(pipeline, ia_info, rs_info); + clip.ViewportXYClipTestEnable = (raster_mode == VK_POLYGON_MODE_FILL); #if GEN_GEN >= 8 - clip.VertexSubPixelPrecisionSelect = _8Bit; + clip.VertexSubPixelPrecisionSelect = _8Bit; #endif + clip.ClipMode = CLIPMODE_NORMAL; - clip.ClipMode = CLIPMODE_NORMAL; - - clip.TriangleStripListProvokingVertexSelect = 0; - clip.LineStripListProvokingVertexSelect = 0; - clip.TriangleFanProvokingVertexSelect = 1; + clip.TriangleStripListProvokingVertexSelect = 0; + clip.LineStripListProvokingVertexSelect = 0; + clip.TriangleFanProvokingVertexSelect = 1; - clip.MinimumPointWidth = 0.125; - clip.MaximumPointWidth = 255.875; + clip.MinimumPointWidth = 0.125; + clip.MaximumPointWidth = 255.875; - const struct brw_vue_prog_data *last = - anv_pipeline_get_last_vue_prog_data(pipeline); + const struct brw_vue_prog_data *last = + anv_pipeline_get_last_vue_prog_data(pipeline); - /* From the Vulkan 1.0.45 spec: - * - * "If the last active vertex processing stage shader entry point's - * interface does not include a variable decorated with - * ViewportIndex, then the first viewport is used." - */ - if (vp_info && (last->vue_map.slots_valid & VARYING_BIT_VIEWPORT)) { - clip.MaximumVPIndex = vp_info->viewportCount - 1; - } else { - clip.MaximumVPIndex = 0; - } + /* From the Vulkan 1.0.45 spec: + * + * "If the last active vertex processing stage shader entry point's + * interface does not include a variable decorated with + * ViewportIndex, then the first viewport is used." + */ + if (vp_info && (last->vue_map.slots_valid & VARYING_BIT_VIEWPORT)) { + clip.MaximumVPIndex = vp_info->viewportCount > 0 ? + vp_info->viewportCount - 1 : 0; + } else { + clip.MaximumVPIndex = 0; + } - /* From the Vulkan 1.0.45 spec: - * - * "If the last active vertex processing stage shader entry point's - * interface does not include a variable decorated with Layer, then - * the first layer is used." - */ - clip.ForceZeroRTAIndexEnable = - !(last->vue_map.slots_valid & VARYING_BIT_LAYER); + /* From the Vulkan 1.0.45 spec: + * + * "If the last active vertex processing stage shader entry point's + * interface does not include a variable decorated with Layer, then + * the first layer is used." + */ + clip.ForceZeroRTAIndexEnable = + !(last->vue_map.slots_valid & VARYING_BIT_LAYER); #if GEN_GEN == 7 - clip.FrontWinding = vk_to_gen_front_face[rs_info->frontFace]; - clip.CullMode = vk_to_gen_cullmode[rs_info->cullMode]; - clip.ViewportZClipTestEnable = pipeline->depth_clip_enable; - clip.UserClipDistanceClipTestEnableBitmask = last->clip_distance_mask; - clip.UserClipDistanceCullTestEnableBitmask = last->cull_distance_mask; + clip.FrontWinding = vk_to_gen_front_face[rs_info->frontFace]; + clip.CullMode = vk_to_gen_cullmode[rs_info->cullMode]; + clip.ViewportZClipTestEnable = pipeline->depth_clip_enable; + clip.UserClipDistanceClipTestEnableBitmask = last->clip_distance_mask; + clip.UserClipDistanceCullTestEnableBitmask = last->cull_distance_mask; #else - clip.NonPerspectiveBarycentricEnable = wm_prog_data ? - (wm_prog_data->barycentric_interp_modes & - BRW_BARYCENTRIC_NONPERSPECTIVE_BITS) != 0 : 0; + clip.NonPerspectiveBarycentricEnable = wm_prog_data ? + (wm_prog_data->barycentric_interp_modes & + BRW_BARYCENTRIC_NONPERSPECTIVE_BITS) != 0 : 0; #endif - } + + GENX(3DSTATE_CLIP_pack)(NULL, pipeline->gen7.clip, &clip); } static void @@ -2260,7 +2266,8 @@ genX(graphics_pipeline_create)( emit_3dstate_clip(pipeline, pCreateInfo->pInputAssemblyState, vp_info, - pCreateInfo->pRasterizationState); + pCreateInfo->pRasterizationState, + dynamic_states); emit_3dstate_streamout(pipeline, pCreateInfo->pRasterizationState); #if GEN_GEN == 12