Tizen 2.0 Release
[profile/ivi/osmesa.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