Module: Mesa Branch: main Commit: 4031443a4a6269a5e42ae53c6473e669f97a1d5d URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4031443a4a6269a5e42ae53c6473e669f97a1d5d
Author: Tapani Pälli <tapani.pa...@intel.com> Date: Mon Oct 30 15:25:39 2023 +0200 iris: implement Wa_18020335297 Set some state and implement dummy draws whenever viewport pointer is being reprogrammed. Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25987> --- src/gallium/drivers/iris/iris_context.h | 3 + src/gallium/drivers/iris/iris_state.c | 118 +++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index cefc62a82fc..b59d23f555f 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -829,6 +829,9 @@ struct iris_context { bool color_blend_zero; bool alpha_blend_zero; + /** State tracking for Wa_18020335297. */ + bool viewport_ptr_set; + /** Do we have integer RT in current framebuffer state? */ bool has_integer_rt; diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index c0a4c9130bc..97121b2adc0 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -6492,6 +6492,87 @@ shader_program_needs_wa_14015055625(struct iris_context *ice, gs_prog_data && gs_prog_data->include_primitive_id; } +static void +emit_wa_18020335297_dummy_draw(struct iris_batch *batch) +{ +#if GFX_VERx10 >= 125 + iris_emit_cmd(batch, GENX(3DSTATE_VFG), vfg) { + vfg.DistributionMode = RR_STRICT; + } + iris_emit_cmd(batch, GENX(3DSTATE_VF), vf) { + vf.GeometryDistributionEnable = true; + } +#endif + +#if GFX_VER >= 12 + iris_emit_cmd(batch, GENX(3DSTATE_PRIMITIVE_REPLICATION), pr) { + pr.ReplicaMask = 1; + } +#endif + + iris_emit_cmd(batch, GENX(3DSTATE_RASTER), rr) { + rr.CullMode = CULLMODE_NONE; + rr.FrontFaceFillMode = FILL_MODE_SOLID; + rr.BackFaceFillMode = FILL_MODE_SOLID; + } + + iris_emit_cmd(batch, GENX(3DSTATE_VF_STATISTICS), vf) { } + iris_emit_cmd(batch, GENX(3DSTATE_VF_SGVS), sgvs) { } + +#if GFX_VER >= 11 + iris_emit_cmd(batch, GENX(3DSTATE_VF_SGVS_2), sgvs2) { } +#endif + + iris_emit_cmd(batch, GENX(3DSTATE_CLIP), clip) { + clip.ClipEnable = true; + clip.ClipMode = CLIPMODE_REJECT_ALL; + } + + iris_emit_cmd(batch, GENX(3DSTATE_VS), vs) { } + iris_emit_cmd(batch, GENX(3DSTATE_GS), gs) { } + iris_emit_cmd(batch, GENX(3DSTATE_HS), hs) { } + iris_emit_cmd(batch, GENX(3DSTATE_TE), te) { } + iris_emit_cmd(batch, GENX(3DSTATE_DS), ds) { } + iris_emit_cmd(batch, GENX(3DSTATE_STREAMOUT), so) { } + + uint32_t vertex_elements[1 + 2 * GENX(VERTEX_ELEMENT_STATE_length)]; + uint32_t *ve_pack_dest = &vertex_elements[1]; + + iris_pack_command(GENX(3DSTATE_VERTEX_ELEMENTS), vertex_elements, ve) { + ve.DWordLength = 1 + GENX(VERTEX_ELEMENT_STATE_length) * 2 - + GENX(3DSTATE_VERTEX_ELEMENTS_length_bias); + } + + for (int i = 0; i < 2; i++) { + iris_pack_state(GENX(VERTEX_ELEMENT_STATE), ve_pack_dest, ve) { + ve.Valid = true; + ve.SourceElementFormat = ISL_FORMAT_R32G32B32A32_FLOAT; + ve.Component0Control = VFCOMP_STORE_0; + ve.Component1Control = VFCOMP_STORE_0; + ve.Component2Control = i == 0 ? VFCOMP_STORE_0 : VFCOMP_STORE_1_FP; + ve.Component3Control = i == 0 ? VFCOMP_STORE_0 : VFCOMP_STORE_1_FP; + } + ve_pack_dest += GENX(VERTEX_ELEMENT_STATE_length); + } + + iris_batch_emit(batch, vertex_elements, sizeof(uint32_t) * + (1 + 2 * GENX(VERTEX_ELEMENT_STATE_length))); + + iris_emit_cmd(batch, GENX(3DSTATE_VF_TOPOLOGY), topo) { + topo.PrimitiveTopologyType = _3DPRIM_TRILIST; + } + + /* Emit dummy draw per slice. */ + for (unsigned i = 0; i < batch->screen->devinfo->num_slices; i++) { + iris_emit_cmd(batch, GENX(3DPRIMITIVE), prim) { + prim.VertexCountPerInstance = 3; + prim.PrimitiveTopologyType = _3DPRIM_TRILIST; + prim.InstanceCount = 1; + prim.VertexAccessType = SEQUENTIAL; + } + } +} + static void iris_upload_dirty_render_state(struct iris_context *ice, struct iris_batch *batch, @@ -6510,8 +6591,8 @@ iris_upload_dirty_render_state(struct iris_context *ice, ice->shaders.prog[MESA_SHADER_TESS_EVAL]) ice->state.stage_dirty |= IRIS_STAGE_DIRTY_TES; - const uint64_t dirty = ice->state.dirty; - const uint64_t stage_dirty = ice->state.stage_dirty; + uint64_t dirty = ice->state.dirty; + uint64_t stage_dirty = ice->state.stage_dirty; if (!(dirty & IRIS_ALL_DIRTY_FOR_RENDER) && !(stage_dirty & IRIS_ALL_STAGE_DIRTY_FOR_RENDER)) @@ -6533,6 +6614,15 @@ iris_upload_dirty_render_state(struct iris_context *ice, if (dirty & IRIS_DIRTY_CC_VIEWPORT) { const struct iris_rasterizer_state *cso_rast = ice->state.cso_rast; uint32_t cc_vp_address; + bool wa_18020335297_applied = false; + + /* Wa_18020335297 - Apply the WA when viewport ptr is reprogrammed. */ + if (intel_needs_workaround(screen->devinfo, 18020335297) && + batch->name == IRIS_BATCH_RENDER && + ice->state.viewport_ptr_set) { + emit_wa_18020335297_dummy_draw(batch); + wa_18020335297_applied = true; + } /* XXX: could avoid streaming for depth_clip [0,1] case. */ uint32_t *cc_vp_map = @@ -6561,6 +6651,30 @@ iris_upload_dirty_render_state(struct iris_context *ice, iris_emit_cmd(batch, GENX(3DSTATE_VIEWPORT_STATE_POINTERS_CC), ptr) { ptr.CCViewportPointer = cc_vp_address; } + + if (wa_18020335297_applied) { +#if GFX_VER >= 12 + iris_emit_cmd(batch, GENX(3DSTATE_PRIMITIVE_REPLICATION), pr) { } +#endif + /* Dirty all emitted WA state to make sure that current real + * state is restored. + */ + dirty |= IRIS_DIRTY_VFG | + IRIS_DIRTY_VF | + IRIS_DIRTY_RASTER | + IRIS_DIRTY_VF_STATISTICS | + IRIS_DIRTY_VF_SGVS | + IRIS_DIRTY_CLIP | + IRIS_DIRTY_STREAMOUT | + IRIS_DIRTY_VERTEX_ELEMENTS | + IRIS_DIRTY_VF_TOPOLOGY; + + for (int stage = 0; stage < MESA_SHADER_FRAGMENT; stage++) { + if (ice->shaders.prog[stage]) + stage_dirty |= (IRIS_STAGE_DIRTY_VS << stage); + } + } + ice->state.viewport_ptr_set = true; } if (dirty & IRIS_DIRTY_SF_CL_VIEWPORT) {