mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 13:20:14 +01:00
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:
parent
43b99e48b1
commit
55951ac28e
7 changed files with 297 additions and 128 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)];
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue