diff options
Diffstat (limited to 'src/intel/vulkan/genX_pipeline.c')
-rw-r--r-- | src/intel/vulkan/genX_pipeline.c | 87 |
1 files changed, 85 insertions, 2 deletions
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index e35bb5e3405..5660711692c 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -448,6 +448,79 @@ static const uint32_t vk_to_gen_front_face[] = { [VK_FRONT_FACE_CLOCKWISE] = 0 }; +/** Returns the final polygon mode for rasterization + * + * This function takes into account polygon mode, primitive topology and the + * different shader stages which might generate their own type of primitives. + */ +static VkPolygonMode +anv_raster_polygon_mode(struct anv_pipeline *pipeline, + const VkPipelineInputAssemblyStateCreateInfo *ia_info, + const VkPipelineRasterizationStateCreateInfo *rs_info) +{ + /* Points always override everything. This saves us from having to handle + * rs_info->polygonMode in all of the line cases below. + */ + if (rs_info->polygonMode == VK_POLYGON_MODE_POINT) + return VK_POLYGON_MODE_POINT; + + if (anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY)) { + switch (get_gs_prog_data(pipeline)->output_topology) { + case _3DPRIM_POINTLIST: + return VK_POLYGON_MODE_POINT; + + case _3DPRIM_LINELIST: + case _3DPRIM_LINESTRIP: + case _3DPRIM_LINELOOP: + return VK_POLYGON_MODE_LINE; + + case _3DPRIM_TRILIST: + case _3DPRIM_TRIFAN: + case _3DPRIM_TRISTRIP: + case _3DPRIM_RECTLIST: + case _3DPRIM_QUADLIST: + case _3DPRIM_QUADSTRIP: + case _3DPRIM_POLYGON: + return rs_info->polygonMode; + } + unreachable("Unsupported GS output topology"); + } else if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) { + switch (get_tes_prog_data(pipeline)->output_topology) { + case BRW_TESS_OUTPUT_TOPOLOGY_POINT: + return VK_POLYGON_MODE_POINT; + + case BRW_TESS_OUTPUT_TOPOLOGY_LINE: + return VK_POLYGON_MODE_LINE; + + case BRW_TESS_OUTPUT_TOPOLOGY_TRI_CW: + case BRW_TESS_OUTPUT_TOPOLOGY_TRI_CCW: + return rs_info->polygonMode; + } + unreachable("Unsupported TCS output topology"); + } else { + switch (ia_info->topology) { + case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: + return VK_POLYGON_MODE_POINT; + + case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: + case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: + case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: + case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: + return VK_POLYGON_MODE_LINE; + + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: + return rs_info->polygonMode; + + default: + unreachable("Unsupported primitive topology"); + } + } +} + static void emit_rs_state(struct anv_pipeline *pipeline, const VkPipelineRasterizationStateCreateInfo *rs_info, @@ -1066,6 +1139,7 @@ emit_cb_state(struct anv_pipeline *pipeline, static void emit_3dstate_clip(struct anv_pipeline *pipeline, + const VkPipelineInputAssemblyStateCreateInfo *ia_info, const VkPipelineViewportStateCreateInfo *vp_info, const VkPipelineRasterizationStateCreateInfo *rs_info) { @@ -1076,9 +1150,16 @@ emit_3dstate_clip(struct anv_pipeline *pipeline, clip.StatisticsEnable = true; clip.EarlyCullEnable = true; clip.APIMode = APIMODE_D3D, - clip.ViewportXYClipTestEnable = true; 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; #endif @@ -1952,7 +2033,9 @@ genX(graphics_pipeline_create)( emit_urb_setup(pipeline); - emit_3dstate_clip(pipeline, pCreateInfo->pViewportState, + emit_3dstate_clip(pipeline, + pCreateInfo->pInputAssemblyState, + pCreateInfo->pViewportState, pCreateInfo->pRasterizationState); emit_3dstate_streamout(pipeline, pCreateInfo->pRasterizationState); |