Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
5564 serge 1
/**********************************************************
2
 * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3
 *
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:
11
 *
12
 * The above copyright notice and this permission notice shall be
13
 * included in all copies or substantial portions of the Software.
14
 *
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
22
 * SOFTWARE.
23
 *
24
 **********************************************************/
25
 
26
 
27
#include "pipe/p_shader_tokens.h"
28
#include "tgsi/tgsi_parse.h"
29
#include "util/u_memory.h"
30
 
31
#include "svga_tgsi_emit.h"
32
 
33
 
34
/**
35
 * Translate TGSI semantic info into SVGA3d semantic info.
36
 * This is called for VS outputs and PS inputs only.
37
 */
38
static boolean
39
translate_vs_ps_semantic(struct svga_shader_emitter *emit,
40
                         struct tgsi_declaration_semantic semantic,
41
                         unsigned *usage,
42
                         unsigned *idx)
43
{
44
   switch (semantic.Name) {
45
   case TGSI_SEMANTIC_POSITION:
46
      *idx = semantic.Index;
47
      *usage = SVGA3D_DECLUSAGE_POSITION;
48
      break;
49
   case TGSI_SEMANTIC_COLOR:
50
      *idx = semantic.Index;
51
      *usage = SVGA3D_DECLUSAGE_COLOR;
52
      break;
53
   case TGSI_SEMANTIC_BCOLOR:
54
      *idx = semantic.Index + 2; /* sharing with COLOR */
55
      *usage = SVGA3D_DECLUSAGE_COLOR;
56
      break;
57
   case TGSI_SEMANTIC_FOG:
58
      *idx = 0;
59
      assert(semantic.Index == 0);
60
      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
61
      break;
62
   case TGSI_SEMANTIC_PSIZE:
63
      *idx = semantic.Index;
64
      *usage = SVGA3D_DECLUSAGE_PSIZE;
65
      break;
66
   case TGSI_SEMANTIC_GENERIC:
67
      *idx = svga_remap_generic_index(emit->key.generic_remap_table,
68
                                      semantic.Index);
69
      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
70
      break;
71
   case TGSI_SEMANTIC_NORMAL:
72
      *idx = semantic.Index;
73
      *usage = SVGA3D_DECLUSAGE_NORMAL;
74
      break;
75
   case TGSI_SEMANTIC_CLIPDIST:
76
   case TGSI_SEMANTIC_CLIPVERTEX:
77
      /* XXX at this time we don't support clip distance or clip vertices */
78
      debug_warn_once("unsupported clip distance/vertex attribute\n");
79
      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
80
      *idx = 0;
81
      return TRUE;
82
   default:
83
      assert(0);
84
      *usage = SVGA3D_DECLUSAGE_TEXCOORD;
85
      *idx = 0;
86
      return FALSE;
87
   }
88
 
89
   return TRUE;
90
}
91
 
92
 
93
/**
94
 * Emit a PS input (or VS depth/fog output) register declaration.
95
 * For example, if usage = SVGA3D_DECLUSAGE_TEXCOORD, reg.num = 1, and
96
 * index = 3, we'll emit "dcl_texcoord3 v1".
97
 */
98
static boolean
99
emit_decl(struct svga_shader_emitter *emit,
100
          SVGA3dShaderDestToken reg,
101
          unsigned usage,
102
          unsigned index)
