Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/**************************************************************************
2
 *
3
 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4
 * All Rights Reserved.
5
 *
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:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
17
 *
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.
25
 *
26
 **************************************************************************/
27
 
28
#include "util/u_debug.h"
29
#include "pipe/p_shader_tokens.h"
30
#include "tgsi_parse.h"
31
#include "tgsi_util.h"
32
 
33
union pointer_hack
34
{
35
   void *pointer;
36
   uint64_t uint64;
37
};
38
 
39
void *
40
tgsi_align_128bit(
41
   void *unaligned )
42
{
43
   union pointer_hack ph;
44
 
45
   ph.uint64 = 0;
46
   ph.pointer = unaligned;
47
   ph.uint64 = (ph.uint64 + 15) & ~15;
48
   return ph.pointer;
49
}
50
 
51
unsigned
52
tgsi_util_get_src_register_swizzle(
53
   const struct tgsi_src_register *reg,
54
   unsigned component )
55
{
56
   switch( component ) {
57
   case 0:
58
      return reg->SwizzleX;
59
   case 1:
60
      return reg->SwizzleY;
61
   case 2:
62
      return reg->SwizzleZ;
63
   case 3:
64
      return reg->SwizzleW;
65
   default:
66
      assert( 0 );
67
   }
68
   return 0;
69
}
70
 
71
 
72
unsigned
73
tgsi_util_get_full_src_register_swizzle(
74
   const struct tgsi_full_src_register  *reg,
75
   unsigned component )
76
{
77
   return tgsi_util_get_src_register_swizzle(
78
      ®->Register,
79
      component );
80
}
81
 
82
void
83
tgsi_util_set_src_register_swizzle(
84
   struct tgsi_src_register *reg,
85
   unsigned swizzle,
86
   unsigned component )
87
{
88
   switch( component ) {
89
   case 0:
90
      reg->SwizzleX = swizzle;
91
      break;
92
   case 1:
93
      reg->SwizzleY = swizzle;
94
      break;
95
   case 2:
96
      reg->SwizzleZ = swizzle;
97
      break;
98
   case 3:
99
      reg->SwizzleW = swizzle;
100
      break;
101
   default:
102
      assert( 0 );
103
   }
104
}
105
 
106
unsigned
107
tgsi_util_get_full_src_register_sign_mode(
108
   const struct  tgsi_full_src_register *reg,
109
   unsigned component )
110
{
111
   unsigned sign_mode;
112
 
113
   if( reg->Register.Absolute ) {
114
      /* Consider only the post-abs negation. */
115
 
116
      if( reg->Register.Negate ) {
117
         sign_mode = TGSI_UTIL_SIGN_SET;
118
      }
119
      else {
120
         sign_mode = TGSI_UTIL_SIGN_CLEAR;
121
      }
122
   }
123
   else {
124
      if( reg->Register.Negate ) {
125
         sign_mode = TGSI_UTIL_SIGN_TOGGLE;
126
      }
127
      else {
128
         sign_mode = TGSI_UTIL_SIGN_KEEP;
129
      }
130
   }
131
 
132
   return sign_mode;
133
}
134
 
135
void
136
tgsi_util_set_full_src_register_sign_mode(
137
   struct tgsi_full_src_register *reg,
138
   unsigned sign_mode )
139
{
140
   switch (sign_mode)
141
   {
142
   case TGSI_UTIL_SIGN_CLEAR:
143
      reg->Register.Negate = 0;
144
      reg->Register.Absolute = 1;
145
      break;
146
 
147
   case TGSI_UTIL_SIGN_SET:
148
      reg->Register.Absolute = 1;
149
      reg->Register.Negate = 1;
150
      break;
151
 
152
   case TGSI_UTIL_SIGN_TOGGLE:
153
      reg->Register.Negate = 1;
154
      reg->Register.Absolute = 0;
155
      break;
156
 
157
   case TGSI_UTIL_SIGN_KEEP:
158
      reg->Register.Negate = 0;
159
      reg->Register.Absolute = 0;
160
      break;
161
 
162
   default:
163
      assert( 0 );
164
   }
165
}
166
 
167
/**
168
 * Determine which channels of the specificed src register are effectively
169
 * used by this instruction.
170
 */
171
unsigned
172
tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
173
                              unsigned src_idx)
