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"
35 * Translate TGSI semantic info into SVGA3d semantic info.
36 * This is called for VS outputs and PS inputs only.
39 translate_vs_ps_semantic(struct svga_shader_emitter
*emit
,
40 struct tgsi_declaration_semantic semantic
,
44 switch (semantic
.Name
) {
45 case TGSI_SEMANTIC_POSITION
:
46 *idx
= semantic
.Index
;
47 *usage
= SVGA3D_DECLUSAGE_POSITION
;
49 case TGSI_SEMANTIC_COLOR
:
50 *idx
= semantic
.Index
;
51 *usage
= SVGA3D_DECLUSAGE_COLOR
;
53 case TGSI_SEMANTIC_BCOLOR
:
54 *idx
= semantic
.Index
+ 2; /* sharing with COLOR */
55 *usage
= SVGA3D_DECLUSAGE_COLOR
;
57 case TGSI_SEMANTIC_FOG
:
59 assert(semantic
.Index
== 0);
60 *usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
62 case TGSI_SEMANTIC_PSIZE
:
63 *idx
= semantic
.Index
;
64 *usage
= SVGA3D_DECLUSAGE_PSIZE
;
66 case TGSI_SEMANTIC_GENERIC
:
67 *idx
= svga_remap_generic_index(emit
->key
.generic_remap_table
,
69 *usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
71 case TGSI_SEMANTIC_NORMAL
:
72 *idx
= semantic
.Index
;
73 *usage
= SVGA3D_DECLUSAGE_NORMAL
;
77 *usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
87 * Emit a PS input (or VS depth/fog output) register declaration.
88 * For example, if usage = SVGA3D_DECLUSAGE_TEXCOORD, reg.num = 1, and
89 * index = 3, we'll emit "dcl_texcoord3 v1".
92 emit_decl(struct svga_shader_emitter
*emit
,
93 SVGA3dShaderDestToken reg
,
98 SVGA3dShaderInstToken opcode
;
100 /* check values against bitfield sizes */
102 assert(usage
<= SVGA3D_DECLUSAGE_MAX
);
104 opcode
= inst_token( SVGA3DOP_DCL
);
111 dcl
.values
[0] |= 1<<31;
113 return (emit_instruction(emit
, opcode
) &&
114 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
119 * Emit declaration for PS front/back-face input register.
122 emit_vface_decl(struct svga_shader_emitter
*emit
)
124 if (!emit
->emitted_vface
) {
125 SVGA3dShaderDestToken reg
=
126 dst_register(SVGA3DREG_MISCTYPE
, SVGA3DMISCREG_FACE
);
128 if (!emit_decl( emit
, reg
, 0, 0 ))
131 emit
->emitted_vface
= TRUE
;
138 * Emit PS input register to pass depth/fog coordinates.
139 * Note that this always goes into texcoord[0].
142 ps30_input_emit_depth_fog( struct svga_shader_emitter
*emit
,
143 struct src_register
*out
)
145 struct src_register reg
;
147 if (emit
->emitted_depth_fog
) {
148 *out
= emit
->ps_depth_fog
;
152 if (emit
->ps30_input_count
>= SVGA3D_INPUTREG_MAX
)
155 reg
= src_register( SVGA3DREG_INPUT
,
156 emit
->ps30_input_count
++ );
158 *out
= emit
->ps_depth_fog
= reg
;
160 emit
->emitted_depth_fog
= TRUE
;
162 return emit_decl( emit
, dst( reg
), SVGA3D_DECLUSAGE_TEXCOORD
, 0 );
167 * Process a PS input declaration.
168 * We'll emit a declaration like "dcl_texcoord1 v2"
171 ps30_input(struct svga_shader_emitter
*emit
,
172 struct tgsi_declaration_semantic semantic
,
175 unsigned usage
, index
;
176 SVGA3dShaderDestToken reg
;
178 if (semantic
.Name
== TGSI_SEMANTIC_POSITION
) {
180 emit
->ps_true_pos
= src_register( SVGA3DREG_MISCTYPE
,
181 SVGA3DMISCREG_POSITION
);
182 emit
->ps_true_pos
.base
.swizzle
= TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X
,
186 reg
= writemask( dst(emit
->ps_true_pos
),
188 emit
->ps_reads_pos
= TRUE
;
190 if (emit
->info
.reads_z
) {
191 emit
->ps_temp_pos
= dst_register( SVGA3DREG_TEMP
,
194 emit
->input_map
[idx
] = src_register( SVGA3DREG_TEMP
,
198 if (!ps30_input_emit_depth_fog( emit
, &emit
->ps_depth_pos
))
201 emit
->ps_depth_pos
.base
.swizzle
= TRANSLATE_SWIZZLE( TGSI_SWIZZLE_Z
,
207 emit
->input_map
[idx
] = emit
->ps_true_pos
;
210 return emit_decl( emit
, reg
, 0, 0 );
212 else if (emit
->key
.fkey
.light_twoside
&&
213 (semantic
.Name
== TGSI_SEMANTIC_COLOR
)) {
215 if (!translate_vs_ps_semantic( emit
, semantic
, &usage
, &index
))
218 emit
->internal_color_idx
[emit
->internal_color_count
] = idx
;
219 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
);
220 emit
->ps30_input_count
++;
221 emit
->internal_color_count
++;
223 reg
= dst( emit
->input_map
[idx
] );
225 if (!emit_decl( emit
, reg
, usage
, index
))
228 semantic
.Name
= TGSI_SEMANTIC_BCOLOR
;
229 if (!translate_vs_ps_semantic( emit
, semantic
, &usage
, &index
))
232 if (emit
->ps30_input_count
>= SVGA3D_INPUTREG_MAX
)
235 reg
= dst_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
++ );
237 if (!emit_decl( emit
, reg
, usage
, index
))
240 if (!emit_vface_decl( emit
))
245 else if (semantic
.Name
== TGSI_SEMANTIC_FACE
) {
246 if (!emit_vface_decl( emit
))
248 emit
->emit_frontface
= TRUE
;
249 emit
->internal_frontface_idx
= idx
;
252 else if (semantic
.Name
== TGSI_SEMANTIC_FOG
) {
254 assert(semantic
.Index
== 0);
256 if (!ps30_input_emit_depth_fog( emit
, &emit
->input_map
[idx
] ))
259 emit
->input_map
[idx
].base
.swizzle
= TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X
,
268 if (!translate_vs_ps_semantic( emit
, semantic
, &usage
, &index
))
271 if (emit
->ps30_input_count
>= SVGA3D_INPUTREG_MAX
)
274 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
++ );
275 reg
= dst( emit
->input_map
[idx
] );
277 if (!emit_decl( emit
, reg
, usage
, index
))
280 if (semantic
.Name
== TGSI_SEMANTIC_GENERIC
&&
281 emit
->key
.fkey
.sprite_origin_lower_left
&&
283 emit
->key
.fkey
.tex
[index
- 1].sprite_texgen
) {
284 /* This is a sprite texture coord with lower-left origin.
285 * We need to invert the texture T coordinate since the SVGA3D
286 * device only supports an upper-left origin.
288 unsigned unit
= index
- 1;
290 emit
->inverted_texcoords
|= (1 << unit
);
292 /* save original texcoord reg */
293 emit
->ps_true_texcoord
[unit
] = emit
->input_map
[idx
];
295 /* this temp register will be the results of the MAD instruction */
296 emit
->ps_inverted_texcoord
[unit
] =
297 src_register(SVGA3DREG_TEMP
, emit
->nr_hw_temp
);
300 emit
->ps_inverted_texcoord_input
[unit
] = idx
;
302 /* replace input_map entry with the temp register */
303 emit
->input_map
[idx
] = emit
->ps_inverted_texcoord
[unit
];
313 * Process a PS output declaration.
314 * Note that we don't actually emit a SVGA3DOpDcl for PS outputs.
317 ps30_output(struct svga_shader_emitter
*emit
,
318 struct tgsi_declaration_semantic semantic
,
321 switch (semantic
.Name
) {
322 case TGSI_SEMANTIC_COLOR
:
323 if (emit
->unit
== PIPE_SHADER_FRAGMENT
&&
324 emit
->key
.fkey
.white_fragments
) {
326 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
327 emit
->nr_hw_temp
++ );
328 emit
->temp_col
[idx
] = emit
->output_map
[idx
];
329 emit
->true_col
[idx
] = dst_register( SVGA3DREG_COLOROUT
,
333 emit
->output_map
[idx
] = dst_register( SVGA3DREG_COLOROUT
,
337 case TGSI_SEMANTIC_POSITION
:
338 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
339 emit
->nr_hw_temp
++ );
340 emit
->temp_pos
= emit
->output_map
[idx
];
341 emit
->true_pos
= dst_register( SVGA3DREG_DEPTHOUT
,
346 /* A wild stab in the dark. */
347 emit
->output_map
[idx
] = dst_register( SVGA3DREG_COLOROUT
, 0 );
356 * Declare a VS input register.
357 * We still make up the input semantics the same as in 2.0
360 vs30_input(struct svga_shader_emitter
*emit
,
361 struct tgsi_declaration_semantic semantic
,
365 SVGA3dShaderInstToken opcode
;
366 unsigned usage
, index
;
368 opcode
= inst_token( SVGA3DOP_DCL
);
372 if (emit
->key
.vkey
.zero_stride_vertex_elements
& (1 << idx
)) {
375 unsigned start_idx
= emit
->info
.file_max
[TGSI_FILE_CONSTANT
] + 1;
376 /* adjust for prescale constants */
377 start_idx
+= emit
->key
.vkey
.need_prescale
? 2 : 0;
378 /* compute the offset from the start of zero stride constants */
379 for (i
= 0; i
< PIPE_MAX_ATTRIBS
&& i
< idx
; ++i
) {
380 if (emit
->key
.vkey
.zero_stride_vertex_elements
& (1<<i
))
383 emit
->input_map
[idx
] = src_register( SVGA3DREG_CONST
,
384 start_idx
+ offset
);
386 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, idx
);
387 dcl
.dst
= dst_register( SVGA3DREG_INPUT
, idx
);
389 assert(dcl
.dst
.reserved0
);
391 svga_generate_vdecl_semantics( idx
, &usage
, &index
);
395 dcl
.values
[0] |= 1<<31;
397 return (emit_instruction(emit
, opcode
) &&
398 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
405 * Declare VS output for holding depth/fog.
408 vs30_output_emit_depth_fog(struct svga_shader_emitter
*emit
,
409 SVGA3dShaderDestToken
*out
)
411 SVGA3dShaderDestToken reg
;
413 if (emit
->emitted_depth_fog
) {
414 *out
= emit
->vs_depth_fog
;
418 reg
= dst_register( SVGA3DREG_OUTPUT
, emit
->vs30_output_count
++ );
420 *out
= emit
->vs_depth_fog
= reg
;
422 emit
->emitted_depth_fog
= TRUE
;
424 return emit_decl( emit
, reg
, SVGA3D_DECLUSAGE_TEXCOORD
, 0 );
429 * Declare a VS output.
430 * VS3.0 outputs have proper declarations and semantic info for
431 * matching against PS inputs.
434 vs30_output(struct svga_shader_emitter
*emit
,
435 struct tgsi_declaration_semantic semantic
,
439 SVGA3dShaderInstToken opcode
;
440 unsigned usage
, index
;
442 opcode
= inst_token( SVGA3DOP_DCL
);
446 if (!translate_vs_ps_semantic( emit
, semantic
, &usage
, &index
))
449 if (emit
->vs30_output_count
>= SVGA3D_OUTPUTREG_MAX
)
452 dcl
.dst
= dst_register( SVGA3DREG_OUTPUT
, emit
->vs30_output_count
++ );
455 dcl
.values
[0] |= 1<<31;
457 if (semantic
.Name
== TGSI_SEMANTIC_POSITION
) {
459 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
460 emit
->nr_hw_temp
++ );
461 emit
->temp_pos
= emit
->output_map
[idx
];
462 emit
->true_pos
= dcl
.dst
;
464 /* Grab an extra output for the depth output */
465 if (!vs30_output_emit_depth_fog( emit
, &emit
->depth_pos
))
469 else if (semantic
.Name
== TGSI_SEMANTIC_PSIZE
) {
470 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
471 emit
->nr_hw_temp
++ );
472 emit
->temp_psiz
= emit
->output_map
[idx
];
474 /* This has the effect of not declaring psiz (below) and not
475 * emitting the final MOV to true_psiz in the postamble.
477 if (!emit
->key
.vkey
.allow_psiz
)
480 emit
->true_psiz
= dcl
.dst
;
482 else if (semantic
.Name
== TGSI_SEMANTIC_FOG
) {
484 * Fog is shared with depth.
485 * So we need to decrement out_count since emit_depth_fog will increment it.
487 emit
->vs30_output_count
--;
489 if (!vs30_output_emit_depth_fog( emit
, &emit
->output_map
[idx
] ))
495 emit
->output_map
[idx
] = dcl
.dst
;
498 return (emit_instruction(emit
, opcode
) &&
499 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
504 ps30_sampler( struct svga_shader_emitter
*emit
,
505 struct tgsi_declaration_semantic semantic
,
509 SVGA3dShaderInstToken opcode
;
511 opcode
= inst_token( SVGA3DOP_DCL
);
515 dcl
.dst
= dst_register( SVGA3DREG_SAMPLER
, idx
);
516 dcl
.type
= svga_tgsi_sampler_type( emit
, idx
);
517 dcl
.values
[0] |= 1<<31;
519 return (emit_instruction(emit
, opcode
) &&
520 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
525 svga_translate_decl_sm30( struct svga_shader_emitter
*emit
,
526 const struct tgsi_full_declaration
*decl
)
528 unsigned first
= decl
->Range
.First
;
529 unsigned last
= decl
->Range
.Last
;
532 for( idx
= first
; idx
<= last
; idx
++ ) {
535 switch (decl
->Declaration
.File
) {
536 case TGSI_FILE_SAMPLER
:
537 assert (emit
->unit
== PIPE_SHADER_FRAGMENT
);
538 ok
= ps30_sampler( emit
, decl
->Semantic
, idx
);
541 case TGSI_FILE_INPUT
:
542 if (emit
->unit
== PIPE_SHADER_VERTEX
)
543 ok
= vs30_input( emit
, decl
->Semantic
, idx
);
545 ok
= ps30_input( emit
, decl
->Semantic
, idx
);
548 case TGSI_FILE_OUTPUT
:
549 if (emit
->unit
== PIPE_SHADER_VERTEX
)
550 ok
= vs30_output( emit
, decl
->Semantic
, idx
);
552 ok
= ps30_output( emit
, decl
->Semantic
, idx
);
556 /* don't need to declare other vars */