1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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"
43 union pointer_hack ph
;
46 ph
.pointer
= unaligned
;
47 ph
.uint64
= (ph
.uint64
+ 15) & ~15;
52 tgsi_util_get_src_register_swizzle(
53 const struct tgsi_src_register
*reg
,
73 tgsi_util_get_full_src_register_swizzle(
74 const struct tgsi_full_src_register
*reg
,
77 return tgsi_util_get_src_register_swizzle(
83 tgsi_util_set_src_register_swizzle(
84 struct tgsi_src_register
*reg
,
90 reg
->SwizzleX
= swizzle
;
93 reg
->SwizzleY
= swizzle
;
96 reg
->SwizzleZ
= swizzle
;
99 reg
->SwizzleW
= swizzle
;
107 tgsi_util_get_full_src_register_sign_mode(
108 const struct tgsi_full_src_register
*reg
,
113 if( reg
->Register
.Absolute
) {
114 /* Consider only the post-abs negation. */
116 if( reg
->Register
.Negate
) {
117 sign_mode
= TGSI_UTIL_SIGN_SET
;
120 sign_mode
= TGSI_UTIL_SIGN_CLEAR
;
124 if( reg
->Register
.Negate
) {
125 sign_mode
= TGSI_UTIL_SIGN_TOGGLE
;
128 sign_mode
= TGSI_UTIL_SIGN_KEEP
;
136 tgsi_util_set_full_src_register_sign_mode(
137 struct tgsi_full_src_register
*reg
,
142 case TGSI_UTIL_SIGN_CLEAR
:
143 reg
->Register
.Negate
= 0;
144 reg
->Register
.Absolute
= 1;
147 case TGSI_UTIL_SIGN_SET
:
148 reg
->Register
.Absolute
= 1;
149 reg
->Register
.Negate
= 1;
152 case TGSI_UTIL_SIGN_TOGGLE
:
153 reg
->Register
.Negate
= 1;
154 reg
->Register
.Absolute
= 0;
157 case TGSI_UTIL_SIGN_KEEP
:
158 reg
->Register
.Negate
= 0;
159 reg
->Register
.Absolute
= 0;
168 * Determine which channels of the specificed src register are effectively
169 * used by this instruction.
172 tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction
*inst
,
175 const struct tgsi_full_src_register
*src
= &inst
->Src
[src_idx
];
176 unsigned write_mask
= inst
->Dst
[0].Register
.WriteMask
;
181 switch (inst
->Instruction
.Opcode
) {
182 case TGSI_OPCODE_MOV
:
183 case TGSI_OPCODE_ARL
:
184 case TGSI_OPCODE_ARR
:
185 case TGSI_OPCODE_RCP
:
186 case TGSI_OPCODE_MUL
:
187 case TGSI_OPCODE_DIV
:
188 case TGSI_OPCODE_ADD
:
189 case TGSI_OPCODE_MIN
:
190 case TGSI_OPCODE_MAX
:
191 case TGSI_OPCODE_SLT
:
192 case TGSI_OPCODE_SGE
:
193 case TGSI_OPCODE_MAD
:
194 case TGSI_OPCODE_SUB
:
195 case TGSI_OPCODE_LRP
:
196 case TGSI_OPCODE_CND
:
197 case TGSI_OPCODE_FRC
:
198 case TGSI_OPCODE_CEIL
:
199 case TGSI_OPCODE_CLAMP
:
200 case TGSI_OPCODE_FLR
:
201 case TGSI_OPCODE_ROUND
:
202 case TGSI_OPCODE_POW
:
203 case TGSI_OPCODE_ABS
:
204 case TGSI_OPCODE_COS
:
205 case TGSI_OPCODE_SIN
:
206 case TGSI_OPCODE_DDX
:
207 case TGSI_OPCODE_DDY
:
208 case TGSI_OPCODE_SEQ
:
209 case TGSI_OPCODE_SGT
:
210 case TGSI_OPCODE_SLE
:
211 case TGSI_OPCODE_SNE
:
212 case TGSI_OPCODE_SSG
:
213 case TGSI_OPCODE_CMP
:
214 case TGSI_OPCODE_TRUNC
:
215 case TGSI_OPCODE_NOT
:
216 case TGSI_OPCODE_AND
:
218 case TGSI_OPCODE_XOR
:
219 case TGSI_OPCODE_SAD
:
220 case TGSI_OPCODE_FSEQ
:
221 case TGSI_OPCODE_FSGE
:
222 case TGSI_OPCODE_FSLT
:
223 case TGSI_OPCODE_FSNE
:
224 case TGSI_OPCODE_F2I
:
225 case TGSI_OPCODE_IDIV
:
226 case TGSI_OPCODE_IMAX
:
227 case TGSI_OPCODE_IMIN
:
228 case TGSI_OPCODE_INEG
:
229 case TGSI_OPCODE_ISGE
:
230 case TGSI_OPCODE_ISHR
:
231 case TGSI_OPCODE_ISLT
:
232 case TGSI_OPCODE_F2U
:
233 case TGSI_OPCODE_U2F
:
234 case TGSI_OPCODE_UADD
:
235 case TGSI_OPCODE_UDIV
:
236 case TGSI_OPCODE_UMAD
:
237 case TGSI_OPCODE_UMAX
:
238 case TGSI_OPCODE_UMIN
:
239 case TGSI_OPCODE_UMOD
:
240 case TGSI_OPCODE_UMUL
:
241 case TGSI_OPCODE_USEQ
:
242 case TGSI_OPCODE_USGE
:
243 case TGSI_OPCODE_USHR
:
244 case TGSI_OPCODE_USLT
:
245 case TGSI_OPCODE_USNE
:
246 case TGSI_OPCODE_IMUL_HI
:
247 case TGSI_OPCODE_UMUL_HI
:
248 /* Channel-wise operations */
249 read_mask
= write_mask
;
252 case TGSI_OPCODE_EX2
:
253 case TGSI_OPCODE_LG2
:
254 case TGSI_OPCODE_RCC
:
255 read_mask
= TGSI_WRITEMASK_X
;
258 case TGSI_OPCODE_SCS
:
259 read_mask
= write_mask
& TGSI_WRITEMASK_XY
? TGSI_WRITEMASK_X
: 0;
262 case TGSI_OPCODE_EXP
:
263 case TGSI_OPCODE_LOG
:
264 read_mask
= write_mask
& TGSI_WRITEMASK_XYZ
? TGSI_WRITEMASK_X
: 0;
267 case TGSI_OPCODE_DP2A
:
268 read_mask
= src_idx
== 2 ? TGSI_WRITEMASK_X
: TGSI_WRITEMASK_XY
;
271 case TGSI_OPCODE_DP2
:
272 read_mask
= TGSI_WRITEMASK_XY
;
275 case TGSI_OPCODE_DP3
:
276 read_mask
= TGSI_WRITEMASK_XYZ
;
279 case TGSI_OPCODE_DP4
:
280 read_mask
= TGSI_WRITEMASK_XYZW
;
283 case TGSI_OPCODE_DPH
:
284 read_mask
= src_idx
== 0 ? TGSI_WRITEMASK_XYZ
: TGSI_WRITEMASK_XYZW
;
287 case TGSI_OPCODE_TEX
:
288 case TGSI_OPCODE_TXD
:
289 case TGSI_OPCODE_TXB
:
290 case TGSI_OPCODE_TXL
:
291 case TGSI_OPCODE_TXP
:
293 /* Note that the SHADOW variants use the Z component too */
294 switch (inst
->Texture
.Texture
) {
295 case TGSI_TEXTURE_1D
:
296 read_mask
= TGSI_WRITEMASK_X
;
298 case TGSI_TEXTURE_SHADOW1D
:
299 read_mask
= TGSI_WRITEMASK_XZ
;
301 case TGSI_TEXTURE_1D_ARRAY
:
302 case TGSI_TEXTURE_2D
:
303 case TGSI_TEXTURE_RECT
:
304 read_mask
= TGSI_WRITEMASK_XY
;
306 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
307 case TGSI_TEXTURE_SHADOW2D
:
308 case TGSI_TEXTURE_SHADOWRECT
:
309 case TGSI_TEXTURE_2D_ARRAY
:
310 case TGSI_TEXTURE_3D
:
311 case TGSI_TEXTURE_CUBE
:
312 case TGSI_TEXTURE_2D_MSAA
:
313 read_mask
= TGSI_WRITEMASK_XYZ
;
315 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
316 case TGSI_TEXTURE_CUBE_ARRAY
:
317 case TGSI_TEXTURE_SHADOWCUBE
:
318 case TGSI_TEXTURE_2D_ARRAY_MSAA
:
319 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
320 read_mask
= TGSI_WRITEMASK_XYZW
;
327 if (inst
->Instruction
.Opcode
!= TGSI_OPCODE_TEX
) {
328 read_mask
|= TGSI_WRITEMASK_W
;
331 /* A safe approximation */
332 read_mask
= TGSI_WRITEMASK_XYZW
;
337 /* Assume all channels are read */
338 read_mask
= TGSI_WRITEMASK_XYZW
;
343 for (chan
= 0; chan
< 4; ++chan
) {
344 if (read_mask
& (1 << chan
)) {
345 usage_mask
|= 1 << tgsi_util_get_full_src_register_swizzle(src
, chan
);
353 * Convert a tgsi_ind_register into a tgsi_src_register
355 struct tgsi_src_register
356 tgsi_util_get_src_from_ind(const struct tgsi_ind_register
*reg
)
358 struct tgsi_src_register src
= { 0 };
360 src
.File
= reg
->File
;
361 src
.Index
= reg
->Index
;
362 src
.SwizzleX
= reg
->Swizzle
;
363 src
.SwizzleY
= reg
->Swizzle
;
364 src
.SwizzleZ
= reg
->Swizzle
;
365 src
.SwizzleW
= reg
->Swizzle
;
371 * Return the dimension of the texture coordinates (layer included for array
372 * textures), as well as the location of the shadow reference value or the
376 tgsi_util_get_texture_coord_dim(int tgsi_tex
, int *shadow_or_sample
)
381 * Depending on the texture target, (src0.xyzw, src1.x) is interpreted
384 * (s, X, X, X, X), for BUFFER
385 * (s, X, X, X, X), for 1D
386 * (s, t, X, X, X), for 2D, RECT
387 * (s, t, r, X, X), for 3D, CUBE
389 * (s, layer, X, X, X), for 1D_ARRAY
390 * (s, t, layer, X, X), for 2D_ARRAY
391 * (s, t, r, layer, X), for CUBE_ARRAY
393 * (s, X, shadow, X, X), for SHADOW1D
394 * (s, t, shadow, X, X), for SHADOW2D, SHADOWRECT
395 * (s, t, r, shadow, X), for SHADOWCUBE
397 * (s, layer, shadow, X, X), for SHADOW1D_ARRAY
398 * (s, t, layer, shadow, X), for SHADOW2D_ARRAY
399 * (s, t, r, layer, shadow), for SHADOWCUBE_ARRAY
401 * (s, t, sample, X, X), for 2D_MSAA
402 * (s, t, layer, sample, X), for 2D_ARRAY_MSAA
405 case TGSI_TEXTURE_BUFFER
:
406 case TGSI_TEXTURE_1D
:
407 case TGSI_TEXTURE_SHADOW1D
:
410 case TGSI_TEXTURE_2D
:
411 case TGSI_TEXTURE_RECT
:
412 case TGSI_TEXTURE_1D_ARRAY
:
413 case TGSI_TEXTURE_SHADOW2D
:
414 case TGSI_TEXTURE_SHADOWRECT
:
415 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
416 case TGSI_TEXTURE_2D_MSAA
:
419 case TGSI_TEXTURE_3D
:
420 case TGSI_TEXTURE_CUBE
:
421 case TGSI_TEXTURE_2D_ARRAY
:
422 case TGSI_TEXTURE_SHADOWCUBE
:
423 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
424 case TGSI_TEXTURE_2D_ARRAY_MSAA
:
427 case TGSI_TEXTURE_CUBE_ARRAY
:
428 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
432 assert(!"unknown texture target");
437 if (shadow_or_sample
) {
439 case TGSI_TEXTURE_SHADOW1D
:
441 *shadow_or_sample
= 2;
443 case TGSI_TEXTURE_SHADOW2D
:
444 case TGSI_TEXTURE_SHADOWRECT
:
445 case TGSI_TEXTURE_SHADOWCUBE
:
446 case TGSI_TEXTURE_SHADOW1D_ARRAY
:
447 case TGSI_TEXTURE_SHADOW2D_ARRAY
:
448 case TGSI_TEXTURE_SHADOWCUBE_ARRAY
:
449 *shadow_or_sample
= dim
;
451 case TGSI_TEXTURE_2D_MSAA
:
452 case TGSI_TEXTURE_2D_ARRAY_MSAA
:
453 *shadow_or_sample
= 3;
456 /* no shadow nor sample */
457 *shadow_or_sample
= -1;