1 /**************************************************************************
3 * Copyright 2007 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "util/u_debug.h"
29 #include "pipe/p_shader_tokens.h"
30 #include "tgsi_parse.h"
31 #include "tgsi_util.h"
32 #include "tgsi_exec.h"
44 union pointer_hack ph
;
47 ph
.pointer
= unaligned
;
48 ph
.uint64
= (ph
.uint64
+ 15) & ~15;
53 tgsi_util_get_src_register_swizzle(
54 const struct tgsi_src_register
*reg
,
74 tgsi_util_get_full_src_register_swizzle(
75 const struct tgsi_full_src_register
*reg
,
78 return tgsi_util_get_src_register_swizzle(
84 tgsi_util_set_src_register_swizzle(
85 struct tgsi_src_register
*reg
,
91 reg
->SwizzleX
= swizzle
;
94 reg
->SwizzleY
= swizzle
;
97 reg
->SwizzleZ
= swizzle
;
100 reg
->SwizzleW
= swizzle
;
108 tgsi_util_get_full_src_register_sign_mode(
109 const struct tgsi_full_src_register
*reg
,
114 if( reg
->Register
.Absolute
) {
115 /* Consider only the post-abs negation. */
117 if( reg
->Register
.Negate
) {
118 sign_mode
= TGSI_UTIL_SIGN_SET
;
121 sign_mode
= TGSI_UTIL_SIGN_CLEAR
;
125 if( reg
->Register
.Negate
) {
126 sign_mode
= TGSI_UTIL_SIGN_TOGGLE
;
129 sign_mode
= TGSI_UTIL_SIGN_KEEP
;
137 tgsi_util_set_full_src_register_sign_mode(
138 struct tgsi_full_src_register
*reg
,
143 case TGSI_UTIL_SIGN_CLEAR
:
144 reg
->Register
.Negate
= 0;
145 reg
->Register
.Absolute
= 1;
148 case TGSI_UTIL_SIGN_SET
:
149 reg
->Register
.Absolute
= 1;
150 reg
->Register
.Negate
= 1;
153 case TGSI_UTIL_SIGN_TOGGLE
:
154 reg
->Register
.Negate
= 1;
155 reg
->Register
.Absolute
= 0;
158 case TGSI_UTIL_SIGN_KEEP
:
159 reg
->Register
.Negate
= 0;
160 reg
->Register
.Absolute
= 0;
169 * Determine which channels of the specificed src register are effectively
170 * used by this instruction.
173 tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction
*inst
,
176 const struct tgsi_full_src_register
*src
= &inst
->Src
[src_idx
];
177 unsigned write_mask
= inst
->Dst
[0].Register
.WriteMask
;
182 switch (inst
->Instruction
.Opcode
) {
183 case TGSI_OPCODE_MOV
:
184 case TGSI_OPCODE_ARL
:
185 case TGSI_OPCODE_ARR
:
186 case TGSI_OPCODE_RCP
:
187 case TGSI_OPCODE_MUL
:
188 case TGSI_OPCODE_DIV
:
189 case TGSI_OPCODE_ADD
:
190 case TGSI_OPCODE_MIN
:
191 case TGSI_OPCODE_MAX
:
192 case TGSI_OPCODE_SLT
:
193 case TGSI_OPCODE_SGE
:
194 case TGSI_OPCODE_MAD
:
195 case TGSI_OPCODE_LRP
:
196 case TGSI_OPCODE_FMA
:
197 case TGSI_OPCODE_FRC
:
198 case TGSI_OPCODE_CEIL
:
199 case TGSI_OPCODE_FLR
:
200 case TGSI_OPCODE_ROUND
:
201 case TGSI_OPCODE_POW
:
202 case TGSI_OPCODE_COS
:
203 case TGSI_OPCODE_SIN
:
204 case TGSI_OPCODE_DDX
:
205 case TGSI_OPCODE_DDY
:
206 case TGSI_OPCODE_SEQ
:
207 case TGSI_OPCODE_SGT
:
208 case TGSI_OPCODE_SLE
:
209 case TGSI_OPCODE_SNE
:
210 case TGSI_OPCODE_SSG
:
211 case TGSI_OPCODE_CMP
:
212 case TGSI_OPCODE_TRUNC
:
213 case TGSI_OPCODE_NOT
:
214 case TGSI_OPCODE_AND
:
216 case TGSI_OPCODE_XOR
:
217 case TGSI_OPCODE_FSEQ
:
218 case TGSI_OPCODE_FSGE
:
219 case TGSI_OPCODE_FSLT
:
220 case TGSI_OPCODE_FSNE
:
221 case TGSI_OPCODE_F2I
:
222 case TGSI_OPCODE_IDIV
:
223 case TGSI_OPCODE_IMAX
:
224 case TGSI_OPCODE_IMIN
:
225 case TGSI_OPCODE_INEG
:
226 case TGSI_OPCODE_ISGE
:
227 case TGSI_OPCODE_ISHR
:
228 case TGSI_OPCODE_ISLT
:
229 case TGSI_OPCODE_F2U
:
230 case TGSI_OPCODE_U2F
:
231 case TGSI_OPCODE_UADD
:
232 case TGSI_OPCODE_UDIV
:
233 case TGSI_OPCODE_UMAD
:
234 case TGSI_OPCODE_UMAX
:
235 case TGSI_OPCODE_UMIN
:
236 case TGSI_OPCODE_UMOD
:
237 case TGSI_OPCODE_UMUL
:
238 case TGSI_OPCODE_USEQ
:
239 case TGSI_OPCODE_USGE
:
240 case TGSI_OPCODE_USHR
:
241 case TGSI_OPCODE_USLT
:
242 case TGSI_OPCODE_USNE
:
243 case TGSI_OPCODE_IMUL_HI
:
244 case TGSI_OPCODE_UMUL_HI
:
245 case TGSI_OPCODE_DDX_FINE
:
246 case TGSI_OPCODE_DDY_FINE
:
247 /* Channel-wise operations */
248 read_mask
= write_mask
;
251 case TGSI_OPCODE_EX2
:
252 case TGSI_OPCODE_LG2
:
253 read_mask
= TGSI_WRITEMASK_X
;
256 case TGSI_OPCODE_SCS
:
257 read_mask
= write_mask
& TGSI_WRITEMASK_XY
? TGSI_WRITEMASK_X
: 0;
260 case TGSI_OPCODE_EXP
:
261 case TGSI_OPCODE_LOG
:
262 read_mask
= write_mask
& TGSI_WRITEMASK_XYZ
? TGSI_WRITEMASK_X
: 0;
265 case TGSI_OPCODE_DP2
:
266 read_mask
= TGSI_WRITEMASK_XY
;
269 case TGSI_OPCODE_DP3
:
270 read_mask
= TGSI_WRITEMASK_XYZ
;
273 case TGSI_OPCODE_DP4
:
274 read_mask
= TGSI_WRITEMASK_XYZW
;
277 case TGSI_OPCODE_TEX
:
278 case TGSI_OPCODE_TXD
:
279 case TGSI_OPCODE_TXB
:
280 case TGSI_OPCODE_TXL
:
281 case TGSI_OPCODE_TXP
:
283 /* Note that the SHADOW variants use the Z component too */
284 switch (inst
->Texture
.Texture
) {
285 case TGSI_TEXTURE_1D
:
286 read_mask
= TGSI_WRITEMASK_X
;
288 case TGSI_TEXTURE_SHADOW1D
:
289 read_mask
= TGSI_WRITEMASK_XZ
;
291 case TGSI_TEXTURE_1D_ARRAY
:
292 case TGSI_TEXTURE_2D
:
293 case TGSI_TEXTURE_RECT
:
294 read_mask
= TGSI_WRITEMASK_XY
;
296 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
297 case TGSI_TEXTURE_SHADOW2D
:
298 case TGSI_TEXTURE_SHADOWRECT
:
299 case TGSI_TEXTURE_2D_ARRAY
:
300 case TGSI_TEXTURE_3D
:
301 case TGSI_TEXTURE_CUBE
:
302 case TGSI_TEXTURE_2D_MSAA
:
303 read_mask
= TGSI_WRITEMASK_XYZ
;
305 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
306 case TGSI_TEXTURE_CUBE_ARRAY
:
307 case TGSI_TEXTURE_SHADOWCUBE
:
308 case TGSI_TEXTURE_2D_ARRAY_MSAA
:
309 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
310 read_mask
= TGSI_WRITEMASK_XYZW
;
317 if (inst
->Instruction
.Opcode
!= TGSI_OPCODE_TEX
) {
318 read_mask
|= TGSI_WRITEMASK_W
;
321 /* A safe approximation */
322 read_mask
= TGSI_WRITEMASK_XYZW
;
327 /* Assume all channels are read */
328 read_mask
= TGSI_WRITEMASK_XYZW
;
333 for (chan
= 0; chan
< 4; ++chan
) {
334 if (read_mask
& (1 << chan
)) {
335 usage_mask
|= 1 << tgsi_util_get_full_src_register_swizzle(src
, chan
);
343 * Convert a tgsi_ind_register into a tgsi_src_register
345 struct tgsi_src_register
346 tgsi_util_get_src_from_ind(const struct tgsi_ind_register
*reg
)
348 struct tgsi_src_register src
= { 0 };
350 src
.File
= reg
->File
;
351 src
.Index
= reg
->Index
;
352 src
.SwizzleX
= reg
->Swizzle
;
353 src
.SwizzleY
= reg
->Swizzle
;
354 src
.SwizzleZ
= reg
->Swizzle
;
355 src
.SwizzleW
= reg
->Swizzle
;
361 * Return the dimension of the texture coordinates (layer included for array
362 * textures), as well as the location of the shadow reference value or the
366 tgsi_util_get_texture_coord_dim(unsigned tgsi_tex
)
369 * Depending on the texture target, (src0.xyzw, src1.x) is interpreted
372 * (s, X, X, X, X), for BUFFER
373 * (s, X, X, X, X), for 1D
374 * (s, t, X, X, X), for 2D, RECT
375 * (s, t, r, X, X), for 3D, CUBE
377 * (s, layer, X, X, X), for 1D_ARRAY
378 * (s, t, layer, X, X), for 2D_ARRAY
379 * (s, t, r, layer, X), for CUBE_ARRAY
381 * (s, X, shadow, X, X), for SHADOW1D
382 * (s, t, shadow, X, X), for SHADOW2D, SHADOWRECT
383 * (s, t, r, shadow, X), for SHADOWCUBE
385 * (s, layer, shadow, X, X), for SHADOW1D_ARRAY
386 * (s, t, layer, shadow, X), for SHADOW2D_ARRAY
387 * (s, t, r, layer, shadow), for SHADOWCUBE_ARRAY
389 * (s, t, sample, X, X), for 2D_MSAA
390 * (s, t, layer, sample, X), for 2D_ARRAY_MSAA
393 case TGSI_TEXTURE_BUFFER
:
394 case TGSI_TEXTURE_1D
:
395 case TGSI_TEXTURE_SHADOW1D
:
397 case TGSI_TEXTURE_2D
:
398 case TGSI_TEXTURE_RECT
:
399 case TGSI_TEXTURE_1D_ARRAY
:
400 case TGSI_TEXTURE_SHADOW2D
:
401 case TGSI_TEXTURE_SHADOWRECT
:
402 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
403 case TGSI_TEXTURE_2D_MSAA
:
405 case TGSI_TEXTURE_3D
:
406 case TGSI_TEXTURE_CUBE
:
407 case TGSI_TEXTURE_2D_ARRAY
:
408 case TGSI_TEXTURE_SHADOWCUBE
:
409 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
410 case TGSI_TEXTURE_2D_ARRAY_MSAA
:
412 case TGSI_TEXTURE_CUBE_ARRAY
:
413 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
416 assert(!"unknown texture target");
423 * Given a TGSI_TEXTURE_x target, return the src register index for the
424 * shadow reference coordinate.
427 tgsi_util_get_shadow_ref_src_index(unsigned tgsi_tex
)
430 case TGSI_TEXTURE_SHADOW1D
:
431 case TGSI_TEXTURE_SHADOW2D
:
432 case TGSI_TEXTURE_SHADOWRECT
:
433 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
435 case TGSI_TEXTURE_SHADOWCUBE
:
436 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
437 case TGSI_TEXTURE_2D_MSAA
:
438 case TGSI_TEXTURE_2D_ARRAY_MSAA
:
440 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
443 /* no shadow nor sample */
450 tgsi_is_shadow_target(unsigned target
)
453 case TGSI_TEXTURE_SHADOW1D
:
454 case TGSI_TEXTURE_SHADOW2D
:
455 case TGSI_TEXTURE_SHADOWRECT
:
456 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
457 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
458 case TGSI_TEXTURE_SHADOWCUBE
:
459 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
: