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