xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_state_ts.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2018-2024 Broadcom. All Rights Reserved.
3  * The term “Broadcom” refers to Broadcom Inc.
4  * and/or its subsidiaries.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "util/u_inlines.h"
9 #include "util/u_memory.h"
10 #include "util/u_simple_shaders.h"
11 
12 #include "svga_context.h"
13 #include "svga_cmd.h"
14 #include "svga_tgsi.h"
15 #include "svga_shader.h"
16 
17 
18 static void
make_tcs_key(struct svga_context * svga,struct svga_compile_key * key)19 make_tcs_key(struct svga_context *svga, struct svga_compile_key *key)
20 {
21    struct svga_tcs_shader *tcs = svga->curr.tcs;
22 
23    memset(key, 0, sizeof *key);
24 
25    /*
26     * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
27     */
28    svga_init_shader_key_common(svga, PIPE_SHADER_TESS_CTRL, &tcs->base, key);
29 
30    /* SVGA_NEW_TCS_PARAM */
31    key->tcs.vertices_per_patch = svga->curr.vertices_per_patch;
32 
33    /* The tessellator parameters come from the layout section in the
34     * tessellation evaluation shader. Get these parameters from the
35     * current tessellation evaluation shader variant.
36     * Note: this requires the tessellation evaluation shader to be
37     * compiled first.
38     */
39    struct svga_tes_variant *tes = svga_tes_variant(svga->state.hw_draw.tes);
40    key->tcs.prim_mode = tes->prim_mode;
41    key->tcs.spacing = tes->spacing;
42    key->tcs.vertices_order_cw = tes->vertices_order_cw;
43    key->tcs.point_mode = tes->point_mode;
44 
45    /* The number of control point output from tcs is determined by the
46     * number of control point input expected in tes. If tes does not expect
47     * any control point input, then vertices_per_patch in the tes key will
48     * be 0, otherwise it will contain the number of vertices out as specified
49     * in the tcs property.
50     */
51    key->tcs.vertices_out = tes->base.key.tes.vertices_per_patch;
52 
53    if (svga->tcs.passthrough)
54       key->tcs.passthrough = 1;
55 
56    key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable;
57 
58    /* tcs is always followed by tes */
59    key->last_vertex_stage = 0;
60 }
61 
62 
63 static enum pipe_error
emit_hw_tcs(struct svga_context * svga,uint64_t dirty)64 emit_hw_tcs(struct svga_context *svga, uint64_t dirty)
65 {
66    struct svga_shader_variant *variant;
67    struct svga_tcs_shader *tcs = svga->curr.tcs;
68    enum pipe_error ret = PIPE_OK;
69    struct svga_compile_key key;
70 
71    assert(svga_have_sm5(svga));
72 
73    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITTCS);
74 
75    if (!tcs) {
76       /* If there is no active tcs, then there should not be
77        * active tes either
78        */
79       assert(!svga->curr.tes);
80       if (svga->state.hw_draw.tcs != NULL) {
81 
82          /** The previous tessellation control shader is made inactive.
83           *  Needs to unbind the tessellation control shader.
84           */
85          ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, NULL);
86          if (ret != PIPE_OK)
87             goto done;
88          svga->state.hw_draw.tcs = NULL;
89       }
90       goto done;
91    }
92 
93    make_tcs_key(svga, &key);
94 
95    /* See if we already have a TCS variant that matches the key */
96    variant = svga_search_shader_key(&tcs->base, &key);
97 
98    if (!variant) {
99       ret = svga_compile_shader(svga, &tcs->base, &key, &variant);
100       if (ret != PIPE_OK)
101          goto done;
102    }
103 
104    if (variant != svga->state.hw_draw.tcs) {
105       /* Bind the new variant */
106       ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, variant);
107       if (ret != PIPE_OK)
108          goto done;
109 
110       svga->rebind.flags.tcs = false;
111       svga->dirty |= SVGA_NEW_TCS_VARIANT;
112       svga->state.hw_draw.tcs = variant;
113    }
114 
115 done:
116    SVGA_STATS_TIME_POP(svga_sws(svga));
117    return ret;
118 }
119 
120 
121 struct svga_tracked_state svga_hw_tcs =
122 {
123    "tessellation control shader (hwtnl)",
124    (SVGA_NEW_VS |
125     SVGA_NEW_TCS |
126     SVGA_NEW_TES |
127     SVGA_NEW_TEXTURE_BINDING |
128     SVGA_NEW_SAMPLER |
129     SVGA_NEW_RAST |
130     SVGA_NEW_TCS_RAW_BUFFER),
131    emit_hw_tcs
132 };
133 
134 
135 static void
make_tes_key(struct svga_context * svga,struct svga_compile_key * key)136 make_tes_key(struct svga_context *svga, struct svga_compile_key *key)
137 {
138    struct svga_tes_shader *tes = svga->curr.tes;
139 
140    memset(key, 0, sizeof *key);
141 
142    /*
143     * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
144     */
145    svga_init_shader_key_common(svga, PIPE_SHADER_TESS_EVAL, &tes->base, key);
146 
147    assert(svga->curr.tcs);
148 
149    key->tes.vertices_per_patch = tes->base.info.tes.reads_control_point ?
150       svga->curr.tcs->base.info.tcs.vertices_out : 0;
151 
152    key->tes.need_prescale = svga->state.hw_clear.prescale[0].enabled &&
153                             (svga->curr.gs == NULL);
154 
155    /* tcs emits tessellation factors as extra outputs.
156     * Since tes depends on them, save the tessFactor output index
157     * from tcs in the tes compile key, so that if a different
158     * tcs is bound and if the tessFactor index is different,
159     * a different tes variant will be generated.
160     */
161    key->tes.tessfactor_index = svga->curr.tcs->base.info.num_outputs;
162 
163    key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable;
164 
165    /* This is the last vertex stage if there is no geometry shader. */
166    key->last_vertex_stage = !svga->curr.gs;
167 
168    key->tes.need_tessinner = svga->curr.tcs->base.info.tcs.writes_tess_factor;
169    key->tes.need_tessouter = svga->curr.tcs->base.info.tcs.writes_tess_factor;
170 }
171 
172 
173 static void
get_passthrough_tcs(struct svga_context * svga)174 get_passthrough_tcs(struct svga_context *svga)
175 {
176    if (svga->tcs.passthrough_tcs &&
177        svga->tcs.vs == svga->curr.vs &&
178        svga->tcs.tes == svga->curr.tes &&
179        svga->tcs.vertices_per_patch == svga->curr.vertices_per_patch) {
180       svga->pipe.bind_tcs_state(&svga->pipe,
181                                 svga->tcs.passthrough_tcs);
182    }
183    else {
184       struct svga_tcs_shader *new_tcs;
185 
186       /* delete older passthrough shader*/
187       if (svga->tcs.passthrough_tcs) {
188          svga->pipe.delete_tcs_state(&svga->pipe,
189                                      svga->tcs.passthrough_tcs);
190       }
191 
192       new_tcs = (struct svga_tcs_shader *)
193          util_make_tess_ctrl_passthrough_shader(&svga->pipe,
194             svga->curr.vs->base.tgsi_info.num_outputs,
195             svga->curr.tes->base.tgsi_info.num_inputs,
196             svga->curr.vs->base.tgsi_info.output_semantic_name,
197             svga->curr.vs->base.tgsi_info.output_semantic_index,
198             svga->curr.tes->base.tgsi_info.input_semantic_name,
199             svga->curr.tes->base.tgsi_info.input_semantic_index,
200             svga->curr.vertices_per_patch);
201       svga->pipe.bind_tcs_state(&svga->pipe, new_tcs);
202       svga->tcs.passthrough_tcs = new_tcs;
203       svga->tcs.vs = svga->curr.vs;
204       svga->tcs.tes = svga->curr.tes;
205       svga->tcs.vertices_per_patch = svga->curr.vertices_per_patch;
206    }
207 
208    struct pipe_constant_buffer cb;
209 
210    cb.buffer = NULL;
211    cb.user_buffer = (void *) svga->curr.default_tesslevels;
212    cb.buffer_offset = 0;
213    cb.buffer_size = 2 * 4 * sizeof(float);
214    svga->pipe.set_constant_buffer(&svga->pipe, PIPE_SHADER_TESS_CTRL, 0, false, &cb);
215 }
216 
217 
218 static enum pipe_error
emit_hw_tes(struct svga_context * svga,uint64_t dirty)219 emit_hw_tes(struct svga_context *svga, uint64_t dirty)
220 {
221    struct svga_shader_variant *variant;
222    struct svga_tes_shader *tes = svga->curr.tes;
223    enum pipe_error ret = PIPE_OK;
224    struct svga_compile_key key;
225 
226    assert(svga_have_sm5(svga));
227 
228    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITTES);
229 
230    if (!tes) {
231       /* The GL spec implies that TES is optional when there's a TCS,
232        * but that's apparently a spec error. Assert if we have a TCS
233        * but no TES.
234        */
235       assert(!svga->curr.tcs);
236       if (svga->state.hw_draw.tes != NULL) {
237 
238          /** The previous tessellation evaluation shader is made inactive.
239           *  Needs to unbind the tessellation evaluation shader.
240           */
241          ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, NULL);
242          if (ret != PIPE_OK)
243             goto done;
244          svga->state.hw_draw.tes = NULL;
245       }
246       goto done;
247    }
248 
249    if (!svga->curr.tcs) {
250       /* TES state is processed before the TCS
251        * shader and that's why we're checking for and creating the
252        * passthough TCS in the emit_hw_tes() function.
253        */
254       get_passthrough_tcs(svga);
255       svga->tcs.passthrough = true;
256    }
257    else {
258       svga->tcs.passthrough = false;
259    }
260 
261    make_tes_key(svga, &key);
262 
263    /* See if we already have a TES variant that matches the key */
264    variant = svga_search_shader_key(&tes->base, &key);
265 
266    if (!variant) {
267       ret = svga_compile_shader(svga, &tes->base, &key, &variant);
268       if (ret != PIPE_OK)
269          goto done;
270    }
271 
272    if (variant != svga->state.hw_draw.tes) {
273       /* Bind the new variant */
274       ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, variant);
275       if (ret != PIPE_OK)
276          goto done;
277 
278       svga->rebind.flags.tes = false;
279       svga->dirty |= SVGA_NEW_TES_VARIANT;
280       svga->state.hw_draw.tes = variant;
281    }
282 
283 done:
284    SVGA_STATS_TIME_POP(svga_sws(svga));
285    return ret;
286 }
287 
288 
289 struct svga_tracked_state svga_hw_tes =
290 {
291    "tessellation evaluation shader (hwtnl)",
292    /* TBD SVGA_NEW_VS/SVGA_NEW_FS/SVGA_NEW_GS are required or not*/
293    (SVGA_NEW_VS |
294     SVGA_NEW_FS |
295     SVGA_NEW_GS |
296     SVGA_NEW_TCS |
297     SVGA_NEW_TES |
298     SVGA_NEW_TEXTURE_BINDING |
299     SVGA_NEW_SAMPLER |
300     SVGA_NEW_RAST |
301     SVGA_NEW_TES_RAW_BUFFER),
302    emit_hw_tes
303 };
304