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
);
131 else if (svga_shader_too_large(svga
, variant
)) {
132 /* too big, use dummy shader */
133 debug_printf("Shader too large (%u bytes),"
134 " using dummy shader instead.\n",
135 (unsigned) (variant
->nr_tokens
136 * sizeof(variant
->tokens
[0])));
137 /* Free the too-large variant */
138 svga_destroy_shader_variant(svga
, SVGA3D_SHADERTYPE_VS
, variant
);
139 /* Use simple pass-through shader instead */
140 variant
= get_compiled_dummy_vertex_shader(svga
, vs
, key
);
147 ret
= svga_define_shader(svga
, SVGA3D_SHADERTYPE_VS
, variant
);
148 if (ret
!= PIPE_OK
) {
149 svga_destroy_shader_variant(svga
, SVGA3D_SHADERTYPE_VS
, variant
);
153 *out_variant
= variant
;
159 /* SVGA_NEW_PRESCALE, SVGA_NEW_RAST, SVGA_NEW_FS
162 make_vs_key(struct svga_context
*svga
, struct svga_compile_key
*key
)
164 const unsigned shader
= PIPE_SHADER_VERTEX
;
166 memset(key
, 0, sizeof *key
);
168 if (svga
->state
.sw
.need_swtnl
&& svga_have_vgpu10(svga
)) {
169 /* Set both of these flags, to match compile_passthrough_vs() */
170 key
->vs
.passthrough
= 1;
171 key
->vs
.undo_viewport
= 1;
175 key
->vs
.need_prescale
= svga
->state
.hw_clear
.prescale
.enabled
&&
176 (svga
->curr
.gs
== NULL
);
177 key
->vs
.allow_psiz
= svga
->curr
.rast
->templ
.point_size_per_vertex
;
180 key
->vs
.fs_generic_inputs
= svga
->curr
.fs
->generic_inputs
;
182 svga_remap_generics(key
->vs
.fs_generic_inputs
, key
->generic_remap_table
);
184 /* SVGA_NEW_VELEMENT */
185 key
->vs
.adjust_attrib_range
= svga
->curr
.velems
->adjust_attrib_range
;
186 key
->vs
.adjust_attrib_w_1
= svga
->curr
.velems
->adjust_attrib_w_1
;
187 key
->vs
.attrib_is_pure_int
= svga
->curr
.velems
->attrib_is_pure_int
;
188 key
->vs
.adjust_attrib_itof
= svga
->curr
.velems
->adjust_attrib_itof
;
189 key
->vs
.adjust_attrib_utof
= svga
->curr
.velems
->adjust_attrib_utof
;
190 key
->vs
.attrib_is_bgra
= svga
->curr
.velems
->attrib_is_bgra
;
191 key
->vs
.attrib_puint_to_snorm
= svga
->curr
.velems
->attrib_puint_to_snorm
;
192 key
->vs
.attrib_puint_to_uscaled
= svga
->curr
.velems
->attrib_puint_to_uscaled
;
193 key
->vs
.attrib_puint_to_sscaled
= svga
->curr
.velems
->attrib_puint_to_sscaled
;
195 /* SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER */
196 svga_init_shader_key_common(svga
, shader
, key
);
199 key
->clip_plane_enable
= svga
->curr
.rast
->templ
.clip_plane_enable
;
204 * svga_reemit_vs_bindings - Reemit the vertex shader bindings
207 svga_reemit_vs_bindings(struct svga_context
*svga
)
210 struct svga_winsys_gb_shader
*gbshader
= NULL
;
211 SVGA3dShaderId shaderId
= SVGA3D_INVALID_ID
;
213 assert(svga
->rebind
.flags
.vs
);
214 assert(svga_have_gb_objects(svga
));
216 if (svga
->state
.hw_draw
.vs
) {
217 gbshader
= svga
->state
.hw_draw
.vs
->gb_shader
;
218 shaderId
= svga
->state
.hw_draw
.vs
->id
;
221 if (!svga_need_to_rebind_resources(svga
)) {
222 ret
= svga
->swc
->resource_rebind(svga
->swc
, NULL
, gbshader
,
227 if (svga_have_vgpu10(svga
))
228 ret
= SVGA3D_vgpu10_SetShader(svga
->swc
, SVGA3D_SHADERTYPE_VS
,
231 ret
= SVGA3D_SetGBShader(svga
->swc
, SVGA3D_SHADERTYPE_VS
, gbshader
);
237 svga
->rebind
.flags
.vs
= FALSE
;
243 * The current vertex shader is already executed by the 'draw'
244 * module, so we just need to generate a simple vertex shader
245 * to pass through all those VS outputs that will
246 * be consumed by the fragment shader.
247 * Used when we employ the 'draw' module.
249 static enum pipe_error
250 compile_passthrough_vs(struct svga_context
*svga
,
251 struct svga_vertex_shader
*vs
,
252 struct svga_fragment_shader
*fs
,
253 struct svga_shader_variant
**out_variant
)
255 struct svga_shader_variant
*variant
= NULL
;
258 unsigned num_elements
;
259 struct svga_vertex_shader new_vs
;
260 struct ureg_src src
[PIPE_MAX_SHADER_INPUTS
];
261 struct ureg_dst dst
[PIPE_MAX_SHADER_OUTPUTS
];
262 struct ureg_program
*ureg
;
264 struct svga_compile_key key
;
267 assert(svga_have_vgpu10(svga
));
270 num_inputs
= fs
->base
.info
.num_inputs
;
272 ureg
= ureg_create(TGSI_PROCESSOR_VERTEX
);
274 return PIPE_ERROR_OUT_OF_MEMORY
;
276 /* draw will always add position */
277 dst
[0] = ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 0);
278 src
[0] = ureg_DECL_vs_input(ureg
, 0);
282 * swtnl backend redefines the input layout based on the
283 * fragment shader's inputs. So we only need to passthrough
284 * those inputs that will be consumed by the fragment shader.
285 * Note: DX10 requires the number of vertex elements
286 * specified in the input layout to be no less than the
287 * number of inputs to the vertex shader.
289 for (i
= 0; i
< num_inputs
; i
++) {
290 switch (fs
->base
.info
.input_semantic_name
[i
]) {
291 case TGSI_SEMANTIC_COLOR
:
292 case TGSI_SEMANTIC_GENERIC
:
293 case TGSI_SEMANTIC_FOG
:
294 dst
[num_elements
] = ureg_DECL_output(ureg
,
295 fs
->base
.info
.input_semantic_name
[i
],
296 fs
->base
.info
.input_semantic_index
[i
]);
297 src
[num_elements
] = ureg_DECL_vs_input(ureg
, num_elements
);
305 for (i
= 0; i
< num_elements
; i
++) {
306 ureg_MOV(ureg
, dst
[i
], src
[i
]);
311 memset(&new_vs
, 0, sizeof(new_vs
));
312 new_vs
.base
.tokens
= ureg_get_tokens(ureg
, &num_tokens
);
313 tgsi_scan_shader(new_vs
.base
.tokens
, &new_vs
.base
.info
);
315 memset(&key
, 0, sizeof(key
));
316 key
.vs
.undo_viewport
= 1;
318 ret
= compile_vs(svga
, &new_vs
, &key
, &variant
);
322 ureg_free_tokens(new_vs
.base
.tokens
);
325 /* Overwrite the variant key to indicate it's a pass-through VS */
326 memset(&variant
->key
, 0, sizeof(variant
->key
));
327 variant
->key
.vs
.passthrough
= 1;
328 variant
->key
.vs
.undo_viewport
= 1;
330 *out_variant
= variant
;
336 static enum pipe_error
337 emit_hw_vs(struct svga_context
*svga
, unsigned dirty
)
339 struct svga_shader_variant
*variant
;
340 struct svga_vertex_shader
*vs
= svga
->curr
.vs
;
341 struct svga_fragment_shader
*fs
= svga
->curr
.fs
;
342 enum pipe_error ret
= PIPE_OK
;
343 struct svga_compile_key key
;
345 /* If there is an active geometry shader, and it has stream output
346 * defined, then we will skip the stream output from the vertex shader
348 if (!svga_have_gs_streamout(svga
)) {
349 /* No GS stream out */
350 if (svga_have_vs_streamout(svga
)) {
351 /* Set VS stream out */
352 svga_set_stream_output(svga
, vs
->base
.stream_output
);
355 /* turn off stream out */
356 svga_set_stream_output(svga
, NULL
);
360 /* SVGA_NEW_NEED_SWTNL */
361 if (svga
->state
.sw
.need_swtnl
&& !svga_have_vgpu10(svga
)) {
362 /* No vertex shader is needed */
366 make_vs_key(svga
, &key
);
368 /* See if we already have a VS variant that matches the key */
369 variant
= svga_search_shader_key(&vs
->base
, &key
);
372 /* Create VS variant now */
373 if (key
.vs
.passthrough
) {
374 ret
= compile_passthrough_vs(svga
, vs
, fs
, &variant
);
377 ret
= compile_vs(svga
, vs
, &key
, &variant
);
382 /* insert the new variant at head of linked list */
384 variant
->next
= vs
->base
.variants
;
385 vs
->base
.variants
= variant
;
389 if (variant
!= svga
->state
.hw_draw
.vs
) {
390 /* Bind the new variant */
392 ret
= svga_set_shader(svga
, SVGA3D_SHADERTYPE_VS
, variant
);
395 svga
->rebind
.flags
.vs
= FALSE
;
398 svga
->dirty
|= SVGA_NEW_VS_VARIANT
;
399 svga
->state
.hw_draw
.vs
= variant
;
405 struct svga_tracked_state svga_hw_vs
=
407 "vertex shader (hwtnl)",
410 SVGA_NEW_TEXTURE_BINDING
|
415 SVGA_NEW_NEED_SWTNL
),