1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include <assert.h>
25bf215546Sopenharmony_ci#include <stdbool.h>
26bf215546Sopenharmony_ci#include <string.h>
27bf215546Sopenharmony_ci#include <unistd.h>
28bf215546Sopenharmony_ci#include <fcntl.h>
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "anv_private.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "genxml/gen_macros.h"
33bf215546Sopenharmony_ci#include "genxml/genX_pack.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_civoid
36bf215546Sopenharmony_cigenX(cmd_buffer_enable_pma_fix)(struct anv_cmd_buffer *cmd_buffer, bool enable)
37bf215546Sopenharmony_ci{
38bf215546Sopenharmony_ci   if (cmd_buffer->state.pma_fix_enabled == enable)
39bf215546Sopenharmony_ci      return;
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci   cmd_buffer->state.pma_fix_enabled = enable;
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci   /* According to the Broadwell PIPE_CONTROL documentation, software should
44bf215546Sopenharmony_ci    * emit a PIPE_CONTROL with the CS Stall and Depth Cache Flush bits set
45bf215546Sopenharmony_ci    * prior to the LRI.  If stencil buffer writes are enabled, then a Render
46bf215546Sopenharmony_ci    * Cache Flush is also necessary.
47bf215546Sopenharmony_ci    *
48bf215546Sopenharmony_ci    * The Skylake docs say to use a depth stall rather than a command
49bf215546Sopenharmony_ci    * streamer stall.  However, the hardware seems to violently disagree.
50bf215546Sopenharmony_ci    * A full command streamer stall seems to be needed in both cases.
51bf215546Sopenharmony_ci    */
52bf215546Sopenharmony_ci   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
53bf215546Sopenharmony_ci      pc.DepthCacheFlushEnable = true;
54bf215546Sopenharmony_ci      pc.CommandStreamerStallEnable = true;
55bf215546Sopenharmony_ci      pc.RenderTargetCacheFlushEnable = true;
56bf215546Sopenharmony_ci#if GFX_VER >= 12
57bf215546Sopenharmony_ci      pc.TileCacheFlushEnable = true;
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci      /* Wa_1409600907: "PIPE_CONTROL with Depth Stall Enable bit must
60bf215546Sopenharmony_ci       * be set with any PIPE_CONTROL with Depth Flush Enable bit set.
61bf215546Sopenharmony_ci       */
62bf215546Sopenharmony_ci      pc.DepthStallEnable = true;
63bf215546Sopenharmony_ci#endif
64bf215546Sopenharmony_ci   }
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci#if GFX_VER == 9
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   uint32_t cache_mode;
69bf215546Sopenharmony_ci   anv_pack_struct(&cache_mode, GENX(CACHE_MODE_0),
70bf215546Sopenharmony_ci                   .STCPMAOptimizationEnable = enable,
71bf215546Sopenharmony_ci                   .STCPMAOptimizationEnableMask = true);
72bf215546Sopenharmony_ci   anv_batch_emit(&cmd_buffer->batch, GENX(MI_LOAD_REGISTER_IMM), lri) {
73bf215546Sopenharmony_ci      lri.RegisterOffset   = GENX(CACHE_MODE_0_num);
74bf215546Sopenharmony_ci      lri.DataDWord        = cache_mode;
75bf215546Sopenharmony_ci   }
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci#elif GFX_VER == 8
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci   uint32_t cache_mode;
80bf215546Sopenharmony_ci   anv_pack_struct(&cache_mode, GENX(CACHE_MODE_1),
81bf215546Sopenharmony_ci                   .NPPMAFixEnable = enable,
82bf215546Sopenharmony_ci                   .NPEarlyZFailsDisable = enable,
83bf215546Sopenharmony_ci                   .NPPMAFixEnableMask = true,
84bf215546Sopenharmony_ci                   .NPEarlyZFailsDisableMask = true);
85bf215546Sopenharmony_ci   anv_batch_emit(&cmd_buffer->batch, GENX(MI_LOAD_REGISTER_IMM), lri) {
86bf215546Sopenharmony_ci      lri.RegisterOffset   = GENX(CACHE_MODE_1_num);
87bf215546Sopenharmony_ci      lri.DataDWord        = cache_mode;
88bf215546Sopenharmony_ci   }
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci#endif /* GFX_VER == 8 */
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   /* After the LRI, a PIPE_CONTROL with both the Depth Stall and Depth Cache
93bf215546Sopenharmony_ci    * Flush bits is often necessary.  We do it regardless because it's easier.
94bf215546Sopenharmony_ci    * The render cache flush is also necessary if stencil writes are enabled.
95bf215546Sopenharmony_ci    *
96bf215546Sopenharmony_ci    * Again, the Skylake docs give a different set of flushes but the BDW
97bf215546Sopenharmony_ci    * flushes seem to work just as well.
98bf215546Sopenharmony_ci    */
99bf215546Sopenharmony_ci   anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
100bf215546Sopenharmony_ci      pc.DepthStallEnable = true;
101bf215546Sopenharmony_ci      pc.DepthCacheFlushEnable = true;
102bf215546Sopenharmony_ci      pc.RenderTargetCacheFlushEnable = true;
103bf215546Sopenharmony_ci#if GFX_VER >= 12
104bf215546Sopenharmony_ci      pc.TileCacheFlushEnable = true;
105bf215546Sopenharmony_ci#endif
106bf215546Sopenharmony_ci   }
107bf215546Sopenharmony_ci}
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ciUNUSED static bool
110bf215546Sopenharmony_ciwant_depth_pma_fix(struct anv_cmd_buffer *cmd_buffer,
111bf215546Sopenharmony_ci                   const struct vk_depth_stencil_state *ds)
112bf215546Sopenharmony_ci{
113bf215546Sopenharmony_ci   assert(GFX_VER == 8);
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci   /* From the Broadwell PRM Vol. 2c CACHE_MODE_1::NP_PMA_FIX_ENABLE:
116bf215546Sopenharmony_ci    *
117bf215546Sopenharmony_ci    *    SW must set this bit in order to enable this fix when following
118bf215546Sopenharmony_ci    *    expression is TRUE.
119bf215546Sopenharmony_ci    *
120bf215546Sopenharmony_ci    *    3DSTATE_WM::ForceThreadDispatch != 1 &&
121bf215546Sopenharmony_ci    *    !(3DSTATE_RASTER::ForceSampleCount != NUMRASTSAMPLES_0) &&
122bf215546Sopenharmony_ci    *    (3DSTATE_DEPTH_BUFFER::SURFACE_TYPE != NULL) &&
123bf215546Sopenharmony_ci    *    (3DSTATE_DEPTH_BUFFER::HIZ Enable) &&
124bf215546Sopenharmony_ci    *    !(3DSTATE_WM::EDSC_Mode == EDSC_PREPS) &&
125bf215546Sopenharmony_ci    *    (3DSTATE_PS_EXTRA::PixelShaderValid) &&
126bf215546Sopenharmony_ci    *    !(3DSTATE_WM_HZ_OP::DepthBufferClear ||
127bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::DepthBufferResolve ||
128bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::Hierarchical Depth Buffer Resolve Enable ||
129bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::StencilBufferClear) &&
130bf215546Sopenharmony_ci    *    (3DSTATE_WM_DEPTH_STENCIL::DepthTestEnable) &&
131bf215546Sopenharmony_ci    *    (((3DSTATE_PS_EXTRA::PixelShaderKillsPixels ||
132bf215546Sopenharmony_ci    *       3DSTATE_PS_EXTRA::oMask Present to RenderTarget ||
133bf215546Sopenharmony_ci    *       3DSTATE_PS_BLEND::AlphaToCoverageEnable ||
134bf215546Sopenharmony_ci    *       3DSTATE_PS_BLEND::AlphaTestEnable ||
135bf215546Sopenharmony_ci    *       3DSTATE_WM_CHROMAKEY::ChromaKeyKillEnable) &&
136bf215546Sopenharmony_ci    *      3DSTATE_WM::ForceKillPix != ForceOff &&
137bf215546Sopenharmony_ci    *      ((3DSTATE_WM_DEPTH_STENCIL::DepthWriteEnable &&
138bf215546Sopenharmony_ci    *        3DSTATE_DEPTH_BUFFER::DEPTH_WRITE_ENABLE) ||
139bf215546Sopenharmony_ci    *       (3DSTATE_WM_DEPTH_STENCIL::Stencil Buffer Write Enable &&
140bf215546Sopenharmony_ci    *        3DSTATE_DEPTH_BUFFER::STENCIL_WRITE_ENABLE &&
141bf215546Sopenharmony_ci    *        3DSTATE_STENCIL_BUFFER::STENCIL_BUFFER_ENABLE))) ||
142bf215546Sopenharmony_ci    *     (3DSTATE_PS_EXTRA:: Pixel Shader Computed Depth mode != PSCDEPTH_OFF))
143bf215546Sopenharmony_ci    */
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci   /* These are always true:
146bf215546Sopenharmony_ci    *    3DSTATE_WM::ForceThreadDispatch != 1 &&
147bf215546Sopenharmony_ci    *    !(3DSTATE_RASTER::ForceSampleCount != NUMRASTSAMPLES_0)
148bf215546Sopenharmony_ci    */
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci   /* We only enable the PMA fix if we know for certain that HiZ is enabled.
151bf215546Sopenharmony_ci    * If we don't know whether HiZ is enabled or not, we disable the PMA fix
152bf215546Sopenharmony_ci    * and there is no harm.
153bf215546Sopenharmony_ci    *
154bf215546Sopenharmony_ci    * (3DSTATE_DEPTH_BUFFER::SURFACE_TYPE != NULL) &&
155bf215546Sopenharmony_ci    * 3DSTATE_DEPTH_BUFFER::HIZ Enable
156bf215546Sopenharmony_ci    */
157bf215546Sopenharmony_ci   if (!cmd_buffer->state.hiz_enabled)
158bf215546Sopenharmony_ci      return false;
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ci   /* 3DSTATE_PS_EXTRA::PixelShaderValid */
161bf215546Sopenharmony_ci   struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
162bf215546Sopenharmony_ci   if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT))
163bf215546Sopenharmony_ci      return false;
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   /* !(3DSTATE_WM::EDSC_Mode == EDSC_PREPS) */
166bf215546Sopenharmony_ci   const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
167bf215546Sopenharmony_ci   if (wm_prog_data->early_fragment_tests)
168bf215546Sopenharmony_ci      return false;
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci   /* We never use anv_pipeline for HiZ ops so this is trivially true:
171bf215546Sopenharmony_ci    *    !(3DSTATE_WM_HZ_OP::DepthBufferClear ||
172bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::DepthBufferResolve ||
173bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::Hierarchical Depth Buffer Resolve Enable ||
174bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::StencilBufferClear)
175bf215546Sopenharmony_ci    */
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci   /* 3DSTATE_WM_DEPTH_STENCIL::DepthTestEnable */
178bf215546Sopenharmony_ci   if (!ds->depth.test_enable)
179bf215546Sopenharmony_ci      return false;
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci   /* (((3DSTATE_PS_EXTRA::PixelShaderKillsPixels ||
182bf215546Sopenharmony_ci    *    3DSTATE_PS_EXTRA::oMask Present to RenderTarget ||
183bf215546Sopenharmony_ci    *    3DSTATE_PS_BLEND::AlphaToCoverageEnable ||
184bf215546Sopenharmony_ci    *    3DSTATE_PS_BLEND::AlphaTestEnable ||
185bf215546Sopenharmony_ci    *    3DSTATE_WM_CHROMAKEY::ChromaKeyKillEnable) &&
186bf215546Sopenharmony_ci    *   3DSTATE_WM::ForceKillPix != ForceOff &&
187bf215546Sopenharmony_ci    *   ((3DSTATE_WM_DEPTH_STENCIL::DepthWriteEnable &&
188bf215546Sopenharmony_ci    *     3DSTATE_DEPTH_BUFFER::DEPTH_WRITE_ENABLE) ||
189bf215546Sopenharmony_ci    *    (3DSTATE_WM_DEPTH_STENCIL::Stencil Buffer Write Enable &&
190bf215546Sopenharmony_ci    *     3DSTATE_DEPTH_BUFFER::STENCIL_WRITE_ENABLE &&
191bf215546Sopenharmony_ci    *     3DSTATE_STENCIL_BUFFER::STENCIL_BUFFER_ENABLE))) ||
192bf215546Sopenharmony_ci    *  (3DSTATE_PS_EXTRA:: Pixel Shader Computed Depth mode != PSCDEPTH_OFF))
193bf215546Sopenharmony_ci    */
194bf215546Sopenharmony_ci   return (pipeline->kill_pixel && (ds->depth.write_enable ||
195bf215546Sopenharmony_ci                                    ds->stencil.write_enable)) ||
196bf215546Sopenharmony_ci          wm_prog_data->computed_depth_mode != PSCDEPTH_OFF;
197bf215546Sopenharmony_ci}
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ciUNUSED static bool
200bf215546Sopenharmony_ciwant_stencil_pma_fix(struct anv_cmd_buffer *cmd_buffer,
201bf215546Sopenharmony_ci                     const struct vk_depth_stencil_state *ds)
202bf215546Sopenharmony_ci{
203bf215546Sopenharmony_ci   if (GFX_VER > 9)
204bf215546Sopenharmony_ci      return false;
205bf215546Sopenharmony_ci   assert(GFX_VER == 9);
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci   /* From the Skylake PRM Vol. 2c CACHE_MODE_1::STC PMA Optimization Enable:
208bf215546Sopenharmony_ci    *
209bf215546Sopenharmony_ci    *    Clearing this bit will force the STC cache to wait for pending
210bf215546Sopenharmony_ci    *    retirement of pixels at the HZ-read stage and do the STC-test for
211bf215546Sopenharmony_ci    *    Non-promoted, R-computed and Computed depth modes instead of
212bf215546Sopenharmony_ci    *    postponing the STC-test to RCPFE.
213bf215546Sopenharmony_ci    *
214bf215546Sopenharmony_ci    *    STC_TEST_EN = 3DSTATE_STENCIL_BUFFER::STENCIL_BUFFER_ENABLE &&
215bf215546Sopenharmony_ci    *                  3DSTATE_WM_DEPTH_STENCIL::StencilTestEnable
216bf215546Sopenharmony_ci    *
217bf215546Sopenharmony_ci    *    STC_WRITE_EN = 3DSTATE_STENCIL_BUFFER::STENCIL_BUFFER_ENABLE &&
218bf215546Sopenharmony_ci    *                   (3DSTATE_WM_DEPTH_STENCIL::Stencil Buffer Write Enable &&
219bf215546Sopenharmony_ci    *                    3DSTATE_DEPTH_BUFFER::STENCIL_WRITE_ENABLE)
220bf215546Sopenharmony_ci    *
221bf215546Sopenharmony_ci    *    COMP_STC_EN = STC_TEST_EN &&
222bf215546Sopenharmony_ci    *                  3DSTATE_PS_EXTRA::PixelShaderComputesStencil
223bf215546Sopenharmony_ci    *
224bf215546Sopenharmony_ci    *    SW parses the pipeline states to generate the following logical
225bf215546Sopenharmony_ci    *    signal indicating if PMA FIX can be enabled.
226bf215546Sopenharmony_ci    *
227bf215546Sopenharmony_ci    *    STC_PMA_OPT =
228bf215546Sopenharmony_ci    *       3DSTATE_WM::ForceThreadDispatch != 1 &&
229bf215546Sopenharmony_ci    *       !(3DSTATE_RASTER::ForceSampleCount != NUMRASTSAMPLES_0) &&
230bf215546Sopenharmony_ci    *       3DSTATE_DEPTH_BUFFER::SURFACE_TYPE != NULL &&
231bf215546Sopenharmony_ci    *       3DSTATE_DEPTH_BUFFER::HIZ Enable &&
232bf215546Sopenharmony_ci    *       !(3DSTATE_WM::EDSC_Mode == 2) &&
233bf215546Sopenharmony_ci    *       3DSTATE_PS_EXTRA::PixelShaderValid &&
234bf215546Sopenharmony_ci    *       !(3DSTATE_WM_HZ_OP::DepthBufferClear ||
235bf215546Sopenharmony_ci    *         3DSTATE_WM_HZ_OP::DepthBufferResolve ||
236bf215546Sopenharmony_ci    *         3DSTATE_WM_HZ_OP::Hierarchical Depth Buffer Resolve Enable ||
237bf215546Sopenharmony_ci    *         3DSTATE_WM_HZ_OP::StencilBufferClear) &&
238bf215546Sopenharmony_ci    *       (COMP_STC_EN || STC_WRITE_EN) &&
239bf215546Sopenharmony_ci    *       ((3DSTATE_PS_EXTRA::PixelShaderKillsPixels ||
240bf215546Sopenharmony_ci    *         3DSTATE_WM::ForceKillPix == ON ||
241bf215546Sopenharmony_ci    *         3DSTATE_PS_EXTRA::oMask Present to RenderTarget ||
242bf215546Sopenharmony_ci    *         3DSTATE_PS_BLEND::AlphaToCoverageEnable ||
243bf215546Sopenharmony_ci    *         3DSTATE_PS_BLEND::AlphaTestEnable ||
244bf215546Sopenharmony_ci    *         3DSTATE_WM_CHROMAKEY::ChromaKeyKillEnable) ||
245bf215546Sopenharmony_ci    *        (3DSTATE_PS_EXTRA::Pixel Shader Computed Depth mode != PSCDEPTH_OFF))
246bf215546Sopenharmony_ci    */
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci   /* These are always true:
249bf215546Sopenharmony_ci    *    3DSTATE_WM::ForceThreadDispatch != 1 &&
250bf215546Sopenharmony_ci    *    !(3DSTATE_RASTER::ForceSampleCount != NUMRASTSAMPLES_0)
251bf215546Sopenharmony_ci    */
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci   /* We only enable the PMA fix if we know for certain that HiZ is enabled.
254bf215546Sopenharmony_ci    * If we don't know whether HiZ is enabled or not, we disable the PMA fix
255bf215546Sopenharmony_ci    * and there is no harm.
256bf215546Sopenharmony_ci    *
257bf215546Sopenharmony_ci    * (3DSTATE_DEPTH_BUFFER::SURFACE_TYPE != NULL) &&
258bf215546Sopenharmony_ci    * 3DSTATE_DEPTH_BUFFER::HIZ Enable
259bf215546Sopenharmony_ci    */
260bf215546Sopenharmony_ci   if (!cmd_buffer->state.hiz_enabled)
261bf215546Sopenharmony_ci      return false;
262bf215546Sopenharmony_ci
263bf215546Sopenharmony_ci   /* We can't possibly know if HiZ is enabled without the depth attachment */
264bf215546Sopenharmony_ci   ASSERTED const struct anv_image_view *d_iview =
265bf215546Sopenharmony_ci      cmd_buffer->state.gfx.depth_att.iview;
266bf215546Sopenharmony_ci   assert(d_iview && d_iview->image->planes[0].aux_usage == ISL_AUX_USAGE_HIZ);
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci   /* 3DSTATE_PS_EXTRA::PixelShaderValid */
269bf215546Sopenharmony_ci   struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
270bf215546Sopenharmony_ci   if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT))
271bf215546Sopenharmony_ci      return false;
272bf215546Sopenharmony_ci
273bf215546Sopenharmony_ci   /* !(3DSTATE_WM::EDSC_Mode == 2) */
274bf215546Sopenharmony_ci   const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
275bf215546Sopenharmony_ci   if (wm_prog_data->early_fragment_tests)
276bf215546Sopenharmony_ci      return false;
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci   /* We never use anv_pipeline for HiZ ops so this is trivially true:
279bf215546Sopenharmony_ci   *    !(3DSTATE_WM_HZ_OP::DepthBufferClear ||
280bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::DepthBufferResolve ||
281bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::Hierarchical Depth Buffer Resolve Enable ||
282bf215546Sopenharmony_ci    *      3DSTATE_WM_HZ_OP::StencilBufferClear)
283bf215546Sopenharmony_ci    */
284bf215546Sopenharmony_ci
285bf215546Sopenharmony_ci   /* 3DSTATE_STENCIL_BUFFER::STENCIL_BUFFER_ENABLE &&
286bf215546Sopenharmony_ci    * 3DSTATE_WM_DEPTH_STENCIL::StencilTestEnable
287bf215546Sopenharmony_ci    */
288bf215546Sopenharmony_ci   const bool stc_test_en = ds->stencil.test_enable;
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   /* 3DSTATE_STENCIL_BUFFER::STENCIL_BUFFER_ENABLE &&
291bf215546Sopenharmony_ci    * (3DSTATE_WM_DEPTH_STENCIL::Stencil Buffer Write Enable &&
292bf215546Sopenharmony_ci    *  3DSTATE_DEPTH_BUFFER::STENCIL_WRITE_ENABLE)
293bf215546Sopenharmony_ci    */
294bf215546Sopenharmony_ci   const bool stc_write_en = ds->stencil.write_enable;
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci   /* STC_TEST_EN && 3DSTATE_PS_EXTRA::PixelShaderComputesStencil */
297bf215546Sopenharmony_ci   const bool comp_stc_en = stc_test_en && wm_prog_data->computed_stencil;
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci   /* COMP_STC_EN || STC_WRITE_EN */
300bf215546Sopenharmony_ci   if (!(comp_stc_en || stc_write_en))
301bf215546Sopenharmony_ci      return false;
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_ci   /* (3DSTATE_PS_EXTRA::PixelShaderKillsPixels ||
304bf215546Sopenharmony_ci    *  3DSTATE_WM::ForceKillPix == ON ||
305bf215546Sopenharmony_ci    *  3DSTATE_PS_EXTRA::oMask Present to RenderTarget ||
306bf215546Sopenharmony_ci    *  3DSTATE_PS_BLEND::AlphaToCoverageEnable ||
307bf215546Sopenharmony_ci    *  3DSTATE_PS_BLEND::AlphaTestEnable ||
308bf215546Sopenharmony_ci    *  3DSTATE_WM_CHROMAKEY::ChromaKeyKillEnable) ||
309bf215546Sopenharmony_ci    * (3DSTATE_PS_EXTRA::Pixel Shader Computed Depth mode != PSCDEPTH_OFF)
310bf215546Sopenharmony_ci    */
311bf215546Sopenharmony_ci   return pipeline->kill_pixel ||
312bf215546Sopenharmony_ci          wm_prog_data->computed_depth_mode != PSCDEPTH_OFF;
313bf215546Sopenharmony_ci}
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_civoid
316bf215546Sopenharmony_cigenX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
317bf215546Sopenharmony_ci{
318bf215546Sopenharmony_ci   struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
319bf215546Sopenharmony_ci   const struct vk_dynamic_graphics_state *dyn =
320bf215546Sopenharmony_ci      &cmd_buffer->vk.dynamic_graphics_state;
321bf215546Sopenharmony_ci
322bf215546Sopenharmony_ci#if GFX_VER >= 11
323bf215546Sopenharmony_ci   if (cmd_buffer->device->vk.enabled_extensions.KHR_fragment_shading_rate &&
324bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_FSR))
325bf215546Sopenharmony_ci      genX(emit_shading_rate)(&cmd_buffer->batch, pipeline, &dyn->fsr);
326bf215546Sopenharmony_ci#endif /* GFX_VER >= 11 */
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
329bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_WIDTH)) {
330bf215546Sopenharmony_ci      uint32_t sf_dw[GENX(3DSTATE_SF_length)];
331bf215546Sopenharmony_ci      struct GENX(3DSTATE_SF) sf = {
332bf215546Sopenharmony_ci         GENX(3DSTATE_SF_header),
333bf215546Sopenharmony_ci      };
334bf215546Sopenharmony_ci#if GFX_VER == 8
335bf215546Sopenharmony_ci      if (cmd_buffer->device->info.platform == INTEL_PLATFORM_CHV) {
336bf215546Sopenharmony_ci         sf.CHVLineWidth = dyn->rs.line.width;
337bf215546Sopenharmony_ci      } else {
338bf215546Sopenharmony_ci         sf.LineWidth = dyn->rs.line.width;
339bf215546Sopenharmony_ci      }
340bf215546Sopenharmony_ci#else
341bf215546Sopenharmony_ci      sf.LineWidth = dyn->rs.line.width,
342bf215546Sopenharmony_ci#endif
343bf215546Sopenharmony_ci      GENX(3DSTATE_SF_pack)(NULL, sf_dw, &sf);
344bf215546Sopenharmony_ci      anv_batch_emit_merge(&cmd_buffer->batch, sf_dw, pipeline->gfx8.sf);
345bf215546Sopenharmony_ci   }
346bf215546Sopenharmony_ci
347bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
348bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) ||
349bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_CULL_MODE) ||
350bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_FRONT_FACE) ||
351bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_ENABLE) ||
352bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_DEPTH_BIAS_FACTORS)) {
353bf215546Sopenharmony_ci      /* Take dynamic primitive topology in to account with
354bf215546Sopenharmony_ci       *    3DSTATE_RASTER::APIMode
355bf215546Sopenharmony_ci       *    3DSTATE_RASTER::DXMultisampleRasterizationEnable
356bf215546Sopenharmony_ci       *    3DSTATE_RASTER::AntialiasingEnable
357bf215546Sopenharmony_ci       */
358bf215546Sopenharmony_ci      uint32_t api_mode = 0;
359bf215546Sopenharmony_ci      bool msaa_raster_enable = false;
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci      VkPolygonMode dynamic_raster_mode =
362bf215546Sopenharmony_ci         genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline,
363bf215546Sopenharmony_ci                                   dyn->ia.primitive_topology);
364bf215546Sopenharmony_ci
365bf215546Sopenharmony_ci      genX(rasterization_mode)(dynamic_raster_mode,
366bf215546Sopenharmony_ci                               pipeline->line_mode, dyn->rs.line.width,
367bf215546Sopenharmony_ci                               &api_mode, &msaa_raster_enable);
368bf215546Sopenharmony_ci
369bf215546Sopenharmony_ci      bool aa_enable = anv_rasterization_aa_mode(dynamic_raster_mode,
370bf215546Sopenharmony_ci                                                 pipeline->line_mode);
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci      uint32_t raster_dw[GENX(3DSTATE_RASTER_length)];
373bf215546Sopenharmony_ci      struct GENX(3DSTATE_RASTER) raster = {
374bf215546Sopenharmony_ci         GENX(3DSTATE_RASTER_header),
375bf215546Sopenharmony_ci         .APIMode = api_mode,
376bf215546Sopenharmony_ci         .DXMultisampleRasterizationEnable = msaa_raster_enable,
377bf215546Sopenharmony_ci         .AntialiasingEnable = aa_enable,
378bf215546Sopenharmony_ci         .CullMode     = genX(vk_to_intel_cullmode)[dyn->rs.cull_mode],
379bf215546Sopenharmony_ci         .FrontWinding = genX(vk_to_intel_front_face)[dyn->rs.front_face],
380bf215546Sopenharmony_ci         .GlobalDepthOffsetEnableSolid       = dyn->rs.depth_bias.enable,
381bf215546Sopenharmony_ci         .GlobalDepthOffsetEnableWireframe   = dyn->rs.depth_bias.enable,
382bf215546Sopenharmony_ci         .GlobalDepthOffsetEnablePoint       = dyn->rs.depth_bias.enable,
383bf215546Sopenharmony_ci         .GlobalDepthOffsetConstant          = dyn->rs.depth_bias.constant,
384bf215546Sopenharmony_ci         .GlobalDepthOffsetScale             = dyn->rs.depth_bias.slope,
385bf215546Sopenharmony_ci         .GlobalDepthOffsetClamp             = dyn->rs.depth_bias.clamp,
386bf215546Sopenharmony_ci      };
387bf215546Sopenharmony_ci      GENX(3DSTATE_RASTER_pack)(NULL, raster_dw, &raster);
388bf215546Sopenharmony_ci      anv_batch_emit_merge(&cmd_buffer->batch, raster_dw,
389bf215546Sopenharmony_ci                           pipeline->gfx8.raster);
390bf215546Sopenharmony_ci   }
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci   /* Stencil reference values moved from COLOR_CALC_STATE in gfx8 to
393bf215546Sopenharmony_ci    * 3DSTATE_WM_DEPTH_STENCIL in gfx9. That means the dirty bits gets split
394bf215546Sopenharmony_ci    * across different state packets for gfx8 and gfx9. We handle that by
395bf215546Sopenharmony_ci    * using a big old #if switch here.
396bf215546Sopenharmony_ci    */
397bf215546Sopenharmony_ci#if GFX_VER == 8
398bf215546Sopenharmony_ci   if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE) ||
399bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS)) {
400bf215546Sopenharmony_ci      struct anv_state cc_state =
401bf215546Sopenharmony_ci         anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
402bf215546Sopenharmony_ci                                            GENX(COLOR_CALC_STATE_length) * 4,
403bf215546Sopenharmony_ci                                            64);
404bf215546Sopenharmony_ci      struct GENX(COLOR_CALC_STATE) cc = {
405bf215546Sopenharmony_ci         .BlendConstantColorRed = dyn->cb.blend_constants[0],
406bf215546Sopenharmony_ci         .BlendConstantColorGreen = dyn->cb.blend_constants[1],
407bf215546Sopenharmony_ci         .BlendConstantColorBlue = dyn->cb.blend_constants[2],
408bf215546Sopenharmony_ci         .BlendConstantColorAlpha = dyn->cb.blend_constants[3],
409bf215546Sopenharmony_ci         .StencilReferenceValue = dyn->ds.stencil.front.reference & 0xff,
410bf215546Sopenharmony_ci         .BackfaceStencilReferenceValue = dyn->ds.stencil.back.reference & 0xff,
411bf215546Sopenharmony_ci      };
412bf215546Sopenharmony_ci      GENX(COLOR_CALC_STATE_pack)(NULL, cc_state.map, &cc);
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CC_STATE_POINTERS), ccp) {
415bf215546Sopenharmony_ci         ccp.ColorCalcStatePointer        = cc_state.offset;
416bf215546Sopenharmony_ci         ccp.ColorCalcStatePointerValid   = true;
417bf215546Sopenharmony_ci      }
418bf215546Sopenharmony_ci   }
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
421bf215546Sopenharmony_ci                                       ANV_CMD_DIRTY_RENDER_TARGETS)) ||
422bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) ||
423bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) ||
424bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) ||
425bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
426bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_OP) ||
427bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
428bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK)) {
429bf215546Sopenharmony_ci      VkImageAspectFlags ds_aspects = 0;
430bf215546Sopenharmony_ci      if (cmd_buffer->state.gfx.depth_att.vk_format != VK_FORMAT_UNDEFINED)
431bf215546Sopenharmony_ci         ds_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
432bf215546Sopenharmony_ci      if (cmd_buffer->state.gfx.stencil_att.vk_format != VK_FORMAT_UNDEFINED)
433bf215546Sopenharmony_ci         ds_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
434bf215546Sopenharmony_ci
435bf215546Sopenharmony_ci      struct vk_depth_stencil_state opt_ds = dyn->ds;
436bf215546Sopenharmony_ci      vk_optimize_depth_stencil_state(&opt_ds, ds_aspects, true);
437bf215546Sopenharmony_ci
438bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_WM_DEPTH_STENCIL), ds) {
439bf215546Sopenharmony_ci         ds.DoubleSidedStencilEnable = true;
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_ci         ds.StencilTestMask = opt_ds.stencil.front.compare_mask & 0xff;
442bf215546Sopenharmony_ci         ds.StencilWriteMask = opt_ds.stencil.front.write_mask & 0xff;
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci         ds.BackfaceStencilTestMask = opt_ds.stencil.back.compare_mask & 0xff;
445bf215546Sopenharmony_ci         ds.BackfaceStencilWriteMask = opt_ds.stencil.back.write_mask & 0xff;
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci         ds.DepthTestEnable = opt_ds.depth.test_enable;
448bf215546Sopenharmony_ci         ds.DepthBufferWriteEnable = opt_ds.depth.write_enable;
449bf215546Sopenharmony_ci         ds.DepthTestFunction = genX(vk_to_intel_compare_op)[opt_ds.depth.compare_op];
450bf215546Sopenharmony_ci         ds.StencilTestEnable = opt_ds.stencil.test_enable;
451bf215546Sopenharmony_ci         ds.StencilBufferWriteEnable = opt_ds.stencil.write_enable;
452bf215546Sopenharmony_ci         ds.StencilFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.front.op.fail];
453bf215546Sopenharmony_ci         ds.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.front.op.pass];
454bf215546Sopenharmony_ci         ds.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.front.op.depth_fail];
455bf215546Sopenharmony_ci         ds.StencilTestFunction = genX(vk_to_intel_compare_op)[opt_ds.stencil.front.op.compare];
456bf215546Sopenharmony_ci         ds.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.back.op.fail];
457bf215546Sopenharmony_ci         ds.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.back.op.pass];
458bf215546Sopenharmony_ci         ds.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.back.op.depth_fail];
459bf215546Sopenharmony_ci         ds.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[opt_ds.stencil.back.op.compare];
460bf215546Sopenharmony_ci      }
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ci      const bool pma = want_depth_pma_fix(cmd_buffer, &opt_ds);
463bf215546Sopenharmony_ci      genX(cmd_buffer_enable_pma_fix)(cmd_buffer, pma);
464bf215546Sopenharmony_ci   }
465bf215546Sopenharmony_ci#else
466bf215546Sopenharmony_ci   if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS)) {
467bf215546Sopenharmony_ci      struct anv_state cc_state =
468bf215546Sopenharmony_ci         anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
469bf215546Sopenharmony_ci                                            GENX(COLOR_CALC_STATE_length) * 4,
470bf215546Sopenharmony_ci                                            64);
471bf215546Sopenharmony_ci      struct GENX(COLOR_CALC_STATE) cc = {
472bf215546Sopenharmony_ci         .BlendConstantColorRed = dyn->cb.blend_constants[0],
473bf215546Sopenharmony_ci         .BlendConstantColorGreen = dyn->cb.blend_constants[1],
474bf215546Sopenharmony_ci         .BlendConstantColorBlue = dyn->cb.blend_constants[2],
475bf215546Sopenharmony_ci         .BlendConstantColorAlpha = dyn->cb.blend_constants[3],
476bf215546Sopenharmony_ci      };
477bf215546Sopenharmony_ci      GENX(COLOR_CALC_STATE_pack)(NULL, cc_state.map, &cc);
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CC_STATE_POINTERS), ccp) {
480bf215546Sopenharmony_ci         ccp.ColorCalcStatePointer = cc_state.offset;
481bf215546Sopenharmony_ci         ccp.ColorCalcStatePointerValid = true;
482bf215546Sopenharmony_ci      }
483bf215546Sopenharmony_ci   }
484bf215546Sopenharmony_ci
485bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
486bf215546Sopenharmony_ci                                       ANV_CMD_DIRTY_RENDER_TARGETS)) ||
487bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) ||
488bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) ||
489bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_COMPARE_OP) ||
490bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
491bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_OP) ||
492bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_COMPARE_MASK) ||
493bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_WRITE_MASK) ||
494bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_REFERENCE)) {
495bf215546Sopenharmony_ci      VkImageAspectFlags ds_aspects = 0;
496bf215546Sopenharmony_ci      if (cmd_buffer->state.gfx.depth_att.vk_format != VK_FORMAT_UNDEFINED)
497bf215546Sopenharmony_ci         ds_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
498bf215546Sopenharmony_ci      if (cmd_buffer->state.gfx.stencil_att.vk_format != VK_FORMAT_UNDEFINED)
499bf215546Sopenharmony_ci         ds_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ci      struct vk_depth_stencil_state opt_ds = dyn->ds;
502bf215546Sopenharmony_ci      vk_optimize_depth_stencil_state(&opt_ds, ds_aspects, true);
503bf215546Sopenharmony_ci
504bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_WM_DEPTH_STENCIL), ds) {
505bf215546Sopenharmony_ci         ds.DoubleSidedStencilEnable = true;
506bf215546Sopenharmony_ci
507bf215546Sopenharmony_ci         ds.StencilTestMask = opt_ds.stencil.front.compare_mask & 0xff;
508bf215546Sopenharmony_ci         ds.StencilWriteMask = opt_ds.stencil.front.write_mask & 0xff;
509bf215546Sopenharmony_ci
510bf215546Sopenharmony_ci         ds.BackfaceStencilTestMask = opt_ds.stencil.back.compare_mask & 0xff;
511bf215546Sopenharmony_ci         ds.BackfaceStencilWriteMask = opt_ds.stencil.back.write_mask & 0xff;
512bf215546Sopenharmony_ci
513bf215546Sopenharmony_ci         ds.StencilReferenceValue = opt_ds.stencil.front.reference & 0xff;
514bf215546Sopenharmony_ci         ds.BackfaceStencilReferenceValue = opt_ds.stencil.back.reference & 0xff;
515bf215546Sopenharmony_ci
516bf215546Sopenharmony_ci         ds.DepthTestEnable = opt_ds.depth.test_enable;
517bf215546Sopenharmony_ci         ds.DepthBufferWriteEnable = opt_ds.depth.write_enable;
518bf215546Sopenharmony_ci         ds.DepthTestFunction = genX(vk_to_intel_compare_op)[opt_ds.depth.compare_op];
519bf215546Sopenharmony_ci         ds.StencilTestEnable = opt_ds.stencil.test_enable;
520bf215546Sopenharmony_ci         ds.StencilBufferWriteEnable = opt_ds.stencil.write_enable;
521bf215546Sopenharmony_ci         ds.StencilFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.front.op.fail];
522bf215546Sopenharmony_ci         ds.StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.front.op.pass];
523bf215546Sopenharmony_ci         ds.StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.front.op.depth_fail];
524bf215546Sopenharmony_ci         ds.StencilTestFunction = genX(vk_to_intel_compare_op)[opt_ds.stencil.front.op.compare];
525bf215546Sopenharmony_ci         ds.BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.back.op.fail];
526bf215546Sopenharmony_ci         ds.BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.back.op.pass];
527bf215546Sopenharmony_ci         ds.BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[opt_ds.stencil.back.op.depth_fail];
528bf215546Sopenharmony_ci         ds.BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[opt_ds.stencil.back.op.compare];
529bf215546Sopenharmony_ci      }
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_ci      const bool pma = want_stencil_pma_fix(cmd_buffer, &opt_ds);
532bf215546Sopenharmony_ci      genX(cmd_buffer_enable_pma_fix)(cmd_buffer, pma);
533bf215546Sopenharmony_ci   }
534bf215546Sopenharmony_ci#endif
535bf215546Sopenharmony_ci
536bf215546Sopenharmony_ci#if GFX_VER >= 12
537bf215546Sopenharmony_ci   if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE) ||
538bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_BOUNDS)) {
539bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_DEPTH_BOUNDS), db) {
540bf215546Sopenharmony_ci         db.DepthBoundsTestEnable = dyn->ds.depth.bounds_test.enable;
541bf215546Sopenharmony_ci         db.DepthBoundsTestMinValue = dyn->ds.depth.bounds_test.min;
542bf215546Sopenharmony_ci         db.DepthBoundsTestMaxValue = dyn->ds.depth.bounds_test.max;
543bf215546Sopenharmony_ci      }
544bf215546Sopenharmony_ci   }
545bf215546Sopenharmony_ci#endif
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci   if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_STIPPLE)) {
548bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_LINE_STIPPLE), ls) {
549bf215546Sopenharmony_ci         ls.LineStipplePattern = dyn->rs.line.stipple.pattern;
550bf215546Sopenharmony_ci         ls.LineStippleInverseRepeatCount =
551bf215546Sopenharmony_ci            1.0f / MAX2(1, dyn->rs.line.stipple.factor);
552bf215546Sopenharmony_ci         ls.LineStippleRepeatCount = dyn->rs.line.stipple.factor;
553bf215546Sopenharmony_ci      }
554bf215546Sopenharmony_ci   }
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE |
557bf215546Sopenharmony_ci                                       ANV_CMD_DIRTY_INDEX_BUFFER)) ||
558bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE)) {
559bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF), vf) {
560bf215546Sopenharmony_ci#if GFX_VERx10 >= 125
561bf215546Sopenharmony_ci         vf.GeometryDistributionEnable = true;
562bf215546Sopenharmony_ci#endif
563bf215546Sopenharmony_ci         vf.IndexedDrawCutIndexEnable  = dyn->ia.primitive_restart_enable;
564bf215546Sopenharmony_ci         vf.CutIndex                   = cmd_buffer->state.gfx.restart_index;
565bf215546Sopenharmony_ci      }
566bf215546Sopenharmony_ci   }
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_ci   if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_INDEX_BUFFER) {
569bf215546Sopenharmony_ci      struct anv_buffer *buffer = cmd_buffer->state.gfx.index_buffer;
570bf215546Sopenharmony_ci      uint32_t offset = cmd_buffer->state.gfx.index_offset;
571bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
572bf215546Sopenharmony_ci         ib.IndexFormat           = cmd_buffer->state.gfx.index_type;
573bf215546Sopenharmony_ci         ib.MOCS                  = anv_mocs(cmd_buffer->device,
574bf215546Sopenharmony_ci                                             buffer->address.bo,
575bf215546Sopenharmony_ci                                             ISL_SURF_USAGE_INDEX_BUFFER_BIT);
576bf215546Sopenharmony_ci#if GFX_VER >= 12
577bf215546Sopenharmony_ci         ib.L3BypassDisable       = true;
578bf215546Sopenharmony_ci#endif
579bf215546Sopenharmony_ci         ib.BufferStartingAddress = anv_address_add(buffer->address, offset);
580bf215546Sopenharmony_ci         ib.BufferSize            = vk_buffer_range(&buffer->vk, offset,
581bf215546Sopenharmony_ci                                                    VK_WHOLE_SIZE);
582bf215546Sopenharmony_ci      }
583bf215546Sopenharmony_ci   }
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci#if GFX_VERx10 >= 125
586bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
587bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_RESTART_ENABLE)) {
588bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VFG), vfg) {
589bf215546Sopenharmony_ci         /* If 3DSTATE_TE: TE Enable == 1 then RR_STRICT else RR_FREE*/
590bf215546Sopenharmony_ci         vfg.DistributionMode =
591bf215546Sopenharmony_ci            anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL) ? RR_STRICT :
592bf215546Sopenharmony_ci                                                                      RR_FREE;
593bf215546Sopenharmony_ci         vfg.DistributionGranularity = BatchLevelGranularity;
594bf215546Sopenharmony_ci         /* Wa_14014890652 */
595bf215546Sopenharmony_ci         if (intel_device_info_is_dg2(&cmd_buffer->device->info))
596bf215546Sopenharmony_ci            vfg.GranularityThresholdDisable = 1;
597bf215546Sopenharmony_ci         vfg.ListCutIndexEnable = dyn->ia.primitive_restart_enable;
598bf215546Sopenharmony_ci         /* 192 vertices for TRILIST_ADJ */
599bf215546Sopenharmony_ci         vfg.ListNBatchSizeScale = 0;
600bf215546Sopenharmony_ci         /* Batch size of 384 vertices */
601bf215546Sopenharmony_ci         vfg.List3BatchSizeScale = 2;
602bf215546Sopenharmony_ci         /* Batch size of 128 vertices */
603bf215546Sopenharmony_ci         vfg.List2BatchSizeScale = 1;
604bf215546Sopenharmony_ci         /* Batch size of 128 vertices */
605bf215546Sopenharmony_ci         vfg.List1BatchSizeScale = 2;
606bf215546Sopenharmony_ci         /* Batch size of 256 vertices for STRIP topologies */
607bf215546Sopenharmony_ci         vfg.StripBatchSizeScale = 3;
608bf215546Sopenharmony_ci         /* 192 control points for PATCHLIST_3 */
609bf215546Sopenharmony_ci         vfg.PatchBatchSizeScale = 1;
610bf215546Sopenharmony_ci         /* 192 control points for PATCHLIST_3 */
611bf215546Sopenharmony_ci         vfg.PatchBatchSizeMultiplier = 31;
612bf215546Sopenharmony_ci      }
613bf215546Sopenharmony_ci   }
614bf215546Sopenharmony_ci#endif
615bf215546Sopenharmony_ci
616bf215546Sopenharmony_ci   if (pipeline->base.device->vk.enabled_extensions.EXT_sample_locations &&
617bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_SAMPLE_LOCATIONS))
618bf215546Sopenharmony_ci      genX(emit_sample_pattern)(&cmd_buffer->batch, dyn->ms.sample_locations);
619bf215546Sopenharmony_ci
620bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
621bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
622bf215546Sopenharmony_ci      /* 3DSTATE_WM in the hope we can avoid spawning fragment shaders
623bf215546Sopenharmony_ci       * threads.
624bf215546Sopenharmony_ci       */
625bf215546Sopenharmony_ci      uint32_t wm_dwords[GENX(3DSTATE_WM_length)];
626bf215546Sopenharmony_ci      struct GENX(3DSTATE_WM) wm = {
627bf215546Sopenharmony_ci         GENX(3DSTATE_WM_header),
628bf215546Sopenharmony_ci
629bf215546Sopenharmony_ci         .ForceThreadDispatchEnable = anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT) &&
630bf215546Sopenharmony_ci                                      (pipeline->force_fragment_thread_dispatch ||
631bf215546Sopenharmony_ci                                       anv_cmd_buffer_all_color_write_masked(cmd_buffer)) ?
632bf215546Sopenharmony_ci                                      ForceON : 0,
633bf215546Sopenharmony_ci      };
634bf215546Sopenharmony_ci      GENX(3DSTATE_WM_pack)(NULL, wm_dwords, &wm);
635bf215546Sopenharmony_ci
636bf215546Sopenharmony_ci      anv_batch_emit_merge(&cmd_buffer->batch, wm_dwords, pipeline->gfx8.wm);
637bf215546Sopenharmony_ci   }
638bf215546Sopenharmony_ci
639bf215546Sopenharmony_ci   if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) ||
640bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_LOGIC_OP) ||
641bf215546Sopenharmony_ci       BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) {
642bf215546Sopenharmony_ci      const uint8_t color_writes = dyn->cb.color_write_enables;
643bf215546Sopenharmony_ci      const struct anv_cmd_graphics_state *state = &cmd_buffer->state.gfx;
644bf215546Sopenharmony_ci      bool has_writeable_rt =
645bf215546Sopenharmony_ci         anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT) &&
646bf215546Sopenharmony_ci         (color_writes & ((1u << state->color_att_count) - 1)) != 0;
647bf215546Sopenharmony_ci
648bf215546Sopenharmony_ci      /* 3DSTATE_PS_BLEND to be consistent with the rest of the
649bf215546Sopenharmony_ci       * BLEND_STATE_ENTRY.
650bf215546Sopenharmony_ci       */
651bf215546Sopenharmony_ci      uint32_t ps_blend_dwords[GENX(3DSTATE_PS_BLEND_length)];
652bf215546Sopenharmony_ci      struct GENX(3DSTATE_PS_BLEND) ps_blend = {
653bf215546Sopenharmony_ci         GENX(3DSTATE_PS_BLEND_header),
654bf215546Sopenharmony_ci         .HasWriteableRT = has_writeable_rt,
655bf215546Sopenharmony_ci      };
656bf215546Sopenharmony_ci      GENX(3DSTATE_PS_BLEND_pack)(NULL, ps_blend_dwords, &ps_blend);
657bf215546Sopenharmony_ci      anv_batch_emit_merge(&cmd_buffer->batch, ps_blend_dwords,
658bf215546Sopenharmony_ci                           pipeline->gfx8.ps_blend);
659bf215546Sopenharmony_ci
660bf215546Sopenharmony_ci      uint32_t blend_dws[GENX(BLEND_STATE_length) +
661bf215546Sopenharmony_ci                         MAX_RTS * GENX(BLEND_STATE_ENTRY_length)];
662bf215546Sopenharmony_ci      uint32_t *dws = blend_dws;
663bf215546Sopenharmony_ci      memset(blend_dws, 0, sizeof(blend_dws));
664bf215546Sopenharmony_ci
665bf215546Sopenharmony_ci      /* Skip this part */
666bf215546Sopenharmony_ci      dws += GENX(BLEND_STATE_length);
667bf215546Sopenharmony_ci
668bf215546Sopenharmony_ci      for (uint32_t i = 0; i < MAX_RTS; i++) {
669bf215546Sopenharmony_ci         /* Disable anything above the current number of color attachments. */
670bf215546Sopenharmony_ci         bool write_disabled = i >= cmd_buffer->state.gfx.color_att_count ||
671bf215546Sopenharmony_ci                               (color_writes & BITFIELD_BIT(i)) == 0;
672bf215546Sopenharmony_ci         struct GENX(BLEND_STATE_ENTRY) entry = {
673bf215546Sopenharmony_ci            .WriteDisableAlpha = write_disabled ||
674bf215546Sopenharmony_ci                                 (pipeline->color_comp_writes[i] &
675bf215546Sopenharmony_ci                                  VK_COLOR_COMPONENT_A_BIT) == 0,
676bf215546Sopenharmony_ci            .WriteDisableRed   = write_disabled ||
677bf215546Sopenharmony_ci                                 (pipeline->color_comp_writes[i] &
678bf215546Sopenharmony_ci                                  VK_COLOR_COMPONENT_R_BIT) == 0,
679bf215546Sopenharmony_ci            .WriteDisableGreen = write_disabled ||
680bf215546Sopenharmony_ci                                 (pipeline->color_comp_writes[i] &
681bf215546Sopenharmony_ci                                  VK_COLOR_COMPONENT_G_BIT) == 0,
682bf215546Sopenharmony_ci            .WriteDisableBlue  = write_disabled ||
683bf215546Sopenharmony_ci                                 (pipeline->color_comp_writes[i] &
684bf215546Sopenharmony_ci                                  VK_COLOR_COMPONENT_B_BIT) == 0,
685bf215546Sopenharmony_ci            .LogicOpFunction   = genX(vk_to_intel_logic_op)[dyn->cb.logic_op],
686bf215546Sopenharmony_ci         };
687bf215546Sopenharmony_ci         GENX(BLEND_STATE_ENTRY_pack)(NULL, dws, &entry);
688bf215546Sopenharmony_ci         dws += GENX(BLEND_STATE_ENTRY_length);
689bf215546Sopenharmony_ci      }
690bf215546Sopenharmony_ci
691bf215546Sopenharmony_ci      uint32_t num_dwords = GENX(BLEND_STATE_length) +
692bf215546Sopenharmony_ci         GENX(BLEND_STATE_ENTRY_length) * MAX_RTS;
693bf215546Sopenharmony_ci
694bf215546Sopenharmony_ci      struct anv_state blend_states =
695bf215546Sopenharmony_ci         anv_cmd_buffer_merge_dynamic(cmd_buffer, blend_dws,
696bf215546Sopenharmony_ci                                      pipeline->gfx8.blend_state, num_dwords, 64);
697bf215546Sopenharmony_ci      anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) {
698bf215546Sopenharmony_ci         bsp.BlendStatePointer      = blend_states.offset;
699bf215546Sopenharmony_ci         bsp.BlendStatePointerValid = true;
700bf215546Sopenharmony_ci      }
701bf215546Sopenharmony_ci   }
702bf215546Sopenharmony_ci
703bf215546Sopenharmony_ci   /* When we're done, there is no more dirty gfx state. */
704bf215546Sopenharmony_ci   vk_dynamic_graphics_state_clear_dirty(&cmd_buffer->vk.dynamic_graphics_state);
705bf215546Sopenharmony_ci   cmd_buffer->state.gfx.dirty = 0;
706bf215546Sopenharmony_ci}
707