1848b8605Smrg/**************************************************************************
2848b8605Smrg *
3848b8605Smrg * Copyright 2007 VMware, Inc.
4848b8605Smrg * All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28848b8605Smrg#include "util/u_debug.h"
29848b8605Smrg#include "pipe/p_shader_tokens.h"
30b8e80941Smrg#include "tgsi_info.h"
31848b8605Smrg#include "tgsi_parse.h"
32848b8605Smrg#include "tgsi_util.h"
33b8e80941Smrg#include "tgsi_exec.h"
34b8e80941Smrg#include "util/bitscan.h"
35848b8605Smrg
36848b8605Smrgunion pointer_hack
37848b8605Smrg{
38848b8605Smrg   void *pointer;
39848b8605Smrg   uint64_t uint64;
40848b8605Smrg};
41848b8605Smrg
42848b8605Smrgvoid *
43b8e80941Smrgtgsi_align_128bit(void *unaligned)
44848b8605Smrg{
45848b8605Smrg   union pointer_hack ph;
46848b8605Smrg
47848b8605Smrg   ph.uint64 = 0;
48848b8605Smrg   ph.pointer = unaligned;
49848b8605Smrg   ph.uint64 = (ph.uint64 + 15) & ~15;
50848b8605Smrg   return ph.pointer;
51848b8605Smrg}
52848b8605Smrg
53848b8605Smrgunsigned
54b8e80941Smrgtgsi_util_get_src_register_swizzle(const struct tgsi_src_register *reg,
55b8e80941Smrg                                   unsigned component)
56848b8605Smrg{
57b8e80941Smrg   switch (component) {
58b8e80941Smrg   case TGSI_CHAN_X:
59848b8605Smrg      return reg->SwizzleX;
60b8e80941Smrg   case TGSI_CHAN_Y:
61848b8605Smrg      return reg->SwizzleY;
62b8e80941Smrg   case TGSI_CHAN_Z:
63848b8605Smrg      return reg->SwizzleZ;
64b8e80941Smrg   case TGSI_CHAN_W:
65848b8605Smrg      return reg->SwizzleW;
66848b8605Smrg   default:
67b8e80941Smrg      assert(0);
68848b8605Smrg   }
69848b8605Smrg   return 0;
70848b8605Smrg}
71848b8605Smrg
72848b8605Smrg
73848b8605Smrgunsigned
74848b8605Smrgtgsi_util_get_full_src_register_swizzle(
75b8e80941Smrg   const struct tgsi_full_src_register *reg,
76b8e80941Smrg   unsigned component)
77848b8605Smrg{
78b8e80941Smrg   return tgsi_util_get_src_register_swizzle(&reg->Register, component);
79848b8605Smrg}
80848b8605Smrg
81b8e80941Smrg
82848b8605Smrgvoid
83b8e80941Smrgtgsi_util_set_src_register_swizzle(struct tgsi_src_register *reg,
84b8e80941Smrg                                   unsigned swizzle,
85b8e80941Smrg                                   unsigned component)
86848b8605Smrg{
87b8e80941Smrg   switch (component) {
88848b8605Smrg   case 0:
89848b8605Smrg      reg->SwizzleX = swizzle;
90848b8605Smrg      break;
91848b8605Smrg   case 1:
92848b8605Smrg      reg->SwizzleY = swizzle;
93848b8605Smrg      break;
94848b8605Smrg   case 2:
95848b8605Smrg      reg->SwizzleZ = swizzle;
96848b8605Smrg      break;
97848b8605Smrg   case 3:
98848b8605Smrg      reg->SwizzleW = swizzle;
99848b8605Smrg      break;
100848b8605Smrg   default:
101b8e80941Smrg      assert(0);
102848b8605Smrg   }
103848b8605Smrg}
104848b8605Smrg
105b8e80941Smrg
106848b8605Smrgunsigned
107848b8605Smrgtgsi_util_get_full_src_register_sign_mode(
108b8e80941Smrg   const struct tgsi_full_src_register *reg,
109b8e80941Smrg   UNUSED unsigned component)
110848b8605Smrg{
111848b8605Smrg   unsigned sign_mode;
112848b8605Smrg
113b8e80941Smrg   if (reg->Register.Absolute) {
114848b8605Smrg      /* Consider only the post-abs negation. */
115848b8605Smrg
116b8e80941Smrg      if (reg->Register.Negate) {
117848b8605Smrg         sign_mode = TGSI_UTIL_SIGN_SET;
118848b8605Smrg      }
119848b8605Smrg      else {
120848b8605Smrg         sign_mode = TGSI_UTIL_SIGN_CLEAR;
121848b8605Smrg      }
122848b8605Smrg   }
123848b8605Smrg   else {
124b8e80941Smrg      if (reg->Register.Negate) {
125848b8605Smrg         sign_mode = TGSI_UTIL_SIGN_TOGGLE;
126848b8605Smrg      }
127848b8605Smrg      else {
128848b8605Smrg         sign_mode = TGSI_UTIL_SIGN_KEEP;
129848b8605Smrg      }
130848b8605Smrg   }
131848b8605Smrg
132848b8605Smrg   return sign_mode;
133848b8605Smrg}
134848b8605Smrg
135b8e80941Smrg
136848b8605Smrgvoid
137b8e80941Smrgtgsi_util_set_full_src_register_sign_mode(struct tgsi_full_src_register *reg,
138b8e80941Smrg                                          unsigned sign_mode)
139848b8605Smrg{
140b8e80941Smrg   switch (sign_mode) {
141848b8605Smrg   case TGSI_UTIL_SIGN_CLEAR:
142848b8605Smrg      reg->Register.Negate = 0;
143848b8605Smrg      reg->Register.Absolute = 1;
144848b8605Smrg      break;
145848b8605Smrg
146848b8605Smrg   case TGSI_UTIL_SIGN_SET:
147848b8605Smrg      reg->Register.Absolute = 1;
148848b8605Smrg      reg->Register.Negate = 1;
149848b8605Smrg      break;
150848b8605Smrg
151848b8605Smrg   case TGSI_UTIL_SIGN_TOGGLE:
152848b8605Smrg      reg->Register.Negate = 1;
153848b8605Smrg      reg->Register.Absolute = 0;
154848b8605Smrg      break;
155848b8605Smrg
156848b8605Smrg   case TGSI_UTIL_SIGN_KEEP:
157848b8605Smrg      reg->Register.Negate = 0;
158848b8605Smrg      reg->Register.Absolute = 0;
159848b8605Smrg      break;
160848b8605Smrg
161848b8605Smrg   default:
162b8e80941Smrg      assert(0);
163848b8605Smrg   }
164848b8605Smrg}
165848b8605Smrg
166b8e80941Smrg
167848b8605Smrg/**
168848b8605Smrg * Determine which channels of the specificed src register are effectively
169848b8605Smrg * used by this instruction.
170848b8605Smrg */
171848b8605Smrgunsigned
172848b8605Smrgtgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
173848b8605Smrg                              unsigned src_idx)
174848b8605Smrg{
175848b8605Smrg   const struct tgsi_full_src_register *src = &inst->Src[src_idx];
176848b8605Smrg   unsigned write_mask = inst->Dst[0].Register.WriteMask;
177848b8605Smrg   unsigned read_mask;
178848b8605Smrg   unsigned usage_mask;
179848b8605Smrg   unsigned chan;
180848b8605Smrg
181848b8605Smrg   switch (inst->Instruction.Opcode) {
182b8e80941Smrg   case TGSI_OPCODE_IF:
183b8e80941Smrg   case TGSI_OPCODE_UIF:
184b8e80941Smrg   case TGSI_OPCODE_EMIT:
185b8e80941Smrg   case TGSI_OPCODE_ENDPRIM:
186848b8605Smrg   case TGSI_OPCODE_RCP:
187b8e80941Smrg   case TGSI_OPCODE_RSQ:
188b8e80941Smrg   case TGSI_OPCODE_SQRT:
189848b8605Smrg   case TGSI_OPCODE_EX2:
190848b8605Smrg   case TGSI_OPCODE_LG2:
191b8e80941Smrg   case TGSI_OPCODE_SIN:
192b8e80941Smrg   case TGSI_OPCODE_COS:
193b8e80941Smrg   case TGSI_OPCODE_POW: /* reads src0.x and src1.x */
194b8e80941Smrg   case TGSI_OPCODE_UP2H:
195b8e80941Smrg   case TGSI_OPCODE_UP2US:
196b8e80941Smrg   case TGSI_OPCODE_UP4B:
197b8e80941Smrg   case TGSI_OPCODE_UP4UB:
198b8e80941Smrg   case TGSI_OPCODE_MEMBAR:
199b8e80941Smrg   case TGSI_OPCODE_BALLOT:
200848b8605Smrg      read_mask = TGSI_WRITEMASK_X;
201848b8605Smrg      break;
202848b8605Smrg
203b8e80941Smrg   case TGSI_OPCODE_DP2:
204b8e80941Smrg   case TGSI_OPCODE_PK2H:
205b8e80941Smrg   case TGSI_OPCODE_PK2US:
206b8e80941Smrg   case TGSI_OPCODE_DFRACEXP:
207b8e80941Smrg   case TGSI_OPCODE_F2D:
208b8e80941Smrg   case TGSI_OPCODE_I2D:
209b8e80941Smrg   case TGSI_OPCODE_U2D:
210b8e80941Smrg   case TGSI_OPCODE_F2U64:
211b8e80941Smrg   case TGSI_OPCODE_F2I64:
212b8e80941Smrg   case TGSI_OPCODE_U2I64:
213b8e80941Smrg   case TGSI_OPCODE_I2I64:
214b8e80941Smrg   case TGSI_OPCODE_TXQS: /* bindless handle possible */
215b8e80941Smrg   case TGSI_OPCODE_RESQ: /* bindless handle possible */
216b8e80941Smrg      read_mask = TGSI_WRITEMASK_XY;
217b8e80941Smrg      break;
218b8e80941Smrg
219b8e80941Smrg   case TGSI_OPCODE_TXQ:
220b8e80941Smrg      if (src_idx == 0)
221b8e80941Smrg         read_mask = TGSI_WRITEMASK_X;
222b8e80941Smrg      else
223b8e80941Smrg         read_mask = TGSI_WRITEMASK_XY;  /* bindless handle possible */
224b8e80941Smrg      break;
225b8e80941Smrg
226b8e80941Smrg   case TGSI_OPCODE_DP3:
227b8e80941Smrg      read_mask = TGSI_WRITEMASK_XYZ;
228b8e80941Smrg      break;
229b8e80941Smrg
230b8e80941Smrg   case TGSI_OPCODE_DSEQ:
231b8e80941Smrg   case TGSI_OPCODE_DSNE:
232b8e80941Smrg   case TGSI_OPCODE_DSLT:
233b8e80941Smrg   case TGSI_OPCODE_DSGE:
234b8e80941Smrg   case TGSI_OPCODE_DP4:
235b8e80941Smrg   case TGSI_OPCODE_PK4B:
236b8e80941Smrg   case TGSI_OPCODE_PK4UB:
237b8e80941Smrg   case TGSI_OPCODE_D2F:
238b8e80941Smrg   case TGSI_OPCODE_D2I:
239b8e80941Smrg   case TGSI_OPCODE_D2U:
240b8e80941Smrg   case TGSI_OPCODE_I2F:
241b8e80941Smrg   case TGSI_OPCODE_U2F:
242b8e80941Smrg   case TGSI_OPCODE_U64SEQ:
243b8e80941Smrg   case TGSI_OPCODE_U64SNE:
244b8e80941Smrg   case TGSI_OPCODE_U64SLT:
245b8e80941Smrg   case TGSI_OPCODE_U64SGE:
246b8e80941Smrg   case TGSI_OPCODE_U642F:
247b8e80941Smrg   case TGSI_OPCODE_I64SLT:
248b8e80941Smrg   case TGSI_OPCODE_I64SGE:
249b8e80941Smrg   case TGSI_OPCODE_I642F:
250b8e80941Smrg      read_mask = TGSI_WRITEMASK_XYZW;
251b8e80941Smrg      break;
252b8e80941Smrg
253b8e80941Smrg   case TGSI_OPCODE_LIT:
254b8e80941Smrg      read_mask = write_mask & TGSI_WRITEMASK_YZ ?
255b8e80941Smrg                     TGSI_WRITEMASK_XY | TGSI_WRITEMASK_W : 0;
256848b8605Smrg      break;
257848b8605Smrg
258848b8605Smrg   case TGSI_OPCODE_EXP:
259848b8605Smrg   case TGSI_OPCODE_LOG:
260848b8605Smrg      read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0;
261848b8605Smrg      break;
262848b8605Smrg
263b8e80941Smrg   case TGSI_OPCODE_DST:
264b8e80941Smrg      if (src_idx == 0)
265b8e80941Smrg         read_mask = TGSI_WRITEMASK_YZ;
266b8e80941Smrg      else
267b8e80941Smrg         read_mask = TGSI_WRITEMASK_YW;
268848b8605Smrg      break;
269848b8605Smrg
270b8e80941Smrg   case TGSI_OPCODE_DLDEXP:
271b8e80941Smrg      if (src_idx == 0) {
272b8e80941Smrg         read_mask = write_mask;
273b8e80941Smrg      } else {
274b8e80941Smrg         read_mask =
275b8e80941Smrg            (write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0) |
276b8e80941Smrg            (write_mask & TGSI_WRITEMASK_ZW ? TGSI_WRITEMASK_Z : 0);
277b8e80941Smrg      }
278848b8605Smrg      break;
279848b8605Smrg
280b8e80941Smrg   case TGSI_OPCODE_READ_INVOC:
281b8e80941Smrg      if (src_idx == 0)
282b8e80941Smrg         read_mask = write_mask;
283b8e80941Smrg      else
284b8e80941Smrg         read_mask = TGSI_WRITEMASK_X;
285848b8605Smrg      break;
286848b8605Smrg
287b8e80941Smrg   case TGSI_OPCODE_FBFETCH:
288b8e80941Smrg      read_mask = 0; /* not a real register read */
289848b8605Smrg      break;
290848b8605Smrg
291848b8605Smrg   case TGSI_OPCODE_TEX:
292b8e80941Smrg   case TGSI_OPCODE_TEX_LZ:
293b8e80941Smrg   case TGSI_OPCODE_TXF_LZ:
294b8e80941Smrg   case TGSI_OPCODE_TXF:
295848b8605Smrg   case TGSI_OPCODE_TXB:
296848b8605Smrg   case TGSI_OPCODE_TXL:
297848b8605Smrg   case TGSI_OPCODE_TXP:
298b8e80941Smrg   case TGSI_OPCODE_TXD:
299b8e80941Smrg   case TGSI_OPCODE_TEX2:
300b8e80941Smrg   case TGSI_OPCODE_TXB2:
301b8e80941Smrg   case TGSI_OPCODE_TXL2:
302b8e80941Smrg   case TGSI_OPCODE_LODQ:
303b8e80941Smrg   case TGSI_OPCODE_TG4: {
304b8e80941Smrg      unsigned dim_layer =
305b8e80941Smrg         tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
306b8e80941Smrg      unsigned dim_layer_shadow, dim;
307b8e80941Smrg
308b8e80941Smrg      /* Add shadow. */
309b8e80941Smrg      if (tgsi_is_shadow_target(inst->Texture.Texture)) {
310b8e80941Smrg         dim_layer_shadow = dim_layer + 1;
311b8e80941Smrg         if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D)
312b8e80941Smrg            dim_layer_shadow = 3;
313b8e80941Smrg      } else {
314b8e80941Smrg         dim_layer_shadow = dim_layer;
315b8e80941Smrg      }
316b8e80941Smrg
317b8e80941Smrg      /* Remove layer. */
318b8e80941Smrg      if (tgsi_is_array_sampler(inst->Texture.Texture))
319b8e80941Smrg         dim = dim_layer - 1;
320b8e80941Smrg      else
321b8e80941Smrg         dim = dim_layer;
322b8e80941Smrg
323b8e80941Smrg      read_mask = TGSI_WRITEMASK_XY; /* bindless handle in the last operand */
324b8e80941Smrg
325b8e80941Smrg      switch (src_idx) {
326b8e80941Smrg      case 0:
327b8e80941Smrg         if (inst->Instruction.Opcode == TGSI_OPCODE_LODQ)
328b8e80941Smrg            read_mask = u_bit_consecutive(0, dim);
329b8e80941Smrg         else
330b8e80941Smrg            read_mask = u_bit_consecutive(0, dim_layer_shadow) & 0xf;
331b8e80941Smrg
332b8e80941Smrg         if (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D)
333b8e80941Smrg            read_mask &= ~TGSI_WRITEMASK_Y;
334b8e80941Smrg
335b8e80941Smrg         if (inst->Instruction.Opcode == TGSI_OPCODE_TXF ||
336b8e80941Smrg             inst->Instruction.Opcode == TGSI_OPCODE_TXB ||
337b8e80941Smrg             inst->Instruction.Opcode == TGSI_OPCODE_TXL ||
338b8e80941Smrg             inst->Instruction.Opcode == TGSI_OPCODE_TXP)
339848b8605Smrg            read_mask |= TGSI_WRITEMASK_W;
340b8e80941Smrg         break;
341b8e80941Smrg
342b8e80941Smrg      case 1:
343b8e80941Smrg         if (inst->Instruction.Opcode == TGSI_OPCODE_TXD)
344b8e80941Smrg            read_mask = u_bit_consecutive(0, dim);
345b8e80941Smrg         else if (inst->Instruction.Opcode == TGSI_OPCODE_TEX2 ||
346b8e80941Smrg                  inst->Instruction.Opcode == TGSI_OPCODE_TXB2 ||
347b8e80941Smrg                  inst->Instruction.Opcode == TGSI_OPCODE_TXL2 ||
348b8e80941Smrg                  inst->Instruction.Opcode == TGSI_OPCODE_TG4)
349b8e80941Smrg            read_mask = TGSI_WRITEMASK_X;
350b8e80941Smrg         break;
351b8e80941Smrg
352b8e80941Smrg      case 2:
353b8e80941Smrg         if (inst->Instruction.Opcode == TGSI_OPCODE_TXD)
354b8e80941Smrg            read_mask = u_bit_consecutive(0, dim);
355b8e80941Smrg         break;
356b8e80941Smrg      }
357b8e80941Smrg      break;
358b8e80941Smrg   }
359b8e80941Smrg
360b8e80941Smrg   case TGSI_OPCODE_LOAD:
361b8e80941Smrg      if (src_idx == 0) {
362b8e80941Smrg         read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */
363b8e80941Smrg      } else {
364b8e80941Smrg         unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture);
365b8e80941Smrg         read_mask = u_bit_consecutive(0, dim);
366b8e80941Smrg      }
367b8e80941Smrg      break;
368b8e80941Smrg
369b8e80941Smrg   case TGSI_OPCODE_STORE:
370b8e80941Smrg      if (src_idx == 0) {
371b8e80941Smrg         unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture);
372b8e80941Smrg         read_mask = u_bit_consecutive(0, dim);
373b8e80941Smrg      } else {
374b8e80941Smrg         read_mask = TGSI_WRITEMASK_XYZW;
375b8e80941Smrg      }
376b8e80941Smrg      break;
377b8e80941Smrg
378b8e80941Smrg   case TGSI_OPCODE_ATOMUADD:
379b8e80941Smrg   case TGSI_OPCODE_ATOMXCHG:
380b8e80941Smrg   case TGSI_OPCODE_ATOMCAS:
381b8e80941Smrg   case TGSI_OPCODE_ATOMAND:
382b8e80941Smrg   case TGSI_OPCODE_ATOMOR:
383b8e80941Smrg   case TGSI_OPCODE_ATOMXOR:
384b8e80941Smrg   case TGSI_OPCODE_ATOMUMIN:
385b8e80941Smrg   case TGSI_OPCODE_ATOMUMAX:
386b8e80941Smrg   case TGSI_OPCODE_ATOMIMIN:
387b8e80941Smrg   case TGSI_OPCODE_ATOMIMAX:
388b8e80941Smrg   case TGSI_OPCODE_ATOMFADD:
389b8e80941Smrg      if (src_idx == 0) {
390b8e80941Smrg         read_mask = TGSI_WRITEMASK_XY; /* bindless handle possible */
391b8e80941Smrg      } else if (src_idx == 1) {
392b8e80941Smrg         unsigned dim = tgsi_util_get_texture_coord_dim(inst->Memory.Texture);
393b8e80941Smrg         read_mask = u_bit_consecutive(0, dim);
394848b8605Smrg      } else {
395848b8605Smrg         read_mask = TGSI_WRITEMASK_XYZW;
396848b8605Smrg      }
397848b8605Smrg      break;
398848b8605Smrg
399b8e80941Smrg   case TGSI_OPCODE_INTERP_CENTROID:
400b8e80941Smrg   case TGSI_OPCODE_INTERP_SAMPLE:
401b8e80941Smrg   case TGSI_OPCODE_INTERP_OFFSET:
402b8e80941Smrg      if (src_idx == 0)
403b8e80941Smrg         read_mask = write_mask;
404b8e80941Smrg      else if (inst->Instruction.Opcode == TGSI_OPCODE_INTERP_OFFSET)
405b8e80941Smrg         read_mask = TGSI_WRITEMASK_XY; /* offset */
406b8e80941Smrg      else
407b8e80941Smrg         read_mask = TGSI_WRITEMASK_X; /* sample */
408b8e80941Smrg      break;
409b8e80941Smrg
410848b8605Smrg   default:
411b8e80941Smrg      if (tgsi_get_opcode_info(inst->Instruction.Opcode)->output_mode ==
412b8e80941Smrg          TGSI_OUTPUT_COMPONENTWISE)
413b8e80941Smrg         read_mask = write_mask;
414b8e80941Smrg      else
415b8e80941Smrg         read_mask = TGSI_WRITEMASK_XYZW; /* assume all channels are read */
416848b8605Smrg      break;
417848b8605Smrg   }
418848b8605Smrg
419848b8605Smrg   usage_mask = 0;
420848b8605Smrg   for (chan = 0; chan < 4; ++chan) {
421848b8605Smrg      if (read_mask & (1 << chan)) {
422848b8605Smrg         usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan);
423848b8605Smrg      }
424848b8605Smrg   }
425848b8605Smrg
426848b8605Smrg   return usage_mask;
427848b8605Smrg}
428848b8605Smrg
429848b8605Smrg/**
430848b8605Smrg * Convert a tgsi_ind_register into a tgsi_src_register
431848b8605Smrg */
432848b8605Smrgstruct tgsi_src_register
433848b8605Smrgtgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg)
434848b8605Smrg{
435848b8605Smrg   struct tgsi_src_register src = { 0 };
436848b8605Smrg
437848b8605Smrg   src.File = reg->File;
438848b8605Smrg   src.Index = reg->Index;
439848b8605Smrg   src.SwizzleX = reg->Swizzle;
440848b8605Smrg   src.SwizzleY = reg->Swizzle;
441848b8605Smrg   src.SwizzleZ = reg->Swizzle;
442848b8605Smrg   src.SwizzleW = reg->Swizzle;
443848b8605Smrg
444848b8605Smrg   return src;
445848b8605Smrg}
446848b8605Smrg
447848b8605Smrg/**
448848b8605Smrg * Return the dimension of the texture coordinates (layer included for array
449848b8605Smrg * textures), as well as the location of the shadow reference value or the
450848b8605Smrg * sample index.
451848b8605Smrg */
452848b8605Smrgint
453b8e80941Smrgtgsi_util_get_texture_coord_dim(enum tgsi_texture_type tgsi_tex)
454848b8605Smrg{
455848b8605Smrg   /*
456848b8605Smrg    * Depending on the texture target, (src0.xyzw, src1.x) is interpreted
457848b8605Smrg    * differently:
458848b8605Smrg    *
459848b8605Smrg    *   (s, X, X, X, X),               for BUFFER
460848b8605Smrg    *   (s, X, X, X, X),               for 1D
461848b8605Smrg    *   (s, t, X, X, X),               for 2D, RECT
462848b8605Smrg    *   (s, t, r, X, X),               for 3D, CUBE
463848b8605Smrg    *
464848b8605Smrg    *   (s, layer, X, X, X),           for 1D_ARRAY
465848b8605Smrg    *   (s, t, layer, X, X),           for 2D_ARRAY
466848b8605Smrg    *   (s, t, r, layer, X),           for CUBE_ARRAY
467848b8605Smrg    *
468848b8605Smrg    *   (s, X, shadow, X, X),          for SHADOW1D
469848b8605Smrg    *   (s, t, shadow, X, X),          for SHADOW2D, SHADOWRECT
470848b8605Smrg    *   (s, t, r, shadow, X),          for SHADOWCUBE
471848b8605Smrg    *
472848b8605Smrg    *   (s, layer, shadow, X, X),      for SHADOW1D_ARRAY
473848b8605Smrg    *   (s, t, layer, shadow, X),      for SHADOW2D_ARRAY
474848b8605Smrg    *   (s, t, r, layer, shadow),      for SHADOWCUBE_ARRAY
475848b8605Smrg    *
476848b8605Smrg    *   (s, t, sample, X, X),          for 2D_MSAA
477848b8605Smrg    *   (s, t, layer, sample, X),      for 2D_ARRAY_MSAA
478848b8605Smrg    */
479848b8605Smrg   switch (tgsi_tex) {
480848b8605Smrg   case TGSI_TEXTURE_BUFFER:
481848b8605Smrg   case TGSI_TEXTURE_1D:
482848b8605Smrg   case TGSI_TEXTURE_SHADOW1D:
483b8e80941Smrg      return 1;
484848b8605Smrg   case TGSI_TEXTURE_2D:
485848b8605Smrg   case TGSI_TEXTURE_RECT:
486848b8605Smrg   case TGSI_TEXTURE_1D_ARRAY:
487848b8605Smrg   case TGSI_TEXTURE_SHADOW2D:
488848b8605Smrg   case TGSI_TEXTURE_SHADOWRECT:
489848b8605Smrg   case TGSI_TEXTURE_SHADOW1D_ARRAY:
490848b8605Smrg   case TGSI_TEXTURE_2D_MSAA:
491b8e80941Smrg      return 2;
492848b8605Smrg   case TGSI_TEXTURE_3D:
493848b8605Smrg   case TGSI_TEXTURE_CUBE:
494848b8605Smrg   case TGSI_TEXTURE_2D_ARRAY:
495848b8605Smrg   case TGSI_TEXTURE_SHADOWCUBE:
496848b8605Smrg   case TGSI_TEXTURE_SHADOW2D_ARRAY:
497848b8605Smrg   case TGSI_TEXTURE_2D_ARRAY_MSAA:
498b8e80941Smrg      return 3;
499848b8605Smrg   case TGSI_TEXTURE_CUBE_ARRAY:
500848b8605Smrg   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
501b8e80941Smrg      return 4;
502848b8605Smrg   default:
503848b8605Smrg      assert(!"unknown texture target");
504b8e80941Smrg      return 0;
505848b8605Smrg   }
506b8e80941Smrg}
507848b8605Smrg
508b8e80941Smrg
509b8e80941Smrg/**
510b8e80941Smrg * Given a TGSI_TEXTURE_x target, return register component where the
511b8e80941Smrg * shadow reference/distance coordinate is found.  Typically, components
512b8e80941Smrg * 0 and 1 are the (s,t) texcoords and component 2 or 3 hold the shadow
513b8e80941Smrg * reference value.  But if we return 4, it means the reference value is
514b8e80941Smrg * found in the 0th component of the second coordinate argument to the
515b8e80941Smrg * TEX2 instruction.
516b8e80941Smrg */
517b8e80941Smrgint
518b8e80941Smrgtgsi_util_get_shadow_ref_src_index(enum tgsi_texture_type tgsi_tex)
519b8e80941Smrg{
520b8e80941Smrg   switch (tgsi_tex) {
521b8e80941Smrg   case TGSI_TEXTURE_SHADOW1D:
522b8e80941Smrg   case TGSI_TEXTURE_SHADOW2D:
523b8e80941Smrg   case TGSI_TEXTURE_SHADOWRECT:
524b8e80941Smrg   case TGSI_TEXTURE_SHADOW1D_ARRAY:
525b8e80941Smrg      return 2;
526b8e80941Smrg   case TGSI_TEXTURE_SHADOWCUBE:
527b8e80941Smrg   case TGSI_TEXTURE_SHADOW2D_ARRAY:
528b8e80941Smrg   case TGSI_TEXTURE_2D_MSAA:
529b8e80941Smrg   case TGSI_TEXTURE_2D_ARRAY_MSAA:
530b8e80941Smrg      return 3;
531b8e80941Smrg   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
532b8e80941Smrg      return 4;
533b8e80941Smrg   default:
534b8e80941Smrg      /* no shadow nor sample */
535b8e80941Smrg      return -1;
536848b8605Smrg   }
537b8e80941Smrg}
538b8e80941Smrg
539848b8605Smrg
540b8e80941Smrgboolean
541b8e80941Smrgtgsi_is_shadow_target(enum tgsi_texture_type target)
542b8e80941Smrg{
543b8e80941Smrg   switch (target) {
544b8e80941Smrg   case TGSI_TEXTURE_SHADOW1D:
545b8e80941Smrg   case TGSI_TEXTURE_SHADOW2D:
546b8e80941Smrg   case TGSI_TEXTURE_SHADOWRECT:
547b8e80941Smrg   case TGSI_TEXTURE_SHADOW1D_ARRAY:
548b8e80941Smrg   case TGSI_TEXTURE_SHADOW2D_ARRAY:
549b8e80941Smrg   case TGSI_TEXTURE_SHADOWCUBE:
550b8e80941Smrg   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
551b8e80941Smrg      return TRUE;
552b8e80941Smrg   default:
553b8e80941Smrg      return FALSE;
554b8e80941Smrg   }
555848b8605Smrg}
556