1 /**********************************************************
2 * Copyright 2018-2020 VMware, Inc. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 **********************************************************/
26 #include "util/u_inlines.h"
27 #include "util/u_memory.h"
28 #include "util/u_simple_shaders.h"
30 #include "svga_context.h"
32 #include "svga_tgsi.h"
33 #include "svga_shader.h"
37 * Translate TGSI shader into an svga shader variant.
39 static enum pipe_error
40 compile_tcs(struct svga_context
*svga
,
41 struct svga_tcs_shader
*tcs
,
42 const struct svga_compile_key
*key
,
43 struct svga_shader_variant
**out_variant
)
45 struct svga_shader_variant
*variant
;
46 enum pipe_error ret
= PIPE_ERROR
;
48 variant
= svga_tgsi_vgpu10_translate(svga
, &tcs
->base
, key
,
49 PIPE_SHADER_TESS_CTRL
);
53 ret
= svga_define_shader(svga
, variant
);
55 svga_destroy_shader_variant(svga
, variant
);
59 *out_variant
= variant
;
66 make_tcs_key(struct svga_context
*svga
, struct svga_compile_key
*key
)
68 struct svga_tcs_shader
*tcs
= svga
->curr
.tcs
;
70 memset(key
, 0, sizeof *key
);
73 * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
75 svga_init_shader_key_common(svga
, PIPE_SHADER_TESS_CTRL
, &tcs
->base
, key
);
77 /* SVGA_NEW_TCS_PARAM */
78 key
->tcs
.vertices_per_patch
= svga
->curr
.vertices_per_patch
;
80 /* The tessellator parameters come from the layout section in the
81 * tessellation evaluation shader. Get these parameters from the
82 * current tessellation evaluation shader variant.
83 * Note: this requires the tessellation evaluation shader to be
86 struct svga_tes_variant
*tes
= svga_tes_variant(svga
->state
.hw_draw
.tes
);
87 key
->tcs
.prim_mode
= tes
->prim_mode
;
88 key
->tcs
.spacing
= tes
->spacing
;
89 key
->tcs
.vertices_order_cw
= tes
->vertices_order_cw
;
90 key
->tcs
.point_mode
= tes
->point_mode
;
92 /* The number of control point output from tcs is determined by the
93 * number of control point input expected in tes. If tes does not expect
94 * any control point input, then vertices_per_patch in the tes key will
95 * be 0, otherwise it will contain the number of vertices out as specified
96 * in the tcs property.
98 key
->tcs
.vertices_out
= tes
->base
.key
.tes
.vertices_per_patch
;
100 if (svga
->tcs
.passthrough
)
101 key
->tcs
.passthrough
= 1;
103 key
->clip_plane_enable
= svga
->curr
.rast
->templ
.clip_plane_enable
;
105 /* tcs is always followed by tes */
106 key
->last_vertex_stage
= 0;
110 static enum pipe_error
111 emit_hw_tcs(struct svga_context
*svga
, uint64_t dirty
)
113 struct svga_shader_variant
*variant
;
114 struct svga_tcs_shader
*tcs
= svga
->curr
.tcs
;
115 enum pipe_error ret
= PIPE_OK
;
116 struct svga_compile_key key
;
118 assert(svga_have_sm5(svga
));
120 SVGA_STATS_TIME_PUSH(svga_sws(svga
), SVGA_STATS_TIME_EMITTCS
);
123 /* If there is no active tcs, then there should not be
126 assert(!svga
->curr
.tes
);
127 if (svga
->state
.hw_draw
.tcs
!= NULL
) {
129 /** The previous tessellation control shader is made inactive.
130 * Needs to unbind the tessellation control shader.
132 ret
= svga_set_shader(svga
, SVGA3D_SHADERTYPE_HS
, NULL
);
135 svga
->state
.hw_draw
.tcs
= NULL
;
140 make_tcs_key(svga
, &key
);
142 /* See if we already have a TCS variant that matches the key */
143 variant
= svga_search_shader_key(&tcs
->base
, &key
);
146 ret
= compile_tcs(svga
, tcs
, &key
, &variant
);
150 /* insert the new variant at head of linked list */
152 variant
->next
= tcs
->base
.variants
;
153 tcs
->base
.variants
= variant
;
156 if (variant
!= svga
->state
.hw_draw
.tcs
) {
157 /* Bind the new variant */
158 ret
= svga_set_shader(svga
, SVGA3D_SHADERTYPE_HS
, variant
);
162 svga
->rebind
.flags
.tcs
= FALSE
;
163 svga
->dirty
|= SVGA_NEW_TCS_VARIANT
;
164 svga
->state
.hw_draw
.tcs
= variant
;
168 SVGA_STATS_TIME_POP(svga_sws(svga
));
173 struct svga_tracked_state svga_hw_tcs
=
175 "tessellation control shader (hwtnl)",
179 SVGA_NEW_TEXTURE_BINDING
|
187 * Translate TGSI shader into an svga shader variant.
189 static enum pipe_error
190 compile_tes(struct svga_context
*svga
,
191 struct svga_tes_shader
*tes
,
192 const struct svga_compile_key
*key
,
193 struct svga_shader_variant
**out_variant
)
195 struct svga_shader_variant
*variant
;
196 enum pipe_error ret
= PIPE_ERROR
;
198 variant
= svga_tgsi_vgpu10_translate(svga
, &tes
->base
, key
,
199 PIPE_SHADER_TESS_EVAL
);
203 ret
= svga_define_shader(svga
, variant
);
204 if (ret
!= PIPE_OK
) {
205 svga_destroy_shader_variant(svga
, variant
);
209 *out_variant
= variant
;
216 make_tes_key(struct svga_context
*svga
, struct svga_compile_key
*key
)
218 struct svga_tes_shader
*tes
= svga
->curr
.tes
;
219 boolean has_control_point_inputs
= FALSE
;
221 memset(key
, 0, sizeof *key
);
224 * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
226 svga_init_shader_key_common(svga
, PIPE_SHADER_TESS_EVAL
, &tes
->base
, key
);
228 assert(svga
->curr
.tcs
);
231 * Check if this tes expects any output control points from tcs.
233 for (unsigned i
= 0; i
< tes
->base
.info
.num_inputs
; i
++) {
234 switch (tes
->base
.info
.input_semantic_name
[i
]) {
235 case TGSI_SEMANTIC_PATCH
:
236 case TGSI_SEMANTIC_TESSOUTER
:
237 case TGSI_SEMANTIC_TESSINNER
:
240 has_control_point_inputs
= TRUE
;
244 key
->tes
.vertices_per_patch
= has_control_point_inputs
?
245 svga
->curr
.tcs
->base
.info
.properties
[TGSI_PROPERTY_TCS_VERTICES_OUT
] : 0;
247 key
->tes
.need_prescale
= svga
->state
.hw_clear
.prescale
[0].enabled
&&
248 (svga
->curr
.gs
== NULL
);
250 /* tcs emits tessellation factors as extra outputs.
251 * Since tes depends on them, save the tessFactor output index
252 * from tcs in the tes compile key, so that if a different
253 * tcs is bound and if the tessFactor index is different,
254 * a different tes variant will be generated.
256 key
->tes
.tessfactor_index
= svga
->curr
.tcs
->base
.info
.num_outputs
;
258 key
->clip_plane_enable
= svga
->curr
.rast
->templ
.clip_plane_enable
;
260 /* This is the last vertex stage if there is no geometry shader. */
261 key
->last_vertex_stage
= !svga
->curr
.gs
;
263 key
->tes
.need_tessinner
= 0;
264 key
->tes
.need_tessouter
= 0;
266 for (unsigned i
= 0; i
< svga
->curr
.tcs
->base
.info
.num_outputs
; i
++) {
267 switch (svga
->curr
.tcs
->base
.info
.output_semantic_name
[i
]) {
268 case TGSI_SEMANTIC_TESSOUTER
:
269 key
->tes
.need_tessouter
= 1;
271 case TGSI_SEMANTIC_TESSINNER
:
272 key
->tes
.need_tessinner
= 1;
283 get_passthrough_tcs(struct svga_context
*svga
)
285 if (svga
->tcs
.passthrough_tcs
&&
286 svga
->tcs
.vs
== svga
->curr
.vs
&&
287 svga
->tcs
.tes
== svga
->curr
.tes
&&
288 svga
->tcs
.vertices_per_patch
== svga
->curr
.vertices_per_patch
) {
289 svga
->pipe
.bind_tcs_state(&svga
->pipe
,
290 svga
->tcs
.passthrough_tcs
);
293 struct svga_tcs_shader
*new_tcs
;
295 /* delete older passthrough shader*/
296 if (svga
->tcs
.passthrough_tcs
) {
297 svga
->pipe
.delete_tcs_state(&svga
->pipe
,
298 svga
->tcs
.passthrough_tcs
);
301 new_tcs
= (struct svga_tcs_shader
*)
302 util_make_tess_ctrl_passthrough_shader(&svga
->pipe
,
303 svga
->curr
.vs
->base
.info
.num_outputs
,
304 svga
->curr
.tes
->base
.info
.num_inputs
,
305 svga
->curr
.vs
->base
.info
.output_semantic_name
,
306 svga
->curr
.vs
->base
.info
.output_semantic_index
,
307 svga
->curr
.tes
->base
.info
.input_semantic_name
,
308 svga
->curr
.tes
->base
.info
.input_semantic_index
,
309 svga
->curr
.vertices_per_patch
);
310 svga
->pipe
.bind_tcs_state(&svga
->pipe
, new_tcs
);
311 svga
->tcs
.passthrough_tcs
= new_tcs
;
312 svga
->tcs
.vs
= svga
->curr
.vs
;
313 svga
->tcs
.tes
= svga
->curr
.tes
;
314 svga
->tcs
.vertices_per_patch
= svga
->curr
.vertices_per_patch
;
317 struct pipe_constant_buffer cb
;
320 cb
.user_buffer
= (void *) svga
->curr
.default_tesslevels
;
321 cb
.buffer_offset
= 0;
322 cb
.buffer_size
= 2 * 4 * sizeof(float);
323 svga
->pipe
.set_constant_buffer(&svga
->pipe
, PIPE_SHADER_TESS_CTRL
, 0, &cb
);
327 static enum pipe_error
328 emit_hw_tes(struct svga_context
*svga
, uint64_t dirty
)
330 struct svga_shader_variant
*variant
;
331 struct svga_tes_shader
*tes
= svga
->curr
.tes
;
332 enum pipe_error ret
= PIPE_OK
;
333 struct svga_compile_key key
;
335 assert(svga_have_sm5(svga
));
337 SVGA_STATS_TIME_PUSH(svga_sws(svga
), SVGA_STATS_TIME_EMITTES
);
340 /* The GL spec implies that TES is optional when there's a TCS,
341 * but that's apparently a spec error. Assert if we have a TCS
344 assert(!svga
->curr
.tcs
);
345 if (svga
->state
.hw_draw
.tes
!= NULL
) {
347 /** The previous tessellation evaluation shader is made inactive.
348 * Needs to unbind the tessellation evaluation shader.
350 ret
= svga_set_shader(svga
, SVGA3D_SHADERTYPE_DS
, NULL
);
353 svga
->state
.hw_draw
.tes
= NULL
;
358 if (!svga
->curr
.tcs
) {
359 /* TES state is processed before the TCS
360 * shader and that's why we're checking for and creating the
361 * passthough TCS in the emit_hw_tes() function.
363 get_passthrough_tcs(svga
);
364 svga
->tcs
.passthrough
= TRUE
;
367 svga
->tcs
.passthrough
= FALSE
;
370 make_tes_key(svga
, &key
);
372 /* See if we already have a TES variant that matches the key */
373 variant
= svga_search_shader_key(&tes
->base
, &key
);
376 ret
= compile_tes(svga
, tes
, &key
, &variant
);
380 /* insert the new variant at head of linked list */
382 variant
->next
= tes
->base
.variants
;
383 tes
->base
.variants
= variant
;
386 if (variant
!= svga
->state
.hw_draw
.tes
) {
387 /* Bind the new variant */
388 ret
= svga_set_shader(svga
, SVGA3D_SHADERTYPE_DS
, variant
);
392 svga
->rebind
.flags
.tes
= FALSE
;
393 svga
->dirty
|= SVGA_NEW_TES_VARIANT
;
394 svga
->state
.hw_draw
.tes
= variant
;
398 SVGA_STATS_TIME_POP(svga_sws(svga
));
403 struct svga_tracked_state svga_hw_tes
=
405 "tessellation evaluation shader (hwtnl)",
406 /* TBD SVGA_NEW_VS/SVGA_NEW_FS/SVGA_NEW_GS are required or not*/
412 SVGA_NEW_TEXTURE_BINDING
|