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"
34 static boolean
ps20_input( struct svga_shader_emitter
*emit
,
35 struct tgsi_declaration_semantic semantic
,
38 struct src_register reg
;
40 SVGA3dShaderInstToken opcode
;
42 opcode
= inst_token( SVGA3DOP_DCL
);
46 switch (semantic
.Name
) {
47 case TGSI_SEMANTIC_POSITION
:
50 reg
= src_register( SVGA3DREG_MISCTYPE
,
51 SVGA3DMISCREG_POSITION
);
53 case TGSI_SEMANTIC_COLOR
:
54 reg
= src_register( SVGA3DREG_INPUT
,
57 case TGSI_SEMANTIC_FOG
:
58 assert(semantic
.Index
== 0);
59 reg
= src_register( SVGA3DREG_TEXTURE
, 0 );
61 case TGSI_SEMANTIC_GENERIC
:
62 reg
= src_register( SVGA3DREG_TEXTURE
,
70 emit
->input_map
[idx
] = reg
;
77 dcl
.values
[0] |= 1<<31;
79 return (emit_instruction(emit
, opcode
) &&
80 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
84 static boolean
ps20_output( struct svga_shader_emitter
*emit
,
85 struct tgsi_declaration_semantic semantic
,
88 SVGA3dShaderDestToken reg
;
90 switch (semantic
.Name
) {
91 case TGSI_SEMANTIC_COLOR
:
92 if (semantic
.Index
< PIPE_MAX_COLOR_BUFS
) {
93 unsigned cbuf
= semantic
.Index
;
95 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
,
97 emit
->temp_col
[cbuf
] = emit
->output_map
[idx
];
98 emit
->true_col
[cbuf
] = dst_register( SVGA3DREG_COLOROUT
,
103 reg
= dst_register( SVGA3DREG_COLOROUT
, 0 );
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
,
115 reg
= dst_register( SVGA3DREG_COLOROUT
, 0 );
123 static boolean
vs20_input( struct svga_shader_emitter
*emit
,
124 struct tgsi_declaration_semantic semantic
,
128 SVGA3dShaderInstToken opcode
;
130 opcode
= inst_token( SVGA3DOP_DCL
);
134 emit
->input_map
[idx
] = src_register( SVGA3DREG_INPUT
, idx
);
135 dcl
.dst
= dst_register( SVGA3DREG_INPUT
, idx
);
137 assert(dcl
.dst
.reserved0
);
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.
145 dcl
.usage
= SVGA3D_DECLUSAGE_POSITION
;
149 dcl
.usage
= SVGA3D_DECLUSAGE_TEXCOORD
;
153 dcl
.values
[0] |= 1<<31;
155 return (emit_instruction(emit
, opcode
) &&
156 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
160 static boolean
vs20_output( struct svga_shader_emitter
*emit
,
161 struct tgsi_declaration_semantic semantic
,
164 /* Don't emit dcl instruction for vs20 inputs
167 /* Just build the register map table:
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
);
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
);
186 case TGSI_SEMANTIC_FOG
:
187 assert(semantic
.Index
== 0);
188 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEXCRDOUT
, 0 );
190 case TGSI_SEMANTIC_COLOR
:
192 emit
->output_map
[idx
] = dst_register( SVGA3DREG_ATTROUT
,
195 case TGSI_SEMANTIC_GENERIC
:
196 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEXCRDOUT
,
197 semantic
.Index
+ 1 );
201 emit
->output_map
[idx
] = dst_register( SVGA3DREG_TEMP
, 0 );
208 static boolean
ps20_sampler( struct svga_shader_emitter
*emit
,
209 struct tgsi_declaration_semantic semantic
,
213 SVGA3dShaderInstToken opcode
;
215 opcode
= inst_token( SVGA3DOP_DCL
);
219 dcl
.dst
= dst_register( SVGA3DREG_SAMPLER
, idx
);
220 dcl
.type
= svga_tgsi_sampler_type( emit
, idx
);
222 return (emit_instruction(emit
, opcode
) &&
223 svga_shader_emit_dwords( emit
, dcl
.values
, Elements(dcl
.values
)));
227 boolean
svga_translate_decl_sm20( struct svga_shader_emitter
*emit
,
228 const struct tgsi_full_declaration
*decl
)
230 unsigned first
= decl
->Range
.First
;
231 unsigned last
= decl
->Range
.Last
;
232 unsigned semantic
= 0;
233 unsigned semantic_idx
= 0;
236 if (decl
->Declaration
.Semantic
) {
237 semantic
= decl
->Semantic
.Name
;
238 semantic_idx
= decl
->Semantic
.Index
;
241 for( idx
= first
; idx
<= last
; idx
++ ) {
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
);
250 case TGSI_FILE_INPUT
:
251 if (emit
->unit
== PIPE_SHADER_VERTEX
)
252 ok
= vs20_input( emit
, decl
->Semantic
, idx
);
254 ok
= ps20_input( emit
, decl
->Semantic
, idx
);
257 case TGSI_FILE_OUTPUT
:
258 if (emit
->unit
== PIPE_SHADER_VERTEX
)
259 ok
= vs20_output( emit
, decl
->Semantic
, idx
);
261 ok
= ps20_output( emit
, decl
->Semantic
, idx
);
265 /* don't need to declare other vars */