103
{
104
   SVGA3DOpDclArgs dcl;
105
   SVGA3dShaderInstToken opcode;
106
 
107
   /* check values against bitfield sizes */
108
   assert(index < 16);
109
   assert(usage <= SVGA3D_DECLUSAGE_MAX);
110
 
111
   opcode = inst_token( SVGA3DOP_DCL );
112
   dcl.values[0] = 0;
113
   dcl.values[1] = 0;
114
 
115
   dcl.dst = reg;
116
   dcl.usage = usage;
117
   dcl.index = index;
118
   dcl.values[0] |= 1<<31;
119
 
120
   return (emit_instruction(emit, opcode) &&
121
           svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
122
}
123
 
124
 
125
/**
126
 * Emit declaration for PS front/back-face input register.
127
 */
128
static boolean
129
emit_vface_decl(struct svga_shader_emitter *emit)
130
{
131
   if (!emit->emitted_vface) {
132
      SVGA3dShaderDestToken reg =
133
         dst_register(SVGA3DREG_MISCTYPE, SVGA3DMISCREG_FACE);
134
 
135
      if (!emit_decl( emit, reg, 0, 0 ))
136
         return FALSE;
137
 
138
      emit->emitted_vface = TRUE;
139
   }
140
   return TRUE;
141
}
142
 
143
 
144
/**
145
 * Emit PS input register to pass depth/fog coordinates.
146
 * Note that this always goes into texcoord[0].
147
 */
148
static boolean
149
ps30_input_emit_depth_fog( struct svga_shader_emitter *emit,
150
                           struct src_register *out )
151
{
152
   struct src_register reg;
153
 
154
   if (emit->emitted_depth_fog) {
155
      *out = emit->ps_depth_fog;
156
      return TRUE;
157
   }
158
 
159
   if (emit->ps30_input_count >= SVGA3D_INPUTREG_MAX)
160
      return FALSE;
161
 
162
   reg = src_register( SVGA3DREG_INPUT,
163
                       emit->ps30_input_count++ );
164
 
165
   *out = emit->ps_depth_fog = reg;
166
 
167
   emit->emitted_depth_fog = TRUE;
168
 
169
   return emit_decl( emit, dst( reg ), SVGA3D_DECLUSAGE_TEXCOORD, 0 );
170
}
171
 
172
 
173
/**
174
 * Process a PS input declaration.
175
 * We'll emit a declaration like "dcl_texcoord1 v2"
176
 */
177
static boolean
178
ps30_input(struct svga_shader_emitter *emit,
179
           struct tgsi_declaration_semantic semantic,
180
           unsigned idx)
181
{
182
   unsigned usage, index;
183
   SVGA3dShaderDestToken reg;
184
 
185
   if (semantic.Name == TGSI_SEMANTIC_POSITION) {
186
 
187
      emit->ps_true_pos = src_register( SVGA3DREG_MISCTYPE,
188
                                        SVGA3DMISCREG_POSITION );
189
      emit->ps_true_pos.base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X,
190
                                                          TGSI_SWIZZLE_Y,
191
                                                          TGSI_SWIZZLE_Y,
192
                                                          TGSI_SWIZZLE_Y );
193
      reg = writemask( dst(emit->ps_true_pos),
194
                       TGSI_WRITEMASK_XY );
195
      emit->ps_reads_pos = TRUE;
196
 
197
      if (emit->info.reads_z) {
198
         emit->ps_temp_pos = dst_register( SVGA3DREG_TEMP,
199
                                           emit->nr_hw_temp );
200
 
201
         emit->input_map[idx] = src_register( SVGA3DREG_TEMP,
202
                                              emit->nr_hw_temp );
203
         emit->nr_hw_temp++;
204
 
205
         if (!ps30_input_emit_depth_fog( emit, &emit->ps_depth_pos ))
206
            return FALSE;
207
 
208
         emit->ps_depth_pos.base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_Z,
209
                                                              TGSI_SWIZZLE_Z,
210
                                                              TGSI_SWIZZLE_Z,
211
                                                              TGSI_SWIZZLE_W );
212
      }
213
      else {
214
         emit->input_map[idx] = emit->ps_true_pos;
215
      }
216
 
217
      return emit_decl( emit, reg, 0, 0 );
218
   }
219
   else if (emit->key.fkey.light_twoside &&
220
            (semantic.Name == TGSI_SEMANTIC_COLOR)) {
221
 
222
      if (!translate_vs_ps_semantic( emit, semantic, &usage, &index ))
223
         return FALSE;
224
 
225
      emit->internal_color_idx[emit->internal_color_count] = idx;
226
      emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count );
227
      emit->ps30_input_count++;
228
      emit->internal_color_count++;
229
 
230
      reg = dst( emit->input_map[idx] );
231
 
232
      if (!emit_decl( emit, reg, usage, index ))
233
         return FALSE;
234
 
235
      semantic.Name = TGSI_SEMANTIC_BCOLOR;
236
      if (!translate_vs_ps_semantic( emit, semantic, &usage, &index ))
237
         return FALSE;
238
 
239
      if (emit->ps30_input_count >= SVGA3D_INPUTREG_MAX)
240
         return FALSE;
