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 <tapani.palli@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5604>
This commit is contained in:
Tapani Pälli
2020-06-10 10:52:29 +03:00
committed by Marge Bot
parent 11f3fb9a4e
commit c34d8ac26e
4 changed files with 88 additions and 54 deletions

View File

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

View File

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

View File

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

View File

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