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: f6fa4a8000 ("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>
This commit is contained in:
Tapani Pälli 2021-06-15 09:55:51 +03:00 committed by Marge Bot
parent 43b99e48b1
commit 55951ac28e
7 changed files with 297 additions and 128 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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,

View file

@ -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)];

View file

@ -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) ?
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);

View file

@ -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,15 +369,42 @@ 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];
/* 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_PRIMITIVE_TOPOLOGY) {
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;
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);
}
cmd_buffer->state.gfx.primitive_topology = topology;
}
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
@ -359,25 +416,9 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
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;
/* 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) {
uint32_t dwords[GENX(3DSTATE_WM_length)];
struct GENX(3DSTATE_WM) wm = {
GENX(3DSTATE_WM_header),
.ThreadDispatchEnable = pipeline->force_fragment_thread_dispatch ||
color_writes,
};
GENX(3DSTATE_WM_pack)(NULL, dwords, &wm);
anv_batch_emit_merge(&cmd_buffer->batch, dwords, pipeline->gfx7.wm);
}
/* Blend states of each RT */
uint32_t surface_count = 0;
struct anv_pipeline_bind_map *map;

View file

@ -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,