241
 
242
      reg = dst_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
243
 
244
      if (!emit_decl( emit, reg, usage, index ))
245
         return FALSE;
246
 
247
      if (!emit_vface_decl( emit ))
248
         return FALSE;
249
 
250
      return TRUE;
251
   }
252
   else if (semantic.Name == TGSI_SEMANTIC_FACE) {
253
      if (!emit_vface_decl( emit ))
254
         return FALSE;
255
      emit->emit_frontface = TRUE;
256
      emit->internal_frontface_idx = idx;
257
      return TRUE;
258
   }
259
   else if (semantic.Name == TGSI_SEMANTIC_FOG) {
260
 
261
      assert(semantic.Index == 0);
262
 
263
      if (!ps30_input_emit_depth_fog( emit, &emit->input_map[idx] ))
264
         return FALSE;
265
 
266
      emit->input_map[idx].base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X,
267
                                                             TGSI_SWIZZLE_X,
268
                                                             TGSI_SWIZZLE_X,
269
                                                             TGSI_SWIZZLE_X );
270
 
271
      return TRUE;
272
   }
273
   else {
274
 
275
      if (!translate_vs_ps_semantic( emit, semantic, &usage, &index ))
276
         return FALSE;
277
 
278
      if (emit->ps30_input_count >= SVGA3D_INPUTREG_MAX)
279
         return FALSE;
280
 
281
      emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count++ );
282
      reg = dst( emit->input_map[idx] );
283
 
284
      if (!emit_decl( emit, reg, usage, index ))
285
         return FALSE;
286
 
287
      if (semantic.Name == TGSI_SEMANTIC_GENERIC &&
288
          emit->key.fkey.sprite_origin_lower_left &&
289
          index >= 1 &&
290
          emit->key.fkey.tex[index - 1].sprite_texgen) {
291
         /* This is a sprite texture coord with lower-left origin.
292
          * We need to invert the texture T coordinate since the SVGA3D
293
          * device only supports an upper-left origin.
294
          */
295
         unsigned unit = index - 1;
296
 
297
         emit->inverted_texcoords |= (1 << unit);
298
 
299
         /* save original texcoord reg */
300
         emit->ps_true_texcoord[unit] = emit->input_map[idx];
301
 
302
         /* this temp register will be the results of the MAD instruction */
303
         emit->ps_inverted_texcoord[unit] =
304
            src_register(SVGA3DREG_TEMP, emit->nr_hw_temp);
305
         emit->nr_hw_temp++;
306
 
307
         emit->ps_inverted_texcoord_input[unit] = idx;
308
 
309
         /* replace input_map entry with the temp register */
310
         emit->input_map[idx] = emit->ps_inverted_texcoord[unit];
311
      }
312
 
313
      return TRUE;
314
   }
315
 
316
}
317
 
318
 
319
/**
320
 * Process a PS output declaration.
321
 * Note that we don't actually emit a SVGA3DOpDcl for PS outputs.
322
 * \idx  register index, such as OUT[2] (not semantic index)
323
 */
324
static boolean
325
ps30_output(struct svga_shader_emitter *emit,
326
            struct tgsi_declaration_semantic semantic,
327
            unsigned idx)
328
{
329
   switch (semantic.Name) {
330
   case TGSI_SEMANTIC_COLOR:
331
      if (emit->unit == PIPE_SHADER_FRAGMENT) {
332
         if (emit->key.fkey.white_fragments) {
333
            /* Used for XOR logicop mode */
334
            emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
335
                                                  emit->nr_hw_temp++ );
336
            emit->temp_color_output[idx] = emit->output_map[idx];
337
            emit->true_color_output[idx] = dst_register(SVGA3DREG_COLOROUT,
338
                                                        semantic.Index);
339
         }
340
         else if (emit->key.fkey.write_color0_to_n_cbufs) {
341
            /* We'll write color output [0] to all render targets.
342
             * Prepare all the output registers here, but only when the
343
             * semantic.Index == 0 so we don't do this more than once.
344
             */
345
            if (semantic.Index == 0) {
346
               unsigned i;
347
               for (i = 0; i < emit->key.fkey.write_color0_to_n_cbufs; i++) {
348
                  emit->output_map[idx+i] = dst_register(SVGA3DREG_TEMP,
349
                                                     emit->nr_hw_temp++);
350
                  emit->temp_color_output[i] = emit->output_map[idx+i];
351
                  emit->true_color_output[i] = dst_register(SVGA3DREG_COLOROUT,
352
                                                            i);
353
               }
354
            }
355
         }
356
         else {
357
            emit->output_map[idx] =
358
               dst_register(SVGA3DREG_COLOROUT, semantic.Index);
359
         }
360
      }
361
      else {
362
         emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,
363
                                               semantic.Index );
364
      }
