1 /**********************************************************
2 * Copyright 2008-2009 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 "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"
34 #include "svga_context.h"
35 #include "svga_state.h"
37 #include "svga_shader.h"
38 #include "svga_tgsi.h"
40 #include "svga_hw_reg.h"
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.
47 static const struct tgsi_token
*
48 get_dummy_vertex_shader(void)
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
;
57 ureg
= ureg_create(TGSI_PROCESSOR_VERTEX
);
61 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 0);
62 src
= ureg_DECL_immediate(ureg
, zero
, 4);
63 ureg_MOV(ureg
, dst
, src
);
66 tokens
= ureg_get_tokens(ureg
, &num_tokens
);
74 static struct svga_shader_variant
*
75 translate_vertex_program(struct svga_context
*svga
,
76 const struct svga_vertex_shader
*vs
,
77 const struct svga_compile_key
*key
)
79 if (svga_have_vgpu10(svga
)) {
80 return svga_tgsi_vgpu10_translate(svga
, &vs
->base
, key
,
84 return svga_tgsi_vgpu9_translate(&vs
->base
, key
, PIPE_SHADER_VERTEX
);
90 * Replace the given shader's instruction with a simple / dummy shader.
91 * We use this when normal shader translation fails.
93 static struct svga_shader_variant
*
94 get_compiled_dummy_vertex_shader(struct svga_context
*svga
,
95 struct svga_vertex_shader
*vs
,
96 const struct svga_compile_key
*key
)
98 const struct tgsi_token
*dummy
= get_dummy_vertex_shader();
99 struct svga_shader_variant
*variant
;
105 FREE((void *) vs
->base
.tokens
);
106 vs
->base
.tokens
= dummy
;
108 variant
= translate_vertex_program(svga
, vs
, key
);
114 * Translate TGSI shader into an svga shader variant.
116 static enum pipe_error
117 compile_vs(struct svga_context
*svga
,
118 struct svga_vertex_shader
*vs
,
119 const struct svga_compile_key
*key
,
120 struct svga_shader_variant
**out_variant
)
122 struct svga_shader_variant
*variant
;
123 enum pipe_error ret
= PIPE_ERROR
;
125 variant
= translate_vertex_program(svga
, vs
, key
);
126 if (variant
== NULL
) {
127 debug_printf("Failed to compile vertex shader,"
128 " using dummy shader instead.\n");
129 variant
= get_compiled_dummy_vertex_shader(svga
, vs
, key
);
136 if (svga_shader_too_large(svga
, variant
)) {
137 /* too big, use dummy shader */
138 debug_printf("Shader too large (%u bytes),"
139 " using dummy shader instead.\n",
140 (unsigned) (variant
->nr_tokens
141 * sizeof(variant
->tokens
[0])));
142 variant
= get_compiled_dummy_vertex_shader(svga
, vs
, key
);
149 ret
= svga_define_shader(svga
, SVGA3D_SHADERTYPE_VS
, variant
);
153 *out_variant
= variant
;
159 svga_destroy_shader_variant(svga
, SVGA3D_SHADERTYPE_VS
, variant
);
164 /* SVGA_NEW_PRESCALE, SVGA_NEW_RAST, SVGA_NEW_FS
167 make_vs_key(struct svga_context
*svga
, struct svga_compile_key
*key
)
169 const unsigned shader
= PIPE_SHADER_VERTEX
;
171 memset(key
, 0, sizeof *key
);
173 if (svga
->state
.sw
.need_swtnl
&& svga_have_vgpu10(svga
)) {
174 /* Set both of these flags, to match compile_passthrough_vs() */
175 key
->vs
.passthrough
= 1;
176 key
->vs
.undo_viewport
= 1;
180 key
->vs
.need_prescale
= svga
->state
.hw_clear
.prescale
.enabled
&&
181 (svga
->curr
.gs
== NULL
);
182 key
->vs
.allow_psiz
= svga
->curr
.rast
->templ
.point_size_per_vertex
;
185 key
->vs
.fs_generic_inputs
= svga
->curr
.fs
->generic_inputs
;
187 svga_remap_generics(key
->vs
.fs_generic_inputs
, key
->generic_remap_table
);
189 /* SVGA_NEW_VELEMENT */
190 key
->vs
.adjust_attrib_range
= svga
->curr
.velems
->adjust_attrib_range
;
191 key
->vs
.adjust_attrib_w_1
= svga
->curr
.velems
->adjust_attrib_w_1
;
192 key
->vs
.attrib_is_pure_int
= svga
->curr
.velems
->attrib_is_pure_int
;
193 key
->vs
.adjust_attrib_itof
= svga
->curr
.velems
->adjust_attrib_itof
;
194 key
->vs
.adjust_attrib_utof
= svga
->curr
.velems
->adjust_attrib_utof
;
195 key
->vs
.attrib_is_bgra
= svga
->curr
.velems
->attrib_is_bgra
;
196 key
->vs
.attrib_puint_to_snorm
= svga
->curr
.velems
->attrib_puint_to_snorm
;
197 key
->vs
.attrib_puint_to_uscaled
= svga
->curr
.velems
->attrib_puint_to_uscaled
;
198 key
->vs
.attrib_puint_to_sscaled
= svga
->curr
.velems
->attrib_puint_to_sscaled
;
200 /* SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER */
201 svga_init_shader_key_common(svga
, shader
, key
);
204 key
->clip_plane_enable
= svga
->curr
.rast
->templ
.clip_plane_enable
;
209 * svga_reemit_vs_bindings - Reemit the vertex shader bindings
212 svga_reemit_vs_bindings(struct svga_context
*svga
)
215 struct svga_winsys_gb_shader
*gbshader
= NULL
;
216 SVGA3dShaderId shaderId
= SVGA3D_INVALID_ID
;
218 assert(svga
->rebind
.flags
.vs
);
219 assert(svga_have_gb_objects(svga
));
221 if (svga
->state
.hw_draw
.vs
) {
222 gbshader
= svga
->state
.hw_draw
.vs
->gb_shader
;
223 shaderId
= svga
->state
.hw_draw
.vs
->id
;
226 if (!svga_need_to_rebind_resources(svga
)) {
227 ret
= svga
->swc
->resource_rebind(svga
->swc
, NULL
, gbshader
,
232 if (svga_have_vgpu10(svga
))
233 ret
= SVGA3D_vgpu10_SetShader(svga
->swc
, SVGA3D_SHADERTYPE_VS
,
236 ret
= SVGA3D_SetGBShader(svga
->swc
, SVGA3D_SHADERTYPE_VS
, gbshader
);
242 svga
->rebind
.flags
.vs
= FALSE
;
248 * The current vertex shader is already executed by the 'draw'
249 * module, so we just need to generate a simple vertex shader
250 * to pass through all those VS outputs that will
251 * be consumed by the fragment shader.
252 * Used when we employ the 'draw' module.
254 static enum pipe_error
255 compile_passthrough_vs(struct svga_context
*svga
,
256 struct svga_vertex_shader
*vs
,
257 struct svga_fragment_shader
*fs
,
258 struct svga_shader_variant
**out_variant
)
260 struct svga_shader_variant
*variant
= NULL
;
263 unsigned num_elements
;
264 struct svga_vertex_shader new_vs
;
265 struct ureg_src src
[PIPE_MAX_SHADER_INPUTS
];
266 struct ureg_dst dst
[PIPE_MAX_SHADER_OUTPUTS
];
267 struct ureg_program
*ureg
;
269 struct svga_compile_key key
;
272 assert(svga_have_vgpu10(svga
));
275 num_inputs
= fs
->base
.info
.num_inputs
;
277 ureg
= ureg_create(TGSI_PROCESSOR_VERTEX
);
279 return PIPE_ERROR_OUT_OF_MEMORY
;
281 /* draw will always add position */
282 dst
[0] = ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 0);
283 src
[0] = ureg_DECL_vs_input(ureg
, 0);
287 * swtnl backend redefines the input layout based on the
288 * fragment shader's inputs. So we only need to passthrough
289 * those inputs that will be consumed by the fragment shader.
290 * Note: DX10 requires the number of vertex elements
291 * specified in the input layout to be no less than the
292 * number of inputs to the vertex shader.
294 for (i
= 0; i
< num_inputs
; i
++) {
295 switch (fs
->base
.info
.input_semantic_name
[i
]) {
296 case TGSI_SEMANTIC_COLOR
:
297 case TGSI_SEMANTIC_GENERIC
:
298 case TGSI_SEMANTIC_FOG
:
299 dst
[num_elements
] = ureg_DECL_output(ureg
,
300 fs
->base
.info
.input_semantic_name
[i
],
301 fs
->base
.info
.input_semantic_index
[i
]);
302 src
[num_elements
] = ureg_DECL_vs_input(ureg
, num_elements
);
310 for (i
= 0; i
< num_elements
; i
++) {
311 ureg_MOV(ureg
, dst
[i
], src
[i
]);
316 memset(&new_vs
, 0, sizeof(new_vs
));
317 new_vs
.base
.tokens
= ureg_get_tokens(ureg
, &num_tokens
);
318 tgsi_scan_shader(new_vs
.base
.tokens
, &new_vs
.base
.info
);
320 memset(&key
, 0, sizeof(key
));
321 key
.vs
.undo_viewport
= 1;
323 ret
= compile_vs(svga
, &new_vs
, &key
, &variant
);
327 ureg_free_tokens(new_vs
.base
.tokens
);
330 /* Overwrite the variant key to indicate it's a pass-through VS */
331 memset(&variant
->key
, 0, sizeof(variant
->key
));
332 variant
->key
.vs
.passthrough
= 1;
333 variant
->key
.vs
.undo_viewport
= 1;
335 *out_variant
= variant
;
341 static enum pipe_error
342 emit_hw_vs(struct svga_context
*svga
, unsigned dirty
)
344 struct svga_shader_variant
*variant
;
345 struct svga_vertex_shader
*vs
= svga
->curr
.vs
;
346 struct svga_fragment_shader
*fs
= svga
->curr
.fs
;
347 enum pipe_error ret
= PIPE_OK
;
348 struct svga_compile_key key
;
350 /* If there is an active geometry shader, and it has stream output
351 * defined, then we will skip the stream output from the vertex shader
353 if (!svga_have_gs_streamout(svga
)) {
354 /* No GS stream out */
355 if (svga_have_vs_streamout(svga
)) {
356 /* Set VS stream out */
357 svga_set_stream_output(svga
, vs
->base
.stream_output
);
360 /* turn off stream out */
361 svga_set_stream_output(svga
, NULL
);
365 /* SVGA_NEW_NEED_SWTNL */
366 if (svga
->state
.sw
.need_swtnl
&& !svga_have_vgpu10(svga
)) {
367 /* No vertex shader is needed */
371 make_vs_key(svga
, &key
);
373 /* See if we already have a VS variant that matches the key */
374 variant
= svga_search_shader_key(&vs
->base
, &key
);
377 /* Create VS variant now */
378 if (key
.vs
.passthrough
) {
379 ret
= compile_passthrough_vs(svga
, vs
, fs
, &variant
);
382 ret
= compile_vs(svga
, vs
, &key
, &variant
);
387 /* insert the new variant at head of linked list */
389 variant
->next
= vs
->base
.variants
;
390 vs
->base
.variants
= variant
;
394 if (variant
!= svga
->state
.hw_draw
.vs
) {
395 /* Bind the new variant */
397 ret
= svga_set_shader(svga
, SVGA3D_SHADERTYPE_VS
, variant
);
400 svga
->rebind
.flags
.vs
= FALSE
;
403 svga
->dirty
|= SVGA_NEW_VS_VARIANT
;
404 svga
->state
.hw_draw
.vs
= variant
;
410 struct svga_tracked_state svga_hw_vs
=
412 "vertex shader (hwtnl)",
415 SVGA_NEW_TEXTURE_BINDING
|
420 SVGA_NEW_NEED_SWTNL
),