• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**********************************************************
2  * Copyright 2008-2022 VMware, Inc.  All rights reserved.
3  *
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:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
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
22  * SOFTWARE.
23  *
24  **********************************************************/
25 
26 #include "util/u_inlines.h"
27 #include "pipe/p_defines.h"
28 #include "util/u_math.h"
29 #include "util/u_memory.h"
30 #include "util/u_bitmask.h"
31 #include "translate/translate.h"
32 #include "tgsi/tgsi_ureg.h"
33 
34 #include "svga_context.h"
35 #include "svga_state.h"
36 #include "svga_cmd.h"
37 #include "svga_shader.h"
38 #include "svga_tgsi.h"
39 
40 #include "svga_hw_reg.h"
41 
42 
43 /**
44  * If we fail to compile a vertex shader we'll use a dummy/fallback shader
45  * that simply emits a (0,0,0,1) vertex position.
46  */
47 static const struct tgsi_token *
get_dummy_vertex_shader(void)48 get_dummy_vertex_shader(void)
49 {
50    static const float zero[4] = { 0.0, 0.0, 0.0, 1.0 };
51    struct ureg_program *ureg;
52    const struct tgsi_token *tokens;
53    struct ureg_src src;
54    struct ureg_dst dst;
55 
56    ureg = ureg_create(PIPE_SHADER_VERTEX);
57    if (!ureg)
58       return NULL;
59 
60    dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
61    src = ureg_DECL_immediate(ureg, zero, 4);
62    ureg_MOV(ureg, dst, src);
63    ureg_END(ureg);
64 
65    tokens = ureg_get_tokens(ureg, NULL);
66 
67    ureg_destroy(ureg);
68 
69    return tokens;
70 }
71 
72 
73 /**
74  * Replace the given shader's instruction with a simple / dummy shader.
75  * We use this when normal shader translation fails.
76  */
77 struct svga_shader_variant *
svga_get_compiled_dummy_vertex_shader(struct svga_context * svga,struct svga_shader * shader,const struct svga_compile_key * key)78 svga_get_compiled_dummy_vertex_shader(struct svga_context *svga,
79                                       struct svga_shader *shader,
80                                       const struct svga_compile_key *key)
81 {
82    struct svga_vertex_shader *vs = (struct svga_vertex_shader *)shader;
83    const struct tgsi_token *dummy = get_dummy_vertex_shader();
84    struct svga_shader_variant *variant;
85 
86    if (!dummy) {
87       return NULL;
88    }
89 
90    FREE((void *) vs->base.tokens);
91    vs->base.tokens = dummy;
92 
93    svga_tgsi_scan_shader(&vs->base);
94 
95    variant = svga_tgsi_compile_shader(svga, shader, key);
96    return variant;
97 }
98 
99 
100 /* SVGA_NEW_PRESCALE, SVGA_NEW_RAST, SVGA_NEW_FS
101  */
102 static void
make_vs_key(struct svga_context * svga,struct svga_compile_key * key)103 make_vs_key(struct svga_context *svga, struct svga_compile_key *key)
104 {
105    struct svga_vertex_shader *vs = svga->curr.vs;
106 
107    memset(key, 0, sizeof *key);
108 
109    if (svga->state.sw.need_swtnl && svga_have_vgpu10(svga)) {
110       /* Set both of these flags, to match compile_passthrough_vs() */
111       key->vs.passthrough = 1;
112       key->vs.undo_viewport = 1;
113       return;
114    }
115 
116    if (svga_have_vgpu10(svga)) {
117       key->vs.need_vertex_id_bias = 1;
118    }
119 
120    /* SVGA_NEW_PRESCALE */
121    key->vs.need_prescale = svga->state.hw_clear.prescale[0].enabled &&
122                            (svga->curr.tes == NULL) &&
123                            (svga->curr.gs == NULL);
124 
125    /* SVGA_NEW_RAST */
126    key->vs.allow_psiz = svga->curr.rast->templ.point_size_per_vertex;
127 
128    /* SVGA_NEW_FS */
129    key->vs.fs_generic_inputs = svga->curr.fs->base.info.generic_inputs_mask;
130 
131    svga_remap_generics(key->vs.fs_generic_inputs, key->generic_remap_table);
132 
133    /* SVGA_NEW_VELEMENT */
134    key->vs.adjust_attrib_range = svga->curr.velems->adjust_attrib_range;
135    key->vs.adjust_attrib_w_1 = svga->curr.velems->adjust_attrib_w_1;
136    key->vs.attrib_is_pure_int = svga->curr.velems->attrib_is_pure_int;
137    key->vs.adjust_attrib_itof = svga->curr.velems->adjust_attrib_itof;
138    key->vs.adjust_attrib_utof = svga->curr.velems->adjust_attrib_utof;
139    key->vs.attrib_is_bgra = svga->curr.velems->attrib_is_bgra;
140    key->vs.attrib_puint_to_snorm = svga->curr.velems->attrib_puint_to_snorm;
141    key->vs.attrib_puint_to_uscaled = svga->curr.velems->attrib_puint_to_uscaled;
142    key->vs.attrib_puint_to_sscaled = svga->curr.velems->attrib_puint_to_sscaled;
143 
144    /* SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER */
145    svga_init_shader_key_common(svga, PIPE_SHADER_VERTEX, &vs->base, key);
146 
147    /* SVGA_NEW_RAST */
148    key->clip_plane_enable = svga->curr.rast->templ.clip_plane_enable;
149 
150    /* Determine if this shader is the last shader in the vertex
151     * processing stage.
152     */
153    key->last_vertex_stage = !(svga->curr.gs ||
154                               svga->curr.tcs || svga->curr.tes);
155 }
156 
157 
158 /**
159  * svga_reemit_vs_bindings - Reemit the vertex shader bindings
160  */
161 enum pipe_error
svga_reemit_vs_bindings(struct svga_context * svga)162 svga_reemit_vs_bindings(struct svga_context *svga)
163 {
164    enum pipe_error ret;
165    struct svga_winsys_gb_shader *gbshader = NULL;
166    SVGA3dShaderId shaderId = SVGA3D_INVALID_ID;
167 
168    assert(svga->rebind.flags.vs);
169    assert(svga_have_gb_objects(svga));
170 
171    if (svga->state.hw_draw.vs) {
172       gbshader = svga->state.hw_draw.vs->gb_shader;
173       shaderId = svga->state.hw_draw.vs->id;
174    }
175 
176    if (!svga_need_to_rebind_resources(svga)) {
177       ret =  svga->swc->resource_rebind(svga->swc, NULL, gbshader,
178                                         SVGA_RELOC_READ);
179    }
180    else {
181       if (svga_have_vgpu10(svga))
182          ret = SVGA3D_vgpu10_SetShader(svga->swc, SVGA3D_SHADERTYPE_VS,
183                                        gbshader, shaderId);
184       else
185          ret = SVGA3D_SetGBShader(svga->swc, SVGA3D_SHADERTYPE_VS, gbshader);
186    }
187 
188    if (ret != PIPE_OK)
189       return ret;
190 
191    svga->rebind.flags.vs = FALSE;
192    return PIPE_OK;
193 }
194 
195 
196 /**
197  * The current vertex shader is already executed by the 'draw'
198  * module, so we just need to generate a simple vertex shader
199  * to pass through all those VS outputs that will
200  * be consumed by the fragment shader.
201  * Used when we employ the 'draw' module.
202  */
203 static enum pipe_error
compile_passthrough_vs(struct svga_context * svga,struct svga_vertex_shader * vs,struct svga_fragment_shader * fs,struct svga_shader_variant ** out_variant)204 compile_passthrough_vs(struct svga_context *svga,
205                        struct svga_vertex_shader *vs,
206                        struct svga_fragment_shader *fs,
207                        struct svga_shader_variant **out_variant)
208 {
209    struct svga_shader_variant *variant = NULL;
210    unsigned num_inputs;
211    unsigned i;
212    unsigned num_elements;
213    struct svga_vertex_shader new_vs;
214    struct ureg_src src[PIPE_MAX_SHADER_INPUTS];
215    struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS];
216    struct ureg_program *ureg;
217    struct svga_compile_key key;
218    enum pipe_error ret;
219 
220    assert(svga_have_vgpu10(svga));
221    assert(fs);
222 
223    num_inputs = fs->base.tgsi_info.num_inputs;
224 
225    ureg = ureg_create(PIPE_SHADER_VERTEX);
226    if (!ureg)
227       return PIPE_ERROR_OUT_OF_MEMORY;
228 
229    /* draw will always add position */
230    dst[0] = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
231    src[0] = ureg_DECL_vs_input(ureg, 0);
232    num_elements = 1;
233 
234    /**
235     * swtnl backend redefines the input layout based on the
236     * fragment shader's inputs. So we only need to passthrough
237     * those inputs that will be consumed by the fragment shader.
238     * Note: DX10 requires the number of vertex elements
239     * specified in the input layout to be no less than the
240     * number of inputs to the vertex shader.
241     */
242    for (i = 0; i < num_inputs; i++) {
243       switch (fs->base.tgsi_info.input_semantic_name[i]) {
244       case TGSI_SEMANTIC_COLOR:
245       case TGSI_SEMANTIC_GENERIC:
246       case TGSI_SEMANTIC_FOG:
247          dst[num_elements] = ureg_DECL_output(ureg,
248                                 fs->base.tgsi_info.input_semantic_name[i],
249                                 fs->base.tgsi_info.input_semantic_index[i]);
250          src[num_elements] = ureg_DECL_vs_input(ureg, num_elements);
251          num_elements++;
252          break;
253       default:
254          break;
255       }
256    }
257 
258    for (i = 0; i < num_elements; i++) {
259       ureg_MOV(ureg, dst[i], src[i]);
260    }
261 
262    ureg_END(ureg);
263 
264    memset(&new_vs, 0, sizeof(new_vs));
265    new_vs.base.tokens = ureg_get_tokens(ureg, NULL);
266    svga_tgsi_scan_shader(&new_vs.base);
267 
268    memset(&key, 0, sizeof(key));
269    key.vs.undo_viewport = 1;
270 
271    ret = svga_compile_shader(svga, &new_vs.base, &key, &variant);
272    if (ret != PIPE_OK)
273       return ret;
274 
275    ureg_free_tokens(new_vs.base.tokens);
276    ureg_destroy(ureg);
277 
278    /* Overwrite the variant key to indicate it's a pass-through VS */
279    memset(&variant->key, 0, sizeof(variant->key));
280    variant->key.vs.passthrough = 1;
281    variant->key.vs.undo_viewport = 1;
282 
283    *out_variant = variant;
284 
285    return PIPE_OK;
286 }
287 
288 
289 static enum pipe_error
emit_hw_vs(struct svga_context * svga,uint64_t dirty)290 emit_hw_vs(struct svga_context *svga, uint64_t dirty)
291 {
292    struct svga_shader_variant *variant;
293    struct svga_vertex_shader *vs = svga->curr.vs;
294    struct svga_fragment_shader *fs = svga->curr.fs;
295    enum pipe_error ret = PIPE_OK;
296    struct svga_compile_key key;
297 
298    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_EMITVS);
299 
300    /* If there is an active geometry shader, and it has stream output
301     * defined, then we will skip the stream output from the vertex shader
302     */
303    if (!svga_have_gs_streamout(svga)) {
304       /* No GS stream out */
305       if (svga_have_vs_streamout(svga)) {
306          /* Set VS stream out */
307          ret = svga_set_stream_output(svga, vs->base.stream_output);
308       }
309       else {
310          /* turn off stream out */
311          ret = svga_set_stream_output(svga, NULL);
312       }
313       if (ret != PIPE_OK) {
314          goto done;
315       }
316    }
317 
318    /* SVGA_NEW_NEED_SWTNL */
319    if (svga->state.sw.need_swtnl && !svga_have_vgpu10(svga)) {
320       /* No vertex shader is needed */
321       variant = NULL;
322    }
323    else {
324       make_vs_key(svga, &key);
325 
326       /* See if we already have a VS variant that matches the key */
327       variant = svga_search_shader_key(&vs->base, &key);
328 
329       if (!variant) {
330          /* Create VS variant now */
331          if (key.vs.passthrough) {
332             ret = compile_passthrough_vs(svga, vs, fs, &variant);
333          }
334          else {
335             ret = svga_compile_shader(svga, &vs->base, &key, &variant);
336          }
337          if (ret != PIPE_OK)
338             goto done;
339       }
340    }
341 
342    if (variant != svga->state.hw_draw.vs) {
343       /* Bind the new variant */
344       if (variant) {
345          ret = svga_set_shader(svga, SVGA3D_SHADERTYPE_VS, variant);
346          if (ret != PIPE_OK)
347             goto done;
348          svga->rebind.flags.vs = FALSE;
349       }
350 
351       svga->dirty |= SVGA_NEW_VS_VARIANT;
352       svga->state.hw_draw.vs = variant;
353    }
354 
355 done:
356    SVGA_STATS_TIME_POP(svga_sws(svga));
357    return ret;
358 }
359 
360 struct svga_tracked_state svga_hw_vs =
361 {
362    "vertex shader (hwtnl)",
363    (SVGA_NEW_VS |
364     SVGA_NEW_FS |
365     SVGA_NEW_TEXTURE_BINDING |
366     SVGA_NEW_SAMPLER |
367     SVGA_NEW_RAST |
368     SVGA_NEW_PRESCALE |
369     SVGA_NEW_VELEMENT |
370     SVGA_NEW_NEED_SWTNL |
371     SVGA_NEW_VS_RAW_BUFFER),
372    emit_hw_vs
373 };
374