365
      break;
366
   case TGSI_SEMANTIC_POSITION:
367
      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
368
                                            emit->nr_hw_temp++ );
369
      emit->temp_pos = emit->output_map[idx];
370
      emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT,
371
                                     semantic.Index );
372
      break;
373
   default:
374
      assert(0);
375
      /* A wild stab in the dark. */
376
      emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, 0 );
377
      break;
378
   }
379
 
380
   return TRUE;
381
}
382
 
383
 
384
/**
385
 * Declare a VS input register.
386
 * We still make up the input semantics the same as in 2.0
387
 */
388
static boolean
389
vs30_input(struct svga_shader_emitter *emit,
390
           struct tgsi_declaration_semantic semantic,
391
           unsigned idx)
392
{
393
   SVGA3DOpDclArgs dcl;
394
   SVGA3dShaderInstToken opcode;
395
   unsigned usage, index;
396
 
397
   opcode = inst_token( SVGA3DOP_DCL );
398
   dcl.values[0] = 0;
399
   dcl.values[1] = 0;
400
 
401
   emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx );
402
   dcl.dst = dst_register( SVGA3DREG_INPUT, idx );
403
 
404
   assert(dcl.dst.reserved0);
405
 
406
   svga_generate_vdecl_semantics( idx, &usage, &index );
407
 
408
   dcl.usage = usage;
409
   dcl.index = index;
410
   dcl.values[0] |= 1<<31;
411
 
412
   return (emit_instruction(emit, opcode) &&
413
           svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
414
}
415
 
416
 
417
/**
418
 * Declare VS output for holding depth/fog.
419
 */
420
static boolean
421
vs30_output_emit_depth_fog(struct svga_shader_emitter *emit,
422
                           SVGA3dShaderDestToken *out)
423
{
424
   SVGA3dShaderDestToken reg;
425
 
426
   if (emit->emitted_depth_fog) {
427
      *out = emit->vs_depth_fog;
428
      return TRUE;
429
   }
430
 
431
   reg = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ );
432
 
433
   *out = emit->vs_depth_fog = reg;
434
 
435
   emit->emitted_depth_fog = TRUE;
436
 
437
   return emit_decl( emit, reg, SVGA3D_DECLUSAGE_TEXCOORD, 0 );
438
}
439
 
440
 
441
/**
442
 * Declare a VS output.
443
 * VS3.0 outputs have proper declarations and semantic info for
444
 * matching against PS inputs.
445
 */
446
static boolean
447
vs30_output(struct svga_shader_emitter *emit,
448
            struct tgsi_declaration_semantic semantic,
449
            unsigned idx)
450
{
451
   SVGA3DOpDclArgs dcl;
452
   SVGA3dShaderInstToken opcode;
453
   unsigned usage, index;
454
 
455
   opcode = inst_token( SVGA3DOP_DCL );
456
   dcl.values[0] = 0;
457
   dcl.values[1] = 0;
458
 
459
   if (!translate_vs_ps_semantic( emit, semantic, &usage, &index ))
460
      return FALSE;
461
 
462
   if (emit->vs30_output_count >= SVGA3D_OUTPUTREG_MAX)
463
      return FALSE;
464
 
465
   dcl.dst = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ );
466
   dcl.usage = usage;
467
   dcl.index = index;
468
   dcl.values[0] |= 1<<31;
469
 
470
   if (semantic.Name == TGSI_SEMANTIC_POSITION) {
471
      assert(idx == 0);
472
      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
473
                                            emit->nr_hw_temp++ );
474
      emit->temp_pos = emit->output_map[idx];
475
      emit->true_pos = dcl.dst;
476
 
477
      /* Grab an extra output for the depth output */
478
      if (!vs30_output_emit_depth_fog( emit, &emit->depth_pos ))
