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"
32 #include "svga_context.h"
37 static boolean
ps20_input( struct svga_shader_emitter
*emit
,
38 struct tgsi_declaration_semantic semantic
,
41 struct src_register reg
;
43 SVGA3dShaderInstToken opcode
;
45 opcode
= inst_token( SVGA3DOP_DCL
);
49 switch (semantic
.SemanticName
) {
50 case TGSI_SEMANTIC_POSITION
:
53 reg
= src_register( SVGA3DREG_MISCTYPE
,
54 SVGA3DMISCREG_POSITION
);
56 case TGSI_SEMANTIC_COLOR
:
57 reg
= src_register( SVGA3DREG_INPUT
,
58 semantic
.SemanticIndex
);
60 case TGSI_SEMANTIC_FOG
:
61 assert(semantic
.SemanticIndex
== 0);
62 reg
= src_register( SVGA3DREG_TEXTURE
, 0 );
64 case TGSI_SEMANTIC_GENERIC
:
65 reg
= src_register( SVGA3DREG_TEXTURE
,
66 semantic
.SemanticIndex
+ 1 );
73 emit
->input_map
[idx
] = reg
;
80 dcl
.values
[0] |= 1<<31;
82 return (emit_instruction(emit
, opcode
) &&
83 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
87 static boolean
ps20_output( struct svga_shader_emitter
*emit
,
88 struct tgsi_declaration_semantic semantic
,
91 SVGA3dShaderDestToken reg
;
93 switch (semantic
.SemanticName
) {
94 case TGSI_SEMANTIC_COLOR
:
95 if (semantic
.SemanticIndex
< PIPE_MAX_COLOR_BUFS
) {
96 unsigned cbuf
= semantic
.SemanticIndex
;
98 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
100 emit
->temp_col
[cbuf
] = emit
->output_map
[idx
];
101 emit
->true_col
[cbuf
] = dst_register( SVGA3DREG_COLOROUT
,
102 semantic
.SemanticIndex
);
106 reg
= dst_register( SVGA3DREG_COLOROUT
, 0 );
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
.SemanticIndex
);
118 reg
= dst_register( SVGA3DREG_COLOROUT
, 0 );
126 static boolean
vs20_input( struct svga_shader_emitter
*emit
,
127 struct tgsi_declaration_semantic semantic
,
131 SVGA3dShaderInstToken opcode
;
133 opcode
= inst_token( SVGA3DOP_DCL
);
137 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, idx
);
138 dcl
.dst
= dst_register( SVGA3DREG_INPUT
, idx
);
140 assert(dcl
.dst
.reserved0
);
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.
148 dcl
.usage
= SVGA3D_DECLUSAGE_POSITION
;
152 dcl
.usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
156 dcl
.values
[0] |= 1<<31;
158 return (emit_instruction(emit
, opcode
) &&
159 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
163 static boolean
vs20_output( struct svga_shader_emitter
*emit
,
164 struct tgsi_declaration_semantic semantic
,
167 /* Don't emit dcl instruction for vs20 inputs
170 /* Just build the register map table:
172 switch (semantic
.SemanticName
) {
173 case TGSI_SEMANTIC_POSITION
:
174 assert(semantic
.SemanticIndex
== 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
);
181 case TGSI_SEMANTIC_PSIZE
:
182 assert(semantic
.SemanticIndex
== 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
);
189 case TGSI_SEMANTIC_FOG
:
190 assert(semantic
.SemanticIndex
== 0);
191 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEXCRDOUT
, 0 );
193 case TGSI_SEMANTIC_COLOR
:
195 emit
->output_map
[idx
] = dst_register( SVGA3DREG_ATTROUT
,
196 semantic
.SemanticIndex
);
198 case TGSI_SEMANTIC_GENERIC
:
199 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEXCRDOUT
,
200 semantic
.SemanticIndex
+ 1 );
204 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
, 0 );
211 static boolean
ps20_sampler( struct svga_shader_emitter
*emit
,
212 struct tgsi_declaration_semantic semantic
,
216 SVGA3dShaderInstToken opcode
;
218 opcode
= inst_token( SVGA3DOP_DCL
);
222 dcl
.dst
= dst_register( SVGA3DREG_SAMPLER
, idx
);
223 dcl
.type
= svga_tgsi_sampler_type( emit
, idx
);
225 return (emit_instruction(emit
, opcode
) &&
226 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
230 boolean
svga_translate_decl_sm20( struct svga_shader_emitter
*emit
,
231 const struct tgsi_full_declaration
*decl
)
233 unsigned first
= decl
->DeclarationRange
.First
;
234 unsigned last
= decl
->DeclarationRange
.Last
;
235 unsigned semantic
= 0;
236 unsigned semantic_idx
= 0;
239 if (decl
->Declaration
.Semantic
) {
240 semantic
= decl
->Semantic
.SemanticName
;
241 semantic_idx
= decl
->Semantic
.SemanticIndex
;
244 for( idx
= first
; idx
<= last
; idx
++ ) {
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
);
253 case TGSI_FILE_INPUT
:
254 if (emit
->unit
== PIPE_SHADER_VERTEX
)
255 ok
= vs20_input( emit
, decl
->Semantic
, idx
);
257 ok
= ps20_input( emit
, decl
->Semantic
, idx
);
260 case TGSI_FILE_OUTPUT
:
261 if (emit
->unit
== PIPE_SHADER_VERTEX
)
262 ok
= vs20_output( emit
, decl
->Semantic
, idx
);
264 ok
= ps20_output( emit
, decl
->Semantic
, idx
);
268 /* don't need to declare other vars */