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 **********************************************************/
27 #include "pipe/p_shader_tokens.h"
28 #include "tgsi/tgsi_parse.h"
29 #include "util/u_memory.h"
31 #include "svga_tgsi_emit.h"
33 static boolean
translate_vs_ps_semantic( struct tgsi_declaration_semantic semantic
,
37 switch (semantic
.Name
) {
38 case TGSI_SEMANTIC_POSITION
:
39 *idx
= semantic
.Index
;
40 *usage
= SVGA3D_DECLUSAGE_POSITION
;
42 case TGSI_SEMANTIC_COLOR
:
44 *idx
= semantic
.Index
;
45 *usage
= SVGA3D_DECLUSAGE_COLOR
;
47 case TGSI_SEMANTIC_BCOLOR
:
48 *idx
= semantic
.Index
+ 2; /* sharing with COLOR */
49 *usage
= SVGA3D_DECLUSAGE_COLOR
;
51 case TGSI_SEMANTIC_FOG
:
53 assert(semantic
.Index
== 0);
54 *usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
56 case TGSI_SEMANTIC_PSIZE
:
57 *idx
= semantic
.Index
;
58 *usage
= SVGA3D_DECLUSAGE_PSIZE
;
60 case TGSI_SEMANTIC_GENERIC
:
61 *idx
= semantic
.Index
+ 1; /* texcoord[0] is reserved for fog & position */
62 *usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
64 case TGSI_SEMANTIC_NORMAL
:
65 *idx
= semantic
.Index
;
66 *usage
= SVGA3D_DECLUSAGE_NORMAL
;
70 *usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
79 static boolean
emit_decl( struct svga_shader_emitter
*emit
,
80 SVGA3dShaderDestToken reg
,
85 SVGA3dShaderInstToken opcode
;
87 opcode
= inst_token( SVGA3DOP_DCL
);
94 dcl
.values
[0] |= 1<<31;
96 return (emit_instruction(emit
, opcode
) &&
97 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
100 static boolean
emit_vface_decl( struct svga_shader_emitter
*emit
)
102 if (!emit
->emitted_vface
) {
103 SVGA3dShaderDestToken reg
=
104 dst_register( SVGA3DREG_MISCTYPE
,
105 SVGA3DMISCREG_FACE
);
107 if (!emit_decl( emit
, reg
, 0, 0 ))
110 emit
->emitted_vface
= TRUE
;
116 ps30_input_emit_depth_fog( struct svga_shader_emitter
*emit
,
117 struct src_register
*out
)
119 struct src_register reg
;
122 if (emit
->emitted_depth_fog
) {
123 *out
= emit
->ps_depth_fog
;
127 if (emit
->ps30_input_count
>= SVGA3D_INPUTREG_MAX
)
130 reg
= src_register( SVGA3DREG_INPUT
,
131 emit
->ps30_input_count
++ );
133 *out
= emit
->ps_depth_fog
= reg
;
135 emit
->emitted_depth_fog
= TRUE
;
137 return emit_decl( emit
, dst( reg
), SVGA3D_DECLUSAGE_TEXCOORD
, 0 );
140 static boolean
ps30_input( struct svga_shader_emitter
*emit
,
141 struct tgsi_declaration_semantic semantic
,
144 unsigned usage
, index
;
145 SVGA3dShaderDestToken reg
;
147 if (semantic
.Name
== TGSI_SEMANTIC_POSITION
) {
149 emit
->ps_true_pos
= src_register( SVGA3DREG_MISCTYPE
,
150 SVGA3DMISCREG_POSITION
);
151 emit
->ps_true_pos
.base
.swizzle
= TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X
,
155 reg
= writemask( dst(emit
->ps_true_pos
),
157 emit
->ps_reads_pos
= TRUE
;
159 if (emit
->info
.reads_z
) {
160 emit
->ps_temp_pos
= dst_register( SVGA3DREG_TEMP
,
163 emit
->input_map
[idx
] = src_register( SVGA3DREG_TEMP
,
167 if (!ps30_input_emit_depth_fog( emit
, &emit
->ps_depth_pos
))
170 emit
->ps_depth_pos
.base
.swizzle
= TRANSLATE_SWIZZLE( TGSI_SWIZZLE_Z
,
176 emit
->input_map
[idx
] = emit
->ps_true_pos
;
179 return emit_decl( emit
, reg
, 0, 0 );
181 else if (emit
->key
.fkey
.light_twoside
&&
182 (semantic
.Name
== TGSI_SEMANTIC_COLOR
)) {
184 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
187 emit
->internal_color_idx
[emit
->internal_color_count
] = idx
;
188 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
);
189 emit
->ps30_input_count
++;
190 emit
->internal_color_count
++;
192 reg
= dst( emit
->input_map
[idx
] );
194 if (!emit_decl( emit
, reg
, usage
, index
))
197 semantic
.Name
= TGSI_SEMANTIC_BCOLOR
;
198 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
201 if (emit
->ps30_input_count
>= SVGA3D_INPUTREG_MAX
)
204 reg
= dst_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
++ );
206 if (!emit_decl( emit
, reg
, usage
, index
))
209 if (!emit_vface_decl( emit
))
214 else if (semantic
.Name
== TGSI_SEMANTIC_FACE
) {
215 if (!emit_vface_decl( emit
))
217 emit
->emit_frontface
= TRUE
;
218 emit
->internal_frontface_idx
= idx
;
221 else if (semantic
.Name
== TGSI_SEMANTIC_FOG
) {
223 assert(semantic
.Index
== 0);
225 if (!ps30_input_emit_depth_fog( emit
, &emit
->input_map
[idx
] ))
228 emit
->input_map
[idx
].base
.swizzle
= TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X
,
237 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
240 if (emit
->ps30_input_count
>= SVGA3D_INPUTREG_MAX
)
243 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
++ );
244 reg
= dst( emit
->input_map
[idx
] );
246 if (!emit_decl( emit
, reg
, usage
, index
))
249 if (semantic
.Name
== TGSI_SEMANTIC_GENERIC
&&
250 emit
->key
.fkey
.sprite_origin_lower_left
&&
252 emit
->key
.fkey
.tex
[index
- 1].sprite_texgen
) {
253 /* This is a sprite texture coord with lower-left origin.
254 * We need to invert the texture T coordinate since the SVGA3D
255 * device only supports an upper-left origin.
257 unsigned unit
= index
- 1;
259 emit
->inverted_texcoords
|= (1 << unit
);
261 /* save original texcoord reg */
262 emit
->ps_true_texcoord
[unit
] = emit
->input_map
[idx
];
264 /* this temp register will be the results of the MAD instruction */
265 emit
->ps_inverted_texcoord
[unit
] =
266 src_register(SVGA3DREG_TEMP
, emit
->nr_hw_temp
);
269 emit
->ps_inverted_texcoord_input
[unit
] = idx
;
271 /* replace input_map entry with the temp register */
272 emit
->input_map
[idx
] = emit
->ps_inverted_texcoord
[unit
];
281 /* PS output registers are the same as 2.0
283 static boolean
ps30_output( struct svga_shader_emitter
*emit
,
284 struct tgsi_declaration_semantic semantic
,
287 SVGA3dShaderDestToken reg
;
289 switch (semantic
.Name
) {
290 case TGSI_SEMANTIC_COLOR
:
291 if (emit
->unit
== PIPE_SHADER_FRAGMENT
&&
292 emit
->key
.fkey
.white_fragments
) {
294 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
295 emit
->nr_hw_temp
++ );
296 emit
->temp_col
[idx
] = emit
->output_map
[idx
];
297 emit
->true_col
[idx
] = dst_register( SVGA3DREG_COLOROUT
,
301 emit
->output_map
[idx
] = dst_register( SVGA3DREG_COLOROUT
,
305 case TGSI_SEMANTIC_POSITION
:
306 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
307 emit
->nr_hw_temp
++ );
308 emit
->temp_pos
= emit
->output_map
[idx
];
309 emit
->true_pos
= dst_register( SVGA3DREG_DEPTHOUT
,
314 reg
= dst_register( SVGA3DREG_COLOROUT
, 0 );
322 /* We still make up the input semantics the same as in 2.0
324 static boolean
vs30_input( struct svga_shader_emitter
*emit
,
325 struct tgsi_declaration_semantic semantic
,
329 SVGA3dShaderInstToken opcode
;
330 unsigned usage
, index
;
332 opcode
= inst_token( SVGA3DOP_DCL
);
336 if (emit
->key
.vkey
.zero_stride_vertex_elements
& (1 << idx
)) {
339 unsigned start_idx
= emit
->info
.file_max
[TGSI_FILE_CONSTANT
] + 1;
340 /* adjust for prescale constants */
341 start_idx
+= emit
->key
.vkey
.need_prescale
? 2 : 0;
342 /* compute the offset from the start of zero stride constants */
343 for (i
= 0; i
< PIPE_MAX_ATTRIBS
&& i
< idx
; ++i
) {
344 if (emit
->key
.vkey
.zero_stride_vertex_elements
& (1<<i
))
347 emit
->input_map
[idx
] = src_register( SVGA3DREG_CONST
,
348 start_idx
+ offset
);
350 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, idx
);
351 dcl
.dst
= dst_register( SVGA3DREG_INPUT
, idx
);
353 assert(dcl
.dst
.reserved0
);
355 svga_generate_vdecl_semantics( idx
, &usage
, &index
);
359 dcl
.values
[0] |= 1<<31;
361 return (emit_instruction(emit
, opcode
) &&
362 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
367 static boolean
vs30_output_emit_depth_fog( struct svga_shader_emitter
*emit
,
368 SVGA3dShaderDestToken
*out
)
370 SVGA3dShaderDestToken reg
;
372 if (emit
->emitted_depth_fog
) {
373 *out
= emit
->vs_depth_fog
;
377 reg
= dst_register( SVGA3DREG_OUTPUT
, emit
->vs30_output_count
++ );
379 *out
= emit
->vs_depth_fog
= reg
;
381 emit
->emitted_depth_fog
= TRUE
;
383 return emit_decl( emit
, reg
, SVGA3D_DECLUSAGE_TEXCOORD
, 0 );
386 /* VS3.0 outputs have proper declarations and semantic info for
387 * matching against PS inputs.
389 static boolean
vs30_output( struct svga_shader_emitter
*emit
,
390 struct tgsi_declaration_semantic semantic
,
394 SVGA3dShaderInstToken opcode
;
395 unsigned usage
, index
;
397 opcode
= inst_token( SVGA3DOP_DCL
);
401 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
404 if (emit
->vs30_output_count
>= SVGA3D_OUTPUTREG_MAX
)
407 dcl
.dst
= dst_register( SVGA3DREG_OUTPUT
, emit
->vs30_output_count
++ );
410 dcl
.values
[0] |= 1<<31;
412 if (semantic
.Name
== TGSI_SEMANTIC_POSITION
) {
414 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
415 emit
->nr_hw_temp
++ );
416 emit
->temp_pos
= emit
->output_map
[idx
];
417 emit
->true_pos
= dcl
.dst
;
419 /* Grab an extra output for the depth output */
420 if (!vs30_output_emit_depth_fog( emit
, &emit
->depth_pos
))
424 else if (semantic
.Name
== TGSI_SEMANTIC_PSIZE
) {
425 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
426 emit
->nr_hw_temp
++ );
427 emit
->temp_psiz
= emit
->output_map
[idx
];
429 /* This has the effect of not declaring psiz (below) and not
430 * emitting the final MOV to true_psiz in the postamble.
432 if (!emit
->key
.vkey
.allow_psiz
)
435 emit
->true_psiz
= dcl
.dst
;
437 else if (semantic
.Name
== TGSI_SEMANTIC_FOG
) {
439 * Fog is shared with depth.
440 * So we need to decrement out_count since emit_depth_fog will increment it.
442 emit
->vs30_output_count
--;
444 if (!vs30_output_emit_depth_fog( emit
, &emit
->output_map
[idx
] ))
450 emit
->output_map
[idx
] = dcl
.dst
;
454 return (emit_instruction(emit
, opcode
) &&
455 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
458 static boolean
ps30_sampler( struct svga_shader_emitter
*emit
,
459 struct tgsi_declaration_semantic semantic
,
463 SVGA3dShaderInstToken opcode
;
465 opcode
= inst_token( SVGA3DOP_DCL
);
469 dcl
.dst
= dst_register( SVGA3DREG_SAMPLER
, idx
);
470 dcl
.type
= svga_tgsi_sampler_type( emit
, idx
);
471 dcl
.values
[0] |= 1<<31;
473 return (emit_instruction(emit
, opcode
) &&
474 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
478 boolean
svga_translate_decl_sm30( struct svga_shader_emitter
*emit
,
479 const struct tgsi_full_declaration
*decl
)
481 unsigned first
= decl
->Range
.First
;
482 unsigned last
= decl
->Range
.Last
;
483 unsigned semantic
= 0;
484 unsigned semantic_idx
= 0;
487 if (decl
->Declaration
.Semantic
) {
488 semantic
= decl
->Semantic
.Name
;
489 semantic_idx
= decl
->Semantic
.Index
;
492 for( idx
= first
; idx
<= last
; idx
++ ) {
495 switch (decl
->Declaration
.File
) {
496 case TGSI_FILE_SAMPLER
:
497 assert (emit
->unit
== PIPE_SHADER_FRAGMENT
);
498 ok
= ps30_sampler( emit
, decl
->Semantic
, idx
);
501 case TGSI_FILE_INPUT
:
502 if (emit
->unit
== PIPE_SHADER_VERTEX
)
503 ok
= vs30_input( emit
, decl
->Semantic
, idx
);
505 ok
= ps30_input( emit
, decl
->Semantic
, idx
);
508 case TGSI_FILE_OUTPUT
:
509 if (emit
->unit
== PIPE_SHADER_VERTEX
)
510 ok
= vs30_output( emit
, decl
->Semantic
, idx
);
512 ok
= ps30_output( emit
, decl
->Semantic
, idx
);
516 /* don't need to declare other vars */