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 */
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
;
115 static boolean
ps30_input( struct svga_shader_emitter
*emit
,
116 struct tgsi_declaration_semantic semantic
,
119 unsigned usage
, index
;
120 SVGA3dShaderDestToken reg
;
122 if (semantic
.Name
== TGSI_SEMANTIC_POSITION
) {
123 emit
->input_map
[idx
] = src_register( SVGA3DREG_MISCTYPE
,
124 SVGA3DMISCREG_POSITION
);
126 emit
->input_map
[idx
].base
.swizzle
= TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X
,
131 reg
= writemask( dst(emit
->input_map
[idx
]),
134 return emit_decl( emit
, reg
, 0, 0 );
136 else if (emit
->key
.fkey
.light_twoside
&&
137 (semantic
.Name
== TGSI_SEMANTIC_COLOR
)) {
139 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
142 emit
->internal_color_idx
[emit
->internal_color_count
] = idx
;
143 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
);
144 emit
->ps30_input_count
++;
145 emit
->internal_color_count
++;
147 reg
= dst( emit
->input_map
[idx
] );
149 if (!emit_decl( emit
, reg
, usage
, index
))
152 semantic
.Name
= TGSI_SEMANTIC_BCOLOR
;
153 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
156 reg
= dst_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
++ );
158 if (!emit_decl( emit
, reg
, usage
, index
))
161 if (!emit_vface_decl( emit
))
166 else if (semantic
.Name
== TGSI_SEMANTIC_FACE
) {
167 if (!emit_vface_decl( emit
))
169 emit
->emit_frontface
= TRUE
;
170 emit
->internal_frontface_idx
= idx
;
175 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
178 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, emit
->ps30_input_count
++ );
179 reg
= dst( emit
->input_map
[idx
] );
181 return emit_decl( emit
, reg
, usage
, index
);
187 /* PS output registers are the same as 2.0
189 static boolean
ps30_output( struct svga_shader_emitter
*emit
,
190 struct tgsi_declaration_semantic semantic
,
193 SVGA3dShaderDestToken reg
;
195 switch (semantic
.Name
) {
196 case TGSI_SEMANTIC_COLOR
:
197 emit
->output_map
[idx
] = dst_register( SVGA3DREG_COLOROUT
,
200 case TGSI_SEMANTIC_POSITION
:
201 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
202 emit
->nr_hw_temp
++ );
203 emit
->temp_pos
= emit
->output_map
[idx
];
204 emit
->true_pos
= dst_register( SVGA3DREG_DEPTHOUT
,
209 reg
= dst_register( SVGA3DREG_COLOROUT
, 0 );
217 /* We still make up the input semantics the same as in 2.0
219 static boolean
vs30_input( struct svga_shader_emitter
*emit
,
220 struct tgsi_declaration_semantic semantic
,
224 SVGA3dShaderInstToken opcode
;
225 unsigned usage
, index
;
227 opcode
= inst_token( SVGA3DOP_DCL
);
231 if (emit
->key
.vkey
.zero_stride_vertex_elements
& (1 << idx
)) {
234 unsigned start_idx
= emit
->info
.file_max
[TGSI_FILE_CONSTANT
] + 1;
235 /* adjust for prescale constants */
236 start_idx
+= emit
->key
.vkey
.need_prescale
? 2 : 0;
237 /* compute the offset from the start of zero stride constants */
238 for (i
= 0; i
< PIPE_MAX_ATTRIBS
&& i
< idx
; ++i
) {
239 if (emit
->key
.vkey
.zero_stride_vertex_elements
& (1<<i
))
242 emit
->input_map
[idx
] = src_register( SVGA3DREG_CONST
,
243 start_idx
+ offset
);
245 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, idx
);
246 dcl
.dst
= dst_register( SVGA3DREG_INPUT
, idx
);
248 assert(dcl
.dst
.reserved0
);
250 svga_generate_vdecl_semantics( idx
, &usage
, &index
);
254 dcl
.values
[0] |= 1<<31;
256 return (emit_instruction(emit
, opcode
) &&
257 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
262 /* VS3.0 outputs have proper declarations and semantic info for
263 * matching against PS inputs.
265 static boolean
vs30_output( struct svga_shader_emitter
*emit
,
266 struct tgsi_declaration_semantic semantic
,
270 SVGA3dShaderInstToken opcode
;
271 unsigned usage
, index
;
273 opcode
= inst_token( SVGA3DOP_DCL
);
277 if (!translate_vs_ps_semantic( semantic
, &usage
, &index
))
280 dcl
.dst
= dst_register( SVGA3DREG_OUTPUT
, idx
);
283 dcl
.values
[0] |= 1<<31;
285 if (semantic
.Name
== TGSI_SEMANTIC_POSITION
) {
287 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
288 emit
->nr_hw_temp
++ );
289 emit
->temp_pos
= emit
->output_map
[idx
];
290 emit
->true_pos
= dcl
.dst
;
292 else if (semantic
.Name
== TGSI_SEMANTIC_PSIZE
) {
293 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
294 emit
->nr_hw_temp
++ );
295 emit
->temp_psiz
= emit
->output_map
[idx
];
297 /* This has the effect of not declaring psiz (below) and not
298 * emitting the final MOV to true_psiz in the postamble.
300 if (!emit
->key
.vkey
.allow_psiz
)
303 emit
->true_psiz
= dcl
.dst
;
306 emit
->output_map
[idx
] = dcl
.dst
;
310 return (emit_instruction(emit
, opcode
) &&
311 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
314 static boolean
ps30_sampler( struct svga_shader_emitter
*emit
,
315 struct tgsi_declaration_semantic semantic
,
319 SVGA3dShaderInstToken opcode
;
321 opcode
= inst_token( SVGA3DOP_DCL
);
325 dcl
.dst
= dst_register( SVGA3DREG_SAMPLER
, idx
);
326 dcl
.type
= svga_tgsi_sampler_type( emit
, idx
);
327 dcl
.values
[0] |= 1<<31;
329 return (emit_instruction(emit
, opcode
) &&
330 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
334 boolean
svga_translate_decl_sm30( struct svga_shader_emitter
*emit
,
335 const struct tgsi_full_declaration
*decl
)
337 unsigned first
= decl
->Range
.First
;
338 unsigned last
= decl
->Range
.Last
;
339 unsigned semantic
= 0;
340 unsigned semantic_idx
= 0;
343 if (decl
->Declaration
.Semantic
) {
344 semantic
= decl
->Semantic
.Name
;
345 semantic_idx
= decl
->Semantic
.Index
;
348 for( idx
= first
; idx
<= last
; idx
++ ) {
351 switch (decl
->Declaration
.File
) {
352 case TGSI_FILE_SAMPLER
:
353 assert (emit
->unit
== PIPE_SHADER_FRAGMENT
);
354 ok
= ps30_sampler( emit
, decl
->Semantic
, idx
);
357 case TGSI_FILE_INPUT
:
358 if (emit
->unit
== PIPE_SHADER_VERTEX
)
359 ok
= vs30_input( emit
, decl
->Semantic
, idx
);
361 ok
= ps30_input( emit
, decl
->Semantic
, idx
);
364 case TGSI_FILE_OUTPUT
:
365 if (emit
->unit
== PIPE_SHADER_VERTEX
)
366 ok
= vs30_output( emit
, decl
->Semantic
, idx
);
368 ok
= ps30_output( emit
, decl
->Semantic
, idx
);
372 /* don't need to declare other vars */