174
{
175
   const struct tgsi_full_src_register *src = &inst->Src[src_idx];
176
   unsigned write_mask = inst->Dst[0].Register.WriteMask;
177
   unsigned read_mask;
178
   unsigned usage_mask;
179
   unsigned chan;
180
 
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:
217
   case TGSI_OPCODE_OR:
218
   case TGSI_OPCODE_XOR:
219
   case TGSI_OPCODE_SAD:
220
      /* Channel-wise operations */
221
      read_mask = write_mask;
222
      break;
223
 
224
   case TGSI_OPCODE_EX2:
225
   case TGSI_OPCODE_LG2:
226
   case TGSI_OPCODE_RCC:
227
      read_mask = TGSI_WRITEMASK_X;
228
      break;
229
 
230
   case TGSI_OPCODE_SCS:
231
      read_mask = write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0;
232
      break;
233
 
234
   case TGSI_OPCODE_EXP:
235
   case TGSI_OPCODE_LOG:
236
      read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0;
237
      break;
238
 
239
   case TGSI_OPCODE_DP2A:
240
      read_mask = src_idx == 2 ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_XY;
241
      break;
242
 
243
   case TGSI_OPCODE_DP2:
244
      read_mask = TGSI_WRITEMASK_XY;
245
      break;
246
 
247
   case TGSI_OPCODE_DP3:
248
      read_mask = TGSI_WRITEMASK_XYZ;
249
      break;
250
 
251
   case TGSI_OPCODE_DP4:
252
      read_mask = TGSI_WRITEMASK_XYZW;
253
      break;
254
 
255
   case TGSI_OPCODE_DPH:
256
      read_mask = src_idx == 0 ? TGSI_WRITEMASK_XYZ : TGSI_WRITEMASK_XYZW;
257
      break;
258
 
259
   case TGSI_OPCODE_TEX:
260
   case TGSI_OPCODE_TXD:
261
   case TGSI_OPCODE_TXB:
262
   case TGSI_OPCODE_TXL:
263
   case TGSI_OPCODE_TXP:
264
      if (src_idx == 0) {
265
         /* Note that the SHADOW variants use the Z component too */
266
         switch (inst->Texture.Texture) {
267
         case TGSI_TEXTURE_1D:
268
            read_mask = TGSI_WRITEMASK_X;
269
            break;
270
         case TGSI_TEXTURE_SHADOW1D:
271
            read_mask = TGSI_WRITEMASK_XZ;
272
            break;
273
         case TGSI_TEXTURE_1D_ARRAY:
274
         case TGSI_TEXTURE_2D:
275
         case TGSI_TEXTURE_RECT:
276
            read_mask = TGSI_WRITEMASK_XY;
277
            break;
278
         case TGSI_TEXTURE_SHADOW1D_ARRAY:
279
         case TGSI_TEXTURE_SHADOW2D:
280
         case TGSI_TEXTURE_SHADOWRECT:
281
         case TGSI_TEXTURE_2D_ARRAY:
282
         case TGSI_TEXTURE_3D:
283
         case TGSI_TEXTURE_CUBE:
284
         case TGSI_TEXTURE_2D_MSAA:
285
            read_mask = TGSI_WRITEMASK_XYZ;
286
            break;
287
         case TGSI_TEXTURE_SHADOW2D_ARRAY:
288
         case TGSI_TEXTURE_CUBE_ARRAY:
289
         case TGSI_TEXTURE_SHADOWCUBE:
290
         case TGSI_TEXTURE_2D_ARRAY_MSAA:
291
         case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
292
            read_mask = TGSI_WRITEMASK_XYZW;
293
            break;
294
         default:
295
            assert(0);
296
            read_mask = 0;
297
         }
298
 
299
         if (inst->Instruction.Opcode != TGSI_OPCODE_TEX) {
300
            read_mask |= TGSI_WRITEMASK_W;
301
         }
302
      } else {
303
         /* A safe approximation */
304
         read_mask = TGSI_WRITEMASK_XYZW;
305
      }
306
      break;
307
 
308
   default:
309
      /* Assume all channels are read */
310
      read_mask = TGSI_WRITEMASK_XYZW;
311
      break;
312
   }
313
 
314
   usage_mask = 0;
315
   for (chan = 0; chan < 4; ++chan) {
316
      if (read_mask & (1 << chan)) {
317
         usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan);
318
      }
319
   }
320
 
321
   return usage_mask;
322
}
323
 
324
/**
325
 * Convert a tgsi_ind_register into a tgsi_src_register
326
 */
