summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2021-06-15 09:55:51 +0300
committerMarge Bot <eric+marge@anholt.net>2021-06-23 12:01:45 +0000
commit55951ac28e7a30c2fae762990962a4410669c989 (patch)
tree4490fe421f34c652e0922e60d4fdc8bff02a932a /src
parent43b99e48b13f462ff2325e35ba3df930ab0ee06c (diff)
anv: fix emitting dynamic primitive topology
Initial implementation missed various fields that derive from the primitive topology. This patch fixes 3DSTATE_RASTER/3DSTATE_SF, 3DSTATE_CLIP and 3DSTATE_WM (gen7.x) emission in the dynamic case. Fixes: f6fa4a80000 ("anv: add support for dynamic primitive topology change") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4924 Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11379>
Diffstat (limited to 'src')
-rw-r--r--src/intel/vulkan/anv_genX.h14
-rw-r--r--src/intel/vulkan/anv_pipeline.c43
-rw-r--r--src/intel/vulkan/anv_private.h17
-rw-r--r--src/intel/vulkan/genX_cmd_buffer.c19
-rw-r--r--src/intel/vulkan/genX_pipeline.c179
-rw-r--r--src/intel/vulkan/gfx7_cmd_buffer.c87
-rw-r--r--src/intel/vulkan/gfx8_cmd_buffer.c62
7 files changed, 295 insertions, 126 deletions
diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
index 3f7aa7eaba2..1a595029d2f 100644
--- a/src/intel/vulkan/anv_genX.h
+++ b/src/intel/vulkan/anv_genX.h
@@ -126,3 +126,17 @@ void genX(blorp_exec)(struct blorp_batch *batch,
void genX(cmd_emit_timestamp)(struct anv_batch *batch,
struct anv_bo *bo,
uint32_t offset);
+
+void
+genX(rasterization_mode)(VkPolygonMode raster_mode,
+ VkLineRasterizationModeEXT line_mode,
+ uint32_t *api_mode,
+ bool *msaa_rasterization_enable);
+
+uint32_t
+genX(ms_rasterization_mode)(struct anv_graphics_pipeline *pipeline,
+ VkPolygonMode raster_mode);
+
+VkPolygonMode
+genX(raster_polygon_mode)(struct anv_graphics_pipeline *pipeline,
+ VkPrimitiveTopology primitive_topology);
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index 3eee533628f..2855e36cc17 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -2244,7 +2244,8 @@ copy_non_dynamic_state(struct anv_graphics_pipeline *pipeline,
ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |
ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE |
ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE |
- ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP);
+ ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP |
+ ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);
}
static void
@@ -2321,6 +2322,25 @@ anv_pipeline_setup_l3_config(struct anv_pipeline *pipeline, bool needs_slm)
pipeline->l3_config = intel_get_l3_config(devinfo, w);
}
+static VkLineRasterizationModeEXT
+vk_line_rasterization_mode(const VkPipelineRasterizationLineStateCreateInfoEXT *line_info,
+ const VkPipelineMultisampleStateCreateInfo *ms_info)
+{
+ VkLineRasterizationModeEXT line_mode =
+ line_info ? line_info->lineRasterizationMode :
+ VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
+
+ if (line_mode == VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT) {
+ if (ms_info && ms_info->rasterizationSamples > 1) {
+ return VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
+ } else {
+ return VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
+ }
+ }
+
+ return line_mode;
+}
+
VkResult
anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
struct anv_device *device,
@@ -2461,6 +2481,27 @@ anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline,
else
pipeline->topology = vk_to_intel_primitive_type[ia_info->topology];
+ /* If rasterization is not enabled, ms_info must be ignored. */
+ const bool raster_enabled =
+ !pCreateInfo->pRasterizationState->rasterizerDiscardEnable ||
+ (pipeline->dynamic_states &
+ ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE);
+
+ const VkPipelineMultisampleStateCreateInfo *ms_info =
+ raster_enabled ? pCreateInfo->pMultisampleState : NULL;
+
+ const VkPipelineRasterizationLineStateCreateInfoEXT *line_info =
+ vk_find_struct_const(pCreateInfo->pRasterizationState->pNext,
+ PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
+
+ /* Store line mode, polygon mode and rasterization samples, these are used
+ * for dynamic primitive topology.
+ */
+ pipeline->line_mode = vk_line_rasterization_mode(line_info, ms_info);
+ pipeline->polygon_mode = pCreateInfo->pRasterizationState->polygonMode;
+ pipeline->rasterization_samples =
+ ms_info ? ms_info->rasterizationSamples : 1;
+
return VK_SUCCESS;
}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index be2d7ff3cb7..4172b07439e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -3529,6 +3529,13 @@ struct anv_graphics_pipeline {
uint32_t topology;
+ /* These fields are required with dynamic primitive topology,
+ * rasterization_samples used only with gen < 8.
+ */
+ VkLineRasterizationModeEXT line_mode;
+ VkPolygonMode polygon_mode;
+ uint32_t rasterization_samples;
+
struct anv_subpass * subpass;
struct anv_shader_bin * shaders[MESA_SHADER_STAGES];
@@ -4441,6 +4448,16 @@ anv_sanitize_image_offset(const VkImageType imageType,
}
}
+static inline uint32_t
+anv_rasterization_aa_mode(VkPolygonMode raster_mode,
+ VkLineRasterizationModeEXT line_mode)
+{
+ if (raster_mode == VK_POLYGON_MODE_LINE &&
+ line_mode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT)
+ return true;
+ return false;
+}
+
VkFormatFeatureFlags
anv_get_image_format_features(const struct intel_device_info *devinfo,
VkFormat vk_format,
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index 5e2b5b37796..47aba611b1f 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -3468,12 +3468,30 @@ cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
#endif
+ ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY |
ANV_CMD_DIRTY_DYNAMIC_VIEWPORT |
ANV_CMD_DIRTY_PIPELINE;
if ((cmd_buffer->state.gfx.dirty & clip_states) == 0)
return;
+ /* Take dynamic primitive topology in to account with
+ * 3DSTATE_CLIP::ViewportXYClipTestEnable
+ */
+ bool xy_clip_test_enable = 0;
+
+ if (cmd_buffer->state.gfx.pipeline->dynamic_states &
+ ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ VkPrimitiveTopology primitive_topology =
+ cmd_buffer->state.gfx.dynamic.primitive_topology;
+
+ VkPolygonMode dynamic_raster_mode =
+ genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
+ primitive_topology);
+
+ xy_clip_test_enable = (dynamic_raster_mode == VK_POLYGON_MODE_FILL);
+ }
+
#if GFX_VER <= 7
const struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
#endif
@@ -3483,6 +3501,7 @@ cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
.FrontWinding = genX(vk_to_intel_front_face)[d->front_face],
.CullMode = genX(vk_to_intel_cullmode)[d->cull_mode],
#endif
+ .ViewportXYClipTestEnable = xy_clip_test_enable,
};
uint32_t dwords[GENX(3DSTATE_CLIP_length)];
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index e7d79de63e8..005782f467b 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -445,34 +445,14 @@ emit_3dstate_sbe(struct anv_graphics_pipeline *pipeline)
#endif
}
-static VkLineRasterizationModeEXT
-vk_line_rasterization_mode(const VkPipelineRasterizationLineStateCreateInfoEXT *line_info,
- const VkPipelineMultisampleStateCreateInfo *ms_info)
-{
- VkLineRasterizationModeEXT line_mode =
- line_info ? line_info->lineRasterizationMode :
- VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
-
- if (line_mode == VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT) {
- if (ms_info && ms_info->rasterizationSamples > 1) {
- return VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
- } else {
- return VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
- }
- }
-
- return line_mode;
-}
-
/** 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_graphics_pipeline *pipeline,
- const VkPipelineInputAssemblyStateCreateInfo *ia_info,
- const VkPipelineRasterizationStateCreateInfo *rs_info)
+VkPolygonMode
+genX(raster_polygon_mode)(struct anv_graphics_pipeline *pipeline,
+ VkPrimitiveTopology primitive_topology)
{
if (anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY)) {
switch (get_gs_prog_data(pipeline)->output_topology) {
@@ -491,7 +471,7 @@ anv_raster_polygon_mode(struct anv_graphics_pipeline *pipeline,
case _3DPRIM_QUADLIST:
case _3DPRIM_QUADSTRIP:
case _3DPRIM_POLYGON:
- return rs_info->polygonMode;
+ return pipeline->polygon_mode;
}
unreachable("Unsupported GS output topology");
} else if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) {
@@ -504,11 +484,11 @@ anv_raster_polygon_mode(struct anv_graphics_pipeline *pipeline,
case BRW_TESS_OUTPUT_TOPOLOGY_TRI_CW:
case BRW_TESS_OUTPUT_TOPOLOGY_TRI_CCW:
- return rs_info->polygonMode;
+ return pipeline->polygon_mode;
}
unreachable("Unsupported TCS output topology");
} else {
- switch (ia_info->topology) {
+ switch (primitive_topology) {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return VK_POLYGON_MODE_POINT;
@@ -523,7 +503,7 @@ anv_raster_polygon_mode(struct anv_graphics_pipeline *pipeline,
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;
+ return pipeline->polygon_mode;
default:
unreachable("Unsupported primitive topology");
@@ -531,21 +511,13 @@ anv_raster_polygon_mode(struct anv_graphics_pipeline *pipeline,
}
}
-#if GFX_VER <= 7
-static uint32_t
-gfx7_ms_rast_mode(struct anv_graphics_pipeline *pipeline,
- const VkPipelineInputAssemblyStateCreateInfo *ia_info,
- const VkPipelineRasterizationStateCreateInfo *rs_info,
- const VkPipelineMultisampleStateCreateInfo *ms_info)
+uint32_t
+genX(ms_rasterization_mode)(struct anv_graphics_pipeline *pipeline,
+ VkPolygonMode raster_mode)
{
- const VkPipelineRasterizationLineStateCreateInfoEXT *line_info =
- vk_find_struct_const(rs_info->pNext,
- PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
-
- VkPolygonMode raster_mode =
- anv_raster_polygon_mode(pipeline, ia_info, rs_info);
+#if GFX_VER <= 7
if (raster_mode == VK_POLYGON_MODE_LINE) {
- switch (vk_line_rasterization_mode(line_info, ms_info)) {
+ switch (pipeline->line_mode) {
case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
return MSRASTMODE_ON_PATTERN;
@@ -557,11 +529,13 @@ gfx7_ms_rast_mode(struct anv_graphics_pipeline *pipeline,
unreachable("Unsupported line rasterization mode");
}
} else {
- return (ms_info && ms_info->rasterizationSamples > 1) ?
- MSRASTMODE_ON_PATTERN : MSRASTMODE_OFF_PIXEL;
+ return pipeline->rasterization_samples > 1 ?
+ MSRASTMODE_ON_PATTERN : MSRASTMODE_OFF_PIXEL;
}
-}
+#else
+ unreachable("Only on gen7");
#endif
+}
static VkProvokingVertexModeEXT
vk_provoking_vertex_mode(const VkPipelineRasterizationStateCreateInfo *rs_info)
@@ -603,6 +577,49 @@ vk_conservative_rasterization_mode(const VkPipelineRasterizationStateCreateInfo
}
#endif
+void
+genX(rasterization_mode)(VkPolygonMode raster_mode,
+ VkLineRasterizationModeEXT line_mode,
+ uint32_t *api_mode,
+ bool *msaa_rasterization_enable)
+{
+#if GFX_VER >= 8
+ if (raster_mode == VK_POLYGON_MODE_LINE) {
+ /* Unfortunately, configuring our line rasterization hardware on gfx8
+ * and later is rather painful. Instead of giving us bits to tell the
+ * hardware what line mode to use like we had on gfx7, we now have an
+ * arcane combination of API Mode and MSAA enable bits which do things
+ * in a table which are expected to magically put the hardware into the
+ * right mode for your API. Sadly, Vulkan isn't any of the APIs the
+ * hardware people thought of so nothing works the way you want it to.
+ *
+ * Look at the table titled "Multisample Rasterization Modes" in Vol 7
+ * of the Skylake PRM for more details.
+ */
+ switch (line_mode) {
+ case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
+ *api_mode = DX100;
+ *msaa_rasterization_enable = true;
+ break;
+
+ case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
+ case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
+ *api_mode = DX9OGL;
+ *msaa_rasterization_enable = false;
+ break;
+
+ default:
+ unreachable("Unsupported line rasterization mode");
+ }
+ } else {
+ *api_mode = DX100;
+ *msaa_rasterization_enable = true;
+ }
+#else
+ unreachable("Invalid call");
+#endif
+}
+
static void
emit_rs_state(struct anv_graphics_pipeline *pipeline,
const VkPipelineInputAssemblyStateCreateInfo *ia_info,
@@ -667,45 +684,18 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline,
#endif
VkPolygonMode raster_mode =
- anv_raster_polygon_mode(pipeline, ia_info, rs_info);
- VkLineRasterizationModeEXT line_mode =
- vk_line_rasterization_mode(line_info, ms_info);
+ genX(raster_polygon_mode)(pipeline, ia_info->topology);
+ bool dynamic_primitive_topology =
+ dynamic_states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
/* For details on 3DSTATE_RASTER multisample state, see the BSpec table
* "Multisample Modes State".
*/
#if GFX_VER >= 8
- if (raster_mode == VK_POLYGON_MODE_LINE) {
- /* Unfortunately, configuring our line rasterization hardware on gfx8
- * and later is rather painful. Instead of giving us bits to tell the
- * hardware what line mode to use like we had on gfx7, we now have an
- * arcane combination of API Mode and MSAA enable bits which do things
- * in a table which are expected to magically put the hardware into the
- * right mode for your API. Sadly, Vulkan isn't any of the APIs the
- * hardware people thought of so nothing works the way you want it to.
- *
- * Look at the table titled "Multisample Rasterization Modes" in Vol 7
- * of the Skylake PRM for more details.
- */
- switch (line_mode) {
- case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
- raster.APIMode = DX100;
- raster.DXMultisampleRasterizationEnable = true;
- break;
-
- case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
- case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
- raster.APIMode = DX9OGL;
- raster.DXMultisampleRasterizationEnable = false;
- break;
-
- default:
- unreachable("Unsupported line rasterization mode");
- }
- } else {
- raster.APIMode = DX100;
- raster.DXMultisampleRasterizationEnable = true;
- }
+ if (!dynamic_primitive_topology)
+ genX(rasterization_mode)(raster_mode, pipeline->line_mode,
+ &raster.APIMode,
+ &raster.DXMultisampleRasterizationEnable);
/* NOTE: 3DSTATE_RASTER::ForcedSampleCount affects the BDW and SKL PMA fix
* computations. If we ever set this bit to a different value, they will
@@ -714,13 +704,17 @@ emit_rs_state(struct anv_graphics_pipeline *pipeline,
raster.ForcedSampleCount = FSC_NUMRASTSAMPLES_0;
raster.ForceMultisampling = false;
#else
- raster.MultisampleRasterizationMode =
- gfx7_ms_rast_mode(pipeline, ia_info, rs_info, ms_info);
+ uint32_t ms_rast_mode = 0;
+
+ if (!dynamic_primitive_topology)
+ ms_rast_mode = genX(ms_rasterization_mode)(pipeline, raster_mode);
+
+ raster.MultisampleRasterizationMode = ms_rast_mode;
#endif
- if (raster_mode == VK_POLYGON_MODE_LINE &&
- line_mode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT)
- raster.AntialiasingEnable = true;
+ raster.AntialiasingEnable =
+ dynamic_primitive_topology ? 0 :
+ anv_rasterization_aa_mode(raster_mode, pipeline->line_mode);
raster.FrontWinding =
dynamic_states & ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE ?
@@ -1423,8 +1417,10 @@ emit_3dstate_clip(struct anv_graphics_pipeline *pipeline,
* 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);
+ genX(raster_polygon_mode)(pipeline, ia_info->topology);
+ clip.ViewportXYClipTestEnable =
+ dynamic_states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY ?
+ 0 : (raster_mode == VK_POLYGON_MODE_FILL);
#if GFX_VER >= 8
clip.VertexSubPixelPrecisionSelect = _8Bit;
@@ -2133,14 +2129,25 @@ emit_3dstate_wm(struct anv_graphics_pipeline *pipeline, struct anv_subpass *subp
} else {
wm.MultisampleDispatchMode = MSDISPMODE_PERSAMPLE;
}
+
+ VkPolygonMode raster_mode =
+ genX(raster_polygon_mode)(pipeline, ia->topology);
+
wm.MultisampleRasterizationMode =
- gfx7_ms_rast_mode(pipeline, ia, raster, multisample);
+ dynamic_states & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY ? 0 :
+ genX(ms_rasterization_mode)(pipeline, raster_mode);
#endif
wm.LineStippleEnable = line && line->stippledLineEnable;
}
- if (dynamic_states & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE) {
+ uint32_t dynamic_wm_states = ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
+
+#if GFX_VER < 8
+ dynamic_wm_states |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
+#endif
+
+ if (dynamic_states & dynamic_wm_states) {
const struct intel_device_info *devinfo = &pipeline->base.device->info;
uint32_t *dws = devinfo->ver >= 8 ? pipeline->gfx8.wm : pipeline->gfx7.wm;
GENX(3DSTATE_WM_pack)(NULL, dws, &wm);
diff --git a/src/intel/vulkan/gfx7_cmd_buffer.c b/src/intel/vulkan/gfx7_cmd_buffer.c
index ff808f27f3d..b092bd8c377 100644
--- a/src/intel/vulkan/gfx7_cmd_buffer.c
+++ b/src/intel/vulkan/gfx7_cmd_buffer.c
@@ -206,13 +206,42 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
+ if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ uint32_t topology;
+ if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
+ topology = pipeline->topology;
+ else
+ topology = genX(vk_to_intel_primitive_type)[d->primitive_topology];
+
+ cmd_buffer->state.gfx.primitive_topology = topology;
+ }
+
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_RENDER_TARGETS |
ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH |
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
- ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE)) {
+ ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
+ ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
+ /* Take dynamic primitive topology in to account with
+ * 3DSTATE_SF::MultisampleRasterizationMode
+ */
+ uint32_t ms_rast_mode = 0;
+
+ if (cmd_buffer->state.gfx.pipeline->dynamic_states &
+ ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ VkPrimitiveTopology primitive_topology =
+ cmd_buffer->state.gfx.dynamic.primitive_topology;
+
+ VkPolygonMode dynamic_raster_mode =
+ genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
+ primitive_topology);
+
+ ms_rast_mode =
+ genX(ms_rasterization_mode)(pipeline, dynamic_raster_mode);
+ }
+
uint32_t sf_dw[GENX(3DSTATE_SF_length)];
struct GENX(3DSTATE_SF) sf = {
GENX(3DSTATE_SF_header),
@@ -226,6 +255,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
.GlobalDepthOffsetEnableSolid = d->depth_bias_enable,
.GlobalDepthOffsetEnableWireframe = d->depth_bias_enable,
.GlobalDepthOffsetEnablePoint = d->depth_bias_enable,
+ .MultisampleRasterizationMode = ms_rast_mode,
};
GENX(3DSTATE_SF_pack)(NULL, sf_dw, &sf);
@@ -339,45 +369,56 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
}
}
- if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
- ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
- uint32_t topology;
- if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
- topology = pipeline->topology;
- else
- topology = genX(vk_to_intel_primitive_type)[d->primitive_topology];
-
- cmd_buffer->state.gfx.primitive_topology = topology;
- }
-
- if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
- genX(emit_multisample)(&cmd_buffer->batch,
- cmd_buffer->state.gfx.dynamic.sample_locations.samples,
- cmd_buffer->state.gfx.dynamic.sample_locations.locations);
- }
-
+ /* 3DSTATE_WM in the hope we can avoid spawning fragment shaders
+ * threads or if we have dirty dynamic primitive topology state and
+ * need to toggle 3DSTATE_WM::MultisampleRasterizationMode dynamically.
+ */
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE ||
- cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP) {
+ cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
const uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
- /* 3DSTATE_WM in the hope we can avoid spawning fragment shaders
- * threads.
- */
+
bool dirty_color_blend =
cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
- if (dirty_color_blend) {
+ bool dirty_primitive_topology =
+ cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
+
+ VkPolygonMode dynamic_raster_mode;
+ VkPrimitiveTopology primitive_topology =
+ cmd_buffer->state.gfx.dynamic.primitive_topology;
+ dynamic_raster_mode =
+ genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
+ primitive_topology);
+
+ if (dirty_color_blend || dirty_primitive_topology) {
uint32_t dwords[GENX(3DSTATE_WM_length)];
struct GENX(3DSTATE_WM) wm = {
GENX(3DSTATE_WM_header),
.ThreadDispatchEnable = pipeline->force_fragment_thread_dispatch ||
color_writes,
+ .MultisampleRasterizationMode =
+ genX(ms_rasterization_mode)(pipeline, dynamic_raster_mode),
};
GENX(3DSTATE_WM_pack)(NULL, dwords, &wm);
anv_batch_emit_merge(&cmd_buffer->batch, dwords, pipeline->gfx7.wm);
}
+ }
+
+ if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
+ genX(emit_multisample)(&cmd_buffer->batch,
+ cmd_buffer->state.gfx.dynamic.sample_locations.samples,
+ cmd_buffer->state.gfx.dynamic.sample_locations.locations);
+ }
+
+ if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE ||
+ cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP) {
+ const uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
+ bool dirty_color_blend =
+ cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
+
/* Blend states of each RT */
uint32_t surface_count = 0;
struct anv_pipeline_bind_map *map;
diff --git a/src/intel/vulkan/gfx8_cmd_buffer.c b/src/intel/vulkan/gfx8_cmd_buffer.c
index f428c022cf8..05092caab6c 100644
--- a/src/intel/vulkan/gfx8_cmd_buffer.c
+++ b/src/intel/vulkan/gfx8_cmd_buffer.c
@@ -420,6 +420,20 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic;
+ if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ uint32_t topology;
+ if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
+ topology = pipeline->topology;
+ else
+ topology = genX(vk_to_intel_primitive_type)[d->primitive_topology];
+
+ cmd_buffer->state.gfx.primitive_topology = topology;
+
+ anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_TOPOLOGY), vft) {
+ vft.PrimitiveTopologyType = topology;
+ }
+ }
+
if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH)) {
uint32_t sf_dw[GENX(3DSTATE_SF_length)];
@@ -443,10 +457,41 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |
ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |
ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |
- ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE)) {
+ ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |
+ ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
+ /* Take dynamic primitive topology in to account with
+ * 3DSTATE_RASTER::APIMode
+ * 3DSTATE_RASTER::DXMultisampleRasterizationEnable
+ * 3DSTATE_RASTER::AntialiasingEnable
+ */
+ uint32_t api_mode = 0;
+ bool msaa_raster_enable = false;
+ bool aa_enable = 0;
+
+ if (cmd_buffer->state.gfx.pipeline->dynamic_states &
+ ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) {
+ VkPrimitiveTopology primitive_topology =
+ cmd_buffer->state.gfx.dynamic.primitive_topology;
+
+ VkPolygonMode dynamic_raster_mode =
+ genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
+ primitive_topology);
+
+ genX(rasterization_mode)(
+ dynamic_raster_mode, pipeline->line_mode, &api_mode,
+ &msaa_raster_enable);
+
+ aa_enable =
+ anv_rasterization_aa_mode(dynamic_raster_mode,
+ pipeline->line_mode);
+ }
+
uint32_t raster_dw[GENX(3DSTATE_RASTER_length)];
struct GENX(3DSTATE_RASTER) raster = {
GENX(3DSTATE_RASTER_header),
+ .APIMode = api_mode,
+ .DXMultisampleRasterizationEnable = msaa_raster_enable,
+ .AntialiasingEnable = aa_enable,
.GlobalDepthOffsetConstant = d->depth_bias.bias,
.GlobalDepthOffsetScale = d->depth_bias.slope,
.GlobalDepthOffsetClamp = d->depth_bias.clamp,
@@ -638,21 +683,6 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
}
}
- if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
- ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) {
- uint32_t topology;
- if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
- topology = pipeline->topology;
- else
- topology = genX(vk_to_intel_primitive_type)[d->primitive_topology];
-
- cmd_buffer->state.gfx.primitive_topology = topology;
-
- anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF_TOPOLOGY), vft) {
- vft.PrimitiveTopologyType = topology;
- }
- }
-
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
genX(emit_sample_pattern)(&cmd_buffer->batch,
cmd_buffer->state.gfx.dynamic.sample_locations.samples,