Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / svga / svga_tgsi_decl_sm20.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
33
34 static boolean ps20_input( struct svga_shader_emitter *emit,
35 struct tgsi_declaration_semantic semantic,
36 unsigned idx )
37 {
38 struct src_register reg;
39 SVGA3DOpDclArgs dcl;
40 SVGA3dShaderInstToken opcode;
41
42 opcode = inst_token( SVGA3DOP_DCL );
43 dcl.values[0] = 0;
44 dcl.values[1] = 0;
45
46 switch (semantic.Name) {
47 case TGSI_SEMANTIC_POSITION:
48 /* Special case:
49 */
50 reg = src_register( SVGA3DREG_MISCTYPE,
51 SVGA3DMISCREG_POSITION );
52 break;
53 case TGSI_SEMANTIC_COLOR:
54 reg = src_register( SVGA3DREG_INPUT,
55 semantic.Index );
56 break;
57 case TGSI_SEMANTIC_FOG:
58 assert(semantic.Index == 0);
59 reg = src_register( SVGA3DREG_TEXTURE, 0 );
60 break;
61 case TGSI_SEMANTIC_GENERIC:
62 reg = src_register( SVGA3DREG_TEXTURE,
63 semantic.Index + 1 );
64 break;
65 default:
66 assert(0);
67 return TRUE;
68 }
69
70 emit->input_map[idx] = reg;
71
72 dcl.dst = dst( reg );
73
74 dcl.usage = 0;
75 dcl.index = 0;
76
77 dcl.values[0] |= 1<<31;
78
79 return (emit_instruction(emit, opcode) &&
80 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
81 }
82
83
84 static boolean ps20_output( struct svga_shader_emitter *emit,
85 struct tgsi_declaration_semantic semantic,
86 unsigned idx )
87 {
88 SVGA3dShaderDestToken reg;
89
90 switch (semantic.Name) {
91 case TGSI_SEMANTIC_COLOR:
92 if (semantic.Index < PIPE_MAX_COLOR_BUFS) {
93 unsigned cbuf = semantic.Index;
94
95 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
96 emit->nr_hw_temp++ );
97 emit->temp_col[cbuf] = emit->output_map[idx];
98 emit->true_col[cbuf] = dst_register( SVGA3DREG_COLOROUT,
99 semantic.Index );
100 }
101 else {
102 assert(0);
103 reg = dst_register( SVGA3DREG_COLOROUT, 0 );
104 }
105 break;
106 case TGSI_SEMANTIC_POSITION:
107 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
108 emit->nr_hw_temp++ );
109 emit->temp_pos = emit->output_map[idx];
110 emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT,
111 semantic.Index );
112 break;
113 default:
114 assert(0);
115 reg = dst_register( SVGA3DREG_COLOROUT, 0 );
116 break;
117 }
118
119 return TRUE;
120 }
121
122
123 static boolean vs20_input( struct svga_shader_emitter *emit,
124 struct tgsi_declaration_semantic semantic,
125 unsigned idx )
126 {
127 SVGA3DOpDclArgs dcl;
128 SVGA3dShaderInstToken opcode;
129
130 opcode = inst_token( SVGA3DOP_DCL );
131 dcl.values[0] = 0;
132 dcl.values[1] = 0;
133
134 emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
135 dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
136
137 assert(dcl.dst.reserved0);
138
139 /* Mesa doesn't provide use with VS input semantics (they're
140 * actually pretty meaningless), so we just generate some plausible
141 * ones here. This has to match what we declare in the vdecl code
142 * in svga_pipe_vertex.c.
143 */
144 if (idx == 0) {
145 dcl.usage = SVGA3D_DECLUSAGE_POSITION;
146 dcl.index = 0;
147 }
148 else {
149 dcl.usage = SVGA3D_DECLUSAGE_TEXCOORD;
150 dcl.index = idx - 1;
151 }
152
153 dcl.values[0] |= 1<<31;
154
155 return (emit_instruction(emit, opcode) &&
156 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
157 }
158
159
160 static boolean vs20_output( struct svga_shader_emitter *emit,
161 struct tgsi_declaration_semantic semantic,
162 unsigned idx )
163 {
164 /* Don't emit dcl instruction for vs20 inputs
165 */
166
167 /* Just build the register map table:
168 */
169 switch (semantic.Name) {
170 case TGSI_SEMANTIC_POSITION:
171 assert(semantic.Index == 0);
172 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
173 emit->nr_hw_temp++ );
174 emit->temp_pos = emit->output_map[idx];
175 emit->true_pos = dst_register( SVGA3DREG_RASTOUT,
176 SVGA3DRASTOUT_POSITION);
177 break;
178 case TGSI_SEMANTIC_PSIZE:
179 assert(semantic.Index == 0);
180 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
181 emit->nr_hw_temp++ );
182 emit->temp_psiz = emit->output_map[idx];
183 emit->true_psiz = dst_register( SVGA3DREG_RASTOUT,
184 SVGA3DRASTOUT_PSIZE );
185 break;
186 case TGSI_SEMANTIC_FOG:
187 assert(semantic.Index == 0);
188 emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT, 0 );
189 break;
190 case TGSI_SEMANTIC_COLOR:
191 /* oD0 */
192 emit->output_map[idx] = dst_register( SVGA3DREG_ATTROUT,
193 semantic.Index );
194 break;
195 case TGSI_SEMANTIC_GENERIC:
196 emit->output_map[idx] = dst_register( SVGA3DREG_TEXCRDOUT,
197 semantic.Index + 1 );
198 break;
199 default:
200 assert(0);
201 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, 0 );
202 return FALSE;
203 }
204
205 return TRUE;
206 }
207
208 static boolean ps20_sampler( struct svga_shader_emitter *emit,
209 struct tgsi_declaration_semantic semantic,
210 unsigned idx )
211 {
212 SVGA3DOpDclArgs dcl;
213 SVGA3dShaderInstToken opcode;
214
215 opcode = inst_token( SVGA3DOP_DCL );
216 dcl.values[0] = 0;
217 dcl.values[1] = 0;
218
219 dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
220 dcl.type = svga_tgsi_sampler_type( emit, idx );
221
222 return (emit_instruction(emit, opcode) &&
223 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
224 }
225
226
227 boolean svga_translate_decl_sm20( struct svga_shader_emitter *emit,
228 const struct tgsi_full_declaration *decl )
229 {
230 unsigned first = decl->Range.First;
231 unsigned last = decl->Range.Last;
232 unsigned semantic = 0;
233 unsigned semantic_idx = 0;
234 unsigned idx;
235
236 if (decl->Declaration.Semantic) {
237 semantic = decl->Semantic.Name;
238 semantic_idx = decl->Semantic.Index;
239 }
240
241 for( idx = first; idx <= last; idx++ ) {
242 boolean ok;
243
244 switch (decl->Declaration.File) {
245 case TGSI_FILE_SAMPLER:
246 assert (emit->unit == PIPE_SHADER_FRAGMENT);
247 ok = ps20_sampler( emit, decl->Semantic, idx );
248 break;
249
250 case TGSI_FILE_INPUT:
251 if (emit->unit == PIPE_SHADER_VERTEX)
252 ok = vs20_input( emit, decl->Semantic, idx );
253 else
254 ok = ps20_input( emit, decl->Semantic, idx );
255 break;
256
257 case TGSI_FILE_OUTPUT:
258 if (emit->unit == PIPE_SHADER_VERTEX)
259 ok = vs20_output( emit, decl->Semantic, idx );
260 else
261 ok = ps20_output( emit, decl->Semantic, idx );
262 break;
263
264 default:
265 /* don't need to declare other vars */
266 ok = TRUE;
267 }
268
269 if (!ok)
270 return FALSE;
271 }
272
273 return TRUE;
274 }
275
276
277