327
struct tgsi_src_register
328
tgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg)
329
{
330
   struct tgsi_src_register src = { 0 };
331
 
332
   src.File = reg->File;
333
   src.Index = reg->Index;
334
   src.SwizzleX = reg->Swizzle;
335
   src.SwizzleY = reg->Swizzle;
336
   src.SwizzleZ = reg->Swizzle;
337
   src.SwizzleW = reg->Swizzle;
338
 
339
   return src;
340
}
341
 
342
/**
343
 * Return the dimension of the texture coordinates (layer included for array
344
 * textures), as well as the location of the shadow reference value or the
345
 * sample index.
346
 */
347
int
348
tgsi_util_get_texture_coord_dim(int tgsi_tex, int *shadow_or_sample)
349
{
350
   int dim;
351
 
352
   /*
353
    * Depending on the texture target, (src0.xyzw, src1.x) is interpreted
354
    * differently:
355
    *
356
    *   (s, X, X, X, X),               for BUFFER
357
    *   (s, X, X, X, X),               for 1D
358
    *   (s, t, X, X, X),               for 2D, RECT
359
    *   (s, t, r, X, X),               for 3D, CUBE
360
    *
361
    *   (s, layer, X, X, X),           for 1D_ARRAY
362
    *   (s, t, layer, X, X),           for 2D_ARRAY
363
    *   (s, t, r, layer, X),           for CUBE_ARRAY
364
    *
365
    *   (s, X, shadow, X, X),          for SHADOW1D
366
    *   (s, t, shadow, X, X),          for SHADOW2D, SHADOWRECT
367
    *   (s, t, r, shadow, X),          for SHADOWCUBE
368
    *
369
    *   (s, layer, shadow, X, X),      for SHADOW1D_ARRAY
370
    *   (s, t, layer, shadow, X),      for SHADOW2D_ARRAY
371
    *   (s, t, r, layer, shadow),      for SHADOWCUBE_ARRAY
372
    *
373
    *   (s, t, sample, X, X),          for 2D_MSAA
374
    *   (s, t, layer, sample, X),      for 2D_ARRAY_MSAA
375
    */
376
   switch (tgsi_tex) {
377
   case TGSI_TEXTURE_BUFFER:
378
   case TGSI_TEXTURE_1D:
379
   case TGSI_TEXTURE_SHADOW1D:
380
      dim = 1;
381
      break;
382
   case TGSI_TEXTURE_2D:
383
   case TGSI_TEXTURE_RECT:
384
   case TGSI_TEXTURE_1D_ARRAY:
385
   case TGSI_TEXTURE_SHADOW2D:
386
   case TGSI_TEXTURE_SHADOWRECT:
387
   case TGSI_TEXTURE_SHADOW1D_ARRAY:
388
   case TGSI_TEXTURE_2D_MSAA:
389
      dim = 2;
390
      break;
391
   case TGSI_TEXTURE_3D:
392
   case TGSI_TEXTURE_CUBE:
393
   case TGSI_TEXTURE_2D_ARRAY:
394
   case TGSI_TEXTURE_SHADOWCUBE:
395
   case TGSI_TEXTURE_SHADOW2D_ARRAY:
396
   case TGSI_TEXTURE_2D_ARRAY_MSAA:
397
      dim = 3;
398
      break;
399
   case TGSI_TEXTURE_CUBE_ARRAY:
400
   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
401
      dim = 4;
402
      break;
403
   default:
404
      assert(!"unknown texture target");
405
      dim = 0;
406
      break;
407
   }
408
 
409
   if (shadow_or_sample) {
410
      switch (tgsi_tex) {
411
      case TGSI_TEXTURE_SHADOW1D:
412
         /* there is a gap */
413
         *shadow_or_sample = 2;
414
         break;
415
      case TGSI_TEXTURE_SHADOW2D:
416
      case TGSI_TEXTURE_SHADOWRECT:
417
      case TGSI_TEXTURE_SHADOWCUBE:
418
      case TGSI_TEXTURE_SHADOW1D_ARRAY:
419
      case TGSI_TEXTURE_SHADOW2D_ARRAY:
420
      case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
421
      case TGSI_TEXTURE_2D_MSAA:
422
      case TGSI_TEXTURE_2D_ARRAY_MSAA:
423
         *shadow_or_sample = dim;
424
         break;
425
      default:
426
         /* no shadow nor sample */
427
         *shadow_or_sample = -1;
428
         break;
429
      }
430
   }
431
 
432
   return dim;
433
}