479
         return FALSE;
480
 
481
   }
482
   else if (semantic.Name == TGSI_SEMANTIC_PSIZE) {
483
      emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
484
                                            emit->nr_hw_temp++ );
485
      emit->temp_psiz = emit->output_map[idx];
486
 
487
      /* This has the effect of not declaring psiz (below) and not
488
       * emitting the final MOV to true_psiz in the postamble.
489
       */
490
      if (!emit->key.vkey.allow_psiz)
491
         return TRUE;
492
 
493
      emit->true_psiz = dcl.dst;
494
   }
495
   else if (semantic.Name == TGSI_SEMANTIC_FOG) {
496
      /*
497
       * Fog is shared with depth.
498
       * So we need to decrement out_count since emit_depth_fog will increment it.
499
       */
500
      emit->vs30_output_count--;
501
 
502
      if (!vs30_output_emit_depth_fog( emit, &emit->output_map[idx] ))
503
         return FALSE;
504
 
505
      return TRUE;
506
   }
507
   else {
508
      emit->output_map[idx] = dcl.dst;
509
   }
510
 
511
   return (emit_instruction(emit, opcode) &&
512
           svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
513
}
514
 
515
 
516
/** Translate PIPE_TEXTURE_x to SVGA3DSAMP_x */
517
static ubyte
518
svga_tgsi_sampler_type(const struct svga_shader_emitter *emit, int idx)
519
{
520
   switch (emit->key.fkey.tex[idx].texture_target) {
521
   case PIPE_TEXTURE_1D:
522
      return SVGA3DSAMP_2D;
523
   case PIPE_TEXTURE_2D:
524
   case PIPE_TEXTURE_RECT:
525
      return SVGA3DSAMP_2D;
526
   case PIPE_TEXTURE_3D:
527
      return SVGA3DSAMP_VOLUME;
528
   case PIPE_TEXTURE_CUBE:
529
      return SVGA3DSAMP_CUBE;
530
   }
531
 
532
   return SVGA3DSAMP_UNKNOWN;
533
}
534
 
535
 
536
static boolean
537
ps30_sampler( struct svga_shader_emitter *emit,
538
              struct tgsi_declaration_semantic semantic,
539
              unsigned idx )
540
{
541
   SVGA3DOpDclArgs dcl;
542
   SVGA3dShaderInstToken opcode;
543
 
544
   opcode = inst_token( SVGA3DOP_DCL );
545
   dcl.values[0] = 0;
546
   dcl.values[1] = 0;
547
 
548
   dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx );
549
   dcl.type = svga_tgsi_sampler_type( emit, idx );
550
   dcl.values[0] |= 1<<31;
551
 
552
   return (emit_instruction(emit, opcode) &&
553
           svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values)));
554
}
555
 
556
 
557
boolean
558
svga_translate_decl_sm30( struct svga_shader_emitter *emit,
559
                          const struct tgsi_full_declaration *decl )
560
{
561
   unsigned first = decl->Range.First;
562
   unsigned last = decl->Range.Last;
563
   unsigned idx;
564
 
565
   for( idx = first; idx <= last; idx++ ) {
566
      boolean ok;
567
 
568
      switch (decl->Declaration.File) {
569
      case TGSI_FILE_SAMPLER:
570
         assert (emit->unit == PIPE_SHADER_FRAGMENT);
571
         ok = ps30_sampler( emit, decl->Semantic, idx );
572
         break;
573
 
574
      case TGSI_FILE_INPUT:
575
         if (emit->unit == PIPE_SHADER_VERTEX)
576
            ok = vs30_input( emit, decl->Semantic, idx );
577
         else
578
            ok = ps30_input( emit, decl->Semantic, idx );
579
         break;
580
 
581
      case TGSI_FILE_OUTPUT:
582
         if (emit->unit == PIPE_SHADER_VERTEX)
583
            ok = vs30_output( emit, decl->Semantic, idx );
584
         else
585
            ok = ps30_output( emit, decl->Semantic, idx );
586
         break;
587
 
588
      default:
589
         /* don't need to declare other vars */
590
         ok = TRUE;
591
      }
592
 
593
      if (!ok)
594
         return FALSE;
595
   }
596
 
597
   return TRUE;
598
}