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