xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_pipe_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 "nir/nir_to_tgsi.h"
9 #include "pipe/p_context.h"
10 #include "util/u_memory.h"
11 
12 #include "svga_context.h"
13 #include "svga_shader.h"
14 
15 static void
svga_set_tess_state(struct pipe_context * pipe,const float default_outer_level[4],const float default_inner_level[2])16 svga_set_tess_state(struct pipe_context *pipe,
17                     const float default_outer_level[4],
18                     const float default_inner_level[2])
19 {
20    struct svga_context *svga = svga_context(pipe);
21    unsigned i;
22 
23    for (i = 0; i < 4; i++) {
24       svga->curr.default_tesslevels[i] = default_outer_level[i];
25    }
26    for (i = 0; i < 2; i++) {
27       svga->curr.default_tesslevels[i + 4] = default_inner_level[i];
28    }
29 }
30 
31 
32 static void
svga_set_patch_vertices(struct pipe_context * pipe,uint8_t patch_vertices)33 svga_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices)
34 {
35    struct svga_context *svga = svga_context(pipe);
36 
37    svga->patch_vertices = patch_vertices;
38 }
39 
40 
41 static void *
svga_create_tcs_state(struct pipe_context * pipe,const struct pipe_shader_state * templ)42 svga_create_tcs_state(struct pipe_context *pipe,
43                       const struct pipe_shader_state *templ)
44 {
45    struct svga_context *svga = svga_context(pipe);
46    struct svga_tcs_shader *tcs;
47 
48    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETCS);
49 
50    tcs = (struct svga_tcs_shader *)
51             svga_create_shader(pipe, templ, PIPE_SHADER_TESS_CTRL,
52                                sizeof(struct svga_tcs_shader));
53    if (!tcs)
54       goto done;
55 
56 done:
57    SVGA_STATS_TIME_POP(svga_sws(svga));
58    (void) svga; /* silence unused var warning */
59 
60    return tcs;
61 }
62 
63 
64 static void
svga_bind_tcs_state(struct pipe_context * pipe,void * shader)65 svga_bind_tcs_state(struct pipe_context *pipe, void *shader)
66 {
67    struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader;
68    struct svga_context *svga = svga_context(pipe);
69 
70    if (tcs == svga->curr.tcs)
71       return;
72 
73    svga->curr.tcs = tcs;
74    svga->dirty |= SVGA_NEW_TCS;
75 
76    /* Check if the shader uses samplers */
77    svga_set_curr_shader_use_samplers_flag(svga, PIPE_SHADER_TESS_CTRL,
78                                           svga_shader_use_samplers(&tcs->base));
79 }
80 
81 
82 static void
svga_delete_tcs_state(struct pipe_context * pipe,void * shader)83 svga_delete_tcs_state(struct pipe_context *pipe, void *shader)
84 {
85    struct svga_context *svga = svga_context(pipe);
86    struct svga_tcs_shader *tcs = (struct svga_tcs_shader *) shader;
87    struct svga_tcs_shader *next_tcs;
88    struct svga_shader_variant *variant, *tmp;
89 
90    svga_hwtnl_flush_retry(svga);
91 
92    assert(tcs->base.parent == NULL);
93 
94    while (tcs) {
95       next_tcs = (struct svga_tcs_shader *)tcs->base.next;
96       for (variant = tcs->base.variants; variant; variant = tmp) {
97          tmp = variant->next;
98 
99          /* Check if deleting currently bound shader */
100          if (variant == svga->state.hw_draw.tcs) {
101             SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_HS, NULL));
102             svga->state.hw_draw.tcs = NULL;
103          }
104 
105          svga_destroy_shader_variant(svga, variant);
106       }
107 
108       FREE((void *)tcs->base.tokens);
109       FREE(tcs);
110       tcs = next_tcs;
111    }
112 }
113 
114 
115 void
svga_cleanup_tcs_state(struct svga_context * svga)116 svga_cleanup_tcs_state(struct svga_context *svga)
117 {
118    if (svga->tcs.passthrough_tcs) {
119       svga_delete_tcs_state(&svga->pipe, svga->tcs.passthrough_tcs);
120    }
121 }
122 
123 
124 static void *
svga_create_tes_state(struct pipe_context * pipe,const struct pipe_shader_state * templ)125 svga_create_tes_state(struct pipe_context *pipe,
126                       const struct pipe_shader_state *templ)
127 {
128    struct svga_context *svga = svga_context(pipe);
129    struct svga_tes_shader *tes;
130 
131    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATETES);
132 
133    tes = (struct svga_tes_shader *)
134             svga_create_shader(pipe, templ, PIPE_SHADER_TESS_EVAL,
135                                sizeof(struct svga_tes_shader));
136 
137    if (!tes)
138       goto done;
139 
140 done:
141    SVGA_STATS_TIME_POP(svga_sws(svga));
142    (void) svga; /* silence unused var warning */
143 
144    return tes;
145 }
146 
147 
148 static void
svga_bind_tes_state(struct pipe_context * pipe,void * shader)149 svga_bind_tes_state(struct pipe_context *pipe, void *shader)
150 {
151    struct svga_tes_shader *tes = (struct svga_tes_shader *) shader;
152    struct svga_context *svga = svga_context(pipe);
153 
154    if (tes == svga->curr.tes)
155       return;
156 
157    svga->curr.tes = tes;
158    svga->dirty |= SVGA_NEW_TES;
159 
160    /* Check if the shader uses samplers */
161    svga_set_curr_shader_use_samplers_flag(svga, PIPE_SHADER_TESS_EVAL,
162                                           svga_shader_use_samplers(&tes->base));
163 }
164 
165 
166 static void
svga_delete_tes_state(struct pipe_context * pipe,void * shader)167 svga_delete_tes_state(struct pipe_context *pipe, void *shader)
168 {
169    struct svga_context *svga = svga_context(pipe);
170    struct svga_tes_shader *tes = (struct svga_tes_shader *) shader;
171    struct svga_tes_shader *next_tes;
172    struct svga_shader_variant *variant, *tmp;
173 
174    svga_hwtnl_flush_retry(svga);
175 
176    assert(tes->base.parent == NULL);
177 
178    while (tes) {
179       next_tes = (struct svga_tes_shader *)tes->base.next;
180       for (variant = tes->base.variants; variant; variant = tmp) {
181          tmp = variant->next;
182 
183          /* Check if deleting currently bound shader */
184          if (variant == svga->state.hw_draw.tes) {
185             SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_DS, NULL));
186             svga->state.hw_draw.tes = NULL;
187          }
188 
189          svga_destroy_shader_variant(svga, variant);
190       }
191 
192       FREE((void *)tes->base.tokens);
193       FREE(tes);
194       tes = next_tes;
195    }
196 }
197 
198 
199 void
svga_init_ts_functions(struct svga_context * svga)200 svga_init_ts_functions(struct svga_context *svga)
201 {
202    svga->pipe.set_tess_state = svga_set_tess_state;
203    svga->pipe.set_patch_vertices = svga_set_patch_vertices;
204    svga->pipe.create_tcs_state = svga_create_tcs_state;
205    svga->pipe.bind_tcs_state = svga_bind_tcs_state;
206    svga->pipe.delete_tcs_state = svga_delete_tcs_state;
207    svga->pipe.create_tes_state = svga_create_tes_state;
208    svga->pipe.bind_tes_state = svga_bind_tes_state;
209    svga->pipe.delete_tes_state = svga_delete_tes_state;
210 }
211