Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / svga / svga_tgsi_decl_sm30.c
1 /**********************************************************
2 * Copyright 2008-2009 VMware, Inc. All rights reserved.
3 *
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:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
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
22 * SOFTWARE.
23 *
24 **********************************************************/
25
26
27 #include "pipe/p_shader_tokens.h"
28 #include "tgsi/tgsi_parse.h"
29 #include "util/u_memory.h"
30
31 #include "svga_tgsi_emit.h"
32 #include "svga_context.h"
33
34 static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semantic,
35 unsigned *usage,
36 unsigned *idx )
37 {
38 switch (semantic.Name) {
39 case TGSI_SEMANTIC_POSITION:
40 *idx = semantic.Index;
41 *usage = SVGA3D_DECLUSAGE_POSITION;
42 break;
43 case TGSI_SEMANTIC_COLOR:
44
45 *idx = semantic.Index;
46 *usage = SVGA3D_DECLUSAGE_COLOR;
47 break;
48 case TGSI_SEMANTIC_BCOLOR:
49 *idx = semantic.Index + 2; /* sharing with COLOR */
50 *usage = SVGA3D_DECLUSAGE_COLOR;
51 break;
52 case TGSI_SEMANTIC_FOG:
53 *idx = 0;
54 assert(semantic.Index == 0);
55 *usage = SVGA3D_DECLUSAGE_TEXCOORD;
56 break;
57 case TGSI_SEMANTIC_PSIZE:
58 *idx = semantic.Index;
59 *usage = SVGA3D_DECLUSAGE_PSIZE;
60 break;
61 case TGSI_SEMANTIC_GENERIC:
62 *idx = semantic.Index + 1; /* texcoord[0] is reserved for fog */
63 *usage = SVGA3D_DECLUSAGE_TEXCOORD;
64 break;
65 case TGSI_SEMANTIC_NORMAL:
66 *idx = semantic.Index;
67 *usage = SVGA3D_DECLUSAGE_NORMAL;
68 break;
69 default:
70 assert(0);
71 *usage = SVGA3D_DECLUSAGE_TEXCOORD;
72 *idx = 0;
73 return FALSE;
74 }
75
76 return TRUE;
77 }
78
79
80 static boolean emit_decl( struct svga_shader_emitter *emit,
81 SVGA3dShaderDestToken reg,
82 unsigned usage,
83 unsigned index )
84 {
85 SVGA3DOpDclArgs dcl;
86 SVGA3dShaderInstToken opcode;
87
88 opcode = inst_token( SVGA3DOP_DCL );
89 dcl.values[0] = 0;
90 dcl.values[1] = 0;
91
92 dcl.dst = reg;
93 dcl.usage = usage;
94 dcl.index = index;
95 dcl.values[0] |= 1<<31;
96
97 return (emit_instruction(emit, opcode) &&
98 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
99 }
100
101 static boolean emit_vface_decl( struct svga_shader_emitter *emit )
102 {
103 if (!emit->emitted_vface) {
104 SVGA3dShaderDestToken reg =
105 dst_register( SVGA3DREG_MISCTYPE,
106 SVGA3DMISCREG_FACE );
107
108 if (!emit_decl( emit, reg, 0, 0 ))
109 return FALSE;
110
111 emit->emitted_vface = TRUE;
112 }
113 return TRUE;
114 }
115
116 static boolean ps30_input( struct svga_shader_emitter *emit,
117 struct tgsi_declaration_semantic semantic,
118 unsigned idx )
119 {
120 unsigned usage, index;
121 SVGA3dShaderDestToken reg;
122
123 if (semantic.Name == TGSI_SEMANTIC_POSITION) {
124 emit->input_map[idx] = src_register( SVGA3DREG_MISCTYPE,
125 SVGA3DMISCREG_POSITION );
126
127 emit->input_map[idx].base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X,
128 TGSI_SWIZZLE_Y,
129 TGSI_SWIZZLE_Y,
130 TGSI_SWIZZLE_Y );
131
132 reg = writemask( dst(emit->input_map[idx]),
133 TGSI_WRITEMASK_XY );
134
135 return emit_decl( emit, reg, 0, 0 );
136 }
137 else if (emit->key.fkey.light_twoside &&
138 (semantic.Name == TGSI_SEMANTIC_COLOR)) {
139
140 if (!translate_vs_ps_semantic( semantic, &usage, &index ))
141 return FALSE;
142
143 emit->internal_color_idx[emit->internal_color_count] = idx;
144 emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count );
145 emit->ps30_input_count++;
146 emit->internal_color_count++;
147
148 reg = dst( emit->input_map[idx] );
149
150 if (!emit_decl( emit, reg, usage, index ))
151 return FALSE;
152
153 semantic.Name = TGSI_SEMANTIC_BCOLOR;
154 if (!translate_vs_ps_semantic( semantic, &usage, &index ))
155 return FALSE;
156
157 reg = dst_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
158
159 if (!emit_decl( emit, reg, usage, index ))
160 return FALSE;
161
162 if (!emit_vface_decl( emit ))
163 return FALSE;
164
165 return TRUE;
166 }
167 else if (semantic.Name == TGSI_SEMANTIC_FACE) {
168 if (!emit_vface_decl( emit ))
169 return FALSE;
170 emit->emit_frontface = TRUE;
171 emit->internal_frontface_idx = idx;
172 return TRUE;
173 }
174 else {
175
176 if (!translate_vs_ps_semantic( semantic, &usage, &index ))
177 return FALSE;
178
179 emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
180 reg = dst( emit->input_map[idx] );
181
182 return emit_decl( emit, reg, usage, index );
183 }
184
185 }
186
187
188 /* PS output registers are the same as 2.0
189 */
190 static boolean ps30_output( struct svga_shader_emitter *emit,
191 struct tgsi_declaration_semantic semantic,
192 unsigned idx )
193 {
194 SVGA3dShaderDestToken reg;
195
196 switch (semantic.Name) {
197 case TGSI_SEMANTIC_COLOR:
198 emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,
199 semantic.Index );
200 break;
201 case TGSI_SEMANTIC_POSITION:
202 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
203 emit->nr_hw_temp++ );
204 emit->temp_pos = emit->output_map[idx];
205 emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT,
206 semantic.Index );
207 break;
208 default:
209 assert(0);
210 reg = dst_register( SVGA3DREG_COLOROUT, 0 );
211 break;
212 }
213
214 return TRUE;
215 }
216
217
218 /* We still make up the input semantics the same as in 2.0
219 */
220 static boolean vs30_input( struct svga_shader_emitter *emit,
221 struct tgsi_declaration_semantic semantic,
222 unsigned idx )
223 {
224 SVGA3DOpDclArgs dcl;
225 SVGA3dShaderInstToken opcode;
226 unsigned usage, index;
227
228 opcode = inst_token( SVGA3DOP_DCL );
229 dcl.values[0] = 0;
230 dcl.values[1] = 0;
231
232 if (emit->key.vkey.zero_stride_vertex_elements & (1 << idx)) {
233 unsigned i;
234 unsigned offset = 0;
235 unsigned start_idx = emit->info.file_max[TGSI_FILE_CONSTANT] + 1;
236 /* adjust for prescale constants */
237 start_idx += emit->key.vkey.need_prescale ? 2 : 0;
238 /* compute the offset from the start of zero stride constants */
239 for (i = 0; i < PIPE_MAX_ATTRIBS && i < idx; ++i) {
240 if (emit->key.vkey.zero_stride_vertex_elements & (1<<i))
241 ++offset;
242 }
243 emit->input_map[idx] = src_register( SVGA3DREG_CONST,
244 start_idx + offset );
245 } else {
246 emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
247 dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
248
249 assert(dcl.dst.reserved0);
250
251 svga_generate_vdecl_semantics( idx, &usage, &index );
252
253 dcl.usage = usage;
254 dcl.index = index;
255 dcl.values[0] |= 1<<31;
256
257 return (emit_instruction(emit, opcode) &&
258 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
259 }
260 return TRUE;
261 }
262
263 /* VS3.0 outputs have proper declarations and semantic info for
264 * matching against PS inputs.
265 */
266 static boolean vs30_output( struct svga_shader_emitter *emit,
267 struct tgsi_declaration_semantic semantic,
268 unsigned idx )
269 {
270 SVGA3DOpDclArgs dcl;
271 SVGA3dShaderInstToken opcode;
272 unsigned usage, index;
273
274 opcode = inst_token( SVGA3DOP_DCL );
275 dcl.values[0] = 0;
276 dcl.values[1] = 0;
277
278 if (!translate_vs_ps_semantic( semantic, &usage, &index ))
279 return FALSE;
280
281 dcl.dst = dst_register( SVGA3DREG_OUTPUT, idx );
282 dcl.usage = usage;
283 dcl.index = index;
284 dcl.values[0] |= 1<<31;
285
286 if (semantic.Name == TGSI_SEMANTIC_POSITION) {
287 assert(idx == 0);
288 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
289 emit->nr_hw_temp++ );
290 emit->temp_pos = emit->output_map[idx];
291 emit->true_pos = dcl.dst;
292 }
293 else if (semantic.Name == TGSI_SEMANTIC_PSIZE) {
294 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
295 emit->nr_hw_temp++ );
296 emit->temp_psiz = emit->output_map[idx];
297
298 /* This has the effect of not declaring psiz (below) and not
299 * emitting the final MOV to true_psiz in the postamble.
300 */
301 if (!emit->key.vkey.allow_psiz)
302 return TRUE;
303
304 emit->true_psiz = dcl.dst;
305 }
306 else {
307 emit->output_map[idx] = dcl.dst;
308 }
309
310
311 return (emit_instruction(emit, opcode) &&
312 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
313 }
314
315 static boolean ps30_sampler( struct svga_shader_emitter *emit,
316 struct tgsi_declaration_semantic semantic,
317 unsigned idx )
318 {
319 SVGA3DOpDclArgs dcl;
320 SVGA3dShaderInstToken opcode;
321
322 opcode = inst_token( SVGA3DOP_DCL );
323 dcl.values[0] = 0;
324 dcl.values[1] = 0;
325
326 dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
327 dcl.type = svga_tgsi_sampler_type( emit, idx );
328 dcl.values[0] |= 1<<31;
329
330 return (emit_instruction(emit, opcode) &&
331 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
332 }
333
334
335 boolean svga_translate_decl_sm30( struct svga_shader_emitter *emit,
336 const struct tgsi_full_declaration *decl )
337 {
338 unsigned first = decl->Range.First;
339 unsigned last = decl->Range.Last;
340 unsigned semantic = 0;
341 unsigned semantic_idx = 0;
342 unsigned idx;
343
344 if (decl->Declaration.Semantic) {
345 semantic = decl->Semantic.Name;
346 semantic_idx = decl->Semantic.Index;
347 }
348
349 for( idx = first; idx <= last; idx++ ) {
350 boolean ok;
351
352 switch (decl->Declaration.File) {
353 case TGSI_FILE_SAMPLER:
354 assert (emit->unit == PIPE_SHADER_FRAGMENT);
355 ok = ps30_sampler( emit, decl->Semantic, idx );
356 break;
357
358 case TGSI_FILE_INPUT:
359 if (emit->unit == PIPE_SHADER_VERTEX)
360 ok = vs30_input( emit, decl->Semantic, idx );
361 else
362 ok = ps30_input( emit, decl->Semantic, idx );
363 break;
364
365 case TGSI_FILE_OUTPUT:
366 if (emit->unit == PIPE_SHADER_VERTEX)
367 ok = vs30_output( emit, decl->Semantic, idx );
368 else
369 ok = ps30_output( emit, decl->Semantic, idx );
370 break;
371
372 default:
373 /* don't need to declare other vars */
374 ok = TRUE;
375 }
376
377 if (!ok)
378 return FALSE;
379 }
380
381 return TRUE;
382 }
383
384
385