1 /**********************************************************
2 * Copyright 1998-2013 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 * @file svga_tgsi_vgpu10.c
28 *
29 * TGSI -> VGPU10 shader translation.
30 *
31 * \author Mingcheng Chen
32 * \author Brian Paul
33 */
34
35 #include "pipe/p_compiler.h"
36 #include "pipe/p_shader_tokens.h"
37 #include "pipe/p_defines.h"
38 #include "tgsi/tgsi_build.h"
39 #include "tgsi/tgsi_dump.h"
40 #include "tgsi/tgsi_info.h"
41 #include "tgsi/tgsi_parse.h"
42 #include "tgsi/tgsi_scan.h"
43 #include "tgsi/tgsi_two_side.h"
44 #include "tgsi/tgsi_aa_point.h"
45 #include "tgsi/tgsi_util.h"
46 #include "util/u_math.h"
47 #include "util/u_memory.h"
48 #include "util/u_bitmask.h"
49 #include "util/u_debug.h"
50 #include "util/u_pstipple.h"
51
52 #include "svga_context.h"
53 #include "svga_debug.h"
54 #include "svga_link.h"
55 #include "svga_shader.h"
56 #include "svga_tgsi.h"
57
58 #include "VGPU10ShaderTokens.h"
59
60
61 #define INVALID_INDEX 99999
62 #define MAX_INTERNAL_TEMPS 3
63 #define MAX_SYSTEM_VALUES 4
64 #define MAX_IMMEDIATE_COUNT \
65 (VGPU10_MAX_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT/4)
66 #define MAX_TEMP_ARRAYS 64 /* Enough? */
67
68
69 /**
70 * Clipping is complicated. There's four different cases which we
71 * handle during VS/GS shader translation:
72 */
73 enum clipping_mode
74 {
75 CLIP_NONE, /**< No clipping enabled */
76 CLIP_LEGACY, /**< The shader has no clipping declarations or code but
77 * one or more user-defined clip planes are enabled. We
78 * generate extra code to emit clip distances.
79 */
80 CLIP_DISTANCE, /**< The shader already declares clip distance output
81 * registers and has code to write to them.
82 */
83 CLIP_VERTEX /**< The shader declares a clip vertex output register and
84 * has code that writes to the register. We convert the
85 * clipvertex position into one or more clip distances.
86 */
87 };
88
89
90 struct svga_shader_emitter_v10
91 {
92 /* The token output buffer */
93 unsigned size;
94 char *buf;
95 char *ptr;
96
97 /* Information about the shader and state (does not change) */
98 struct svga_compile_key key;
99 struct tgsi_shader_info info;
100 unsigned unit;
101
102 unsigned inst_start_token;
103 boolean discard_instruction; /**< throw away current instruction? */
104
105 union tgsi_immediate_data immediates[MAX_IMMEDIATE_COUNT][4];
106 unsigned num_immediates; /**< Number of immediates emitted */
107 unsigned common_immediate_pos[8]; /**< literals for common immediates */
108 unsigned num_common_immediates;
109 boolean immediates_emitted;
110
111 unsigned num_outputs; /**< include any extra outputs */
112 /** The first extra output is reserved for
113 * non-adjusted vertex position for
114 * stream output purpose
115 */
116
117 /* Temporary Registers */
118 unsigned num_shader_temps; /**< num of temps used by original shader */
119 unsigned internal_temp_count; /**< currently allocated internal temps */
120 struct {
121 unsigned start, size;
122 } temp_arrays[MAX_TEMP_ARRAYS];
123 unsigned num_temp_arrays;
124
125 /** Map TGSI temp registers to VGPU10 temp array IDs and indexes */
126 struct {
127 unsigned arrayId, index;
128 } temp_map[VGPU10_MAX_TEMPS]; /**< arrayId, element */
129
130 /** Number of constants used by original shader for each constant buffer.
131 * The size should probably always match with that of svga_state.constbufs.
132 */
133 unsigned num_shader_consts[SVGA_MAX_CONST_BUFS];
134
135 /* Samplers */
136 unsigned num_samplers;
137 ubyte sampler_target[PIPE_MAX_SAMPLERS]; /**< TGSI_TEXTURE_x */
138 ubyte sampler_return_type[PIPE_MAX_SAMPLERS]; /**< TGSI_RETURN_TYPE_x */
139
140 /* Address regs (really implemented with temps) */
141 unsigned num_address_regs;
142 unsigned address_reg_index[MAX_VGPU10_ADDR_REGS];
143
144 /* Output register usage masks */
145 ubyte output_usage_mask[PIPE_MAX_SHADER_OUTPUTS];
146
147 /* To map TGSI system value index to VGPU shader input indexes */
148 ubyte system_value_indexes[MAX_SYSTEM_VALUES];
149
150 struct {
151 /* vertex position scale/translation */
152 unsigned out_index; /**< the real position output reg */
153 unsigned tmp_index; /**< the fake/temp position output reg */
154 unsigned so_index; /**< the non-adjusted position output reg */
155 unsigned prescale_scale_index, prescale_trans_index;
156 boolean need_prescale;
157 } vposition;
158
159 /* For vertex shaders only */
160 struct {
161 /* viewport constant */
162 unsigned viewport_index;
163
164 /* temp index of adjusted vertex attributes */
165 unsigned adjusted_input[PIPE_MAX_SHADER_INPUTS];
166 } vs;
167
168 /* For fragment shaders only */
169 struct {
170 /* apha test */
171 unsigned color_out_index[PIPE_MAX_COLOR_BUFS]; /**< the real color output regs */
172 unsigned color_tmp_index; /**< fake/temp color output reg */
173 unsigned alpha_ref_index; /**< immediate constant for alpha ref */
174
175 /* front-face */
176 unsigned face_input_index; /**< real fragment shader face reg (bool) */
177 unsigned face_tmp_index; /**< temp face reg converted to -1 / +1 */
178
179 unsigned pstipple_sampler_unit;
180
181 unsigned fragcoord_input_index; /**< real fragment position input reg */
182 unsigned fragcoord_tmp_index; /**< 1/w modified position temp reg */
183 } fs;
184
185 /* For geometry shaders only */
186 struct {
187 VGPU10_PRIMITIVE prim_type;/**< VGPU10 primitive type */
188 VGPU10_PRIMITIVE_TOPOLOGY prim_topology; /**< VGPU10 primitive topology */
189 unsigned input_size; /**< size of input arrays */
190 unsigned prim_id_index; /**< primitive id register index */
191 unsigned max_out_vertices; /**< maximum number of output vertices */
192 } gs;
193
194 /* For vertex or geometry shaders */
195 enum clipping_mode clip_mode;
196 unsigned clip_dist_out_index; /**< clip distance output register index */
197 unsigned clip_dist_tmp_index; /**< clip distance temporary register */
198 unsigned clip_dist_so_index; /**< clip distance shadow copy */
199
200 /** Index of temporary holding the clipvertex coordinate */
201 unsigned clip_vertex_out_index; /**< clip vertex output register index */
202 unsigned clip_vertex_tmp_index; /**< clip vertex temporary index */
203
204 /* user clip plane constant slot indexes */
205 unsigned clip_plane_const[PIPE_MAX_CLIP_PLANES];
206
207 unsigned num_output_writes;
208 boolean constant_color_output;
209
210 boolean uses_flat_interp;
211
212 /* For all shaders: const reg index for RECT coord scaling */
213 unsigned texcoord_scale_index[PIPE_MAX_SAMPLERS];
214
215 /* For all shaders: const reg index for texture buffer size */
216 unsigned texture_buffer_size_index[PIPE_MAX_SAMPLERS];
217
218 /* VS/GS/FS Linkage info */
219 struct shader_linkage linkage;
220
221 bool register_overflow; /**< Set if we exceed a VGPU10 register limit */
222 };
223
224
225 static boolean
226 emit_post_helpers(struct svga_shader_emitter_v10 *emit);
227
228 static boolean
229 emit_vertex(struct svga_shader_emitter_v10 *emit,
230 const struct tgsi_full_instruction *inst);
231
232 static char err_buf[128];
233
234 static boolean
expand(struct svga_shader_emitter_v10 * emit)235 expand(struct svga_shader_emitter_v10 *emit)
236 {
237 char *new_buf;
238 unsigned newsize = emit->size * 2;
239
240 if (emit->buf != err_buf)
241 new_buf = REALLOC(emit->buf, emit->size, newsize);
242 else
243 new_buf = NULL;
244
245 if (!new_buf) {
246 emit->ptr = err_buf;
247 emit->buf = err_buf;
248 emit->size = sizeof(err_buf);
249 return FALSE;
250 }
251
252 emit->size = newsize;
253 emit->ptr = new_buf + (emit->ptr - emit->buf);
254 emit->buf = new_buf;
255 return TRUE;
256 }
257
258 /**
259 * Create and initialize a new svga_shader_emitter_v10 object.
260 */
261 static struct svga_shader_emitter_v10 *
alloc_emitter(void)262 alloc_emitter(void)
263 {
264 struct svga_shader_emitter_v10 *emit = CALLOC(1, sizeof(*emit));
265
266 if (!emit)
267 return NULL;
268
269 /* to initialize the output buffer */
270 emit->size = 512;
271 if (!expand(emit)) {
272 FREE(emit);
273 return NULL;
274 }
275 return emit;
276 }
277
278 /**
279 * Free an svga_shader_emitter_v10 object.
280 */
281 static void
free_emitter(struct svga_shader_emitter_v10 * emit)282 free_emitter(struct svga_shader_emitter_v10 *emit)
283 {
284 assert(emit);
285 FREE(emit->buf); /* will be NULL if translation succeeded */
286 FREE(emit);
287 }
288
289 static inline boolean
reserve(struct svga_shader_emitter_v10 * emit,unsigned nr_dwords)290 reserve(struct svga_shader_emitter_v10 *emit,
291 unsigned nr_dwords)
292 {
293 while (emit->ptr - emit->buf + nr_dwords * sizeof(uint32) >= emit->size) {
294 if (!expand(emit))
295 return FALSE;
296 }
297
298 return TRUE;
299 }
300
301 static boolean
emit_dword(struct svga_shader_emitter_v10 * emit,uint32 dword)302 emit_dword(struct svga_shader_emitter_v10 *emit, uint32 dword)
303 {
304 if (!reserve(emit, 1))
305 return FALSE;
306
307 *(uint32 *)emit->ptr = dword;
308 emit->ptr += sizeof dword;
309 return TRUE;
310 }
311
312 static boolean
emit_dwords(struct svga_shader_emitter_v10 * emit,const uint32 * dwords,unsigned nr)313 emit_dwords(struct svga_shader_emitter_v10 *emit,
314 const uint32 *dwords,
315 unsigned nr)
316 {
317 if (!reserve(emit, nr))
318 return FALSE;
319
320 memcpy(emit->ptr, dwords, nr * sizeof *dwords);
321 emit->ptr += nr * sizeof *dwords;
322 return TRUE;
323 }
324
325 /** Return the number of tokens in the emitter's buffer */
326 static unsigned
emit_get_num_tokens(const struct svga_shader_emitter_v10 * emit)327 emit_get_num_tokens(const struct svga_shader_emitter_v10 *emit)
328 {
329 return (emit->ptr - emit->buf) / sizeof(unsigned);
330 }
331
332
333 /**
334 * Check for register overflow. If we overflow we'll set an
335 * error flag. This function can be called for register declarations
336 * or use as src/dst instruction operands.
337 * \param type register type. One of VGPU10_OPERAND_TYPE_x
338 or VGPU10_OPCODE_DCL_x
339 * \param index the register index
340 */
341 static void
check_register_index(struct svga_shader_emitter_v10 * emit,unsigned operandType,unsigned index)342 check_register_index(struct svga_shader_emitter_v10 *emit,
343 unsigned operandType, unsigned index)
344 {
345 bool overflow_before = emit->register_overflow;
346
347 switch (operandType) {
348 case VGPU10_OPERAND_TYPE_TEMP:
349 case VGPU10_OPERAND_TYPE_INDEXABLE_TEMP:
350 case VGPU10_OPCODE_DCL_TEMPS:
351 if (index >= VGPU10_MAX_TEMPS) {
352 emit->register_overflow = TRUE;
353 }
354 break;
355 case VGPU10_OPERAND_TYPE_CONSTANT_BUFFER:
356 case VGPU10_OPCODE_DCL_CONSTANT_BUFFER:
357 if (index >= VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT) {
358 emit->register_overflow = TRUE;
359 }
360 break;
361 case VGPU10_OPERAND_TYPE_INPUT:
362 case VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID:
363 case VGPU10_OPCODE_DCL_INPUT:
364 case VGPU10_OPCODE_DCL_INPUT_SGV:
365 case VGPU10_OPCODE_DCL_INPUT_SIV:
366 case VGPU10_OPCODE_DCL_INPUT_PS:
367 case VGPU10_OPCODE_DCL_INPUT_PS_SGV:
368 case VGPU10_OPCODE_DCL_INPUT_PS_SIV:
369 if ((emit->unit == PIPE_SHADER_VERTEX &&
370 index >= VGPU10_MAX_VS_INPUTS) ||
371 (emit->unit == PIPE_SHADER_GEOMETRY &&
372 index >= VGPU10_MAX_GS_INPUTS) ||
373 (emit->unit == PIPE_SHADER_FRAGMENT &&
374 index >= VGPU10_MAX_FS_INPUTS)) {
375 emit->register_overflow = TRUE;
376 }
377 break;
378 case VGPU10_OPERAND_TYPE_OUTPUT:
379 case VGPU10_OPCODE_DCL_OUTPUT:
380 case VGPU10_OPCODE_DCL_OUTPUT_SGV:
381 case VGPU10_OPCODE_DCL_OUTPUT_SIV:
382 if ((emit->unit == PIPE_SHADER_VERTEX &&
383 index >= VGPU10_MAX_VS_OUTPUTS) ||
384 (emit->unit == PIPE_SHADER_GEOMETRY &&
385 index >= VGPU10_MAX_GS_OUTPUTS) ||
386 (emit->unit == PIPE_SHADER_FRAGMENT &&
387 index >= VGPU10_MAX_FS_OUTPUTS)) {
388 emit->register_overflow = TRUE;
389 }
390 break;
391 case VGPU10_OPERAND_TYPE_SAMPLER:
392 case VGPU10_OPCODE_DCL_SAMPLER:
393 if (index >= VGPU10_MAX_SAMPLERS) {
394 emit->register_overflow = TRUE;
395 }
396 break;
397 case VGPU10_OPERAND_TYPE_RESOURCE:
398 case VGPU10_OPCODE_DCL_RESOURCE:
399 if (index >= VGPU10_MAX_RESOURCES) {
400 emit->register_overflow = TRUE;
401 }
402 break;
403 case VGPU10_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER:
404 if (index >= MAX_IMMEDIATE_COUNT) {
405 emit->register_overflow = TRUE;
406 }
407 break;
408 default:
409 assert(0);
410 ; /* nothing */
411 }
412
413 if (emit->register_overflow && !overflow_before) {
414 debug_printf("svga: vgpu10 register overflow (reg %u, index %u)\n",
415 operandType, index);
416 }
417 }
418
419
420 /**
421 * Examine misc state to determine the clipping mode.
422 */
423 static void
determine_clipping_mode(struct svga_shader_emitter_v10 * emit)424 determine_clipping_mode(struct svga_shader_emitter_v10 *emit)
425 {
426 if (emit->info.num_written_clipdistance > 0) {
427 emit->clip_mode = CLIP_DISTANCE;
428 }
429 else if (emit->info.writes_clipvertex) {
430 emit->clip_mode = CLIP_VERTEX;
431 }
432 else if (emit->key.clip_plane_enable) {
433 emit->clip_mode = CLIP_LEGACY;
434 }
435 else {
436 emit->clip_mode = CLIP_NONE;
437 }
438 }
439
440
441 /**
442 * For clip distance register declarations and clip distance register
443 * writes we need to mask the declaration usage or instruction writemask
444 * (respectively) against the set of the really-enabled clipping planes.
445 *
446 * The piglit test spec/glsl-1.30/execution/clipping/vs-clip-distance-enables
447 * has a VS that writes to all 8 clip distance registers, but the plane enable
448 * flags are a subset of that.
449 *
450 * This function is used to apply the plane enable flags to the register
451 * declaration or instruction writemask.
452 *
453 * \param writemask the declaration usage mask or instruction writemask
454 * \param clip_reg_index which clip plane register is being declared/written.
455 * The legal values are 0 and 1 (two clip planes per
456 * register, for a total of 8 clip planes)
457 */
458 static unsigned
apply_clip_plane_mask(struct svga_shader_emitter_v10 * emit,unsigned writemask,unsigned clip_reg_index)459 apply_clip_plane_mask(struct svga_shader_emitter_v10 *emit,
460 unsigned writemask, unsigned clip_reg_index)
461 {
462 unsigned shift;
463
464 assert(clip_reg_index < 2);
465
466 /* four clip planes per clip register: */
467 shift = clip_reg_index * 4;
468 writemask &= ((emit->key.clip_plane_enable >> shift) & 0xf);
469
470 return writemask;
471 }
472
473
474 /**
475 * Translate gallium shader type into VGPU10 type.
476 */
477 static VGPU10_PROGRAM_TYPE
translate_shader_type(unsigned type)478 translate_shader_type(unsigned type)
479 {
480 switch (type) {
481 case PIPE_SHADER_VERTEX:
482 return VGPU10_VERTEX_SHADER;
483 case PIPE_SHADER_GEOMETRY:
484 return VGPU10_GEOMETRY_SHADER;
485 case PIPE_SHADER_FRAGMENT:
486 return VGPU10_PIXEL_SHADER;
487 default:
488 assert(!"Unexpected shader type");
489 return VGPU10_VERTEX_SHADER;
490 }
491 }
492
493
494 /**
495 * Translate a TGSI_OPCODE_x into a VGPU10_OPCODE_x
496 * Note: we only need to translate the opcodes for "simple" instructions,
497 * as seen below. All other opcodes are handled/translated specially.
498 */
499 static VGPU10_OPCODE_TYPE
translate_opcode(unsigned opcode)500 translate_opcode(unsigned opcode)
501 {
502 switch (opcode) {
503 case TGSI_OPCODE_MOV:
504 return VGPU10_OPCODE_MOV;
505 case TGSI_OPCODE_MUL:
506 return VGPU10_OPCODE_MUL;
507 case TGSI_OPCODE_ADD:
508 return VGPU10_OPCODE_ADD;
509 case TGSI_OPCODE_DP3:
510 return VGPU10_OPCODE_DP3;
511 case TGSI_OPCODE_DP4:
512 return VGPU10_OPCODE_DP4;
513 case TGSI_OPCODE_MIN:
514 return VGPU10_OPCODE_MIN;
515 case TGSI_OPCODE_MAX:
516 return VGPU10_OPCODE_MAX;
517 case TGSI_OPCODE_MAD:
518 return VGPU10_OPCODE_MAD;
519 case TGSI_OPCODE_SQRT:
520 return VGPU10_OPCODE_SQRT;
521 case TGSI_OPCODE_FRC:
522 return VGPU10_OPCODE_FRC;
523 case TGSI_OPCODE_FLR:
524 return VGPU10_OPCODE_ROUND_NI;
525 case TGSI_OPCODE_FSEQ:
526 return VGPU10_OPCODE_EQ;
527 case TGSI_OPCODE_FSGE:
528 return VGPU10_OPCODE_GE;
529 case TGSI_OPCODE_FSNE:
530 return VGPU10_OPCODE_NE;
531 case TGSI_OPCODE_DDX:
532 return VGPU10_OPCODE_DERIV_RTX;
533 case TGSI_OPCODE_DDY:
534 return VGPU10_OPCODE_DERIV_RTY;
535 case TGSI_OPCODE_RET:
536 return VGPU10_OPCODE_RET;
537 case TGSI_OPCODE_DIV:
538 return VGPU10_OPCODE_DIV;
539 case TGSI_OPCODE_IDIV:
540 return VGPU10_OPCODE_IDIV;
541 case TGSI_OPCODE_DP2:
542 return VGPU10_OPCODE_DP2;
543 case TGSI_OPCODE_BRK:
544 return VGPU10_OPCODE_BREAK;
545 case TGSI_OPCODE_IF:
546 return VGPU10_OPCODE_IF;
547 case TGSI_OPCODE_ELSE:
548 return VGPU10_OPCODE_ELSE;
549 case TGSI_OPCODE_ENDIF:
550 return VGPU10_OPCODE_ENDIF;
551 case TGSI_OPCODE_CEIL:
552 return VGPU10_OPCODE_ROUND_PI;
553 case TGSI_OPCODE_I2F:
554 return VGPU10_OPCODE_ITOF;
555 case TGSI_OPCODE_NOT:
556 return VGPU10_OPCODE_NOT;
557 case TGSI_OPCODE_TRUNC:
558 return VGPU10_OPCODE_ROUND_Z;
559 case TGSI_OPCODE_SHL:
560 return VGPU10_OPCODE_ISHL;
561 case TGSI_OPCODE_AND:
562 return VGPU10_OPCODE_AND;
563 case TGSI_OPCODE_OR:
564 return VGPU10_OPCODE_OR;
565 case TGSI_OPCODE_XOR:
566 return VGPU10_OPCODE_XOR;
567 case TGSI_OPCODE_CONT:
568 return VGPU10_OPCODE_CONTINUE;
569 case TGSI_OPCODE_EMIT:
570 return VGPU10_OPCODE_EMIT;
571 case TGSI_OPCODE_ENDPRIM:
572 return VGPU10_OPCODE_CUT;
573 case TGSI_OPCODE_BGNLOOP:
574 return VGPU10_OPCODE_LOOP;
575 case TGSI_OPCODE_ENDLOOP:
576 return VGPU10_OPCODE_ENDLOOP;
577 case TGSI_OPCODE_ENDSUB:
578 return VGPU10_OPCODE_RET;
579 case TGSI_OPCODE_NOP:
580 return VGPU10_OPCODE_NOP;
581 case TGSI_OPCODE_BREAKC:
582 return VGPU10_OPCODE_BREAKC;
583 case TGSI_OPCODE_END:
584 return VGPU10_OPCODE_RET;
585 case TGSI_OPCODE_F2I:
586 return VGPU10_OPCODE_FTOI;
587 case TGSI_OPCODE_IMAX:
588 return VGPU10_OPCODE_IMAX;
589 case TGSI_OPCODE_IMIN:
590 return VGPU10_OPCODE_IMIN;
591 case TGSI_OPCODE_UDIV:
592 case TGSI_OPCODE_UMOD:
593 case TGSI_OPCODE_MOD:
594 return VGPU10_OPCODE_UDIV;
595 case TGSI_OPCODE_IMUL_HI:
596 return VGPU10_OPCODE_IMUL;
597 case TGSI_OPCODE_INEG:
598 return VGPU10_OPCODE_INEG;
599 case TGSI_OPCODE_ISHR:
600 return VGPU10_OPCODE_ISHR;
601 case TGSI_OPCODE_ISGE:
602 return VGPU10_OPCODE_IGE;
603 case TGSI_OPCODE_ISLT:
604 return VGPU10_OPCODE_ILT;
605 case TGSI_OPCODE_F2U:
606 return VGPU10_OPCODE_FTOU;
607 case TGSI_OPCODE_UADD:
608 return VGPU10_OPCODE_IADD;
609 case TGSI_OPCODE_U2F:
610 return VGPU10_OPCODE_UTOF;
611 case TGSI_OPCODE_UCMP:
612 return VGPU10_OPCODE_MOVC;
613 case TGSI_OPCODE_UMAD:
614 return VGPU10_OPCODE_UMAD;
615 case TGSI_OPCODE_UMAX:
616 return VGPU10_OPCODE_UMAX;
617 case TGSI_OPCODE_UMIN:
618 return VGPU10_OPCODE_UMIN;
619 case TGSI_OPCODE_UMUL:
620 case TGSI_OPCODE_UMUL_HI:
621 return VGPU10_OPCODE_UMUL;
622 case TGSI_OPCODE_USEQ:
623 return VGPU10_OPCODE_IEQ;
624 case TGSI_OPCODE_USGE:
625 return VGPU10_OPCODE_UGE;
626 case TGSI_OPCODE_USHR:
627 return VGPU10_OPCODE_USHR;
628 case TGSI_OPCODE_USLT:
629 return VGPU10_OPCODE_ULT;
630 case TGSI_OPCODE_USNE:
631 return VGPU10_OPCODE_INE;
632 case TGSI_OPCODE_SWITCH:
633 return VGPU10_OPCODE_SWITCH;
634 case TGSI_OPCODE_CASE:
635 return VGPU10_OPCODE_CASE;
636 case TGSI_OPCODE_DEFAULT:
637 return VGPU10_OPCODE_DEFAULT;
638 case TGSI_OPCODE_ENDSWITCH:
639 return VGPU10_OPCODE_ENDSWITCH;
640 case TGSI_OPCODE_FSLT:
641 return VGPU10_OPCODE_LT;
642 case TGSI_OPCODE_ROUND:
643 return VGPU10_OPCODE_ROUND_NE;
644 default:
645 assert(!"Unexpected TGSI opcode in translate_opcode()");
646 return VGPU10_OPCODE_NOP;
647 }
648 }
649
650
651 /**
652 * Translate a TGSI register file type into a VGPU10 operand type.
653 * \param array is the TGSI_FILE_TEMPORARY register an array?
654 */
655 static VGPU10_OPERAND_TYPE
translate_register_file(enum tgsi_file_type file,boolean array)656 translate_register_file(enum tgsi_file_type file, boolean array)
657 {
658 switch (file) {
659 case TGSI_FILE_CONSTANT:
660 return VGPU10_OPERAND_TYPE_CONSTANT_BUFFER;
661 case TGSI_FILE_INPUT:
662 return VGPU10_OPERAND_TYPE_INPUT;
663 case TGSI_FILE_OUTPUT:
664 return VGPU10_OPERAND_TYPE_OUTPUT;
665 case TGSI_FILE_TEMPORARY:
666 return array ? VGPU10_OPERAND_TYPE_INDEXABLE_TEMP
667 : VGPU10_OPERAND_TYPE_TEMP;
668 case TGSI_FILE_IMMEDIATE:
669 /* all immediates are 32-bit values at this time so
670 * VGPU10_OPERAND_TYPE_IMMEDIATE64 is not possible at this time.
671 */
672 return VGPU10_OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER;
673 case TGSI_FILE_SAMPLER:
674 return VGPU10_OPERAND_TYPE_SAMPLER;
675 case TGSI_FILE_SYSTEM_VALUE:
676 return VGPU10_OPERAND_TYPE_INPUT;
677
678 /* XXX TODO more cases to finish */
679
680 default:
681 assert(!"Bad tgsi register file!");
682 return VGPU10_OPERAND_TYPE_NULL;
683 }
684 }
685
686
687 /**
688 * Emit a null dst register
689 */
690 static void
emit_null_dst_register(struct svga_shader_emitter_v10 * emit)691 emit_null_dst_register(struct svga_shader_emitter_v10 *emit)
692 {
693 VGPU10OperandToken0 operand;
694
695 operand.value = 0;
696 operand.operandType = VGPU10_OPERAND_TYPE_NULL;
697 operand.numComponents = VGPU10_OPERAND_0_COMPONENT;
698
699 emit_dword(emit, operand.value);
700 }
701
702
703 /**
704 * If the given register is a temporary, return the array ID.
705 * Else return zero.
706 */
707 static unsigned
get_temp_array_id(const struct svga_shader_emitter_v10 * emit,unsigned file,unsigned index)708 get_temp_array_id(const struct svga_shader_emitter_v10 *emit,
709 unsigned file, unsigned index)
710 {
711 if (file == TGSI_FILE_TEMPORARY) {
712 return emit->temp_map[index].arrayId;
713 }
714 else {
715 return 0;
716 }
717 }
718
719
720 /**
721 * If the given register is a temporary, convert the index from a TGSI
722 * TEMPORARY index to a VGPU10 temp index.
723 */
724 static unsigned
remap_temp_index(const struct svga_shader_emitter_v10 * emit,unsigned file,unsigned index)725 remap_temp_index(const struct svga_shader_emitter_v10 *emit,
726 unsigned file, unsigned index)
727 {
728 if (file == TGSI_FILE_TEMPORARY) {
729 return emit->temp_map[index].index;
730 }
731 else {
732 return index;
733 }
734 }
735
736
737 /**
738 * Setup the operand0 fields related to indexing (1D, 2D, relative, etc).
739 * Note: the operandType field must already be initialized.
740 */
741 static VGPU10OperandToken0
setup_operand0_indexing(struct svga_shader_emitter_v10 * emit,VGPU10OperandToken0 operand0,unsigned file,boolean indirect,boolean index2D,unsigned tempArrayID)742 setup_operand0_indexing(struct svga_shader_emitter_v10 *emit,
743 VGPU10OperandToken0 operand0,
744 unsigned file,
745 boolean indirect, boolean index2D,
746 unsigned tempArrayID)
747 {
748 unsigned indexDim, index0Rep, index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
749
750 /*
751 * Compute index dimensions
752 */
753 if (operand0.operandType == VGPU10_OPERAND_TYPE_IMMEDIATE32 ||
754 operand0.operandType == VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID) {
755 /* there's no swizzle for in-line immediates */
756 indexDim = VGPU10_OPERAND_INDEX_0D;
757 assert(operand0.selectionMode == 0);
758 }
759 else {
760 if (index2D ||
761 tempArrayID > 0 ||
762 operand0.operandType == VGPU10_OPERAND_TYPE_CONSTANT_BUFFER) {
763 indexDim = VGPU10_OPERAND_INDEX_2D;
764 }
765 else {
766 indexDim = VGPU10_OPERAND_INDEX_1D;
767 }
768 }
769
770 /*
771 * Compute index representations (immediate, relative, etc).
772 */
773 if (tempArrayID > 0) {
774 assert(file == TGSI_FILE_TEMPORARY);
775 /* First index is the array ID, second index is the array element */
776 index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
777 if (indirect) {
778 index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE;
779 }
780 else {
781 index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
782 }
783 }
784 else if (indirect) {
785 if (file == TGSI_FILE_CONSTANT) {
786 /* index[0] indicates which constant buffer while index[1] indicates
787 * the position in the constant buffer.
788 */
789 index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
790 index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE;
791 }
792 else {
793 /* All other register files are 1-dimensional */
794 index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE;
795 }
796 }
797 else {
798 index0Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
799 index1Rep = VGPU10_OPERAND_INDEX_IMMEDIATE32;
800 }
801
802 operand0.indexDimension = indexDim;
803 operand0.index0Representation = index0Rep;
804 operand0.index1Representation = index1Rep;
805
806 return operand0;
807 }
808
809
810 /**
811 * Emit the operand for expressing an address register for indirect indexing.
812 * Note that the address register is really just a temp register.
813 * \param addr_reg_index which address register to use
814 */
815 static void
emit_indirect_register(struct svga_shader_emitter_v10 * emit,unsigned addr_reg_index)816 emit_indirect_register(struct svga_shader_emitter_v10 *emit,
817 unsigned addr_reg_index)
818 {
819 unsigned tmp_reg_index;
820 VGPU10OperandToken0 operand0;
821
822 assert(addr_reg_index < MAX_VGPU10_ADDR_REGS);
823
824 tmp_reg_index = emit->address_reg_index[addr_reg_index];
825
826 /* operand0 is a simple temporary register, selecting one component */
827 operand0.value = 0;
828 operand0.operandType = VGPU10_OPERAND_TYPE_TEMP;
829 operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
830 operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
831 operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
832 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE;
833 operand0.swizzleX = 0;
834 operand0.swizzleY = 1;
835 operand0.swizzleZ = 2;
836 operand0.swizzleW = 3;
837
838 emit_dword(emit, operand0.value);
839 emit_dword(emit, remap_temp_index(emit, TGSI_FILE_TEMPORARY, tmp_reg_index));
840 }
841
842
843 /**
844 * Translate the dst register of a TGSI instruction and emit VGPU10 tokens.
845 * \param emit the emitter context
846 * \param reg the TGSI dst register to translate
847 */
848 static void
emit_dst_register(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_dst_register * reg)849 emit_dst_register(struct svga_shader_emitter_v10 *emit,
850 const struct tgsi_full_dst_register *reg)
851 {
852 unsigned file = reg->Register.File;
853 unsigned index = reg->Register.Index;
854 const unsigned sem_name = emit->info.output_semantic_name[index];
855 const unsigned sem_index = emit->info.output_semantic_index[index];
856 unsigned writemask = reg->Register.WriteMask;
857 const unsigned indirect = reg->Register.Indirect;
858 const unsigned tempArrayId = get_temp_array_id(emit, file, index);
859 const unsigned index2d = reg->Register.Dimension;
860 VGPU10OperandToken0 operand0;
861
862 if (file == TGSI_FILE_OUTPUT) {
863 if (emit->unit == PIPE_SHADER_VERTEX ||
864 emit->unit == PIPE_SHADER_GEOMETRY) {
865 if (index == emit->vposition.out_index &&
866 emit->vposition.tmp_index != INVALID_INDEX) {
867 /* replace OUTPUT[POS] with TEMP[POS]. We need to store the
868 * vertex position result in a temporary so that we can modify
869 * it in the post_helper() code.
870 */
871 file = TGSI_FILE_TEMPORARY;
872 index = emit->vposition.tmp_index;
873 }
874 else if (sem_name == TGSI_SEMANTIC_CLIPDIST &&
875 emit->clip_dist_tmp_index != INVALID_INDEX) {
876 /* replace OUTPUT[CLIPDIST] with TEMP[CLIPDIST].
877 * We store the clip distance in a temporary first, then
878 * we'll copy it to the shadow copy and to CLIPDIST with the
879 * enabled planes mask in emit_clip_distance_instructions().
880 */
881 file = TGSI_FILE_TEMPORARY;
882 index = emit->clip_dist_tmp_index + sem_index;
883 }
884 else if (sem_name == TGSI_SEMANTIC_CLIPVERTEX &&
885 emit->clip_vertex_tmp_index != INVALID_INDEX) {
886 /* replace the CLIPVERTEX output register with a temporary */
887 assert(emit->clip_mode == CLIP_VERTEX);
888 assert(sem_index == 0);
889 file = TGSI_FILE_TEMPORARY;
890 index = emit->clip_vertex_tmp_index;
891 }
892 }
893 else if (emit->unit == PIPE_SHADER_FRAGMENT) {
894 if (sem_name == TGSI_SEMANTIC_POSITION) {
895 /* Fragment depth output register */
896 operand0.value = 0;
897 operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT_DEPTH;
898 operand0.indexDimension = VGPU10_OPERAND_INDEX_0D;
899 operand0.numComponents = VGPU10_OPERAND_1_COMPONENT;
900 emit_dword(emit, operand0.value);
901 return;
902 }
903 else if (index == emit->fs.color_out_index[0] &&
904 emit->fs.color_tmp_index != INVALID_INDEX) {
905 /* replace OUTPUT[COLOR] with TEMP[COLOR]. We need to store the
906 * fragment color result in a temporary so that we can read it
907 * it in the post_helper() code.
908 */
909 file = TGSI_FILE_TEMPORARY;
910 index = emit->fs.color_tmp_index;
911 }
912 else {
913 /* Typically, for fragment shaders, the output register index
914 * matches the color semantic index. But not when we write to
915 * the fragment depth register. In that case, OUT[0] will be
916 * fragdepth and OUT[1] will be the 0th color output. We need
917 * to use the semantic index for color outputs.
918 */
919 assert(sem_name == TGSI_SEMANTIC_COLOR);
920 index = emit->info.output_semantic_index[index];
921
922 emit->num_output_writes++;
923 }
924 }
925 }
926
927 /* init operand tokens to all zero */
928 operand0.value = 0;
929
930 operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
931
932 /* the operand has a writemask */
933 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
934
935 /* Which of the four dest components to write to. Note that we can use a
936 * simple assignment here since TGSI writemasks match VGPU10 writemasks.
937 */
938 STATIC_ASSERT(TGSI_WRITEMASK_X == VGPU10_OPERAND_4_COMPONENT_MASK_X);
939 operand0.mask = writemask;
940
941 /* translate TGSI register file type to VGPU10 operand type */
942 operand0.operandType = translate_register_file(file, tempArrayId > 0);
943
944 check_register_index(emit, operand0.operandType, index);
945
946 operand0 = setup_operand0_indexing(emit, operand0, file, indirect,
947 index2d, tempArrayId);
948
949 /* Emit tokens */
950 emit_dword(emit, operand0.value);
951 if (tempArrayId > 0) {
952 emit_dword(emit, tempArrayId);
953 }
954
955 emit_dword(emit, remap_temp_index(emit, file, index));
956
957 if (indirect) {
958 emit_indirect_register(emit, reg->Indirect.Index);
959 }
960 }
961
962
963 /**
964 * Translate a src register of a TGSI instruction and emit VGPU10 tokens.
965 */
966 static void
emit_src_register(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_src_register * reg)967 emit_src_register(struct svga_shader_emitter_v10 *emit,
968 const struct tgsi_full_src_register *reg)
969 {
970 unsigned file = reg->Register.File;
971 unsigned index = reg->Register.Index;
972 const unsigned indirect = reg->Register.Indirect;
973 const unsigned tempArrayId = get_temp_array_id(emit, file, index);
974 const unsigned index2d = reg->Register.Dimension;
975 const unsigned swizzleX = reg->Register.SwizzleX;
976 const unsigned swizzleY = reg->Register.SwizzleY;
977 const unsigned swizzleZ = reg->Register.SwizzleZ;
978 const unsigned swizzleW = reg->Register.SwizzleW;
979 const unsigned absolute = reg->Register.Absolute;
980 const unsigned negate = reg->Register.Negate;
981 bool is_prim_id = FALSE;
982
983 VGPU10OperandToken0 operand0;
984 VGPU10OperandToken1 operand1;
985
986 if (emit->unit == PIPE_SHADER_FRAGMENT &&
987 file == TGSI_FILE_INPUT) {
988 if (index == emit->fs.face_input_index) {
989 /* Replace INPUT[FACE] with TEMP[FACE] */
990 file = TGSI_FILE_TEMPORARY;
991 index = emit->fs.face_tmp_index;
992 }
993 else if (index == emit->fs.fragcoord_input_index) {
994 /* Replace INPUT[POSITION] with TEMP[POSITION] */
995 file = TGSI_FILE_TEMPORARY;
996 index = emit->fs.fragcoord_tmp_index;
997 }
998 else {
999 /* We remap fragment shader inputs to that FS input indexes
1000 * match up with VS/GS output indexes.
1001 */
1002 index = emit->linkage.input_map[index];
1003 }
1004 }
1005 else if (emit->unit == PIPE_SHADER_GEOMETRY &&
1006 file == TGSI_FILE_INPUT) {
1007 is_prim_id = (index == emit->gs.prim_id_index);
1008 index = emit->linkage.input_map[index];
1009 }
1010 else if (emit->unit == PIPE_SHADER_VERTEX) {
1011 if (file == TGSI_FILE_INPUT) {
1012 /* if input is adjusted... */
1013 if ((emit->key.vs.adjust_attrib_w_1 |
1014 emit->key.vs.adjust_attrib_itof |
1015 emit->key.vs.adjust_attrib_utof |
1016 emit->key.vs.attrib_is_bgra |
1017 emit->key.vs.attrib_puint_to_snorm |
1018 emit->key.vs.attrib_puint_to_uscaled |
1019 emit->key.vs.attrib_puint_to_sscaled) & (1 << index)) {
1020 file = TGSI_FILE_TEMPORARY;
1021 index = emit->vs.adjusted_input[index];
1022 }
1023 }
1024 else if (file == TGSI_FILE_SYSTEM_VALUE) {
1025 assert(index < ARRAY_SIZE(emit->system_value_indexes));
1026 index = emit->system_value_indexes[index];
1027 }
1028 }
1029
1030 operand0.value = operand1.value = 0;
1031
1032 if (is_prim_id) {
1033 operand0.numComponents = VGPU10_OPERAND_0_COMPONENT;
1034 operand0.operandType = VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID;
1035 }
1036 else {
1037 operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
1038 operand0.operandType = translate_register_file(file, tempArrayId > 0);
1039 }
1040
1041 operand0 = setup_operand0_indexing(emit, operand0, file, indirect,
1042 index2d, tempArrayId);
1043
1044 if (operand0.operandType != VGPU10_OPERAND_TYPE_IMMEDIATE32 &&
1045 operand0.operandType != VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID) {
1046 /* there's no swizzle for in-line immediates */
1047 if (swizzleX == swizzleY &&
1048 swizzleX == swizzleZ &&
1049 swizzleX == swizzleW) {
1050 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE;
1051 }
1052 else {
1053 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE;
1054 }
1055
1056 operand0.swizzleX = swizzleX;
1057 operand0.swizzleY = swizzleY;
1058 operand0.swizzleZ = swizzleZ;
1059 operand0.swizzleW = swizzleW;
1060
1061 if (absolute || negate) {
1062 operand0.extended = 1;
1063 operand1.extendedOperandType = VGPU10_EXTENDED_OPERAND_MODIFIER;
1064 if (absolute && !negate)
1065 operand1.operandModifier = VGPU10_OPERAND_MODIFIER_ABS;
1066 if (!absolute && negate)
1067 operand1.operandModifier = VGPU10_OPERAND_MODIFIER_NEG;
1068 if (absolute && negate)
1069 operand1.operandModifier = VGPU10_OPERAND_MODIFIER_ABSNEG;
1070 }
1071 }
1072
1073 /* Emit the operand tokens */
1074 emit_dword(emit, operand0.value);
1075 if (operand0.extended)
1076 emit_dword(emit, operand1.value);
1077
1078 if (operand0.operandType == VGPU10_OPERAND_TYPE_IMMEDIATE32) {
1079 /* Emit the four float/int in-line immediate values */
1080 unsigned *c;
1081 assert(index < ARRAY_SIZE(emit->immediates));
1082 assert(file == TGSI_FILE_IMMEDIATE);
1083 assert(swizzleX < 4);
1084 assert(swizzleY < 4);
1085 assert(swizzleZ < 4);
1086 assert(swizzleW < 4);
1087 c = (unsigned *) emit->immediates[index];
1088 emit_dword(emit, c[swizzleX]);
1089 emit_dword(emit, c[swizzleY]);
1090 emit_dword(emit, c[swizzleZ]);
1091 emit_dword(emit, c[swizzleW]);
1092 }
1093 else if (operand0.indexDimension >= VGPU10_OPERAND_INDEX_1D) {
1094 /* Emit the register index(es) */
1095 if (index2d ||
1096 operand0.operandType == VGPU10_OPERAND_TYPE_CONSTANT_BUFFER) {
1097 emit_dword(emit, reg->Dimension.Index);
1098 }
1099
1100 if (tempArrayId > 0) {
1101 emit_dword(emit, tempArrayId);
1102 }
1103
1104 emit_dword(emit, remap_temp_index(emit, file, index));
1105
1106 if (indirect) {
1107 emit_indirect_register(emit, reg->Indirect.Index);
1108 }
1109 }
1110 }
1111
1112
1113 /**
1114 * Emit a resource operand (for use with a SAMPLE instruction).
1115 */
1116 static void
emit_resource_register(struct svga_shader_emitter_v10 * emit,unsigned resource_number)1117 emit_resource_register(struct svga_shader_emitter_v10 *emit,
1118 unsigned resource_number)
1119 {
1120 VGPU10OperandToken0 operand0;
1121
1122 check_register_index(emit, VGPU10_OPERAND_TYPE_RESOURCE, resource_number);
1123
1124 /* init */
1125 operand0.value = 0;
1126
1127 operand0.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
1128 operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
1129 operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
1130 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE;
1131 operand0.swizzleX = VGPU10_COMPONENT_X;
1132 operand0.swizzleY = VGPU10_COMPONENT_Y;
1133 operand0.swizzleZ = VGPU10_COMPONENT_Z;
1134 operand0.swizzleW = VGPU10_COMPONENT_W;
1135
1136 emit_dword(emit, operand0.value);
1137 emit_dword(emit, resource_number);
1138 }
1139
1140
1141 /**
1142 * Emit a sampler operand (for use with a SAMPLE instruction).
1143 */
1144 static void
emit_sampler_register(struct svga_shader_emitter_v10 * emit,unsigned sampler_number)1145 emit_sampler_register(struct svga_shader_emitter_v10 *emit,
1146 unsigned sampler_number)
1147 {
1148 VGPU10OperandToken0 operand0;
1149
1150 check_register_index(emit, VGPU10_OPERAND_TYPE_SAMPLER, sampler_number);
1151
1152 /* init */
1153 operand0.value = 0;
1154
1155 operand0.operandType = VGPU10_OPERAND_TYPE_SAMPLER;
1156 operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
1157
1158 emit_dword(emit, operand0.value);
1159 emit_dword(emit, sampler_number);
1160 }
1161
1162
1163 /**
1164 * Emit an operand which reads the IS_FRONT_FACING register.
1165 */
1166 static void
emit_face_register(struct svga_shader_emitter_v10 * emit)1167 emit_face_register(struct svga_shader_emitter_v10 *emit)
1168 {
1169 VGPU10OperandToken0 operand0;
1170 unsigned index = emit->linkage.input_map[emit->fs.face_input_index];
1171
1172 /* init */
1173 operand0.value = 0;
1174
1175 operand0.operandType = VGPU10_OPERAND_TYPE_INPUT;
1176 operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
1177 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SELECT_1_MODE;
1178 operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
1179
1180 operand0.swizzleX = VGPU10_COMPONENT_X;
1181 operand0.swizzleY = VGPU10_COMPONENT_X;
1182 operand0.swizzleZ = VGPU10_COMPONENT_X;
1183 operand0.swizzleW = VGPU10_COMPONENT_X;
1184
1185 emit_dword(emit, operand0.value);
1186 emit_dword(emit, index);
1187 }
1188
1189
1190 /**
1191 * Emit the token for a VGPU10 opcode.
1192 * \param saturate clamp result to [0,1]?
1193 */
1194 static void
emit_opcode(struct svga_shader_emitter_v10 * emit,unsigned vgpu10_opcode,boolean saturate)1195 emit_opcode(struct svga_shader_emitter_v10 *emit,
1196 unsigned vgpu10_opcode, boolean saturate)
1197 {
1198 VGPU10OpcodeToken0 token0;
1199
1200 token0.value = 0; /* init all fields to zero */
1201 token0.opcodeType = vgpu10_opcode;
1202 token0.instructionLength = 0; /* Filled in by end_emit_instruction() */
1203 token0.saturate = saturate;
1204
1205 emit_dword(emit, token0.value);
1206 }
1207
1208
1209 /**
1210 * Emit the token for a VGPU10 resinfo instruction.
1211 * \param modifier return type modifier, _uint or _rcpFloat.
1212 * TODO: We may want to remove this parameter if it will
1213 * only ever be used as _uint.
1214 */
1215 static void
emit_opcode_resinfo(struct svga_shader_emitter_v10 * emit,VGPU10_RESINFO_RETURN_TYPE modifier)1216 emit_opcode_resinfo(struct svga_shader_emitter_v10 *emit,
1217 VGPU10_RESINFO_RETURN_TYPE modifier)
1218 {
1219 VGPU10OpcodeToken0 token0;
1220
1221 token0.value = 0; /* init all fields to zero */
1222 token0.opcodeType = VGPU10_OPCODE_RESINFO;
1223 token0.instructionLength = 0; /* Filled in by end_emit_instruction() */
1224 token0.resinfoReturnType = modifier;
1225
1226 emit_dword(emit, token0.value);
1227 }
1228
1229
1230 /**
1231 * Emit opcode tokens for a texture sample instruction. Texture instructions
1232 * can be rather complicated (texel offsets, etc) so we have this specialized
1233 * function.
1234 */
1235 static void
emit_sample_opcode(struct svga_shader_emitter_v10 * emit,unsigned vgpu10_opcode,boolean saturate,const int offsets[3])1236 emit_sample_opcode(struct svga_shader_emitter_v10 *emit,
1237 unsigned vgpu10_opcode, boolean saturate,
1238 const int offsets[3])
1239 {
1240 VGPU10OpcodeToken0 token0;
1241 VGPU10OpcodeToken1 token1;
1242
1243 token0.value = 0; /* init all fields to zero */
1244 token0.opcodeType = vgpu10_opcode;
1245 token0.instructionLength = 0; /* Filled in by end_emit_instruction() */
1246 token0.saturate = saturate;
1247
1248 if (offsets[0] || offsets[1] || offsets[2]) {
1249 assert(offsets[0] >= VGPU10_MIN_TEXEL_FETCH_OFFSET);
1250 assert(offsets[1] >= VGPU10_MIN_TEXEL_FETCH_OFFSET);
1251 assert(offsets[2] >= VGPU10_MIN_TEXEL_FETCH_OFFSET);
1252 assert(offsets[0] <= VGPU10_MAX_TEXEL_FETCH_OFFSET);
1253 assert(offsets[1] <= VGPU10_MAX_TEXEL_FETCH_OFFSET);
1254 assert(offsets[2] <= VGPU10_MAX_TEXEL_FETCH_OFFSET);
1255
1256 token0.extended = 1;
1257 token1.value = 0;
1258 token1.opcodeType = VGPU10_EXTENDED_OPCODE_SAMPLE_CONTROLS;
1259 token1.offsetU = offsets[0];
1260 token1.offsetV = offsets[1];
1261 token1.offsetW = offsets[2];
1262 }
1263
1264 emit_dword(emit, token0.value);
1265 if (token0.extended) {
1266 emit_dword(emit, token1.value);
1267 }
1268 }
1269
1270
1271 /**
1272 * Emit a DISCARD opcode token.
1273 * If nonzero is set, we'll discard the fragment if the X component is not 0.
1274 * Otherwise, we'll discard the fragment if the X component is 0.
1275 */
1276 static void
emit_discard_opcode(struct svga_shader_emitter_v10 * emit,boolean nonzero)1277 emit_discard_opcode(struct svga_shader_emitter_v10 *emit, boolean nonzero)
1278 {
1279 VGPU10OpcodeToken0 opcode0;
1280
1281 opcode0.value = 0;
1282 opcode0.opcodeType = VGPU10_OPCODE_DISCARD;
1283 if (nonzero)
1284 opcode0.testBoolean = VGPU10_INSTRUCTION_TEST_NONZERO;
1285
1286 emit_dword(emit, opcode0.value);
1287 }
1288
1289
1290 /**
1291 * We need to call this before we begin emitting a VGPU10 instruction.
1292 */
1293 static void
begin_emit_instruction(struct svga_shader_emitter_v10 * emit)1294 begin_emit_instruction(struct svga_shader_emitter_v10 *emit)
1295 {
1296 assert(emit->inst_start_token == 0);
1297 /* Save location of the instruction's VGPU10OpcodeToken0 token.
1298 * Note, we can't save a pointer because it would become invalid if
1299 * we have to realloc the output buffer.
1300 */
1301 emit->inst_start_token = emit_get_num_tokens(emit);
1302 }
1303
1304
1305 /**
1306 * We need to call this after we emit the last token of a VGPU10 instruction.
1307 * This function patches in the opcode token's instructionLength field.
1308 */
1309 static void
end_emit_instruction(struct svga_shader_emitter_v10 * emit)1310 end_emit_instruction(struct svga_shader_emitter_v10 *emit)
1311 {
1312 VGPU10OpcodeToken0 *tokens = (VGPU10OpcodeToken0 *) emit->buf;
1313 unsigned inst_length;
1314
1315 assert(emit->inst_start_token > 0);
1316
1317 if (emit->discard_instruction) {
1318 /* Back up the emit->ptr to where this instruction started so
1319 * that we discard the current instruction.
1320 */
1321 emit->ptr = (char *) (tokens + emit->inst_start_token);
1322 }
1323 else {
1324 /* Compute instruction length and patch that into the start of
1325 * the instruction.
1326 */
1327 inst_length = emit_get_num_tokens(emit) - emit->inst_start_token;
1328
1329 assert(inst_length > 0);
1330
1331 tokens[emit->inst_start_token].instructionLength = inst_length;
1332 }
1333
1334 emit->inst_start_token = 0; /* reset to zero for error checking */
1335 emit->discard_instruction = FALSE;
1336 }
1337
1338
1339 /**
1340 * Return index for a free temporary register.
1341 */
1342 static unsigned
get_temp_index(struct svga_shader_emitter_v10 * emit)1343 get_temp_index(struct svga_shader_emitter_v10 *emit)
1344 {
1345 assert(emit->internal_temp_count < MAX_INTERNAL_TEMPS);
1346 return emit->num_shader_temps + emit->internal_temp_count++;
1347 }
1348
1349
1350 /**
1351 * Release the temporaries which were generated by get_temp_index().
1352 */
1353 static void
free_temp_indexes(struct svga_shader_emitter_v10 * emit)1354 free_temp_indexes(struct svga_shader_emitter_v10 *emit)
1355 {
1356 emit->internal_temp_count = 0;
1357 }
1358
1359
1360 /**
1361 * Create a tgsi_full_src_register.
1362 */
1363 static struct tgsi_full_src_register
make_src_reg(unsigned file,unsigned index)1364 make_src_reg(unsigned file, unsigned index)
1365 {
1366 struct tgsi_full_src_register reg;
1367
1368 memset(®, 0, sizeof(reg));
1369 reg.Register.File = file;
1370 reg.Register.Index = index;
1371 reg.Register.SwizzleX = TGSI_SWIZZLE_X;
1372 reg.Register.SwizzleY = TGSI_SWIZZLE_Y;
1373 reg.Register.SwizzleZ = TGSI_SWIZZLE_Z;
1374 reg.Register.SwizzleW = TGSI_SWIZZLE_W;
1375 return reg;
1376 }
1377
1378
1379 /**
1380 * Create a tgsi_full_src_register for a temporary.
1381 */
1382 static struct tgsi_full_src_register
make_src_temp_reg(unsigned index)1383 make_src_temp_reg(unsigned index)
1384 {
1385 return make_src_reg(TGSI_FILE_TEMPORARY, index);
1386 }
1387
1388
1389 /**
1390 * Create a tgsi_full_src_register for a constant.
1391 */
1392 static struct tgsi_full_src_register
make_src_const_reg(unsigned index)1393 make_src_const_reg(unsigned index)
1394 {
1395 return make_src_reg(TGSI_FILE_CONSTANT, index);
1396 }
1397
1398
1399 /**
1400 * Create a tgsi_full_src_register for an immediate constant.
1401 */
1402 static struct tgsi_full_src_register
make_src_immediate_reg(unsigned index)1403 make_src_immediate_reg(unsigned index)
1404 {
1405 return make_src_reg(TGSI_FILE_IMMEDIATE, index);
1406 }
1407
1408
1409 /**
1410 * Create a tgsi_full_dst_register.
1411 */
1412 static struct tgsi_full_dst_register
make_dst_reg(unsigned file,unsigned index)1413 make_dst_reg(unsigned file, unsigned index)
1414 {
1415 struct tgsi_full_dst_register reg;
1416
1417 memset(®, 0, sizeof(reg));
1418 reg.Register.File = file;
1419 reg.Register.Index = index;
1420 reg.Register.WriteMask = TGSI_WRITEMASK_XYZW;
1421 return reg;
1422 }
1423
1424
1425 /**
1426 * Create a tgsi_full_dst_register for a temporary.
1427 */
1428 static struct tgsi_full_dst_register
make_dst_temp_reg(unsigned index)1429 make_dst_temp_reg(unsigned index)
1430 {
1431 return make_dst_reg(TGSI_FILE_TEMPORARY, index);
1432 }
1433
1434
1435 /**
1436 * Create a tgsi_full_dst_register for an output.
1437 */
1438 static struct tgsi_full_dst_register
make_dst_output_reg(unsigned index)1439 make_dst_output_reg(unsigned index)
1440 {
1441 return make_dst_reg(TGSI_FILE_OUTPUT, index);
1442 }
1443
1444
1445 /**
1446 * Create negated tgsi_full_src_register.
1447 */
1448 static struct tgsi_full_src_register
negate_src(const struct tgsi_full_src_register * reg)1449 negate_src(const struct tgsi_full_src_register *reg)
1450 {
1451 struct tgsi_full_src_register neg = *reg;
1452 neg.Register.Negate = !reg->Register.Negate;
1453 return neg;
1454 }
1455
1456 /**
1457 * Create absolute value of a tgsi_full_src_register.
1458 */
1459 static struct tgsi_full_src_register
absolute_src(const struct tgsi_full_src_register * reg)1460 absolute_src(const struct tgsi_full_src_register *reg)
1461 {
1462 struct tgsi_full_src_register absolute = *reg;
1463 absolute.Register.Absolute = 1;
1464 return absolute;
1465 }
1466
1467
1468 /** Return the named swizzle term from the src register */
1469 static inline unsigned
get_swizzle(const struct tgsi_full_src_register * reg,unsigned term)1470 get_swizzle(const struct tgsi_full_src_register *reg, unsigned term)
1471 {
1472 switch (term) {
1473 case TGSI_SWIZZLE_X:
1474 return reg->Register.SwizzleX;
1475 case TGSI_SWIZZLE_Y:
1476 return reg->Register.SwizzleY;
1477 case TGSI_SWIZZLE_Z:
1478 return reg->Register.SwizzleZ;
1479 case TGSI_SWIZZLE_W:
1480 return reg->Register.SwizzleW;
1481 default:
1482 assert(!"Bad swizzle");
1483 return TGSI_SWIZZLE_X;
1484 }
1485 }
1486
1487
1488 /**
1489 * Create swizzled tgsi_full_src_register.
1490 */
1491 static struct tgsi_full_src_register
swizzle_src(const struct tgsi_full_src_register * reg,unsigned swizzleX,unsigned swizzleY,unsigned swizzleZ,unsigned swizzleW)1492 swizzle_src(const struct tgsi_full_src_register *reg,
1493 unsigned swizzleX, unsigned swizzleY,
1494 unsigned swizzleZ, unsigned swizzleW)
1495 {
1496 struct tgsi_full_src_register swizzled = *reg;
1497 /* Note: we swizzle the current swizzle */
1498 swizzled.Register.SwizzleX = get_swizzle(reg, swizzleX);
1499 swizzled.Register.SwizzleY = get_swizzle(reg, swizzleY);
1500 swizzled.Register.SwizzleZ = get_swizzle(reg, swizzleZ);
1501 swizzled.Register.SwizzleW = get_swizzle(reg, swizzleW);
1502 return swizzled;
1503 }
1504
1505
1506 /**
1507 * Create swizzled tgsi_full_src_register where all the swizzle
1508 * terms are the same.
1509 */
1510 static struct tgsi_full_src_register
scalar_src(const struct tgsi_full_src_register * reg,unsigned swizzle)1511 scalar_src(const struct tgsi_full_src_register *reg, unsigned swizzle)
1512 {
1513 struct tgsi_full_src_register swizzled = *reg;
1514 /* Note: we swizzle the current swizzle */
1515 swizzled.Register.SwizzleX =
1516 swizzled.Register.SwizzleY =
1517 swizzled.Register.SwizzleZ =
1518 swizzled.Register.SwizzleW = get_swizzle(reg, swizzle);
1519 return swizzled;
1520 }
1521
1522
1523 /**
1524 * Create new tgsi_full_dst_register with writemask.
1525 * \param mask bitmask of TGSI_WRITEMASK_[XYZW]
1526 */
1527 static struct tgsi_full_dst_register
writemask_dst(const struct tgsi_full_dst_register * reg,unsigned mask)1528 writemask_dst(const struct tgsi_full_dst_register *reg, unsigned mask)
1529 {
1530 struct tgsi_full_dst_register masked = *reg;
1531 masked.Register.WriteMask = mask;
1532 return masked;
1533 }
1534
1535
1536 /**
1537 * Check if the register's swizzle is XXXX, YYYY, ZZZZ, or WWWW.
1538 */
1539 static boolean
same_swizzle_terms(const struct tgsi_full_src_register * reg)1540 same_swizzle_terms(const struct tgsi_full_src_register *reg)
1541 {
1542 return (reg->Register.SwizzleX == reg->Register.SwizzleY &&
1543 reg->Register.SwizzleY == reg->Register.SwizzleZ &&
1544 reg->Register.SwizzleZ == reg->Register.SwizzleW);
1545 }
1546
1547
1548 /**
1549 * Search the vector for the value 'x' and return its position.
1550 */
1551 static int
find_imm_in_vec4(const union tgsi_immediate_data vec[4],union tgsi_immediate_data x)1552 find_imm_in_vec4(const union tgsi_immediate_data vec[4],
1553 union tgsi_immediate_data x)
1554 {
1555 unsigned i;
1556 for (i = 0; i < 4; i++) {
1557 if (vec[i].Int == x.Int)
1558 return i;
1559 }
1560 return -1;
1561 }
1562
1563
1564 /**
1565 * Helper used by make_immediate_reg(), make_immediate_reg_4().
1566 */
1567 static int
find_immediate(struct svga_shader_emitter_v10 * emit,union tgsi_immediate_data x,unsigned startIndex)1568 find_immediate(struct svga_shader_emitter_v10 *emit,
1569 union tgsi_immediate_data x, unsigned startIndex)
1570 {
1571 const unsigned endIndex = emit->num_immediates;
1572 unsigned i;
1573
1574 assert(emit->immediates_emitted);
1575
1576 /* Search immediates for x, y, z, w */
1577 for (i = startIndex; i < endIndex; i++) {
1578 if (x.Int == emit->immediates[i][0].Int ||
1579 x.Int == emit->immediates[i][1].Int ||
1580 x.Int == emit->immediates[i][2].Int ||
1581 x.Int == emit->immediates[i][3].Int) {
1582 return i;
1583 }
1584 }
1585 /* Should never try to use an immediate value that wasn't pre-declared */
1586 assert(!"find_immediate() failed!");
1587 return -1;
1588 }
1589
1590
1591 /**
1592 * Return a tgsi_full_src_register for an immediate/literal
1593 * union tgsi_immediate_data[4] value.
1594 * Note: the values must have been previously declared/allocated in
1595 * emit_pre_helpers(). And, all of x,y,z,w must be located in the same
1596 * vec4 immediate.
1597 */
1598 static struct tgsi_full_src_register
make_immediate_reg_4(struct svga_shader_emitter_v10 * emit,const union tgsi_immediate_data imm[4])1599 make_immediate_reg_4(struct svga_shader_emitter_v10 *emit,
1600 const union tgsi_immediate_data imm[4])
1601 {
1602 struct tgsi_full_src_register reg;
1603 unsigned i;
1604
1605 for (i = 0; i < emit->num_common_immediates; i++) {
1606 /* search for first component value */
1607 int immpos = find_immediate(emit, imm[0], i);
1608 int x, y, z, w;
1609
1610 assert(immpos >= 0);
1611
1612 /* find remaining components within the immediate vector */
1613 x = find_imm_in_vec4(emit->immediates[immpos], imm[0]);
1614 y = find_imm_in_vec4(emit->immediates[immpos], imm[1]);
1615 z = find_imm_in_vec4(emit->immediates[immpos], imm[2]);
1616 w = find_imm_in_vec4(emit->immediates[immpos], imm[3]);
1617
1618 if (x >=0 && y >= 0 && z >= 0 && w >= 0) {
1619 /* found them all */
1620 memset(®, 0, sizeof(reg));
1621 reg.Register.File = TGSI_FILE_IMMEDIATE;
1622 reg.Register.Index = immpos;
1623 reg.Register.SwizzleX = x;
1624 reg.Register.SwizzleY = y;
1625 reg.Register.SwizzleZ = z;
1626 reg.Register.SwizzleW = w;
1627 return reg;
1628 }
1629 /* else, keep searching */
1630 }
1631
1632 assert(!"Failed to find immediate register!");
1633
1634 /* Just return IMM[0].xxxx */
1635 memset(®, 0, sizeof(reg));
1636 reg.Register.File = TGSI_FILE_IMMEDIATE;
1637 return reg;
1638 }
1639
1640
1641 /**
1642 * Return a tgsi_full_src_register for an immediate/literal
1643 * union tgsi_immediate_data value of the form {value, value, value, value}.
1644 * \sa make_immediate_reg_4() regarding allowed values.
1645 */
1646 static struct tgsi_full_src_register
make_immediate_reg(struct svga_shader_emitter_v10 * emit,union tgsi_immediate_data value)1647 make_immediate_reg(struct svga_shader_emitter_v10 *emit,
1648 union tgsi_immediate_data value)
1649 {
1650 struct tgsi_full_src_register reg;
1651 int immpos = find_immediate(emit, value, 0);
1652
1653 assert(immpos >= 0);
1654
1655 memset(®, 0, sizeof(reg));
1656 reg.Register.File = TGSI_FILE_IMMEDIATE;
1657 reg.Register.Index = immpos;
1658 reg.Register.SwizzleX =
1659 reg.Register.SwizzleY =
1660 reg.Register.SwizzleZ =
1661 reg.Register.SwizzleW = find_imm_in_vec4(emit->immediates[immpos], value);
1662
1663 return reg;
1664 }
1665
1666
1667 /**
1668 * Return a tgsi_full_src_register for an immediate/literal float[4] value.
1669 * \sa make_immediate_reg_4() regarding allowed values.
1670 */
1671 static struct tgsi_full_src_register
make_immediate_reg_float4(struct svga_shader_emitter_v10 * emit,float x,float y,float z,float w)1672 make_immediate_reg_float4(struct svga_shader_emitter_v10 *emit,
1673 float x, float y, float z, float w)
1674 {
1675 union tgsi_immediate_data imm[4];
1676 imm[0].Float = x;
1677 imm[1].Float = y;
1678 imm[2].Float = z;
1679 imm[3].Float = w;
1680 return make_immediate_reg_4(emit, imm);
1681 }
1682
1683
1684 /**
1685 * Return a tgsi_full_src_register for an immediate/literal float value
1686 * of the form {value, value, value, value}.
1687 * \sa make_immediate_reg_4() regarding allowed values.
1688 */
1689 static struct tgsi_full_src_register
make_immediate_reg_float(struct svga_shader_emitter_v10 * emit,float value)1690 make_immediate_reg_float(struct svga_shader_emitter_v10 *emit, float value)
1691 {
1692 union tgsi_immediate_data imm;
1693 imm.Float = value;
1694 return make_immediate_reg(emit, imm);
1695 }
1696
1697
1698 /**
1699 * Return a tgsi_full_src_register for an immediate/literal int[4] vector.
1700 */
1701 static struct tgsi_full_src_register
make_immediate_reg_int4(struct svga_shader_emitter_v10 * emit,int x,int y,int z,int w)1702 make_immediate_reg_int4(struct svga_shader_emitter_v10 *emit,
1703 int x, int y, int z, int w)
1704 {
1705 union tgsi_immediate_data imm[4];
1706 imm[0].Int = x;
1707 imm[1].Int = y;
1708 imm[2].Int = z;
1709 imm[3].Int = w;
1710 return make_immediate_reg_4(emit, imm);
1711 }
1712
1713
1714 /**
1715 * Return a tgsi_full_src_register for an immediate/literal int value
1716 * of the form {value, value, value, value}.
1717 * \sa make_immediate_reg_4() regarding allowed values.
1718 */
1719 static struct tgsi_full_src_register
make_immediate_reg_int(struct svga_shader_emitter_v10 * emit,int value)1720 make_immediate_reg_int(struct svga_shader_emitter_v10 *emit, int value)
1721 {
1722 union tgsi_immediate_data imm;
1723 imm.Int = value;
1724 return make_immediate_reg(emit, imm);
1725 }
1726
1727
1728 /**
1729 * Allocate space for a union tgsi_immediate_data[4] immediate.
1730 * \return the index/position of the immediate.
1731 */
1732 static unsigned
alloc_immediate_4(struct svga_shader_emitter_v10 * emit,const union tgsi_immediate_data imm[4])1733 alloc_immediate_4(struct svga_shader_emitter_v10 *emit,
1734 const union tgsi_immediate_data imm[4])
1735 {
1736 unsigned n = emit->num_immediates++;
1737 assert(!emit->immediates_emitted);
1738 assert(n < ARRAY_SIZE(emit->immediates));
1739 emit->immediates[n][0] = imm[0];
1740 emit->immediates[n][1] = imm[1];
1741 emit->immediates[n][2] = imm[2];
1742 emit->immediates[n][3] = imm[3];
1743 return n;
1744 }
1745
1746
1747 /**
1748 * Allocate space for a float[4] immediate.
1749 * \return the index/position of the immediate.
1750 */
1751 static unsigned
alloc_immediate_float4(struct svga_shader_emitter_v10 * emit,float x,float y,float z,float w)1752 alloc_immediate_float4(struct svga_shader_emitter_v10 *emit,
1753 float x, float y, float z, float w)
1754 {
1755 union tgsi_immediate_data imm[4];
1756 imm[0].Float = x;
1757 imm[1].Float = y;
1758 imm[2].Float = z;
1759 imm[3].Float = w;
1760 return alloc_immediate_4(emit, imm);
1761 }
1762
1763
1764 /**
1765 * Allocate space for an int[4] immediate.
1766 * \return the index/position of the immediate.
1767 */
1768 static unsigned
alloc_immediate_int4(struct svga_shader_emitter_v10 * emit,int x,int y,int z,int w)1769 alloc_immediate_int4(struct svga_shader_emitter_v10 *emit,
1770 int x, int y, int z, int w)
1771 {
1772 union tgsi_immediate_data imm[4];
1773 imm[0].Int = x;
1774 imm[1].Int = y;
1775 imm[2].Int = z;
1776 imm[3].Int = w;
1777 return alloc_immediate_4(emit, imm);
1778 }
1779
1780
1781 /**
1782 * Allocate a shader input to store a system value.
1783 */
1784 static unsigned
alloc_system_value_index(struct svga_shader_emitter_v10 * emit,unsigned index)1785 alloc_system_value_index(struct svga_shader_emitter_v10 *emit, unsigned index)
1786 {
1787 const unsigned n = emit->info.file_max[TGSI_FILE_INPUT] + 1 + index;
1788 assert(index < ARRAY_SIZE(emit->system_value_indexes));
1789 emit->system_value_indexes[index] = n;
1790 return n;
1791 }
1792
1793
1794 /**
1795 * Translate a TGSI immediate value (union tgsi_immediate_data[4]) to VGPU10.
1796 */
1797 static boolean
emit_vgpu10_immediate(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_immediate * imm)1798 emit_vgpu10_immediate(struct svga_shader_emitter_v10 *emit,
1799 const struct tgsi_full_immediate *imm)
1800 {
1801 /* We don't actually emit any code here. We just save the
1802 * immediate values and emit them later.
1803 */
1804 alloc_immediate_4(emit, imm->u);
1805 return TRUE;
1806 }
1807
1808
1809 /**
1810 * Emit a VGPU10_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER block
1811 * containing all the immediate values previously allocated
1812 * with alloc_immediate_4().
1813 */
1814 static boolean
emit_vgpu10_immediates_block(struct svga_shader_emitter_v10 * emit)1815 emit_vgpu10_immediates_block(struct svga_shader_emitter_v10 *emit)
1816 {
1817 VGPU10OpcodeToken0 token;
1818
1819 assert(!emit->immediates_emitted);
1820
1821 token.value = 0;
1822 token.opcodeType = VGPU10_OPCODE_CUSTOMDATA;
1823 token.customDataClass = VGPU10_CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER;
1824
1825 /* Note: no begin/end_emit_instruction() calls */
1826 emit_dword(emit, token.value);
1827 emit_dword(emit, 2 + 4 * emit->num_immediates);
1828 emit_dwords(emit, (unsigned *) emit->immediates, 4 * emit->num_immediates);
1829
1830 emit->immediates_emitted = TRUE;
1831
1832 return TRUE;
1833 }
1834
1835
1836 /**
1837 * Translate a fragment shader's TGSI_INTERPOLATE_x mode to a vgpu10
1838 * interpolation mode.
1839 * \return a VGPU10_INTERPOLATION_x value
1840 */
1841 static unsigned
translate_interpolation(const struct svga_shader_emitter_v10 * emit,unsigned interp,unsigned interpolate_loc)1842 translate_interpolation(const struct svga_shader_emitter_v10 *emit,
1843 unsigned interp, unsigned interpolate_loc)
1844 {
1845 if (interp == TGSI_INTERPOLATE_COLOR) {
1846 interp = emit->key.fs.flatshade ?
1847 TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;
1848 }
1849
1850 switch (interp) {
1851 case TGSI_INTERPOLATE_CONSTANT:
1852 return VGPU10_INTERPOLATION_CONSTANT;
1853 case TGSI_INTERPOLATE_LINEAR:
1854 return interpolate_loc == TGSI_INTERPOLATE_LOC_CENTROID ?
1855 VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID :
1856 VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE;
1857 case TGSI_INTERPOLATE_PERSPECTIVE:
1858 return interpolate_loc == TGSI_INTERPOLATE_LOC_CENTROID ?
1859 VGPU10_INTERPOLATION_LINEAR_CENTROID :
1860 VGPU10_INTERPOLATION_LINEAR;
1861 default:
1862 assert(!"Unexpected interpolation mode");
1863 return VGPU10_INTERPOLATION_CONSTANT;
1864 }
1865 }
1866
1867
1868 /**
1869 * Translate a TGSI property to VGPU10.
1870 * Don't emit any instructions yet, only need to gather the primitive property information.
1871 * The output primitive topology might be changed later. The final property instructions
1872 * will be emitted as part of the pre-helper code.
1873 */
1874 static boolean
emit_vgpu10_property(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_property * prop)1875 emit_vgpu10_property(struct svga_shader_emitter_v10 *emit,
1876 const struct tgsi_full_property *prop)
1877 {
1878 static const VGPU10_PRIMITIVE primType[] = {
1879 VGPU10_PRIMITIVE_POINT, /* PIPE_PRIM_POINTS */
1880 VGPU10_PRIMITIVE_LINE, /* PIPE_PRIM_LINES */
1881 VGPU10_PRIMITIVE_LINE, /* PIPE_PRIM_LINE_LOOP */
1882 VGPU10_PRIMITIVE_LINE, /* PIPE_PRIM_LINE_STRIP */
1883 VGPU10_PRIMITIVE_TRIANGLE, /* PIPE_PRIM_TRIANGLES */
1884 VGPU10_PRIMITIVE_TRIANGLE, /* PIPE_PRIM_TRIANGLE_STRIP */
1885 VGPU10_PRIMITIVE_TRIANGLE, /* PIPE_PRIM_TRIANGLE_FAN */
1886 VGPU10_PRIMITIVE_UNDEFINED, /* PIPE_PRIM_QUADS */
1887 VGPU10_PRIMITIVE_UNDEFINED, /* PIPE_PRIM_QUAD_STRIP */
1888 VGPU10_PRIMITIVE_UNDEFINED, /* PIPE_PRIM_POLYGON */
1889 VGPU10_PRIMITIVE_LINE_ADJ, /* PIPE_PRIM_LINES_ADJACENCY */
1890 VGPU10_PRIMITIVE_LINE_ADJ, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
1891 VGPU10_PRIMITIVE_TRIANGLE_ADJ, /* PIPE_PRIM_TRIANGLES_ADJACENCY */
1892 VGPU10_PRIMITIVE_TRIANGLE_ADJ /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
1893 };
1894
1895 static const VGPU10_PRIMITIVE_TOPOLOGY primTopology[] = {
1896 VGPU10_PRIMITIVE_TOPOLOGY_POINTLIST, /* PIPE_PRIM_POINTS */
1897 VGPU10_PRIMITIVE_TOPOLOGY_LINELIST, /* PIPE_PRIM_LINES */
1898 VGPU10_PRIMITIVE_TOPOLOGY_LINELIST, /* PIPE_PRIM_LINE_LOOP */
1899 VGPU10_PRIMITIVE_TOPOLOGY_LINESTRIP, /* PIPE_PRIM_LINE_STRIP */
1900 VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLELIST, /* PIPE_PRIM_TRIANGLES */
1901 VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* PIPE_PRIM_TRIANGLE_STRIP */
1902 VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* PIPE_PRIM_TRIANGLE_FAN */
1903 VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED, /* PIPE_PRIM_QUADS */
1904 VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED, /* PIPE_PRIM_QUAD_STRIP */
1905 VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED, /* PIPE_PRIM_POLYGON */
1906 VGPU10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, /* PIPE_PRIM_LINES_ADJACENCY */
1907 VGPU10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */
1908 VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ, /* PIPE_PRIM_TRIANGLES_ADJACENCY */
1909 VGPU10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */
1910 };
1911
1912 static const unsigned inputArraySize[] = {
1913 0, /* VGPU10_PRIMITIVE_UNDEFINED */
1914 1, /* VGPU10_PRIMITIVE_POINT */
1915 2, /* VGPU10_PRIMITIVE_LINE */
1916 3, /* VGPU10_PRIMITIVE_TRIANGLE */
1917 0,
1918 0,
1919 4, /* VGPU10_PRIMITIVE_LINE_ADJ */
1920 6 /* VGPU10_PRIMITIVE_TRIANGLE_ADJ */
1921 };
1922
1923 switch (prop->Property.PropertyName) {
1924 case TGSI_PROPERTY_GS_INPUT_PRIM:
1925 assert(prop->u[0].Data < ARRAY_SIZE(primType));
1926 emit->gs.prim_type = primType[prop->u[0].Data];
1927 assert(emit->gs.prim_type != VGPU10_PRIMITIVE_UNDEFINED);
1928 emit->gs.input_size = inputArraySize[emit->gs.prim_type];
1929 break;
1930
1931 case TGSI_PROPERTY_GS_OUTPUT_PRIM:
1932 assert(prop->u[0].Data < ARRAY_SIZE(primTopology));
1933 emit->gs.prim_topology = primTopology[prop->u[0].Data];
1934 assert(emit->gs.prim_topology != VGPU10_PRIMITIVE_TOPOLOGY_UNDEFINED);
1935 break;
1936
1937 case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
1938 emit->gs.max_out_vertices = prop->u[0].Data;
1939 break;
1940
1941 default:
1942 break;
1943 }
1944
1945 return TRUE;
1946 }
1947
1948
1949 static void
emit_property_instruction(struct svga_shader_emitter_v10 * emit,VGPU10OpcodeToken0 opcode0,unsigned nData,unsigned data)1950 emit_property_instruction(struct svga_shader_emitter_v10 *emit,
1951 VGPU10OpcodeToken0 opcode0, unsigned nData,
1952 unsigned data)
1953 {
1954 begin_emit_instruction(emit);
1955 emit_dword(emit, opcode0.value);
1956 if (nData)
1957 emit_dword(emit, data);
1958 end_emit_instruction(emit);
1959 }
1960
1961
1962 /**
1963 * Emit property instructions
1964 */
1965 static void
emit_property_instructions(struct svga_shader_emitter_v10 * emit)1966 emit_property_instructions(struct svga_shader_emitter_v10 *emit)
1967 {
1968 VGPU10OpcodeToken0 opcode0;
1969
1970 assert(emit->unit == PIPE_SHADER_GEOMETRY);
1971
1972 /* emit input primitive type declaration */
1973 opcode0.value = 0;
1974 opcode0.opcodeType = VGPU10_OPCODE_DCL_GS_INPUT_PRIMITIVE;
1975 opcode0.primitive = emit->gs.prim_type;
1976 emit_property_instruction(emit, opcode0, 0, 0);
1977
1978 /* emit output primitive topology declaration */
1979 opcode0.value = 0;
1980 opcode0.opcodeType = VGPU10_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY;
1981 opcode0.primitiveTopology = emit->gs.prim_topology;
1982 emit_property_instruction(emit, opcode0, 0, 0);
1983
1984 /* emit max output vertices */
1985 opcode0.value = 0;
1986 opcode0.opcodeType = VGPU10_OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT;
1987 emit_property_instruction(emit, opcode0, 1, emit->gs.max_out_vertices);
1988 }
1989
1990
1991 /**
1992 * Emit a vgpu10 declaration "instruction".
1993 * \param index the register index
1994 * \param size array size of the operand. In most cases, it is 1,
1995 * but for inputs to geometry shader, the array size varies
1996 * depending on the primitive type.
1997 */
1998 static void
emit_decl_instruction(struct svga_shader_emitter_v10 * emit,VGPU10OpcodeToken0 opcode0,VGPU10OperandToken0 operand0,VGPU10NameToken name_token,unsigned index,unsigned size)1999 emit_decl_instruction(struct svga_shader_emitter_v10 *emit,
2000 VGPU10OpcodeToken0 opcode0,
2001 VGPU10OperandToken0 operand0,
2002 VGPU10NameToken name_token,
2003 unsigned index, unsigned size)
2004 {
2005 assert(opcode0.opcodeType);
2006 assert(operand0.mask);
2007
2008 begin_emit_instruction(emit);
2009 emit_dword(emit, opcode0.value);
2010
2011 emit_dword(emit, operand0.value);
2012
2013 if (operand0.indexDimension == VGPU10_OPERAND_INDEX_1D) {
2014 /* Next token is the index of the register to declare */
2015 emit_dword(emit, index);
2016 }
2017 else if (operand0.indexDimension >= VGPU10_OPERAND_INDEX_2D) {
2018 /* Next token is the size of the register */
2019 emit_dword(emit, size);
2020
2021 /* Followed by the index of the register */
2022 emit_dword(emit, index);
2023 }
2024
2025 if (name_token.value) {
2026 emit_dword(emit, name_token.value);
2027 }
2028
2029 end_emit_instruction(emit);
2030 }
2031
2032
2033 /**
2034 * Emit the declaration for a shader input.
2035 * \param opcodeType opcode type, one of VGPU10_OPCODE_DCL_INPUTx
2036 * \param operandType operand type, one of VGPU10_OPERAND_TYPE_INPUT_x
2037 * \param dim index dimension
2038 * \param index the input register index
2039 * \param size array size of the operand. In most cases, it is 1,
2040 * but for inputs to geometry shader, the array size varies
2041 * depending on the primitive type.
2042 * \param name one of VGPU10_NAME_x
2043 * \parma numComp number of components
2044 * \param selMode component selection mode
2045 * \param usageMask bitfield of VGPU10_OPERAND_4_COMPONENT_MASK_x values
2046 * \param interpMode interpolation mode
2047 */
2048 static void
emit_input_declaration(struct svga_shader_emitter_v10 * emit,unsigned opcodeType,unsigned operandType,unsigned dim,unsigned index,unsigned size,unsigned name,unsigned numComp,unsigned selMode,unsigned usageMask,unsigned interpMode)2049 emit_input_declaration(struct svga_shader_emitter_v10 *emit,
2050 unsigned opcodeType, unsigned operandType,
2051 unsigned dim, unsigned index, unsigned size,
2052 unsigned name, unsigned numComp,
2053 unsigned selMode, unsigned usageMask,
2054 unsigned interpMode)
2055 {
2056 VGPU10OpcodeToken0 opcode0;
2057 VGPU10OperandToken0 operand0;
2058 VGPU10NameToken name_token;
2059
2060 assert(usageMask <= VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
2061 assert(opcodeType == VGPU10_OPCODE_DCL_INPUT ||
2062 opcodeType == VGPU10_OPCODE_DCL_INPUT_SIV ||
2063 opcodeType == VGPU10_OPCODE_DCL_INPUT_PS ||
2064 opcodeType == VGPU10_OPCODE_DCL_INPUT_PS_SGV);
2065 assert(operandType == VGPU10_OPERAND_TYPE_INPUT ||
2066 operandType == VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID);
2067 assert(numComp <= VGPU10_OPERAND_4_COMPONENT);
2068 assert(selMode <= VGPU10_OPERAND_4_COMPONENT_MASK_MODE);
2069 assert(dim <= VGPU10_OPERAND_INDEX_3D);
2070 assert(name == VGPU10_NAME_UNDEFINED ||
2071 name == VGPU10_NAME_POSITION ||
2072 name == VGPU10_NAME_INSTANCE_ID ||
2073 name == VGPU10_NAME_VERTEX_ID ||
2074 name == VGPU10_NAME_PRIMITIVE_ID ||
2075 name == VGPU10_NAME_IS_FRONT_FACE);
2076 assert(interpMode == VGPU10_INTERPOLATION_UNDEFINED ||
2077 interpMode == VGPU10_INTERPOLATION_CONSTANT ||
2078 interpMode == VGPU10_INTERPOLATION_LINEAR ||
2079 interpMode == VGPU10_INTERPOLATION_LINEAR_CENTROID ||
2080 interpMode == VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE ||
2081 interpMode == VGPU10_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID);
2082
2083 check_register_index(emit, opcodeType, index);
2084
2085 opcode0.value = operand0.value = name_token.value = 0;
2086
2087 opcode0.opcodeType = opcodeType;
2088 opcode0.interpolationMode = interpMode;
2089
2090 operand0.operandType = operandType;
2091 operand0.numComponents = numComp;
2092 operand0.selectionMode = selMode;
2093 operand0.mask = usageMask;
2094 operand0.indexDimension = dim;
2095 operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
2096 if (dim == VGPU10_OPERAND_INDEX_2D)
2097 operand0.index1Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
2098
2099 name_token.name = name;
2100
2101 emit_decl_instruction(emit, opcode0, operand0, name_token, index, size);
2102 }
2103
2104
2105 /**
2106 * Emit the declaration for a shader output.
2107 * \param type one of VGPU10_OPCODE_DCL_OUTPUTx
2108 * \param index the output register index
2109 * \param name one of VGPU10_NAME_x
2110 * \param usageMask bitfield of VGPU10_OPERAND_4_COMPONENT_MASK_x values
2111 */
2112 static void
emit_output_declaration(struct svga_shader_emitter_v10 * emit,unsigned type,unsigned index,unsigned name,unsigned usageMask)2113 emit_output_declaration(struct svga_shader_emitter_v10 *emit,
2114 unsigned type, unsigned index,
2115 unsigned name, unsigned usageMask)
2116 {
2117 VGPU10OpcodeToken0 opcode0;
2118 VGPU10OperandToken0 operand0;
2119 VGPU10NameToken name_token;
2120
2121 assert(usageMask <= VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
2122 assert(type == VGPU10_OPCODE_DCL_OUTPUT ||
2123 type == VGPU10_OPCODE_DCL_OUTPUT_SGV ||
2124 type == VGPU10_OPCODE_DCL_OUTPUT_SIV);
2125 assert(name == VGPU10_NAME_UNDEFINED ||
2126 name == VGPU10_NAME_POSITION ||
2127 name == VGPU10_NAME_PRIMITIVE_ID ||
2128 name == VGPU10_NAME_RENDER_TARGET_ARRAY_INDEX ||
2129 name == VGPU10_NAME_CLIP_DISTANCE);
2130
2131 check_register_index(emit, type, index);
2132
2133 opcode0.value = operand0.value = name_token.value = 0;
2134
2135 opcode0.opcodeType = type;
2136 operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT;
2137 operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
2138 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
2139 operand0.mask = usageMask;
2140 operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
2141 operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
2142
2143 name_token.name = name;
2144
2145 emit_decl_instruction(emit, opcode0, operand0, name_token, index, 1);
2146 }
2147
2148
2149 /**
2150 * Emit the declaration for the fragment depth output.
2151 */
2152 static void
emit_fragdepth_output_declaration(struct svga_shader_emitter_v10 * emit)2153 emit_fragdepth_output_declaration(struct svga_shader_emitter_v10 *emit)
2154 {
2155 VGPU10OpcodeToken0 opcode0;
2156 VGPU10OperandToken0 operand0;
2157 VGPU10NameToken name_token;
2158
2159 assert(emit->unit == PIPE_SHADER_FRAGMENT);
2160
2161 opcode0.value = operand0.value = name_token.value = 0;
2162
2163 opcode0.opcodeType = VGPU10_OPCODE_DCL_OUTPUT;
2164 operand0.operandType = VGPU10_OPERAND_TYPE_OUTPUT_DEPTH;
2165 operand0.numComponents = VGPU10_OPERAND_1_COMPONENT;
2166 operand0.indexDimension = VGPU10_OPERAND_INDEX_0D;
2167 operand0.mask = VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
2168
2169 emit_decl_instruction(emit, opcode0, operand0, name_token, 0, 1);
2170 }
2171
2172
2173 /**
2174 * Emit the declaration for a system value input/output.
2175 */
2176 static void
emit_system_value_declaration(struct svga_shader_emitter_v10 * emit,unsigned semantic_name,unsigned index)2177 emit_system_value_declaration(struct svga_shader_emitter_v10 *emit,
2178 unsigned semantic_name, unsigned index)
2179 {
2180 switch (semantic_name) {
2181 case TGSI_SEMANTIC_INSTANCEID:
2182 index = alloc_system_value_index(emit, index);
2183 emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT_SIV,
2184 VGPU10_OPERAND_TYPE_INPUT,
2185 VGPU10_OPERAND_INDEX_1D,
2186 index, 1,
2187 VGPU10_NAME_INSTANCE_ID,
2188 VGPU10_OPERAND_4_COMPONENT,
2189 VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
2190 VGPU10_OPERAND_4_COMPONENT_MASK_X,
2191 VGPU10_INTERPOLATION_UNDEFINED);
2192 break;
2193 case TGSI_SEMANTIC_VERTEXID:
2194 index = alloc_system_value_index(emit, index);
2195 emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT_SIV,
2196 VGPU10_OPERAND_TYPE_INPUT,
2197 VGPU10_OPERAND_INDEX_1D,
2198 index, 1,
2199 VGPU10_NAME_VERTEX_ID,
2200 VGPU10_OPERAND_4_COMPONENT,
2201 VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
2202 VGPU10_OPERAND_4_COMPONENT_MASK_X,
2203 VGPU10_INTERPOLATION_UNDEFINED);
2204 break;
2205 default:
2206 ; /* XXX */
2207 }
2208 }
2209
2210 /**
2211 * Translate a TGSI declaration to VGPU10.
2212 */
2213 static boolean
emit_vgpu10_declaration(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_declaration * decl)2214 emit_vgpu10_declaration(struct svga_shader_emitter_v10 *emit,
2215 const struct tgsi_full_declaration *decl)
2216 {
2217 switch (decl->Declaration.File) {
2218 case TGSI_FILE_INPUT:
2219 /* do nothing - see emit_input_declarations() */
2220 return TRUE;
2221
2222 case TGSI_FILE_OUTPUT:
2223 assert(decl->Range.First == decl->Range.Last);
2224 emit->output_usage_mask[decl->Range.First] = decl->Declaration.UsageMask;
2225 return TRUE;
2226
2227 case TGSI_FILE_TEMPORARY:
2228 /* Don't declare the temps here. Just keep track of how many
2229 * and emit the declaration later.
2230 */
2231 if (decl->Declaration.Array) {
2232 /* Indexed temporary array. Save the start index of the array
2233 * and the size of the array.
2234 */
2235 const unsigned arrayID = MIN2(decl->Array.ArrayID, MAX_TEMP_ARRAYS);
2236 unsigned i;
2237
2238 assert(arrayID < ARRAY_SIZE(emit->temp_arrays));
2239
2240 /* Save this array so we can emit the declaration for it later */
2241 emit->temp_arrays[arrayID].start = decl->Range.First;
2242 emit->temp_arrays[arrayID].size =
2243 decl->Range.Last - decl->Range.First + 1;
2244
2245 emit->num_temp_arrays = MAX2(emit->num_temp_arrays, arrayID + 1);
2246 assert(emit->num_temp_arrays <= MAX_TEMP_ARRAYS);
2247 emit->num_temp_arrays = MIN2(emit->num_temp_arrays, MAX_TEMP_ARRAYS);
2248
2249 /* Fill in the temp_map entries for this array */
2250 for (i = decl->Range.First; i <= decl->Range.Last; i++) {
2251 emit->temp_map[i].arrayId = arrayID;
2252 emit->temp_map[i].index = i - decl->Range.First;
2253 }
2254 }
2255
2256 /* for all temps, indexed or not, keep track of highest index */
2257 emit->num_shader_temps = MAX2(emit->num_shader_temps,
2258 decl->Range.Last + 1);
2259 return TRUE;
2260
2261 case TGSI_FILE_CONSTANT:
2262 /* Don't declare constants here. Just keep track and emit later. */
2263 {
2264 unsigned constbuf = 0, num_consts;
2265 if (decl->Declaration.Dimension) {
2266 constbuf = decl->Dim.Index2D;
2267 }
2268 /* We throw an assertion here when, in fact, the shader should never
2269 * have linked due to constbuf index out of bounds, so we shouldn't
2270 * have reached here.
2271 */
2272 assert(constbuf < ARRAY_SIZE(emit->num_shader_consts));
2273
2274 num_consts = MAX2(emit->num_shader_consts[constbuf],
2275 decl->Range.Last + 1);
2276
2277 if (num_consts > VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT) {
2278 debug_printf("Warning: constant buffer is declared to size [%u]"
2279 " but [%u] is the limit.\n",
2280 num_consts,
2281 VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT);
2282 }
2283 /* The linker doesn't enforce the max UBO size so we clamp here */
2284 emit->num_shader_consts[constbuf] =
2285 MIN2(num_consts, VGPU10_MAX_CONSTANT_BUFFER_ELEMENT_COUNT);
2286 }
2287 return TRUE;
2288
2289 case TGSI_FILE_IMMEDIATE:
2290 assert(!"TGSI_FILE_IMMEDIATE not handled yet!");
2291 return FALSE;
2292
2293 case TGSI_FILE_SYSTEM_VALUE:
2294 emit_system_value_declaration(emit, decl->Semantic.Name,
2295 decl->Range.First);
2296 return TRUE;
2297
2298 case TGSI_FILE_SAMPLER:
2299 /* Don't declare samplers here. Just keep track and emit later. */
2300 emit->num_samplers = MAX2(emit->num_samplers, decl->Range.Last + 1);
2301 return TRUE;
2302
2303 #if 0
2304 case TGSI_FILE_RESOURCE:
2305 /*opcode0.opcodeType = VGPU10_OPCODE_DCL_RESOURCE;*/
2306 /* XXX more, VGPU10_RETURN_TYPE_FLOAT */
2307 assert(!"TGSI_FILE_RESOURCE not handled yet");
2308 return FALSE;
2309 #endif
2310
2311 case TGSI_FILE_ADDRESS:
2312 emit->num_address_regs = MAX2(emit->num_address_regs,
2313 decl->Range.Last + 1);
2314 return TRUE;
2315
2316 case TGSI_FILE_SAMPLER_VIEW:
2317 {
2318 unsigned unit = decl->Range.First;
2319 assert(decl->Range.First == decl->Range.Last);
2320 emit->sampler_target[unit] = decl->SamplerView.Resource;
2321 /* Note: we can ignore YZW return types for now */
2322 emit->sampler_return_type[unit] = decl->SamplerView.ReturnTypeX;
2323 }
2324 return TRUE;
2325
2326 default:
2327 assert(!"Unexpected type of declaration");
2328 return FALSE;
2329 }
2330 }
2331
2332
2333
2334 /**
2335 * Emit all input declarations.
2336 */
2337 static boolean
emit_input_declarations(struct svga_shader_emitter_v10 * emit)2338 emit_input_declarations(struct svga_shader_emitter_v10 *emit)
2339 {
2340 unsigned i;
2341
2342 if (emit->unit == PIPE_SHADER_FRAGMENT) {
2343
2344 for (i = 0; i < emit->linkage.num_inputs; i++) {
2345 unsigned semantic_name = emit->info.input_semantic_name[i];
2346 unsigned usage_mask = emit->info.input_usage_mask[i];
2347 unsigned index = emit->linkage.input_map[i];
2348 unsigned type, interpolationMode, name;
2349
2350 if (usage_mask == 0)
2351 continue; /* register is not actually used */
2352
2353 if (semantic_name == TGSI_SEMANTIC_POSITION) {
2354 /* fragment position input */
2355 type = VGPU10_OPCODE_DCL_INPUT_PS_SGV;
2356 interpolationMode = VGPU10_INTERPOLATION_LINEAR;
2357 name = VGPU10_NAME_POSITION;
2358 if (usage_mask & TGSI_WRITEMASK_W) {
2359 /* we need to replace use of 'w' with '1/w' */
2360 emit->fs.fragcoord_input_index = i;
2361 }
2362 }
2363 else if (semantic_name == TGSI_SEMANTIC_FACE) {
2364 /* fragment front-facing input */
2365 type = VGPU10_OPCODE_DCL_INPUT_PS_SGV;
2366 interpolationMode = VGPU10_INTERPOLATION_CONSTANT;
2367 name = VGPU10_NAME_IS_FRONT_FACE;
2368 emit->fs.face_input_index = i;
2369 }
2370 else if (semantic_name == TGSI_SEMANTIC_PRIMID) {
2371 /* primitive ID */
2372 type = VGPU10_OPCODE_DCL_INPUT_PS_SGV;
2373 interpolationMode = VGPU10_INTERPOLATION_CONSTANT;
2374 name = VGPU10_NAME_PRIMITIVE_ID;
2375 }
2376 else {
2377 /* general fragment input */
2378 type = VGPU10_OPCODE_DCL_INPUT_PS;
2379 interpolationMode =
2380 translate_interpolation(emit,
2381 emit->info.input_interpolate[i],
2382 emit->info.input_interpolate_loc[i]);
2383
2384 /* keeps track if flat interpolation mode is being used */
2385 emit->uses_flat_interp = emit->uses_flat_interp ||
2386 (interpolationMode == VGPU10_INTERPOLATION_CONSTANT);
2387
2388 name = VGPU10_NAME_UNDEFINED;
2389 }
2390
2391 emit_input_declaration(emit, type,
2392 VGPU10_OPERAND_TYPE_INPUT,
2393 VGPU10_OPERAND_INDEX_1D, index, 1,
2394 name,
2395 VGPU10_OPERAND_4_COMPONENT,
2396 VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
2397 VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
2398 interpolationMode);
2399 }
2400 }
2401 else if (emit->unit == PIPE_SHADER_GEOMETRY) {
2402
2403 for (i = 0; i < emit->info.num_inputs; i++) {
2404 unsigned semantic_name = emit->info.input_semantic_name[i];
2405 unsigned usage_mask = emit->info.input_usage_mask[i];
2406 unsigned index = emit->linkage.input_map[i];
2407 unsigned opcodeType, operandType;
2408 unsigned numComp, selMode;
2409 unsigned name;
2410 unsigned dim;
2411
2412 if (usage_mask == 0)
2413 continue; /* register is not actually used */
2414
2415 opcodeType = VGPU10_OPCODE_DCL_INPUT;
2416 operandType = VGPU10_OPERAND_TYPE_INPUT;
2417 numComp = VGPU10_OPERAND_4_COMPONENT;
2418 selMode = VGPU10_OPERAND_4_COMPONENT_MASK_MODE;
2419 name = VGPU10_NAME_UNDEFINED;
2420
2421 /* all geometry shader inputs are two dimensional except gl_PrimitiveID */
2422 dim = VGPU10_OPERAND_INDEX_2D;
2423
2424 if (semantic_name == TGSI_SEMANTIC_PRIMID) {
2425 /* Primitive ID */
2426 operandType = VGPU10_OPERAND_TYPE_INPUT_PRIMITIVEID;
2427 dim = VGPU10_OPERAND_INDEX_0D;
2428 numComp = VGPU10_OPERAND_0_COMPONENT;
2429 selMode = 0;
2430
2431 /* also save the register index so we can check for
2432 * primitive id when emit src register. We need to modify the
2433 * operand type, index dimension when emit primitive id src reg.
2434 */
2435 emit->gs.prim_id_index = i;
2436 }
2437 else if (semantic_name == TGSI_SEMANTIC_POSITION) {
2438 /* vertex position input */
2439 opcodeType = VGPU10_OPCODE_DCL_INPUT_SIV;
2440 name = VGPU10_NAME_POSITION;
2441 }
2442
2443 emit_input_declaration(emit, opcodeType, operandType,
2444 dim, index,
2445 emit->gs.input_size,
2446 name,
2447 numComp, selMode,
2448 VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
2449 VGPU10_INTERPOLATION_UNDEFINED);
2450 }
2451 }
2452 else {
2453 assert(emit->unit == PIPE_SHADER_VERTEX);
2454
2455 for (i = 0; i < emit->info.file_max[TGSI_FILE_INPUT] + 1; i++) {
2456 unsigned usage_mask = emit->info.input_usage_mask[i];
2457 unsigned index = i;
2458
2459 if (usage_mask == 0)
2460 continue; /* register is not actually used */
2461
2462 emit_input_declaration(emit, VGPU10_OPCODE_DCL_INPUT,
2463 VGPU10_OPERAND_TYPE_INPUT,
2464 VGPU10_OPERAND_INDEX_1D, index, 1,
2465 VGPU10_NAME_UNDEFINED,
2466 VGPU10_OPERAND_4_COMPONENT,
2467 VGPU10_OPERAND_4_COMPONENT_MASK_MODE,
2468 VGPU10_OPERAND_4_COMPONENT_MASK_ALL,
2469 VGPU10_INTERPOLATION_UNDEFINED);
2470 }
2471 }
2472
2473 return TRUE;
2474 }
2475
2476
2477 /**
2478 * Emit all output declarations.
2479 */
2480 static boolean
emit_output_declarations(struct svga_shader_emitter_v10 * emit)2481 emit_output_declarations(struct svga_shader_emitter_v10 *emit)
2482 {
2483 unsigned i;
2484
2485 for (i = 0; i < emit->info.num_outputs; i++) {
2486 /*const unsigned usage_mask = emit->info.output_usage_mask[i];*/
2487 const unsigned semantic_name = emit->info.output_semantic_name[i];
2488 const unsigned semantic_index = emit->info.output_semantic_index[i];
2489 unsigned index = i;
2490
2491 if (emit->unit == PIPE_SHADER_FRAGMENT) {
2492 if (semantic_name == TGSI_SEMANTIC_COLOR) {
2493 assert(semantic_index < ARRAY_SIZE(emit->fs.color_out_index));
2494
2495 emit->fs.color_out_index[semantic_index] = index;
2496
2497 /* The semantic index is the shader's color output/buffer index */
2498 emit_output_declaration(emit,
2499 VGPU10_OPCODE_DCL_OUTPUT, semantic_index,
2500 VGPU10_NAME_UNDEFINED,
2501 VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
2502
2503 if (semantic_index == 0) {
2504 if (emit->key.fs.write_color0_to_n_cbufs > 1) {
2505 /* Emit declarations for the additional color outputs
2506 * for broadcasting.
2507 */
2508 unsigned j;
2509 for (j = 1; j < emit->key.fs.write_color0_to_n_cbufs; j++) {
2510 /* Allocate a new output index */
2511 unsigned idx = emit->info.num_outputs + j - 1;
2512 emit->fs.color_out_index[j] = idx;
2513 emit_output_declaration(emit,
2514 VGPU10_OPCODE_DCL_OUTPUT, idx,
2515 VGPU10_NAME_UNDEFINED,
2516 VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
2517 emit->info.output_semantic_index[idx] = j;
2518 }
2519 }
2520 }
2521 else {
2522 assert(!emit->key.fs.write_color0_to_n_cbufs);
2523 }
2524 }
2525 else if (semantic_name == TGSI_SEMANTIC_POSITION) {
2526 /* Fragment depth output */
2527 emit_fragdepth_output_declaration(emit);
2528 }
2529 else {
2530 assert(!"Bad output semantic name");
2531 }
2532 }
2533 else {
2534 /* VS or GS */
2535 unsigned name, type;
2536 unsigned writemask = VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
2537
2538 switch (semantic_name) {
2539 case TGSI_SEMANTIC_POSITION:
2540 assert(emit->unit != PIPE_SHADER_FRAGMENT);
2541 type = VGPU10_OPCODE_DCL_OUTPUT_SIV;
2542 name = VGPU10_NAME_POSITION;
2543 /* Save the index of the vertex position output register */
2544 emit->vposition.out_index = index;
2545 break;
2546 case TGSI_SEMANTIC_CLIPDIST:
2547 type = VGPU10_OPCODE_DCL_OUTPUT_SIV;
2548 name = VGPU10_NAME_CLIP_DISTANCE;
2549 /* save the starting index of the clip distance output register */
2550 if (semantic_index == 0)
2551 emit->clip_dist_out_index = index;
2552 writemask = emit->output_usage_mask[index];
2553 writemask = apply_clip_plane_mask(emit, writemask, semantic_index);
2554 if (writemask == 0x0) {
2555 continue; /* discard this do-nothing declaration */
2556 }
2557 break;
2558 case TGSI_SEMANTIC_PRIMID:
2559 assert(emit->unit == PIPE_SHADER_GEOMETRY);
2560 type = VGPU10_OPCODE_DCL_OUTPUT_SGV;
2561 name = VGPU10_NAME_PRIMITIVE_ID;
2562 break;
2563 case TGSI_SEMANTIC_LAYER:
2564 assert(emit->unit == PIPE_SHADER_GEOMETRY);
2565 type = VGPU10_OPCODE_DCL_OUTPUT_SGV;
2566 name = VGPU10_NAME_RENDER_TARGET_ARRAY_INDEX;
2567 break;
2568 case TGSI_SEMANTIC_CLIPVERTEX:
2569 type = VGPU10_OPCODE_DCL_OUTPUT;
2570 name = VGPU10_NAME_UNDEFINED;
2571 emit->clip_vertex_out_index = index;
2572 break;
2573 default:
2574 /* generic output */
2575 type = VGPU10_OPCODE_DCL_OUTPUT;
2576 name = VGPU10_NAME_UNDEFINED;
2577 }
2578
2579 emit_output_declaration(emit, type, index, name, writemask);
2580 }
2581 }
2582
2583 if (emit->vposition.so_index != INVALID_INDEX &&
2584 emit->vposition.out_index != INVALID_INDEX) {
2585
2586 assert(emit->unit != PIPE_SHADER_FRAGMENT);
2587
2588 /* Emit the declaration for the non-adjusted vertex position
2589 * for stream output purpose
2590 */
2591 emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT,
2592 emit->vposition.so_index,
2593 VGPU10_NAME_UNDEFINED,
2594 VGPU10_OPERAND_4_COMPONENT_MASK_ALL);
2595 }
2596
2597 if (emit->clip_dist_so_index != INVALID_INDEX &&
2598 emit->clip_dist_out_index != INVALID_INDEX) {
2599
2600 assert(emit->unit != PIPE_SHADER_FRAGMENT);
2601
2602 /* Emit the declaration for the clip distance shadow copy which
2603 * will be used for stream output purpose and for clip distance
2604 * varying variable
2605 */
2606 emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT,
2607 emit->clip_dist_so_index,
2608 VGPU10_NAME_UNDEFINED,
2609 emit->output_usage_mask[emit->clip_dist_out_index]);
2610
2611 if (emit->info.num_written_clipdistance > 4) {
2612 /* for the second clip distance register, each handles 4 planes */
2613 emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT,
2614 emit->clip_dist_so_index + 1,
2615 VGPU10_NAME_UNDEFINED,
2616 emit->output_usage_mask[emit->clip_dist_out_index+1]);
2617 }
2618 }
2619
2620 return TRUE;
2621 }
2622
2623
2624 /**
2625 * Emit the declaration for the temporary registers.
2626 */
2627 static boolean
emit_temporaries_declaration(struct svga_shader_emitter_v10 * emit)2628 emit_temporaries_declaration(struct svga_shader_emitter_v10 *emit)
2629 {
2630 unsigned total_temps, reg, i;
2631
2632 total_temps = emit->num_shader_temps;
2633
2634 /* If there is indirect access to non-indexable temps in the shader,
2635 * convert those temps to indexable temps. This works around a bug
2636 * in the GLSL->TGSI translator exposed in piglit test
2637 * glsl-1.20/execution/fs-const-array-of-struct-of-array.shader_test.
2638 * Internal temps added by the driver remain as non-indexable temps.
2639 */
2640 if ((emit->info.indirect_files & (1 << TGSI_FILE_TEMPORARY)) &&
2641 emit->num_temp_arrays == 0) {
2642 unsigned arrayID;
2643
2644 arrayID = 1;
2645 emit->num_temp_arrays = arrayID + 1;
2646 emit->temp_arrays[arrayID].start = 0;
2647 emit->temp_arrays[arrayID].size = total_temps;
2648
2649 /* Fill in the temp_map entries for this temp array */
2650 for (i = 0; i < total_temps; i++) {
2651 emit->temp_map[i].arrayId = arrayID;
2652 emit->temp_map[i].index = i;
2653 }
2654 }
2655
2656 /* Allocate extra temps for specially-implemented instructions,
2657 * such as LIT.
2658 */
2659 total_temps += MAX_INTERNAL_TEMPS;
2660
2661 if (emit->unit == PIPE_SHADER_VERTEX || emit->unit == PIPE_SHADER_GEOMETRY) {
2662 if (emit->vposition.need_prescale || emit->key.vs.undo_viewport ||
2663 emit->key.clip_plane_enable ||
2664 emit->vposition.so_index != INVALID_INDEX) {
2665 emit->vposition.tmp_index = total_temps;
2666 total_temps += 1;
2667 }
2668
2669 if (emit->unit == PIPE_SHADER_VERTEX) {
2670 unsigned attrib_mask = (emit->key.vs.adjust_attrib_w_1 |
2671 emit->key.vs.adjust_attrib_itof |
2672 emit->key.vs.adjust_attrib_utof |
2673 emit->key.vs.attrib_is_bgra |
2674 emit->key.vs.attrib_puint_to_snorm |
2675 emit->key.vs.attrib_puint_to_uscaled |
2676 emit->key.vs.attrib_puint_to_sscaled);
2677 while (attrib_mask) {
2678 unsigned index = u_bit_scan(&attrib_mask);
2679 emit->vs.adjusted_input[index] = total_temps++;
2680 }
2681 }
2682
2683 if (emit->clip_mode == CLIP_DISTANCE) {
2684 /* We need to write the clip distance to a temporary register
2685 * first. Then it will be copied to the shadow copy for
2686 * the clip distance varying variable and stream output purpose.
2687 * It will also be copied to the actual CLIPDIST register
2688 * according to the enabled clip planes
2689 */
2690 emit->clip_dist_tmp_index = total_temps++;
2691 if (emit->info.num_written_clipdistance > 4)
2692 total_temps++; /* second clip register */
2693 }
2694 else if (emit->clip_mode == CLIP_VERTEX) {
2695 /* We need to convert the TGSI CLIPVERTEX output to one or more
2696 * clip distances. Allocate a temp reg for the clipvertex here.
2697 */
2698 assert(emit->info.writes_clipvertex > 0);
2699 emit->clip_vertex_tmp_index = total_temps;
2700 total_temps++;
2701 }
2702 }
2703 else if (emit->unit == PIPE_SHADER_FRAGMENT) {
2704 if (emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS ||
2705 emit->key.fs.white_fragments ||
2706 emit->key.fs.write_color0_to_n_cbufs > 1) {
2707 /* Allocate a temp to hold the output color */
2708 emit->fs.color_tmp_index = total_temps;
2709 total_temps += 1;
2710 }
2711
2712 if (emit->fs.face_input_index != INVALID_INDEX) {
2713 /* Allocate a temp for the +/-1 face register */
2714 emit->fs.face_tmp_index = total_temps;
2715 total_temps += 1;
2716 }
2717
2718 if (emit->fs.fragcoord_input_index != INVALID_INDEX) {
2719 /* Allocate a temp for modified fragment position register */
2720 emit->fs.fragcoord_tmp_index = total_temps;
2721 total_temps += 1;
2722 }
2723 }
2724
2725 for (i = 0; i < emit->num_address_regs; i++) {
2726 emit->address_reg_index[i] = total_temps++;
2727 }
2728
2729 /* Initialize the temp_map array which maps TGSI temp indexes to VGPU10
2730 * temp indexes. Basically, we compact all the non-array temp register
2731 * indexes into a consecutive series.
2732 *
2733 * Before, we may have some TGSI declarations like:
2734 * DCL TEMP[0..1], LOCAL
2735 * DCL TEMP[2..4], ARRAY(1), LOCAL
2736 * DCL TEMP[5..7], ARRAY(2), LOCAL
2737 * plus, some extra temps, like TEMP[8], TEMP[9] for misc things
2738 *
2739 * After, we'll have a map like this:
2740 * temp_map[0] = { array 0, index 0 }
2741 * temp_map[1] = { array 0, index 1 }
2742 * temp_map[2] = { array 1, index 0 }
2743 * temp_map[3] = { array 1, index 1 }
2744 * temp_map[4] = { array 1, index 2 }
2745 * temp_map[5] = { array 2, index 0 }
2746 * temp_map[6] = { array 2, index 1 }
2747 * temp_map[7] = { array 2, index 2 }
2748 * temp_map[8] = { array 0, index 2 }
2749 * temp_map[9] = { array 0, index 3 }
2750 *
2751 * We'll declare two arrays of 3 elements, plus a set of four non-indexed
2752 * temps numbered 0..3
2753 *
2754 * Any time we emit a temporary register index, we'll have to use the
2755 * temp_map[] table to convert the TGSI index to the VGPU10 index.
2756 *
2757 * Finally, we recompute the total_temps value here.
2758 */
2759 reg = 0;
2760 for (i = 0; i < total_temps; i++) {
2761 if (emit->temp_map[i].arrayId == 0) {
2762 emit->temp_map[i].index = reg++;
2763 }
2764 }
2765
2766 if (0) {
2767 debug_printf("total_temps %u\n", total_temps);
2768 for (i = 0; i < total_temps; i++) {
2769 debug_printf("temp %u -> array %u index %u\n",
2770 i, emit->temp_map[i].arrayId, emit->temp_map[i].index);
2771 }
2772 }
2773
2774 total_temps = reg;
2775
2776 /* Emit declaration of ordinary temp registers */
2777 if (total_temps > 0) {
2778 VGPU10OpcodeToken0 opcode0;
2779
2780 opcode0.value = 0;
2781 opcode0.opcodeType = VGPU10_OPCODE_DCL_TEMPS;
2782
2783 begin_emit_instruction(emit);
2784 emit_dword(emit, opcode0.value);
2785 emit_dword(emit, total_temps);
2786 end_emit_instruction(emit);
2787 }
2788
2789 /* Emit declarations for indexable temp arrays. Skip 0th entry since
2790 * it's unused.
2791 */
2792 for (i = 1; i < emit->num_temp_arrays; i++) {
2793 unsigned num_temps = emit->temp_arrays[i].size;
2794
2795 if (num_temps > 0) {
2796 VGPU10OpcodeToken0 opcode0;
2797
2798 opcode0.value = 0;
2799 opcode0.opcodeType = VGPU10_OPCODE_DCL_INDEXABLE_TEMP;
2800
2801 begin_emit_instruction(emit);
2802 emit_dword(emit, opcode0.value);
2803 emit_dword(emit, i); /* which array */
2804 emit_dword(emit, num_temps);
2805 emit_dword(emit, 4); /* num components */
2806 end_emit_instruction(emit);
2807
2808 total_temps += num_temps;
2809 }
2810 }
2811
2812 /* Check that the grand total of all regular and indexed temps is
2813 * under the limit.
2814 */
2815 check_register_index(emit, VGPU10_OPCODE_DCL_TEMPS, total_temps - 1);
2816
2817 return TRUE;
2818 }
2819
2820
2821 static boolean
emit_constant_declaration(struct svga_shader_emitter_v10 * emit)2822 emit_constant_declaration(struct svga_shader_emitter_v10 *emit)
2823 {
2824 VGPU10OpcodeToken0 opcode0;
2825 VGPU10OperandToken0 operand0;
2826 unsigned total_consts, i;
2827
2828 opcode0.value = 0;
2829 opcode0.opcodeType = VGPU10_OPCODE_DCL_CONSTANT_BUFFER;
2830 opcode0.accessPattern = VGPU10_CB_IMMEDIATE_INDEXED;
2831 /* XXX or, access pattern = VGPU10_CB_DYNAMIC_INDEXED */
2832
2833 operand0.value = 0;
2834 operand0.numComponents = VGPU10_OPERAND_4_COMPONENT;
2835 operand0.indexDimension = VGPU10_OPERAND_INDEX_2D;
2836 operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
2837 operand0.index1Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
2838 operand0.operandType = VGPU10_OPERAND_TYPE_CONSTANT_BUFFER;
2839 operand0.selectionMode = VGPU10_OPERAND_4_COMPONENT_SWIZZLE_MODE;
2840 operand0.swizzleX = 0;
2841 operand0.swizzleY = 1;
2842 operand0.swizzleZ = 2;
2843 operand0.swizzleW = 3;
2844
2845 /**
2846 * Emit declaration for constant buffer [0]. We also allocate
2847 * room for the extra constants here.
2848 */
2849 total_consts = emit->num_shader_consts[0];
2850
2851 /* Now, allocate constant slots for the "extra" constants */
2852
2853 /* Vertex position scale/translation */
2854 if (emit->vposition.need_prescale) {
2855 emit->vposition.prescale_scale_index = total_consts++;
2856 emit->vposition.prescale_trans_index = total_consts++;
2857 }
2858
2859 if (emit->unit == PIPE_SHADER_VERTEX) {
2860 if (emit->key.vs.undo_viewport) {
2861 emit->vs.viewport_index = total_consts++;
2862 }
2863 }
2864
2865 /* user-defined clip planes */
2866 if (emit->key.clip_plane_enable) {
2867 unsigned n = util_bitcount(emit->key.clip_plane_enable);
2868 assert(emit->unit == PIPE_SHADER_VERTEX ||
2869 emit->unit == PIPE_SHADER_GEOMETRY);
2870 for (i = 0; i < n; i++) {
2871 emit->clip_plane_const[i] = total_consts++;
2872 }
2873 }
2874
2875 /* Texcoord scale factors for RECT textures */
2876 {
2877 for (i = 0; i < emit->num_samplers; i++) {
2878 if (emit->key.tex[i].unnormalized) {
2879 emit->texcoord_scale_index[i] = total_consts++;
2880 }
2881 }
2882 }
2883
2884 /* Texture buffer sizes */
2885 for (i = 0; i < emit->num_samplers; i++) {
2886 if (emit->sampler_target[i] == TGSI_TEXTURE_BUFFER) {
2887 emit->texture_buffer_size_index[i] = total_consts++;
2888 }
2889 }
2890
2891 if (total_consts > 0) {
2892 begin_emit_instruction(emit);
2893 emit_dword(emit, opcode0.value);
2894 emit_dword(emit, operand0.value);
2895 emit_dword(emit, 0); /* which const buffer slot */
2896 emit_dword(emit, total_consts);
2897 end_emit_instruction(emit);
2898 }
2899
2900 /* Declare remaining constant buffers (UBOs) */
2901 for (i = 1; i < ARRAY_SIZE(emit->num_shader_consts); i++) {
2902 if (emit->num_shader_consts[i] > 0) {
2903 begin_emit_instruction(emit);
2904 emit_dword(emit, opcode0.value);
2905 emit_dword(emit, operand0.value);
2906 emit_dword(emit, i); /* which const buffer slot */
2907 emit_dword(emit, emit->num_shader_consts[i]);
2908 end_emit_instruction(emit);
2909 }
2910 }
2911
2912 return TRUE;
2913 }
2914
2915
2916 /**
2917 * Emit declarations for samplers.
2918 */
2919 static boolean
emit_sampler_declarations(struct svga_shader_emitter_v10 * emit)2920 emit_sampler_declarations(struct svga_shader_emitter_v10 *emit)
2921 {
2922 unsigned i;
2923
2924 for (i = 0; i < emit->num_samplers; i++) {
2925 VGPU10OpcodeToken0 opcode0;
2926 VGPU10OperandToken0 operand0;
2927
2928 opcode0.value = 0;
2929 opcode0.opcodeType = VGPU10_OPCODE_DCL_SAMPLER;
2930 opcode0.samplerMode = VGPU10_SAMPLER_MODE_DEFAULT;
2931
2932 operand0.value = 0;
2933 operand0.numComponents = VGPU10_OPERAND_0_COMPONENT;
2934 operand0.operandType = VGPU10_OPERAND_TYPE_SAMPLER;
2935 operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
2936 operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
2937
2938 begin_emit_instruction(emit);
2939 emit_dword(emit, opcode0.value);
2940 emit_dword(emit, operand0.value);
2941 emit_dword(emit, i);
2942 end_emit_instruction(emit);
2943 }
2944
2945 return TRUE;
2946 }
2947
2948
2949 /**
2950 * Translate TGSI_TEXTURE_x to VGAPU10_RESOURCE_DIMENSION_x.
2951 */
2952 static unsigned
tgsi_texture_to_resource_dimension(unsigned target,boolean is_array)2953 tgsi_texture_to_resource_dimension(unsigned target, boolean is_array)
2954 {
2955 switch (target) {
2956 case TGSI_TEXTURE_BUFFER:
2957 return VGPU10_RESOURCE_DIMENSION_BUFFER;
2958 case TGSI_TEXTURE_1D:
2959 return VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
2960 case TGSI_TEXTURE_2D:
2961 case TGSI_TEXTURE_RECT:
2962 return VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2963 case TGSI_TEXTURE_3D:
2964 return VGPU10_RESOURCE_DIMENSION_TEXTURE3D;
2965 case TGSI_TEXTURE_CUBE:
2966 return VGPU10_RESOURCE_DIMENSION_TEXTURECUBE;
2967 case TGSI_TEXTURE_SHADOW1D:
2968 return VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
2969 case TGSI_TEXTURE_SHADOW2D:
2970 case TGSI_TEXTURE_SHADOWRECT:
2971 return VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2972 case TGSI_TEXTURE_1D_ARRAY:
2973 case TGSI_TEXTURE_SHADOW1D_ARRAY:
2974 return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE1DARRAY
2975 : VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
2976 case TGSI_TEXTURE_2D_ARRAY:
2977 case TGSI_TEXTURE_SHADOW2D_ARRAY:
2978 return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY
2979 : VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2980 case TGSI_TEXTURE_SHADOWCUBE:
2981 return VGPU10_RESOURCE_DIMENSION_TEXTURECUBE;
2982 case TGSI_TEXTURE_2D_MSAA:
2983 return VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS;
2984 case TGSI_TEXTURE_2D_ARRAY_MSAA:
2985 return is_array ? VGPU10_RESOURCE_DIMENSION_TEXTURE2DMSARRAY
2986 : VGPU10_RESOURCE_DIMENSION_TEXTURE2DMS;
2987 case TGSI_TEXTURE_CUBE_ARRAY:
2988 return VGPU10_RESOURCE_DIMENSION_TEXTURECUBEARRAY;
2989 default:
2990 assert(!"Unexpected resource type");
2991 return VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
2992 }
2993 }
2994
2995
2996 /**
2997 * Given a tgsi_return_type, return true iff it is an integer type.
2998 */
2999 static boolean
is_integer_type(enum tgsi_return_type type)3000 is_integer_type(enum tgsi_return_type type)
3001 {
3002 switch (type) {
3003 case TGSI_RETURN_TYPE_SINT:
3004 case TGSI_RETURN_TYPE_UINT:
3005 return TRUE;
3006 case TGSI_RETURN_TYPE_FLOAT:
3007 case TGSI_RETURN_TYPE_UNORM:
3008 case TGSI_RETURN_TYPE_SNORM:
3009 return FALSE;
3010 case TGSI_RETURN_TYPE_COUNT:
3011 default:
3012 assert(!"is_integer_type: Unknown tgsi_return_type");
3013 return FALSE;
3014 }
3015 }
3016
3017
3018 /**
3019 * Emit declarations for resources.
3020 * XXX When we're sure that all TGSI shaders will be generated with
3021 * sampler view declarations (Ex: DCL SVIEW[n], 2D, UINT) we may
3022 * rework this code.
3023 */
3024 static boolean
emit_resource_declarations(struct svga_shader_emitter_v10 * emit)3025 emit_resource_declarations(struct svga_shader_emitter_v10 *emit)
3026 {
3027 unsigned i;
3028
3029 /* Emit resource decl for each sampler */
3030 for (i = 0; i < emit->num_samplers; i++) {
3031 VGPU10OpcodeToken0 opcode0;
3032 VGPU10OperandToken0 operand0;
3033 VGPU10ResourceReturnTypeToken return_type;
3034 VGPU10_RESOURCE_RETURN_TYPE rt;
3035
3036 opcode0.value = 0;
3037 opcode0.opcodeType = VGPU10_OPCODE_DCL_RESOURCE;
3038 opcode0.resourceDimension =
3039 tgsi_texture_to_resource_dimension(emit->sampler_target[i],
3040 emit->key.tex[i].is_array);
3041 operand0.value = 0;
3042 operand0.numComponents = VGPU10_OPERAND_0_COMPONENT;
3043 operand0.operandType = VGPU10_OPERAND_TYPE_RESOURCE;
3044 operand0.indexDimension = VGPU10_OPERAND_INDEX_1D;
3045 operand0.index0Representation = VGPU10_OPERAND_INDEX_IMMEDIATE32;
3046
3047 #if 1
3048 /* convert TGSI_RETURN_TYPE_x to VGPU10_RETURN_TYPE_x */
3049 STATIC_ASSERT(VGPU10_RETURN_TYPE_UNORM == TGSI_RETURN_TYPE_UNORM + 1);
3050 STATIC_ASSERT(VGPU10_RETURN_TYPE_SNORM == TGSI_RETURN_TYPE_SNORM + 1);
3051 STATIC_ASSERT(VGPU10_RETURN_TYPE_SINT == TGSI_RETURN_TYPE_SINT + 1);
3052 STATIC_ASSERT(VGPU10_RETURN_TYPE_UINT == TGSI_RETURN_TYPE_UINT + 1);
3053 STATIC_ASSERT(VGPU10_RETURN_TYPE_FLOAT == TGSI_RETURN_TYPE_FLOAT + 1);
3054 assert(emit->sampler_return_type[i] <= TGSI_RETURN_TYPE_FLOAT);
3055 rt = emit->sampler_return_type[i] + 1;
3056 #else
3057 switch (emit->sampler_return_type[i]) {
3058 case TGSI_RETURN_TYPE_UNORM: rt = VGPU10_RETURN_TYPE_UNORM; break;
3059 case TGSI_RETURN_TYPE_SNORM: rt = VGPU10_RETURN_TYPE_SNORM; break;
3060 case TGSI_RETURN_TYPE_SINT: rt = VGPU10_RETURN_TYPE_SINT; break;
3061 case TGSI_RETURN_TYPE_UINT: rt = VGPU10_RETURN_TYPE_UINT; break;
3062 case TGSI_RETURN_TYPE_FLOAT: rt = VGPU10_RETURN_TYPE_FLOAT; break;
3063 case TGSI_RETURN_TYPE_COUNT:
3064 default:
3065 rt = VGPU10_RETURN_TYPE_FLOAT;
3066 assert(!"emit_resource_declarations: Unknown tgsi_return_type");
3067 }
3068 #endif
3069
3070 return_type.value = 0;
3071 return_type.component0 = rt;
3072 return_type.component1 = rt;
3073 return_type.component2 = rt;
3074 return_type.component3 = rt;
3075
3076 begin_emit_instruction(emit);
3077 emit_dword(emit, opcode0.value);
3078 emit_dword(emit, operand0.value);
3079 emit_dword(emit, i);
3080 emit_dword(emit, return_type.value);
3081 end_emit_instruction(emit);
3082 }
3083
3084 return TRUE;
3085 }
3086
3087 static void
emit_instruction_op1(struct svga_shader_emitter_v10 * emit,unsigned opcode,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src,boolean saturate)3088 emit_instruction_op1(struct svga_shader_emitter_v10 *emit,
3089 unsigned opcode,
3090 const struct tgsi_full_dst_register *dst,
3091 const struct tgsi_full_src_register *src,
3092 boolean saturate)
3093 {
3094 begin_emit_instruction(emit);
3095 emit_opcode(emit, opcode, saturate);
3096 emit_dst_register(emit, dst);
3097 emit_src_register(emit, src);
3098 end_emit_instruction(emit);
3099 }
3100
3101 static void
emit_instruction_op2(struct svga_shader_emitter_v10 * emit,unsigned opcode,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src1,const struct tgsi_full_src_register * src2,boolean saturate)3102 emit_instruction_op2(struct svga_shader_emitter_v10 *emit,
3103 unsigned opcode,
3104 const struct tgsi_full_dst_register *dst,
3105 const struct tgsi_full_src_register *src1,
3106 const struct tgsi_full_src_register *src2,
3107 boolean saturate)
3108 {
3109 begin_emit_instruction(emit);
3110 emit_opcode(emit, opcode, saturate);
3111 emit_dst_register(emit, dst);
3112 emit_src_register(emit, src1);
3113 emit_src_register(emit, src2);
3114 end_emit_instruction(emit);
3115 }
3116
3117 static void
emit_instruction_op3(struct svga_shader_emitter_v10 * emit,unsigned opcode,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src1,const struct tgsi_full_src_register * src2,const struct tgsi_full_src_register * src3,boolean saturate)3118 emit_instruction_op3(struct svga_shader_emitter_v10 *emit,
3119 unsigned opcode,
3120 const struct tgsi_full_dst_register *dst,
3121 const struct tgsi_full_src_register *src1,
3122 const struct tgsi_full_src_register *src2,
3123 const struct tgsi_full_src_register *src3,
3124 boolean saturate)
3125 {
3126 begin_emit_instruction(emit);
3127 emit_opcode(emit, opcode, saturate);
3128 emit_dst_register(emit, dst);
3129 emit_src_register(emit, src1);
3130 emit_src_register(emit, src2);
3131 emit_src_register(emit, src3);
3132 end_emit_instruction(emit);
3133 }
3134
3135 /**
3136 * Emit the actual clip distance instructions to be used for clipping
3137 * by copying the clip distance from the temporary registers to the
3138 * CLIPDIST registers written with the enabled planes mask.
3139 * Also copy the clip distance from the temporary to the clip distance
3140 * shadow copy register which will be referenced by the input shader
3141 */
3142 static void
emit_clip_distance_instructions(struct svga_shader_emitter_v10 * emit)3143 emit_clip_distance_instructions(struct svga_shader_emitter_v10 *emit)
3144 {
3145 struct tgsi_full_src_register tmp_clip_dist_src;
3146 struct tgsi_full_dst_register clip_dist_dst;
3147
3148 unsigned i;
3149 unsigned clip_plane_enable = emit->key.clip_plane_enable;
3150 unsigned clip_dist_tmp_index = emit->clip_dist_tmp_index;
3151 int num_written_clipdist = emit->info.num_written_clipdistance;
3152
3153 assert(emit->clip_dist_out_index != INVALID_INDEX);
3154 assert(emit->clip_dist_tmp_index != INVALID_INDEX);
3155
3156 /**
3157 * Temporary reset the temporary clip dist register index so
3158 * that the copy to the real clip dist register will not
3159 * attempt to copy to the temporary register again
3160 */
3161 emit->clip_dist_tmp_index = INVALID_INDEX;
3162
3163 for (i = 0; i < 2 && num_written_clipdist > 0; i++, num_written_clipdist-=4) {
3164
3165 tmp_clip_dist_src = make_src_temp_reg(clip_dist_tmp_index + i);
3166
3167 /**
3168 * copy to the shadow copy for use by varying variable and
3169 * stream output. All clip distances
3170 * will be written regardless of the enabled clipping planes.
3171 */
3172 clip_dist_dst = make_dst_reg(TGSI_FILE_OUTPUT,
3173 emit->clip_dist_so_index + i);
3174
3175 /* MOV clip_dist_so, tmp_clip_dist */
3176 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &clip_dist_dst,
3177 &tmp_clip_dist_src, FALSE);
3178
3179 /**
3180 * copy those clip distances to enabled clipping planes
3181 * to CLIPDIST registers for clipping
3182 */
3183 if (clip_plane_enable & 0xf) {
3184 clip_dist_dst = make_dst_reg(TGSI_FILE_OUTPUT,
3185 emit->clip_dist_out_index + i);
3186 clip_dist_dst = writemask_dst(&clip_dist_dst, clip_plane_enable & 0xf);
3187
3188 /* MOV CLIPDIST, tmp_clip_dist */
3189 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &clip_dist_dst,
3190 &tmp_clip_dist_src, FALSE);
3191 }
3192 /* four clip planes per clip register */
3193 clip_plane_enable >>= 4;
3194 }
3195 /**
3196 * set the temporary clip dist register index back to the
3197 * temporary index for the next vertex
3198 */
3199 emit->clip_dist_tmp_index = clip_dist_tmp_index;
3200 }
3201
3202 /* Declare clip distance output registers for user-defined clip planes
3203 * or the TGSI_CLIPVERTEX output.
3204 */
3205 static void
emit_clip_distance_declarations(struct svga_shader_emitter_v10 * emit)3206 emit_clip_distance_declarations(struct svga_shader_emitter_v10 *emit)
3207 {
3208 unsigned num_clip_planes = util_bitcount(emit->key.clip_plane_enable);
3209 unsigned index = emit->num_outputs;
3210 unsigned plane_mask;
3211
3212 assert(emit->unit == PIPE_SHADER_VERTEX ||
3213 emit->unit == PIPE_SHADER_GEOMETRY);
3214 assert(num_clip_planes <= 8);
3215
3216 if (emit->clip_mode != CLIP_LEGACY &&
3217 emit->clip_mode != CLIP_VERTEX) {
3218 return;
3219 }
3220
3221 if (num_clip_planes == 0)
3222 return;
3223
3224 /* Declare one or two clip output registers. The number of components
3225 * in the mask reflects the number of clip planes. For example, if 5
3226 * clip planes are needed, we'll declare outputs similar to:
3227 * dcl_output_siv o2.xyzw, clip_distance
3228 * dcl_output_siv o3.x, clip_distance
3229 */
3230 emit->clip_dist_out_index = index; /* save the starting clip dist reg index */
3231
3232 plane_mask = (1 << num_clip_planes) - 1;
3233 if (plane_mask & 0xf) {
3234 unsigned cmask = plane_mask & VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
3235 emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT_SIV, index,
3236 VGPU10_NAME_CLIP_DISTANCE, cmask);
3237 emit->num_outputs++;
3238 }
3239 if (plane_mask & 0xf0) {
3240 unsigned cmask = (plane_mask >> 4) & VGPU10_OPERAND_4_COMPONENT_MASK_ALL;
3241 emit_output_declaration(emit, VGPU10_OPCODE_DCL_OUTPUT_SIV, index + 1,
3242 VGPU10_NAME_CLIP_DISTANCE, cmask);
3243 emit->num_outputs++;
3244 }
3245 }
3246
3247
3248 /**
3249 * Emit the instructions for writing to the clip distance registers
3250 * to handle legacy/automatic clip planes.
3251 * For each clip plane, the distance is the dot product of the vertex
3252 * position (found in TEMP[vpos_tmp_index]) and the clip plane coefficients.
3253 * This is not used when the shader has an explicit CLIPVERTEX or CLIPDISTANCE
3254 * output registers already declared.
3255 */
3256 static void
emit_clip_distance_from_vpos(struct svga_shader_emitter_v10 * emit,unsigned vpos_tmp_index)3257 emit_clip_distance_from_vpos(struct svga_shader_emitter_v10 *emit,
3258 unsigned vpos_tmp_index)
3259 {
3260 unsigned i, num_clip_planes = util_bitcount(emit->key.clip_plane_enable);
3261
3262 assert(emit->clip_mode == CLIP_LEGACY);
3263 assert(num_clip_planes <= 8);
3264
3265 assert(emit->unit == PIPE_SHADER_VERTEX ||
3266 emit->unit == PIPE_SHADER_GEOMETRY);
3267
3268 for (i = 0; i < num_clip_planes; i++) {
3269 struct tgsi_full_dst_register dst;
3270 struct tgsi_full_src_register plane_src, vpos_src;
3271 unsigned reg_index = emit->clip_dist_out_index + i / 4;
3272 unsigned comp = i % 4;
3273 unsigned writemask = VGPU10_OPERAND_4_COMPONENT_MASK_X << comp;
3274
3275 /* create dst, src regs */
3276 dst = make_dst_reg(TGSI_FILE_OUTPUT, reg_index);
3277 dst = writemask_dst(&dst, writemask);
3278
3279 plane_src = make_src_const_reg(emit->clip_plane_const[i]);
3280 vpos_src = make_src_temp_reg(vpos_tmp_index);
3281
3282 /* DP4 clip_dist, plane, vpos */
3283 emit_instruction_op2(emit, VGPU10_OPCODE_DP4, &dst,
3284 &plane_src, &vpos_src, FALSE);
3285 }
3286 }
3287
3288
3289 /**
3290 * Emit the instructions for computing the clip distance results from
3291 * the clip vertex temporary.
3292 * For each clip plane, the distance is the dot product of the clip vertex
3293 * position (found in a temp reg) and the clip plane coefficients.
3294 */
3295 static void
emit_clip_vertex_instructions(struct svga_shader_emitter_v10 * emit)3296 emit_clip_vertex_instructions(struct svga_shader_emitter_v10 *emit)
3297 {
3298 const unsigned num_clip = util_bitcount(emit->key.clip_plane_enable);
3299 unsigned i;
3300 struct tgsi_full_dst_register dst;
3301 struct tgsi_full_src_register clipvert_src;
3302 const unsigned clip_vertex_tmp = emit->clip_vertex_tmp_index;
3303
3304 assert(emit->unit == PIPE_SHADER_VERTEX ||
3305 emit->unit == PIPE_SHADER_GEOMETRY);
3306
3307 assert(emit->clip_mode == CLIP_VERTEX);
3308
3309 clipvert_src = make_src_temp_reg(clip_vertex_tmp);
3310
3311 for (i = 0; i < num_clip; i++) {
3312 struct tgsi_full_src_register plane_src;
3313 unsigned reg_index = emit->clip_dist_out_index + i / 4;
3314 unsigned comp = i % 4;
3315 unsigned writemask = VGPU10_OPERAND_4_COMPONENT_MASK_X << comp;
3316
3317 /* create dst, src regs */
3318 dst = make_dst_reg(TGSI_FILE_OUTPUT, reg_index);
3319 dst = writemask_dst(&dst, writemask);
3320
3321 plane_src = make_src_const_reg(emit->clip_plane_const[i]);
3322
3323 /* DP4 clip_dist, plane, vpos */
3324 emit_instruction_op2(emit, VGPU10_OPCODE_DP4, &dst,
3325 &plane_src, &clipvert_src, FALSE);
3326 }
3327
3328 /* copy temporary clip vertex register to the clip vertex register */
3329
3330 assert(emit->clip_vertex_out_index != INVALID_INDEX);
3331
3332 /**
3333 * temporary reset the temporary clip vertex register index so
3334 * that copy to the clip vertex register will not attempt
3335 * to copy to the temporary register again
3336 */
3337 emit->clip_vertex_tmp_index = INVALID_INDEX;
3338
3339 /* MOV clip_vertex, clip_vertex_tmp */
3340 dst = make_dst_reg(TGSI_FILE_OUTPUT, emit->clip_vertex_out_index);
3341 emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
3342 &dst, &clipvert_src, FALSE);
3343
3344 /**
3345 * set the temporary clip vertex register index back to the
3346 * temporary index for the next vertex
3347 */
3348 emit->clip_vertex_tmp_index = clip_vertex_tmp;
3349 }
3350
3351 /**
3352 * Emit code to convert RGBA to BGRA
3353 */
3354 static void
emit_swap_r_b(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src)3355 emit_swap_r_b(struct svga_shader_emitter_v10 *emit,
3356 const struct tgsi_full_dst_register *dst,
3357 const struct tgsi_full_src_register *src)
3358 {
3359 struct tgsi_full_src_register bgra_src =
3360 swizzle_src(src, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_W);
3361
3362 begin_emit_instruction(emit);
3363 emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
3364 emit_dst_register(emit, dst);
3365 emit_src_register(emit, &bgra_src);
3366 end_emit_instruction(emit);
3367 }
3368
3369
3370 /** Convert from 10_10_10_2 normalized to 10_10_10_2_snorm */
3371 static void
emit_puint_to_snorm(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src)3372 emit_puint_to_snorm(struct svga_shader_emitter_v10 *emit,
3373 const struct tgsi_full_dst_register *dst,
3374 const struct tgsi_full_src_register *src)
3375 {
3376 struct tgsi_full_src_register half = make_immediate_reg_float(emit, 0.5f);
3377 struct tgsi_full_src_register two =
3378 make_immediate_reg_float4(emit, 2.0f, 2.0f, 2.0f, 3.0f);
3379 struct tgsi_full_src_register neg_two =
3380 make_immediate_reg_float4(emit, -2.0f, -2.0f, -2.0f, -1.66666f);
3381
3382 unsigned val_tmp = get_temp_index(emit);
3383 struct tgsi_full_dst_register val_dst = make_dst_temp_reg(val_tmp);
3384 struct tgsi_full_src_register val_src = make_src_temp_reg(val_tmp);
3385
3386 unsigned bias_tmp = get_temp_index(emit);
3387 struct tgsi_full_dst_register bias_dst = make_dst_temp_reg(bias_tmp);
3388 struct tgsi_full_src_register bias_src = make_src_temp_reg(bias_tmp);
3389
3390 /* val = src * 2.0 */
3391 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &val_dst,
3392 src, &two, FALSE);
3393
3394 /* bias = src > 0.5 */
3395 emit_instruction_op2(emit, VGPU10_OPCODE_GE, &bias_dst,
3396 src, &half, FALSE);
3397
3398 /* bias = bias & -2.0 */
3399 emit_instruction_op2(emit, VGPU10_OPCODE_AND, &bias_dst,
3400 &bias_src, &neg_two, FALSE);
3401
3402 /* dst = val + bias */
3403 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, dst,
3404 &val_src, &bias_src, FALSE);
3405
3406 free_temp_indexes(emit);
3407 }
3408
3409
3410 /** Convert from 10_10_10_2_unorm to 10_10_10_2_uscaled */
3411 static void
emit_puint_to_uscaled(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src)3412 emit_puint_to_uscaled(struct svga_shader_emitter_v10 *emit,
3413 const struct tgsi_full_dst_register *dst,
3414 const struct tgsi_full_src_register *src)
3415 {
3416 struct tgsi_full_src_register scale =
3417 make_immediate_reg_float4(emit, 1023.0f, 1023.0f, 1023.0f, 3.0f);
3418
3419 /* dst = src * scale */
3420 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, dst, src, &scale, FALSE);
3421 }
3422
3423
3424 /** Convert from R32_UINT to 10_10_10_2_sscaled */
3425 static void
emit_puint_to_sscaled(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src)3426 emit_puint_to_sscaled(struct svga_shader_emitter_v10 *emit,
3427 const struct tgsi_full_dst_register *dst,
3428 const struct tgsi_full_src_register *src)
3429 {
3430 struct tgsi_full_src_register lshift =
3431 make_immediate_reg_int4(emit, 22, 12, 2, 0);
3432 struct tgsi_full_src_register rshift =
3433 make_immediate_reg_int4(emit, 22, 22, 22, 30);
3434
3435 struct tgsi_full_src_register src_xxxx = scalar_src(src, TGSI_SWIZZLE_X);
3436
3437 unsigned tmp = get_temp_index(emit);
3438 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
3439 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
3440
3441 /*
3442 * r = (pixel << 22) >> 22; # signed int in [511, -512]
3443 * g = (pixel << 12) >> 22; # signed int in [511, -512]
3444 * b = (pixel << 2) >> 22; # signed int in [511, -512]
3445 * a = (pixel << 0) >> 30; # signed int in [1, -2]
3446 * dst = i_to_f(r,g,b,a); # convert to float
3447 */
3448 emit_instruction_op2(emit, VGPU10_OPCODE_ISHL, &tmp_dst,
3449 &src_xxxx, &lshift, FALSE);
3450 emit_instruction_op2(emit, VGPU10_OPCODE_ISHR, &tmp_dst,
3451 &tmp_src, &rshift, FALSE);
3452 emit_instruction_op1(emit, VGPU10_OPCODE_ITOF, dst, &tmp_src, FALSE);
3453
3454 free_temp_indexes(emit);
3455 }
3456
3457
3458 /**
3459 * Emit code for TGSI_OPCODE_ARL or TGSI_OPCODE_UARL instruction.
3460 */
3461 static boolean
emit_arl_uarl(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3462 emit_arl_uarl(struct svga_shader_emitter_v10 *emit,
3463 const struct tgsi_full_instruction *inst)
3464 {
3465 unsigned index = inst->Dst[0].Register.Index;
3466 struct tgsi_full_dst_register dst;
3467 unsigned opcode;
3468
3469 assert(index < MAX_VGPU10_ADDR_REGS);
3470 dst = make_dst_temp_reg(emit->address_reg_index[index]);
3471
3472 /* ARL dst, s0
3473 * Translates into:
3474 * FTOI address_tmp, s0
3475 *
3476 * UARL dst, s0
3477 * Translates into:
3478 * MOV address_tmp, s0
3479 */
3480 if (inst->Instruction.Opcode == TGSI_OPCODE_ARL)
3481 opcode = VGPU10_OPCODE_FTOI;
3482 else
3483 opcode = VGPU10_OPCODE_MOV;
3484
3485 emit_instruction_op1(emit, opcode, &dst, &inst->Src[0], FALSE);
3486
3487 return TRUE;
3488 }
3489
3490
3491 /**
3492 * Emit code for TGSI_OPCODE_CAL instruction.
3493 */
3494 static boolean
emit_cal(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3495 emit_cal(struct svga_shader_emitter_v10 *emit,
3496 const struct tgsi_full_instruction *inst)
3497 {
3498 unsigned label = inst->Label.Label;
3499 VGPU10OperandToken0 operand;
3500 operand.value = 0;
3501 operand.operandType = VGPU10_OPERAND_TYPE_LABEL;
3502
3503 begin_emit_instruction(emit);
3504 emit_dword(emit, operand.value);
3505 emit_dword(emit, label);
3506 end_emit_instruction(emit);
3507
3508 return TRUE;
3509 }
3510
3511
3512 /**
3513 * Emit code for TGSI_OPCODE_IABS instruction.
3514 */
3515 static boolean
emit_iabs(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3516 emit_iabs(struct svga_shader_emitter_v10 *emit,
3517 const struct tgsi_full_instruction *inst)
3518 {
3519 /* dst.x = (src0.x < 0) ? -src0.x : src0.x
3520 * dst.y = (src0.y < 0) ? -src0.y : src0.y
3521 * dst.z = (src0.z < 0) ? -src0.z : src0.z
3522 * dst.w = (src0.w < 0) ? -src0.w : src0.w
3523 *
3524 * Translates into
3525 * IMAX dst, src, neg(src)
3526 */
3527 struct tgsi_full_src_register neg_src = negate_src(&inst->Src[0]);
3528 emit_instruction_op2(emit, VGPU10_OPCODE_IMAX, &inst->Dst[0],
3529 &inst->Src[0], &neg_src, FALSE);
3530
3531 return TRUE;
3532 }
3533
3534
3535 /**
3536 * Emit code for TGSI_OPCODE_CMP instruction.
3537 */
3538 static boolean
emit_cmp(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3539 emit_cmp(struct svga_shader_emitter_v10 *emit,
3540 const struct tgsi_full_instruction *inst)
3541 {
3542 /* dst.x = (src0.x < 0) ? src1.x : src2.x
3543 * dst.y = (src0.y < 0) ? src1.y : src2.y
3544 * dst.z = (src0.z < 0) ? src1.z : src2.z
3545 * dst.w = (src0.w < 0) ? src1.w : src2.w
3546 *
3547 * Translates into
3548 * LT tmp, src0, 0.0
3549 * MOVC dst, tmp, src1, src2
3550 */
3551 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
3552 unsigned tmp = get_temp_index(emit);
3553 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
3554 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
3555
3556 emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst,
3557 &inst->Src[0], &zero, FALSE);
3558 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0],
3559 &tmp_src, &inst->Src[1], &inst->Src[2],
3560 inst->Instruction.Saturate);
3561
3562 free_temp_indexes(emit);
3563
3564 return TRUE;
3565 }
3566
3567
3568 /**
3569 * Emit code for TGSI_OPCODE_DP2A instruction.
3570 */
3571 static boolean
emit_dp2a(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3572 emit_dp2a(struct svga_shader_emitter_v10 *emit,
3573 const struct tgsi_full_instruction *inst)
3574 {
3575 /* dst.x = src0.x * src1.x + src0.y * src1.y + src2.x
3576 * dst.y = src0.x * src1.x + src0.y * src1.y + src2.x
3577 * dst.z = src0.x * src1.x + src0.y * src1.y + src2.x
3578 * dst.w = src0.x * src1.x + src0.y * src1.y + src2.x
3579 * Translate into
3580 * MAD tmp.x, s0.y, s1.y, s2.x
3581 * MAD tmp.x, s0.x, s1.x, tmp.x
3582 * MOV dst.xyzw, tmp.xxxx
3583 */
3584 unsigned tmp = get_temp_index(emit);
3585 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
3586 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
3587
3588 struct tgsi_full_src_register tmp_src_xxxx =
3589 scalar_src(&tmp_src, TGSI_SWIZZLE_X);
3590 struct tgsi_full_dst_register tmp_dst_x =
3591 writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
3592
3593 struct tgsi_full_src_register src0_xxxx =
3594 scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
3595 struct tgsi_full_src_register src0_yyyy =
3596 scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
3597 struct tgsi_full_src_register src1_xxxx =
3598 scalar_src(&inst->Src[1], TGSI_SWIZZLE_X);
3599 struct tgsi_full_src_register src1_yyyy =
3600 scalar_src(&inst->Src[1], TGSI_SWIZZLE_Y);
3601 struct tgsi_full_src_register src2_xxxx =
3602 scalar_src(&inst->Src[2], TGSI_SWIZZLE_X);
3603
3604 emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &tmp_dst_x, &src0_yyyy,
3605 &src1_yyyy, &src2_xxxx, FALSE);
3606 emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &tmp_dst_x, &src0_xxxx,
3607 &src1_xxxx, &tmp_src_xxxx, FALSE);
3608 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
3609 &tmp_src_xxxx, inst->Instruction.Saturate);
3610
3611 free_temp_indexes(emit);
3612
3613 return TRUE;
3614 }
3615
3616
3617 /**
3618 * Emit code for TGSI_OPCODE_DPH instruction.
3619 */
3620 static boolean
emit_dph(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3621 emit_dph(struct svga_shader_emitter_v10 *emit,
3622 const struct tgsi_full_instruction *inst)
3623 {
3624 /*
3625 * DP3 tmp, s0, s1
3626 * ADD dst, tmp, s1.wwww
3627 */
3628
3629 struct tgsi_full_src_register s1_wwww =
3630 swizzle_src(&inst->Src[1], TGSI_SWIZZLE_W, TGSI_SWIZZLE_W,
3631 TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);
3632
3633 unsigned tmp = get_temp_index(emit);
3634 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
3635 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
3636
3637 /* DP3 tmp, s0, s1 */
3638 emit_instruction_op2(emit, VGPU10_OPCODE_DP3, &tmp_dst, &inst->Src[0],
3639 &inst->Src[1], FALSE);
3640
3641 /* ADD dst, tmp, s1.wwww */
3642 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &inst->Dst[0], &tmp_src,
3643 &s1_wwww, inst->Instruction.Saturate);
3644
3645 free_temp_indexes(emit);
3646
3647 return TRUE;
3648 }
3649
3650
3651 /**
3652 * Emit code for TGSI_OPCODE_DST instruction.
3653 */
3654 static boolean
emit_dst(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3655 emit_dst(struct svga_shader_emitter_v10 *emit,
3656 const struct tgsi_full_instruction *inst)
3657 {
3658 /*
3659 * dst.x = 1
3660 * dst.y = src0.y * src1.y
3661 * dst.z = src0.z
3662 * dst.w = src1.w
3663 */
3664
3665 struct tgsi_full_src_register s0_yyyy =
3666 scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
3667 struct tgsi_full_src_register s0_zzzz =
3668 scalar_src(&inst->Src[0], TGSI_SWIZZLE_Z);
3669 struct tgsi_full_src_register s1_yyyy =
3670 scalar_src(&inst->Src[1], TGSI_SWIZZLE_Y);
3671 struct tgsi_full_src_register s1_wwww =
3672 scalar_src(&inst->Src[1], TGSI_SWIZZLE_W);
3673
3674 /*
3675 * If dst and either src0 and src1 are the same we need
3676 * to create a temporary for it and insert a extra move.
3677 */
3678 unsigned tmp_move = get_temp_index(emit);
3679 struct tgsi_full_src_register move_src = make_src_temp_reg(tmp_move);
3680 struct tgsi_full_dst_register move_dst = make_dst_temp_reg(tmp_move);
3681
3682 /* MOV dst.x, 1.0 */
3683 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
3684 struct tgsi_full_dst_register dst_x =
3685 writemask_dst(&move_dst, TGSI_WRITEMASK_X);
3686 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
3687
3688 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_x, &one, FALSE);
3689 }
3690
3691 /* MUL dst.y, s0.y, s1.y */
3692 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3693 struct tgsi_full_dst_register dst_y =
3694 writemask_dst(&move_dst, TGSI_WRITEMASK_Y);
3695
3696 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &dst_y, &s0_yyyy,
3697 &s1_yyyy, inst->Instruction.Saturate);
3698 }
3699
3700 /* MOV dst.z, s0.z */
3701 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3702 struct tgsi_full_dst_register dst_z =
3703 writemask_dst(&move_dst, TGSI_WRITEMASK_Z);
3704
3705 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_z, &s0_zzzz,
3706 inst->Instruction.Saturate);
3707 }
3708
3709 /* MOV dst.w, s1.w */
3710 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3711 struct tgsi_full_dst_register dst_w =
3712 writemask_dst(&move_dst, TGSI_WRITEMASK_W);
3713
3714 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &s1_wwww,
3715 inst->Instruction.Saturate);
3716 }
3717
3718 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &move_src,
3719 FALSE);
3720 free_temp_indexes(emit);
3721
3722 return TRUE;
3723 }
3724
3725
3726
3727 /**
3728 * Emit code for TGSI_OPCODE_ENDPRIM (GS only)
3729 */
3730 static boolean
emit_endprim(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3731 emit_endprim(struct svga_shader_emitter_v10 *emit,
3732 const struct tgsi_full_instruction *inst)
3733 {
3734 assert(emit->unit == PIPE_SHADER_GEOMETRY);
3735
3736 /* We can't use emit_simple() because the TGSI instruction has one
3737 * operand (vertex stream number) which we must ignore for VGPU10.
3738 */
3739 begin_emit_instruction(emit);
3740 emit_opcode(emit, VGPU10_OPCODE_CUT, FALSE);
3741 end_emit_instruction(emit);
3742 return TRUE;
3743 }
3744
3745
3746 /**
3747 * Emit code for TGSI_OPCODE_EX2 (2^x) instruction.
3748 */
3749 static boolean
emit_ex2(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3750 emit_ex2(struct svga_shader_emitter_v10 *emit,
3751 const struct tgsi_full_instruction *inst)
3752 {
3753 /* Note that TGSI_OPCODE_EX2 computes only one value from src.x
3754 * while VGPU10 computes four values.
3755 *
3756 * dst = EX2(src):
3757 * dst.xyzw = 2.0 ^ src.x
3758 */
3759
3760 struct tgsi_full_src_register src_xxxx =
3761 swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
3762 TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
3763
3764 /* EXP tmp, s0.xxxx */
3765 emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &inst->Dst[0], &src_xxxx,
3766 inst->Instruction.Saturate);
3767
3768 return TRUE;
3769 }
3770
3771
3772 /**
3773 * Emit code for TGSI_OPCODE_EXP instruction.
3774 */
3775 static boolean
emit_exp(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3776 emit_exp(struct svga_shader_emitter_v10 *emit,
3777 const struct tgsi_full_instruction *inst)
3778 {
3779 /*
3780 * dst.x = 2 ^ floor(s0.x)
3781 * dst.y = s0.x - floor(s0.x)
3782 * dst.z = 2 ^ s0.x
3783 * dst.w = 1.0
3784 */
3785
3786 struct tgsi_full_src_register src_xxxx =
3787 scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
3788 unsigned tmp = get_temp_index(emit);
3789 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
3790 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
3791
3792 /*
3793 * If dst and src are the same we need to create
3794 * a temporary for it and insert a extra move.
3795 */
3796 unsigned tmp_move = get_temp_index(emit);
3797 struct tgsi_full_src_register move_src = make_src_temp_reg(tmp_move);
3798 struct tgsi_full_dst_register move_dst = make_dst_temp_reg(tmp_move);
3799
3800 /* only use X component of temp reg */
3801 tmp_dst = writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
3802 tmp_src = scalar_src(&tmp_src, TGSI_SWIZZLE_X);
3803
3804 /* ROUND_NI tmp.x, s0.x */
3805 emit_instruction_op1(emit, VGPU10_OPCODE_ROUND_NI, &tmp_dst,
3806 &src_xxxx, FALSE); /* round to -infinity */
3807
3808 /* EXP dst.x, tmp.x */
3809 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
3810 struct tgsi_full_dst_register dst_x =
3811 writemask_dst(&move_dst, TGSI_WRITEMASK_X);
3812
3813 emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &dst_x, &tmp_src,
3814 inst->Instruction.Saturate);
3815 }
3816
3817 /* ADD dst.y, s0.x, -tmp */
3818 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
3819 struct tgsi_full_dst_register dst_y =
3820 writemask_dst(&move_dst, TGSI_WRITEMASK_Y);
3821 struct tgsi_full_src_register neg_tmp_src = negate_src(&tmp_src);
3822
3823 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &dst_y, &src_xxxx,
3824 &neg_tmp_src, inst->Instruction.Saturate);
3825 }
3826
3827 /* EXP dst.z, s0.x */
3828 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
3829 struct tgsi_full_dst_register dst_z =
3830 writemask_dst(&move_dst, TGSI_WRITEMASK_Z);
3831
3832 emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &dst_z, &src_xxxx,
3833 inst->Instruction.Saturate);
3834 }
3835
3836 /* MOV dst.w, 1.0 */
3837 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
3838 struct tgsi_full_dst_register dst_w =
3839 writemask_dst(&move_dst, TGSI_WRITEMASK_W);
3840 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
3841
3842 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &one,
3843 FALSE);
3844 }
3845
3846 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &move_src,
3847 FALSE);
3848
3849 free_temp_indexes(emit);
3850
3851 return TRUE;
3852 }
3853
3854
3855 /**
3856 * Emit code for TGSI_OPCODE_IF instruction.
3857 */
3858 static boolean
emit_if(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3859 emit_if(struct svga_shader_emitter_v10 *emit,
3860 const struct tgsi_full_instruction *inst)
3861 {
3862 VGPU10OpcodeToken0 opcode0;
3863
3864 /* The src register should be a scalar */
3865 assert(inst->Src[0].Register.SwizzleX == inst->Src[0].Register.SwizzleY &&
3866 inst->Src[0].Register.SwizzleX == inst->Src[0].Register.SwizzleZ &&
3867 inst->Src[0].Register.SwizzleX == inst->Src[0].Register.SwizzleW);
3868
3869 /* The only special thing here is that we need to set the
3870 * VGPU10_INSTRUCTION_TEST_NONZERO flag since we want to test if
3871 * src.x is non-zero.
3872 */
3873 opcode0.value = 0;
3874 opcode0.opcodeType = VGPU10_OPCODE_IF;
3875 opcode0.testBoolean = VGPU10_INSTRUCTION_TEST_NONZERO;
3876
3877 begin_emit_instruction(emit);
3878 emit_dword(emit, opcode0.value);
3879 emit_src_register(emit, &inst->Src[0]);
3880 end_emit_instruction(emit);
3881
3882 return TRUE;
3883 }
3884
3885
3886 /**
3887 * Emit code for TGSI_OPCODE_KILL_IF instruction (kill fragment if any of
3888 * the register components are negative).
3889 */
3890 static boolean
emit_kill_if(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3891 emit_kill_if(struct svga_shader_emitter_v10 *emit,
3892 const struct tgsi_full_instruction *inst)
3893 {
3894 unsigned tmp = get_temp_index(emit);
3895 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
3896 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
3897
3898 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
3899
3900 struct tgsi_full_dst_register tmp_dst_x =
3901 writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
3902 struct tgsi_full_src_register tmp_src_xxxx =
3903 scalar_src(&tmp_src, TGSI_SWIZZLE_X);
3904
3905 /* tmp = src[0] < 0.0 */
3906 emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst, &inst->Src[0],
3907 &zero, FALSE);
3908
3909 if (!same_swizzle_terms(&inst->Src[0])) {
3910 /* If the swizzle is not XXXX, YYYY, ZZZZ or WWWW we need to
3911 * logically OR the swizzle terms. Most uses of KILL_IF only
3912 * test one channel so it's good to avoid these extra steps.
3913 */
3914 struct tgsi_full_src_register tmp_src_yyyy =
3915 scalar_src(&tmp_src, TGSI_SWIZZLE_Y);
3916 struct tgsi_full_src_register tmp_src_zzzz =
3917 scalar_src(&tmp_src, TGSI_SWIZZLE_Z);
3918 struct tgsi_full_src_register tmp_src_wwww =
3919 scalar_src(&tmp_src, TGSI_SWIZZLE_W);
3920
3921 emit_instruction_op2(emit, VGPU10_OPCODE_OR, &tmp_dst_x, &tmp_src_xxxx,
3922 &tmp_src_yyyy, FALSE);
3923 emit_instruction_op2(emit, VGPU10_OPCODE_OR, &tmp_dst_x, &tmp_src_xxxx,
3924 &tmp_src_zzzz, FALSE);
3925 emit_instruction_op2(emit, VGPU10_OPCODE_OR, &tmp_dst_x, &tmp_src_xxxx,
3926 &tmp_src_wwww, FALSE);
3927 }
3928
3929 begin_emit_instruction(emit);
3930 emit_discard_opcode(emit, TRUE); /* discard if src0.x is non-zero */
3931 emit_src_register(emit, &tmp_src_xxxx);
3932 end_emit_instruction(emit);
3933
3934 free_temp_indexes(emit);
3935
3936 return TRUE;
3937 }
3938
3939
3940 /**
3941 * Emit code for TGSI_OPCODE_KILL instruction (unconditional discard).
3942 */
3943 static boolean
emit_kill(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3944 emit_kill(struct svga_shader_emitter_v10 *emit,
3945 const struct tgsi_full_instruction *inst)
3946 {
3947 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
3948
3949 /* DISCARD if 0.0 is zero */
3950 begin_emit_instruction(emit);
3951 emit_discard_opcode(emit, FALSE);
3952 emit_src_register(emit, &zero);
3953 end_emit_instruction(emit);
3954
3955 return TRUE;
3956 }
3957
3958
3959 /**
3960 * Emit code for TGSI_OPCODE_LG2 instruction.
3961 */
3962 static boolean
emit_lg2(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3963 emit_lg2(struct svga_shader_emitter_v10 *emit,
3964 const struct tgsi_full_instruction *inst)
3965 {
3966 /* Note that TGSI_OPCODE_LG2 computes only one value from src.x
3967 * while VGPU10 computes four values.
3968 *
3969 * dst = LG2(src):
3970 * dst.xyzw = log2(src.x)
3971 */
3972
3973 struct tgsi_full_src_register src_xxxx =
3974 swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
3975 TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
3976
3977 /* LOG tmp, s0.xxxx */
3978 emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &inst->Dst[0], &src_xxxx,
3979 inst->Instruction.Saturate);
3980
3981 return TRUE;
3982 }
3983
3984
3985 /**
3986 * Emit code for TGSI_OPCODE_LIT instruction.
3987 */
3988 static boolean
emit_lit(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)3989 emit_lit(struct svga_shader_emitter_v10 *emit,
3990 const struct tgsi_full_instruction *inst)
3991 {
3992 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
3993
3994 /*
3995 * If dst and src are the same we need to create
3996 * a temporary for it and insert a extra move.
3997 */
3998 unsigned tmp_move = get_temp_index(emit);
3999 struct tgsi_full_src_register move_src = make_src_temp_reg(tmp_move);
4000 struct tgsi_full_dst_register move_dst = make_dst_temp_reg(tmp_move);
4001
4002 /*
4003 * dst.x = 1
4004 * dst.y = max(src.x, 0)
4005 * dst.z = (src.x > 0) ? max(src.y, 0)^{clamp(src.w, -128, 128))} : 0
4006 * dst.w = 1
4007 */
4008
4009 /* MOV dst.x, 1.0 */
4010 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
4011 struct tgsi_full_dst_register dst_x =
4012 writemask_dst(&move_dst, TGSI_WRITEMASK_X);
4013 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_x, &one, FALSE);
4014 }
4015
4016 /* MOV dst.w, 1.0 */
4017 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
4018 struct tgsi_full_dst_register dst_w =
4019 writemask_dst(&move_dst, TGSI_WRITEMASK_W);
4020 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &one, FALSE);
4021 }
4022
4023 /* MAX dst.y, src.x, 0.0 */
4024 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
4025 struct tgsi_full_dst_register dst_y =
4026 writemask_dst(&move_dst, TGSI_WRITEMASK_Y);
4027 struct tgsi_full_src_register zero =
4028 make_immediate_reg_float(emit, 0.0f);
4029 struct tgsi_full_src_register src_xxxx =
4030 swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
4031 TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
4032
4033 emit_instruction_op2(emit, VGPU10_OPCODE_MAX, &dst_y, &src_xxxx,
4034 &zero, inst->Instruction.Saturate);
4035 }
4036
4037 /*
4038 * tmp1 = clamp(src.w, -128, 128);
4039 * MAX tmp1, src.w, -128
4040 * MIN tmp1, tmp1, 128
4041 *
4042 * tmp2 = max(tmp2, 0);
4043 * MAX tmp2, src.y, 0
4044 *
4045 * tmp1 = pow(tmp2, tmp1);
4046 * LOG tmp2, tmp2
4047 * MUL tmp1, tmp2, tmp1
4048 * EXP tmp1, tmp1
4049 *
4050 * tmp1 = (src.w == 0) ? 1 : tmp1;
4051 * EQ tmp2, 0, src.w
4052 * MOVC tmp1, tmp2, 1.0, tmp1
4053 *
4054 * dst.z = (0 < src.x) ? tmp1 : 0;
4055 * LT tmp2, 0, src.x
4056 * MOVC dst.z, tmp2, tmp1, 0.0
4057 */
4058 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
4059 struct tgsi_full_dst_register dst_z =
4060 writemask_dst(&move_dst, TGSI_WRITEMASK_Z);
4061
4062 unsigned tmp1 = get_temp_index(emit);
4063 struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
4064 struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
4065 unsigned tmp2 = get_temp_index(emit);
4066 struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
4067 struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
4068
4069 struct tgsi_full_src_register src_xxxx =
4070 scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
4071 struct tgsi_full_src_register src_yyyy =
4072 scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
4073 struct tgsi_full_src_register src_wwww =
4074 scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
4075
4076 struct tgsi_full_src_register zero =
4077 make_immediate_reg_float(emit, 0.0f);
4078 struct tgsi_full_src_register lowerbound =
4079 make_immediate_reg_float(emit, -128.0f);
4080 struct tgsi_full_src_register upperbound =
4081 make_immediate_reg_float(emit, 128.0f);
4082
4083 emit_instruction_op2(emit, VGPU10_OPCODE_MAX, &tmp1_dst, &src_wwww,
4084 &lowerbound, FALSE);
4085 emit_instruction_op2(emit, VGPU10_OPCODE_MIN, &tmp1_dst, &tmp1_src,
4086 &upperbound, FALSE);
4087 emit_instruction_op2(emit, VGPU10_OPCODE_MAX, &tmp2_dst, &src_yyyy,
4088 &zero, FALSE);
4089
4090 /* POW tmp1, tmp2, tmp1 */
4091 /* LOG tmp2, tmp2 */
4092 emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &tmp2_dst, &tmp2_src,
4093 FALSE);
4094
4095 /* MUL tmp1, tmp2, tmp1 */
4096 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst, &tmp2_src,
4097 &tmp1_src, FALSE);
4098
4099 /* EXP tmp1, tmp1 */
4100 emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &tmp1_dst, &tmp1_src,
4101 FALSE);
4102
4103 /* EQ tmp2, 0, src.w */
4104 emit_instruction_op2(emit, VGPU10_OPCODE_EQ, &tmp2_dst, &zero,
4105 &src_wwww, FALSE);
4106 /* MOVC tmp1.z, tmp2, tmp1, 1.0 */
4107 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &tmp1_dst,
4108 &tmp2_src, &one, &tmp1_src, FALSE);
4109
4110 /* LT tmp2, 0, src.x */
4111 emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp2_dst, &zero,
4112 &src_xxxx, FALSE);
4113 /* MOVC dst.z, tmp2, tmp1, 0.0 */
4114 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &dst_z,
4115 &tmp2_src, &tmp1_src, &zero, FALSE);
4116 }
4117
4118 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &move_src,
4119 FALSE);
4120 free_temp_indexes(emit);
4121
4122 return TRUE;
4123 }
4124
4125
4126 /**
4127 * Emit code for TGSI_OPCODE_LOG instruction.
4128 */
4129 static boolean
emit_log(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4130 emit_log(struct svga_shader_emitter_v10 *emit,
4131 const struct tgsi_full_instruction *inst)
4132 {
4133 /*
4134 * dst.x = floor(lg2(abs(s0.x)))
4135 * dst.y = abs(s0.x) / (2 ^ floor(lg2(abs(s0.x))))
4136 * dst.z = lg2(abs(s0.x))
4137 * dst.w = 1.0
4138 */
4139
4140 struct tgsi_full_src_register src_xxxx =
4141 scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
4142 unsigned tmp = get_temp_index(emit);
4143 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4144 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4145 struct tgsi_full_src_register abs_src_xxxx = absolute_src(&src_xxxx);
4146
4147 /* only use X component of temp reg */
4148 tmp_dst = writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
4149 tmp_src = scalar_src(&tmp_src, TGSI_SWIZZLE_X);
4150
4151 /* LOG tmp.x, abs(s0.x) */
4152 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XYZ) {
4153 emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &tmp_dst,
4154 &abs_src_xxxx, FALSE);
4155 }
4156
4157 /* MOV dst.z, tmp.x */
4158 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
4159 struct tgsi_full_dst_register dst_z =
4160 writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_Z);
4161
4162 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_z,
4163 &tmp_src, inst->Instruction.Saturate);
4164 }
4165
4166 /* FLR tmp.x, tmp.x */
4167 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) {
4168 emit_instruction_op1(emit, VGPU10_OPCODE_ROUND_NI, &tmp_dst,
4169 &tmp_src, FALSE);
4170 }
4171
4172 /* MOV dst.x, tmp.x */
4173 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
4174 struct tgsi_full_dst_register dst_x =
4175 writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_X);
4176
4177 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_x, &tmp_src,
4178 inst->Instruction.Saturate);
4179 }
4180
4181 /* EXP tmp.x, tmp.x */
4182 /* DIV dst.y, abs(s0.x), tmp.x */
4183 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
4184 struct tgsi_full_dst_register dst_y =
4185 writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_Y);
4186
4187 emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &tmp_dst, &tmp_src,
4188 FALSE);
4189 emit_instruction_op2(emit, VGPU10_OPCODE_DIV, &dst_y, &abs_src_xxxx,
4190 &tmp_src, inst->Instruction.Saturate);
4191 }
4192
4193 /* MOV dst.w, 1.0 */
4194 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
4195 struct tgsi_full_dst_register dst_w =
4196 writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_W);
4197 struct tgsi_full_src_register one =
4198 make_immediate_reg_float(emit, 1.0f);
4199
4200 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst_w, &one, FALSE);
4201 }
4202
4203 free_temp_indexes(emit);
4204
4205 return TRUE;
4206 }
4207
4208
4209 /**
4210 * Emit code for TGSI_OPCODE_LRP instruction.
4211 */
4212 static boolean
emit_lrp(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4213 emit_lrp(struct svga_shader_emitter_v10 *emit,
4214 const struct tgsi_full_instruction *inst)
4215 {
4216 /* dst = LRP(s0, s1, s2):
4217 * dst = s0 * (s1 - s2) + s2
4218 * Translates into:
4219 * SUB tmp, s1, s2; tmp = s1 - s2
4220 * MAD dst, s0, tmp, s2; dst = s0 * t1 + s2
4221 */
4222 unsigned tmp = get_temp_index(emit);
4223 struct tgsi_full_src_register src_tmp = make_src_temp_reg(tmp);
4224 struct tgsi_full_dst_register dst_tmp = make_dst_temp_reg(tmp);
4225 struct tgsi_full_src_register neg_src2 = negate_src(&inst->Src[2]);
4226
4227 /* ADD tmp, s1, -s2 */
4228 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &dst_tmp,
4229 &inst->Src[1], &neg_src2, FALSE);
4230
4231 /* MAD dst, s1, tmp, s3 */
4232 emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &inst->Dst[0],
4233 &inst->Src[0], &src_tmp, &inst->Src[2],
4234 inst->Instruction.Saturate);
4235
4236 free_temp_indexes(emit);
4237
4238 return TRUE;
4239 }
4240
4241
4242 /**
4243 * Emit code for TGSI_OPCODE_POW instruction.
4244 */
4245 static boolean
emit_pow(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4246 emit_pow(struct svga_shader_emitter_v10 *emit,
4247 const struct tgsi_full_instruction *inst)
4248 {
4249 /* Note that TGSI_OPCODE_POW computes only one value from src0.x and
4250 * src1.x while VGPU10 computes four values.
4251 *
4252 * dst = POW(src0, src1):
4253 * dst.xyzw = src0.x ^ src1.x
4254 */
4255 unsigned tmp = get_temp_index(emit);
4256 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4257 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4258 struct tgsi_full_src_register src0_xxxx =
4259 swizzle_src(&inst->Src[0], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
4260 TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
4261 struct tgsi_full_src_register src1_xxxx =
4262 swizzle_src(&inst->Src[1], TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
4263 TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
4264
4265 /* LOG tmp, s0.xxxx */
4266 emit_instruction_op1(emit, VGPU10_OPCODE_LOG, &tmp_dst, &src0_xxxx,
4267 FALSE);
4268
4269 /* MUL tmp, tmp, s1.xxxx */
4270 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_dst, &tmp_src,
4271 &src1_xxxx, FALSE);
4272
4273 /* EXP tmp, s0.xxxx */
4274 emit_instruction_op1(emit, VGPU10_OPCODE_EXP, &inst->Dst[0],
4275 &tmp_src, inst->Instruction.Saturate);
4276
4277 /* free tmp */
4278 free_temp_indexes(emit);
4279
4280 return TRUE;
4281 }
4282
4283
4284 /**
4285 * Emit code for TGSI_OPCODE_RCP (reciprocal) instruction.
4286 */
4287 static boolean
emit_rcp(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4288 emit_rcp(struct svga_shader_emitter_v10 *emit,
4289 const struct tgsi_full_instruction *inst)
4290 {
4291 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
4292
4293 unsigned tmp = get_temp_index(emit);
4294 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4295 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4296
4297 struct tgsi_full_dst_register tmp_dst_x =
4298 writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
4299 struct tgsi_full_src_register tmp_src_xxxx =
4300 scalar_src(&tmp_src, TGSI_SWIZZLE_X);
4301
4302 /* DIV tmp.x, 1.0, s0 */
4303 emit_instruction_op2(emit, VGPU10_OPCODE_DIV, &tmp_dst_x, &one,
4304 &inst->Src[0], FALSE);
4305
4306 /* MOV dst, tmp.xxxx */
4307 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
4308 &tmp_src_xxxx, inst->Instruction.Saturate);
4309
4310 free_temp_indexes(emit);
4311
4312 return TRUE;
4313 }
4314
4315
4316 /**
4317 * Emit code for TGSI_OPCODE_RSQ instruction.
4318 */
4319 static boolean
emit_rsq(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4320 emit_rsq(struct svga_shader_emitter_v10 *emit,
4321 const struct tgsi_full_instruction *inst)
4322 {
4323 /* dst = RSQ(src):
4324 * dst.xyzw = 1 / sqrt(src.x)
4325 * Translates into:
4326 * RSQ tmp, src.x
4327 * MOV dst, tmp.xxxx
4328 */
4329
4330 unsigned tmp = get_temp_index(emit);
4331 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4332 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4333
4334 struct tgsi_full_dst_register tmp_dst_x =
4335 writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
4336 struct tgsi_full_src_register tmp_src_xxxx =
4337 scalar_src(&tmp_src, TGSI_SWIZZLE_X);
4338
4339 /* RSQ tmp, src.x */
4340 emit_instruction_op1(emit, VGPU10_OPCODE_RSQ, &tmp_dst_x,
4341 &inst->Src[0], FALSE);
4342
4343 /* MOV dst, tmp.xxxx */
4344 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
4345 &tmp_src_xxxx, inst->Instruction.Saturate);
4346
4347 /* free tmp */
4348 free_temp_indexes(emit);
4349
4350 return TRUE;
4351 }
4352
4353
4354 /**
4355 * Emit code for TGSI_OPCODE_SCS instruction.
4356 */
4357 static boolean
emit_scs(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4358 emit_scs(struct svga_shader_emitter_v10 *emit,
4359 const struct tgsi_full_instruction *inst)
4360 {
4361 /* dst.x = cos(src.x)
4362 * dst.y = sin(src.x)
4363 * dst.z = 0.0
4364 * dst.w = 1.0
4365 */
4366 struct tgsi_full_dst_register dst_x =
4367 writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_X);
4368 struct tgsi_full_dst_register dst_y =
4369 writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_Y);
4370 struct tgsi_full_dst_register dst_zw =
4371 writemask_dst(&inst->Dst[0], TGSI_WRITEMASK_ZW);
4372
4373 struct tgsi_full_src_register zero_one =
4374 make_immediate_reg_float4(emit, 0.0f, 0.0f, 0.0f, 1.0f);
4375
4376 begin_emit_instruction(emit);
4377 emit_opcode(emit, VGPU10_OPCODE_SINCOS, inst->Instruction.Saturate);
4378 emit_dst_register(emit, &dst_y);
4379 emit_dst_register(emit, &dst_x);
4380 emit_src_register(emit, &inst->Src[0]);
4381 end_emit_instruction(emit);
4382
4383 emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
4384 &dst_zw, &zero_one, inst->Instruction.Saturate);
4385
4386 return TRUE;
4387 }
4388
4389
4390 /**
4391 * Emit code for TGSI_OPCODE_SEQ (Set Equal) instruction.
4392 */
4393 static boolean
emit_seq(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4394 emit_seq(struct svga_shader_emitter_v10 *emit,
4395 const struct tgsi_full_instruction *inst)
4396 {
4397 /* dst = SEQ(s0, s1):
4398 * dst = s0 == s1 ? 1.0 : 0.0 (per component)
4399 * Translates into:
4400 * EQ tmp, s0, s1; tmp = s0 == s1 : 0xffffffff : 0 (per comp)
4401 * MOVC dst, tmp, 1.0, 0.0; dst = tmp ? 1.0 : 0.0 (per component)
4402 */
4403 unsigned tmp = get_temp_index(emit);
4404 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4405 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4406 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
4407 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
4408
4409 /* EQ tmp, s0, s1 */
4410 emit_instruction_op2(emit, VGPU10_OPCODE_EQ, &tmp_dst, &inst->Src[0],
4411 &inst->Src[1], FALSE);
4412
4413 /* MOVC dst, tmp, one, zero */
4414 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
4415 &one, &zero, FALSE);
4416
4417 free_temp_indexes(emit);
4418
4419 return TRUE;
4420 }
4421
4422
4423 /**
4424 * Emit code for TGSI_OPCODE_SGE (Set Greater than or Equal) instruction.
4425 */
4426 static boolean
emit_sge(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4427 emit_sge(struct svga_shader_emitter_v10 *emit,
4428 const struct tgsi_full_instruction *inst)
4429 {
4430 /* dst = SGE(s0, s1):
4431 * dst = s0 >= s1 ? 1.0 : 0.0 (per component)
4432 * Translates into:
4433 * GE tmp, s0, s1; tmp = s0 >= s1 : 0xffffffff : 0 (per comp)
4434 * MOVC dst, tmp, 1.0, 0.0; dst = tmp ? 1.0 : 0.0 (per component)
4435 */
4436 unsigned tmp = get_temp_index(emit);
4437 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4438 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4439 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
4440 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
4441
4442 /* GE tmp, s0, s1 */
4443 emit_instruction_op2(emit, VGPU10_OPCODE_GE, &tmp_dst, &inst->Src[0],
4444 &inst->Src[1], FALSE);
4445
4446 /* MOVC dst, tmp, one, zero */
4447 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
4448 &one, &zero, FALSE);
4449
4450 free_temp_indexes(emit);
4451
4452 return TRUE;
4453 }
4454
4455
4456 /**
4457 * Emit code for TGSI_OPCODE_SGT (Set Greater than) instruction.
4458 */
4459 static boolean
emit_sgt(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4460 emit_sgt(struct svga_shader_emitter_v10 *emit,
4461 const struct tgsi_full_instruction *inst)
4462 {
4463 /* dst = SGT(s0, s1):
4464 * dst = s0 > s1 ? 1.0 : 0.0 (per component)
4465 * Translates into:
4466 * LT tmp, s1, s0; tmp = s1 < s0 ? 0xffffffff : 0 (per comp)
4467 * MOVC dst, tmp, 1.0, 0.0; dst = tmp ? 1.0 : 0.0 (per component)
4468 */
4469 unsigned tmp = get_temp_index(emit);
4470 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4471 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4472 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
4473 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
4474
4475 /* LT tmp, s1, s0 */
4476 emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst, &inst->Src[1],
4477 &inst->Src[0], FALSE);
4478
4479 /* MOVC dst, tmp, one, zero */
4480 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
4481 &one, &zero, FALSE);
4482
4483 free_temp_indexes(emit);
4484
4485 return TRUE;
4486 }
4487
4488
4489 /**
4490 * Emit code for TGSI_OPCODE_SIN and TGSI_OPCODE_COS instructions.
4491 */
4492 static boolean
emit_sincos(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4493 emit_sincos(struct svga_shader_emitter_v10 *emit,
4494 const struct tgsi_full_instruction *inst)
4495 {
4496 unsigned tmp = get_temp_index(emit);
4497 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4498 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4499
4500 struct tgsi_full_src_register tmp_src_xxxx =
4501 scalar_src(&tmp_src, TGSI_SWIZZLE_X);
4502 struct tgsi_full_dst_register tmp_dst_x =
4503 writemask_dst(&tmp_dst, TGSI_WRITEMASK_X);
4504
4505 begin_emit_instruction(emit);
4506 emit_opcode(emit, VGPU10_OPCODE_SINCOS, FALSE);
4507
4508 if(inst->Instruction.Opcode == TGSI_OPCODE_SIN)
4509 {
4510 emit_dst_register(emit, &tmp_dst_x); /* first destination register */
4511 emit_null_dst_register(emit); /* second destination register */
4512 }
4513 else {
4514 emit_null_dst_register(emit);
4515 emit_dst_register(emit, &tmp_dst_x);
4516 }
4517
4518 emit_src_register(emit, &inst->Src[0]);
4519 end_emit_instruction(emit);
4520
4521 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0],
4522 &tmp_src_xxxx, inst->Instruction.Saturate);
4523
4524 free_temp_indexes(emit);
4525
4526 return TRUE;
4527 }
4528
4529
4530 /**
4531 * Emit code for TGSI_OPCODE_SLE (Set Less than or Equal) instruction.
4532 */
4533 static boolean
emit_sle(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4534 emit_sle(struct svga_shader_emitter_v10 *emit,
4535 const struct tgsi_full_instruction *inst)
4536 {
4537 /* dst = SLE(s0, s1):
4538 * dst = s0 <= s1 ? 1.0 : 0.0 (per component)
4539 * Translates into:
4540 * GE tmp, s1, s0; tmp = s1 >= s0 : 0xffffffff : 0 (per comp)
4541 * MOVC dst, tmp, 1.0, 0.0; dst = tmp ? 1.0 : 0.0 (per component)
4542 */
4543 unsigned tmp = get_temp_index(emit);
4544 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4545 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4546 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
4547 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
4548
4549 /* GE tmp, s1, s0 */
4550 emit_instruction_op2(emit, VGPU10_OPCODE_GE, &tmp_dst, &inst->Src[1],
4551 &inst->Src[0], FALSE);
4552
4553 /* MOVC dst, tmp, one, zero */
4554 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
4555 &one, &zero, FALSE);
4556
4557 free_temp_indexes(emit);
4558
4559 return TRUE;
4560 }
4561
4562
4563 /**
4564 * Emit code for TGSI_OPCODE_SLT (Set Less than) instruction.
4565 */
4566 static boolean
emit_slt(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4567 emit_slt(struct svga_shader_emitter_v10 *emit,
4568 const struct tgsi_full_instruction *inst)
4569 {
4570 /* dst = SLT(s0, s1):
4571 * dst = s0 < s1 ? 1.0 : 0.0 (per component)
4572 * Translates into:
4573 * LT tmp, s0, s1; tmp = s0 < s1 ? 0xffffffff : 0 (per comp)
4574 * MOVC dst, tmp, 1.0, 0.0; dst = tmp ? 1.0 : 0.0 (per component)
4575 */
4576 unsigned tmp = get_temp_index(emit);
4577 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4578 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4579 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
4580 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
4581
4582 /* LT tmp, s0, s1 */
4583 emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp_dst, &inst->Src[0],
4584 &inst->Src[1], FALSE);
4585
4586 /* MOVC dst, tmp, one, zero */
4587 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
4588 &one, &zero, FALSE);
4589
4590 free_temp_indexes(emit);
4591
4592 return TRUE;
4593 }
4594
4595
4596 /**
4597 * Emit code for TGSI_OPCODE_SNE (Set Not Equal) instruction.
4598 */
4599 static boolean
emit_sne(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4600 emit_sne(struct svga_shader_emitter_v10 *emit,
4601 const struct tgsi_full_instruction *inst)
4602 {
4603 /* dst = SNE(s0, s1):
4604 * dst = s0 != s1 ? 1.0 : 0.0 (per component)
4605 * Translates into:
4606 * EQ tmp, s0, s1; tmp = s0 == s1 : 0xffffffff : 0 (per comp)
4607 * MOVC dst, tmp, 1.0, 0.0; dst = tmp ? 1.0 : 0.0 (per component)
4608 */
4609 unsigned tmp = get_temp_index(emit);
4610 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4611 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4612 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
4613 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
4614
4615 /* NE tmp, s0, s1 */
4616 emit_instruction_op2(emit, VGPU10_OPCODE_NE, &tmp_dst, &inst->Src[0],
4617 &inst->Src[1], FALSE);
4618
4619 /* MOVC dst, tmp, one, zero */
4620 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp_src,
4621 &one, &zero, FALSE);
4622
4623 free_temp_indexes(emit);
4624
4625 return TRUE;
4626 }
4627
4628
4629 /**
4630 * Emit code for TGSI_OPCODE_SSG (Set Sign) instruction.
4631 */
4632 static boolean
emit_ssg(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4633 emit_ssg(struct svga_shader_emitter_v10 *emit,
4634 const struct tgsi_full_instruction *inst)
4635 {
4636 /* dst.x = (src.x > 0.0) ? 1.0 : (src.x < 0.0) ? -1.0 : 0.0
4637 * dst.y = (src.y > 0.0) ? 1.0 : (src.y < 0.0) ? -1.0 : 0.0
4638 * dst.z = (src.z > 0.0) ? 1.0 : (src.z < 0.0) ? -1.0 : 0.0
4639 * dst.w = (src.w > 0.0) ? 1.0 : (src.w < 0.0) ? -1.0 : 0.0
4640 * Translates into:
4641 * LT tmp1, src, zero; tmp1 = src < zero ? 0xffffffff : 0 (per comp)
4642 * MOVC tmp2, tmp1, -1.0, 0.0; tmp2 = tmp1 ? -1.0 : 0.0 (per component)
4643 * LT tmp1, zero, src; tmp1 = zero < src ? 0xffffffff : 0 (per comp)
4644 * MOVC dst, tmp1, 1.0, tmp2; dst = tmp1 ? 1.0 : tmp2 (per component)
4645 */
4646 struct tgsi_full_src_register zero =
4647 make_immediate_reg_float(emit, 0.0f);
4648 struct tgsi_full_src_register one =
4649 make_immediate_reg_float(emit, 1.0f);
4650 struct tgsi_full_src_register neg_one =
4651 make_immediate_reg_float(emit, -1.0f);
4652
4653 unsigned tmp1 = get_temp_index(emit);
4654 struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
4655 struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
4656
4657 unsigned tmp2 = get_temp_index(emit);
4658 struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
4659 struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
4660
4661 emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp1_dst, &inst->Src[0],
4662 &zero, FALSE);
4663 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &tmp2_dst, &tmp1_src,
4664 &neg_one, &zero, FALSE);
4665 emit_instruction_op2(emit, VGPU10_OPCODE_LT, &tmp1_dst, &zero,
4666 &inst->Src[0], FALSE);
4667 emit_instruction_op3(emit, VGPU10_OPCODE_MOVC, &inst->Dst[0], &tmp1_src,
4668 &one, &tmp2_src, FALSE);
4669
4670 free_temp_indexes(emit);
4671
4672 return TRUE;
4673 }
4674
4675
4676 /**
4677 * Emit code for TGSI_OPCODE_ISSG (Integer Set Sign) instruction.
4678 */
4679 static boolean
emit_issg(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)4680 emit_issg(struct svga_shader_emitter_v10 *emit,
4681 const struct tgsi_full_instruction *inst)
4682 {
4683 /* dst.x = (src.x > 0) ? 1 : (src.x < 0) ? -1 : 0
4684 * dst.y = (src.y > 0) ? 1 : (src.y < 0) ? -1 : 0
4685 * dst.z = (src.z > 0) ? 1 : (src.z < 0) ? -1 : 0
4686 * dst.w = (src.w > 0) ? 1 : (src.w < 0) ? -1 : 0
4687 * Translates into:
4688 * ILT tmp1, src, 0 tmp1 = src < 0 ? -1 : 0 (per component)
4689 * ILT tmp2, 0, src tmp2 = 0 < src ? -1 : 0 (per component)
4690 * IADD dst, tmp1, neg(tmp2) dst = tmp1 - tmp2 (per component)
4691 */
4692 struct tgsi_full_src_register zero = make_immediate_reg_float(emit, 0.0f);
4693
4694 unsigned tmp1 = get_temp_index(emit);
4695 struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
4696 struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
4697
4698 unsigned tmp2 = get_temp_index(emit);
4699 struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
4700 struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
4701
4702 struct tgsi_full_src_register neg_tmp2 = negate_src(&tmp2_src);
4703
4704 emit_instruction_op2(emit, VGPU10_OPCODE_ILT, &tmp1_dst,
4705 &inst->Src[0], &zero, FALSE);
4706 emit_instruction_op2(emit, VGPU10_OPCODE_ILT, &tmp2_dst,
4707 &zero, &inst->Src[0], FALSE);
4708 emit_instruction_op2(emit, VGPU10_OPCODE_IADD, &inst->Dst[0],
4709 &tmp1_src, &neg_tmp2, FALSE);
4710
4711 free_temp_indexes(emit);
4712
4713 return TRUE;
4714 }
4715
4716
4717 /**
4718 * Emit a comparison instruction. The dest register will get
4719 * 0 or ~0 values depending on the outcome of comparing src0 to src1.
4720 */
4721 static void
emit_comparison(struct svga_shader_emitter_v10 * emit,SVGA3dCmpFunc func,const struct tgsi_full_dst_register * dst,const struct tgsi_full_src_register * src0,const struct tgsi_full_src_register * src1)4722 emit_comparison(struct svga_shader_emitter_v10 *emit,
4723 SVGA3dCmpFunc func,
4724 const struct tgsi_full_dst_register *dst,
4725 const struct tgsi_full_src_register *src0,
4726 const struct tgsi_full_src_register *src1)
4727 {
4728 struct tgsi_full_src_register immediate;
4729 VGPU10OpcodeToken0 opcode0;
4730 boolean swapSrc = FALSE;
4731
4732 /* Sanity checks for svga vs. gallium enums */
4733 STATIC_ASSERT(SVGA3D_CMP_LESS == (PIPE_FUNC_LESS + 1));
4734 STATIC_ASSERT(SVGA3D_CMP_GREATEREQUAL == (PIPE_FUNC_GEQUAL + 1));
4735
4736 opcode0.value = 0;
4737
4738 switch (func) {
4739 case SVGA3D_CMP_NEVER:
4740 immediate = make_immediate_reg_int(emit, 0);
4741 /* MOV dst, {0} */
4742 begin_emit_instruction(emit);
4743 emit_dword(emit, VGPU10_OPCODE_MOV);
4744 emit_dst_register(emit, dst);
4745 emit_src_register(emit, &immediate);
4746 end_emit_instruction(emit);
4747 return;
4748 case SVGA3D_CMP_ALWAYS:
4749 immediate = make_immediate_reg_int(emit, -1);
4750 /* MOV dst, {-1} */
4751 begin_emit_instruction(emit);
4752 emit_dword(emit, VGPU10_OPCODE_MOV);
4753 emit_dst_register(emit, dst);
4754 emit_src_register(emit, &immediate);
4755 end_emit_instruction(emit);
4756 return;
4757 case SVGA3D_CMP_LESS:
4758 opcode0.opcodeType = VGPU10_OPCODE_LT;
4759 break;
4760 case SVGA3D_CMP_EQUAL:
4761 opcode0.opcodeType = VGPU10_OPCODE_EQ;
4762 break;
4763 case SVGA3D_CMP_LESSEQUAL:
4764 opcode0.opcodeType = VGPU10_OPCODE_GE;
4765 swapSrc = TRUE;
4766 break;
4767 case SVGA3D_CMP_GREATER:
4768 opcode0.opcodeType = VGPU10_OPCODE_LT;
4769 swapSrc = TRUE;
4770 break;
4771 case SVGA3D_CMP_NOTEQUAL:
4772 opcode0.opcodeType = VGPU10_OPCODE_NE;
4773 break;
4774 case SVGA3D_CMP_GREATEREQUAL:
4775 opcode0.opcodeType = VGPU10_OPCODE_GE;
4776 break;
4777 default:
4778 assert(!"Unexpected comparison mode");
4779 opcode0.opcodeType = VGPU10_OPCODE_EQ;
4780 }
4781
4782 begin_emit_instruction(emit);
4783 emit_dword(emit, opcode0.value);
4784 emit_dst_register(emit, dst);
4785 if (swapSrc) {
4786 emit_src_register(emit, src1);
4787 emit_src_register(emit, src0);
4788 }
4789 else {
4790 emit_src_register(emit, src0);
4791 emit_src_register(emit, src1);
4792 }
4793 end_emit_instruction(emit);
4794 }
4795
4796
4797 /**
4798 * Get texel/address offsets for a texture instruction.
4799 */
4800 static void
get_texel_offsets(const struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst,int offsets[3])4801 get_texel_offsets(const struct svga_shader_emitter_v10 *emit,
4802 const struct tgsi_full_instruction *inst, int offsets[3])
4803 {
4804 if (inst->Texture.NumOffsets == 1) {
4805 /* According to OpenGL Shader Language spec the offsets are only
4806 * fetched from a previously-declared immediate/literal.
4807 */
4808 const struct tgsi_texture_offset *off = inst->TexOffsets;
4809 const unsigned index = off[0].Index;
4810 const unsigned swizzleX = off[0].SwizzleX;
4811 const unsigned swizzleY = off[0].SwizzleY;
4812 const unsigned swizzleZ = off[0].SwizzleZ;
4813 const union tgsi_immediate_data *imm = emit->immediates[index];
4814
4815 assert(inst->TexOffsets[0].File == TGSI_FILE_IMMEDIATE);
4816
4817 offsets[0] = imm[swizzleX].Int;
4818 offsets[1] = imm[swizzleY].Int;
4819 offsets[2] = imm[swizzleZ].Int;
4820 }
4821 else {
4822 offsets[0] = offsets[1] = offsets[2] = 0;
4823 }
4824 }
4825
4826
4827 /**
4828 * Set up the coordinate register for texture sampling.
4829 * When we're sampling from a RECT texture we have to scale the
4830 * unnormalized coordinate to a normalized coordinate.
4831 * We do that by multiplying the coordinate by an "extra" constant.
4832 * An alternative would be to use the RESINFO instruction to query the
4833 * texture's size.
4834 */
4835 static struct tgsi_full_src_register
setup_texcoord(struct svga_shader_emitter_v10 * emit,unsigned unit,const struct tgsi_full_src_register * coord)4836 setup_texcoord(struct svga_shader_emitter_v10 *emit,
4837 unsigned unit,
4838 const struct tgsi_full_src_register *coord)
4839 {
4840 if (emit->key.tex[unit].unnormalized) {
4841 unsigned scale_index = emit->texcoord_scale_index[unit];
4842 unsigned tmp = get_temp_index(emit);
4843 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
4844 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
4845 struct tgsi_full_src_register scale_src = make_src_const_reg(scale_index);
4846
4847 /* MUL tmp, coord, const[] */
4848 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_dst,
4849 coord, &scale_src, FALSE);
4850 return tmp_src;
4851 }
4852 else {
4853 /* use texcoord as-is */
4854 return *coord;
4855 }
4856 }
4857
4858
4859 /**
4860 * For SAMPLE_C instructions, emit the extra src register which indicates
4861 * the reference/comparision value.
4862 */
4863 static void
emit_tex_compare_refcoord(struct svga_shader_emitter_v10 * emit,unsigned target,const struct tgsi_full_src_register * coord)4864 emit_tex_compare_refcoord(struct svga_shader_emitter_v10 *emit,
4865 unsigned target,
4866 const struct tgsi_full_src_register *coord)
4867 {
4868 struct tgsi_full_src_register coord_src_ref;
4869 unsigned component;
4870
4871 assert(tgsi_is_shadow_target(target));
4872
4873 assert(target != TGSI_TEXTURE_SHADOWCUBE_ARRAY); /* XXX not implemented */
4874 if (target == TGSI_TEXTURE_SHADOW2D_ARRAY ||
4875 target == TGSI_TEXTURE_SHADOWCUBE)
4876 component = TGSI_SWIZZLE_W;
4877 else
4878 component = TGSI_SWIZZLE_Z;
4879
4880 coord_src_ref = scalar_src(coord, component);
4881
4882 emit_src_register(emit, &coord_src_ref);
4883 }
4884
4885
4886 /**
4887 * Info for implementing texture swizzles.
4888 * The begin_tex_swizzle(), get_tex_swizzle_dst() and end_tex_swizzle()
4889 * functions use this to encapsulate the extra steps needed to perform
4890 * a texture swizzle, or shadow/depth comparisons.
4891 * The shadow/depth comparison is only done here if for the cases where
4892 * there's no VGPU10 opcode (like texture bias lookup w/ shadow compare).
4893 */
4894 struct tex_swizzle_info
4895 {
4896 boolean swizzled;
4897 boolean shadow_compare;
4898 unsigned unit;
4899 unsigned texture_target; /**< TGSI_TEXTURE_x */
4900 struct tgsi_full_src_register tmp_src;
4901 struct tgsi_full_dst_register tmp_dst;
4902 const struct tgsi_full_dst_register *inst_dst;
4903 const struct tgsi_full_src_register *coord_src;
4904 };
4905
4906
4907 /**
4908 * Do setup for handling texture swizzles or shadow compares.
4909 * \param unit the texture unit
4910 * \param inst the TGSI texture instruction
4911 * \param shadow_compare do shadow/depth comparison?
4912 * \param swz returns the swizzle info
4913 */
4914 static void
begin_tex_swizzle(struct svga_shader_emitter_v10 * emit,unsigned unit,const struct tgsi_full_instruction * inst,boolean shadow_compare,struct tex_swizzle_info * swz)4915 begin_tex_swizzle(struct svga_shader_emitter_v10 *emit,
4916 unsigned unit,
4917 const struct tgsi_full_instruction *inst,
4918 boolean shadow_compare,
4919 struct tex_swizzle_info *swz)
4920 {
4921 swz->swizzled = (emit->key.tex[unit].swizzle_r != TGSI_SWIZZLE_X ||
4922 emit->key.tex[unit].swizzle_g != TGSI_SWIZZLE_Y ||
4923 emit->key.tex[unit].swizzle_b != TGSI_SWIZZLE_Z ||
4924 emit->key.tex[unit].swizzle_a != TGSI_SWIZZLE_W);
4925
4926 swz->shadow_compare = shadow_compare;
4927 swz->texture_target = inst->Texture.Texture;
4928
4929 if (swz->swizzled || shadow_compare) {
4930 /* Allocate temp register for the result of the SAMPLE instruction
4931 * and the source of the MOV/compare/swizzle instructions.
4932 */
4933 unsigned tmp = get_temp_index(emit);
4934 swz->tmp_src = make_src_temp_reg(tmp);
4935 swz->tmp_dst = make_dst_temp_reg(tmp);
4936
4937 swz->unit = unit;
4938 }
4939 swz->inst_dst = &inst->Dst[0];
4940 swz->coord_src = &inst->Src[0];
4941 }
4942
4943
4944 /**
4945 * Returns the register to put the SAMPLE instruction results into.
4946 * This will either be the original instruction dst reg (if no swizzle
4947 * and no shadow comparison) or a temporary reg if there is a swizzle.
4948 */
4949 static const struct tgsi_full_dst_register *
get_tex_swizzle_dst(const struct tex_swizzle_info * swz)4950 get_tex_swizzle_dst(const struct tex_swizzle_info *swz)
4951 {
4952 return (swz->swizzled || swz->shadow_compare)
4953 ? &swz->tmp_dst : swz->inst_dst;
4954 }
4955
4956
4957 /**
4958 * This emits the MOV instruction that actually implements a texture swizzle
4959 * and/or shadow comparison.
4960 */
4961 static void
end_tex_swizzle(struct svga_shader_emitter_v10 * emit,const struct tex_swizzle_info * swz)4962 end_tex_swizzle(struct svga_shader_emitter_v10 *emit,
4963 const struct tex_swizzle_info *swz)
4964 {
4965 if (swz->shadow_compare) {
4966 /* Emit extra instructions to compare the fetched texel value against
4967 * a texture coordinate component. The result of the comparison
4968 * is 0.0 or 1.0.
4969 */
4970 struct tgsi_full_src_register coord_src;
4971 struct tgsi_full_src_register texel_src =
4972 scalar_src(&swz->tmp_src, TGSI_SWIZZLE_X);
4973 struct tgsi_full_src_register one =
4974 make_immediate_reg_float(emit, 1.0f);
4975 /* convert gallium comparison func to SVGA comparison func */
4976 SVGA3dCmpFunc compare_func = emit->key.tex[swz->unit].compare_func + 1;
4977
4978 assert(emit->unit == PIPE_SHADER_FRAGMENT);
4979
4980 switch (swz->texture_target) {
4981 case TGSI_TEXTURE_SHADOW2D:
4982 case TGSI_TEXTURE_SHADOWRECT:
4983 case TGSI_TEXTURE_SHADOW1D_ARRAY:
4984 coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_Z);
4985 break;
4986 case TGSI_TEXTURE_SHADOW1D:
4987 coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_Y);
4988 break;
4989 case TGSI_TEXTURE_SHADOWCUBE:
4990 case TGSI_TEXTURE_SHADOW2D_ARRAY:
4991 coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_W);
4992 break;
4993 default:
4994 assert(!"Unexpected texture target in end_tex_swizzle()");
4995 coord_src = scalar_src(swz->coord_src, TGSI_SWIZZLE_Z);
4996 }
4997
4998 /* COMPARE tmp, coord, texel */
4999 /* XXX it would seem that the texel and coord arguments should
5000 * be transposed here, but piglit tests indicate otherwise.
5001 */
5002 emit_comparison(emit, compare_func,
5003 &swz->tmp_dst, &texel_src, &coord_src);
5004
5005 /* AND dest, tmp, {1.0} */
5006 begin_emit_instruction(emit);
5007 emit_opcode(emit, VGPU10_OPCODE_AND, FALSE);
5008 if (swz->swizzled) {
5009 emit_dst_register(emit, &swz->tmp_dst);
5010 }
5011 else {
5012 emit_dst_register(emit, swz->inst_dst);
5013 }
5014 emit_src_register(emit, &swz->tmp_src);
5015 emit_src_register(emit, &one);
5016 end_emit_instruction(emit);
5017 }
5018
5019 if (swz->swizzled) {
5020 unsigned swz_r = emit->key.tex[swz->unit].swizzle_r;
5021 unsigned swz_g = emit->key.tex[swz->unit].swizzle_g;
5022 unsigned swz_b = emit->key.tex[swz->unit].swizzle_b;
5023 unsigned swz_a = emit->key.tex[swz->unit].swizzle_a;
5024 unsigned writemask_0 = 0, writemask_1 = 0;
5025 boolean int_tex = is_integer_type(emit->sampler_return_type[swz->unit]);
5026
5027 /* Swizzle w/out zero/one terms */
5028 struct tgsi_full_src_register src_swizzled =
5029 swizzle_src(&swz->tmp_src,
5030 swz_r < PIPE_SWIZZLE_0 ? swz_r : PIPE_SWIZZLE_X,
5031 swz_g < PIPE_SWIZZLE_0 ? swz_g : PIPE_SWIZZLE_Y,
5032 swz_b < PIPE_SWIZZLE_0 ? swz_b : PIPE_SWIZZLE_Z,
5033 swz_a < PIPE_SWIZZLE_0 ? swz_a : PIPE_SWIZZLE_W);
5034
5035 /* MOV dst, color(tmp).<swizzle> */
5036 emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
5037 swz->inst_dst, &src_swizzled, FALSE);
5038
5039 /* handle swizzle zero terms */
5040 writemask_0 = (((swz_r == PIPE_SWIZZLE_0) << 0) |
5041 ((swz_g == PIPE_SWIZZLE_0) << 1) |
5042 ((swz_b == PIPE_SWIZZLE_0) << 2) |
5043 ((swz_a == PIPE_SWIZZLE_0) << 3));
5044
5045 if (writemask_0) {
5046 struct tgsi_full_src_register zero = int_tex ?
5047 make_immediate_reg_int(emit, 0) :
5048 make_immediate_reg_float(emit, 0.0f);
5049 struct tgsi_full_dst_register dst =
5050 writemask_dst(swz->inst_dst, writemask_0);
5051
5052 /* MOV dst.writemask_0, {0,0,0,0} */
5053 emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
5054 &dst, &zero, FALSE);
5055 }
5056
5057 /* handle swizzle one terms */
5058 writemask_1 = (((swz_r == PIPE_SWIZZLE_1) << 0) |
5059 ((swz_g == PIPE_SWIZZLE_1) << 1) |
5060 ((swz_b == PIPE_SWIZZLE_1) << 2) |
5061 ((swz_a == PIPE_SWIZZLE_1) << 3));
5062
5063 if (writemask_1) {
5064 struct tgsi_full_src_register one = int_tex ?
5065 make_immediate_reg_int(emit, 1) :
5066 make_immediate_reg_float(emit, 1.0f);
5067 struct tgsi_full_dst_register dst =
5068 writemask_dst(swz->inst_dst, writemask_1);
5069
5070 /* MOV dst.writemask_1, {1,1,1,1} */
5071 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &dst, &one, FALSE);
5072 }
5073 }
5074 }
5075
5076
5077 /**
5078 * Emit code for TGSI_OPCODE_SAMPLE instruction.
5079 */
5080 static boolean
emit_sample(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5081 emit_sample(struct svga_shader_emitter_v10 *emit,
5082 const struct tgsi_full_instruction *inst)
5083 {
5084 const unsigned resource_unit = inst->Src[1].Register.Index;
5085 const unsigned sampler_unit = inst->Src[2].Register.Index;
5086 struct tgsi_full_src_register coord;
5087 int offsets[3];
5088 struct tex_swizzle_info swz_info;
5089
5090 begin_tex_swizzle(emit, sampler_unit, inst, FALSE, &swz_info);
5091
5092 get_texel_offsets(emit, inst, offsets);
5093
5094 coord = setup_texcoord(emit, resource_unit, &inst->Src[0]);
5095
5096 /* SAMPLE dst, coord(s0), resource, sampler */
5097 begin_emit_instruction(emit);
5098
5099 emit_sample_opcode(emit, VGPU10_OPCODE_SAMPLE,
5100 inst->Instruction.Saturate, offsets);
5101 emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
5102 emit_src_register(emit, &coord);
5103 emit_resource_register(emit, resource_unit);
5104 emit_sampler_register(emit, sampler_unit);
5105 end_emit_instruction(emit);
5106
5107 end_tex_swizzle(emit, &swz_info);
5108
5109 free_temp_indexes(emit);
5110
5111 return TRUE;
5112 }
5113
5114
5115 /**
5116 * Check if a texture instruction is valid.
5117 * An example of an invalid texture instruction is doing shadow comparison
5118 * with an integer-valued texture.
5119 * If we detect an invalid texture instruction, we replace it with:
5120 * MOV dst, {1,1,1,1};
5121 * \return TRUE if valid, FALSE if invalid.
5122 */
5123 static boolean
is_valid_tex_instruction(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5124 is_valid_tex_instruction(struct svga_shader_emitter_v10 *emit,
5125 const struct tgsi_full_instruction *inst)
5126 {
5127 const unsigned unit = inst->Src[1].Register.Index;
5128 const unsigned target = inst->Texture.Texture;
5129 boolean valid = TRUE;
5130
5131 if (tgsi_is_shadow_target(target) &&
5132 is_integer_type(emit->sampler_return_type[unit])) {
5133 debug_printf("Invalid SAMPLE_C with an integer texture!\n");
5134 valid = FALSE;
5135 }
5136 /* XXX might check for other conditions in the future here */
5137
5138 if (!valid) {
5139 /* emit a MOV dst, {1,1,1,1} instruction. */
5140 struct tgsi_full_src_register one = make_immediate_reg_float(emit, 1.0f);
5141 begin_emit_instruction(emit);
5142 emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
5143 emit_dst_register(emit, &inst->Dst[0]);
5144 emit_src_register(emit, &one);
5145 end_emit_instruction(emit);
5146 }
5147
5148 return valid;
5149 }
5150
5151
5152 /**
5153 * Emit code for TGSI_OPCODE_TEX (simple texture lookup)
5154 */
5155 static boolean
emit_tex(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5156 emit_tex(struct svga_shader_emitter_v10 *emit,
5157 const struct tgsi_full_instruction *inst)
5158 {
5159 const uint unit = inst->Src[1].Register.Index;
5160 unsigned target = inst->Texture.Texture;
5161 unsigned opcode;
5162 struct tgsi_full_src_register coord;
5163 int offsets[3];
5164 struct tex_swizzle_info swz_info;
5165
5166 /* check that the sampler returns a float */
5167 if (!is_valid_tex_instruction(emit, inst))
5168 return TRUE;
5169
5170 begin_tex_swizzle(emit, unit, inst, FALSE, &swz_info);
5171
5172 get_texel_offsets(emit, inst, offsets);
5173
5174 coord = setup_texcoord(emit, unit, &inst->Src[0]);
5175
5176 /* SAMPLE dst, coord(s0), resource, sampler */
5177 begin_emit_instruction(emit);
5178
5179 if (tgsi_is_shadow_target(target))
5180 opcode = VGPU10_OPCODE_SAMPLE_C;
5181 else
5182 opcode = VGPU10_OPCODE_SAMPLE;
5183
5184 emit_sample_opcode(emit, opcode, inst->Instruction.Saturate, offsets);
5185 emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
5186 emit_src_register(emit, &coord);
5187 emit_resource_register(emit, unit);
5188 emit_sampler_register(emit, unit);
5189 if (opcode == VGPU10_OPCODE_SAMPLE_C) {
5190 emit_tex_compare_refcoord(emit, target, &coord);
5191 }
5192 end_emit_instruction(emit);
5193
5194 end_tex_swizzle(emit, &swz_info);
5195
5196 free_temp_indexes(emit);
5197
5198 return TRUE;
5199 }
5200
5201
5202 /**
5203 * Emit code for TGSI_OPCODE_TXP (projective texture)
5204 */
5205 static boolean
emit_txp(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5206 emit_txp(struct svga_shader_emitter_v10 *emit,
5207 const struct tgsi_full_instruction *inst)
5208 {
5209 const uint unit = inst->Src[1].Register.Index;
5210 unsigned target = inst->Texture.Texture;
5211 unsigned opcode;
5212 int offsets[3];
5213 unsigned tmp = get_temp_index(emit);
5214 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
5215 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
5216 struct tgsi_full_src_register src0_wwww =
5217 scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
5218 struct tgsi_full_src_register coord;
5219 struct tex_swizzle_info swz_info;
5220
5221 /* check that the sampler returns a float */
5222 if (!is_valid_tex_instruction(emit, inst))
5223 return TRUE;
5224
5225 begin_tex_swizzle(emit, unit, inst, FALSE, &swz_info);
5226
5227 get_texel_offsets(emit, inst, offsets);
5228
5229 coord = setup_texcoord(emit, unit, &inst->Src[0]);
5230
5231 /* DIV tmp, coord, coord.wwww */
5232 emit_instruction_op2(emit, VGPU10_OPCODE_DIV, &tmp_dst,
5233 &coord, &src0_wwww, FALSE);
5234
5235 /* SAMPLE dst, coord(tmp), resource, sampler */
5236 begin_emit_instruction(emit);
5237
5238 if (tgsi_is_shadow_target(target))
5239 opcode = VGPU10_OPCODE_SAMPLE_C;
5240 else
5241 opcode = VGPU10_OPCODE_SAMPLE;
5242
5243 emit_sample_opcode(emit, opcode, inst->Instruction.Saturate, offsets);
5244 emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
5245 emit_src_register(emit, &tmp_src); /* projected coord */
5246 emit_resource_register(emit, unit);
5247 emit_sampler_register(emit, unit);
5248 if (opcode == VGPU10_OPCODE_SAMPLE_C) {
5249 emit_tex_compare_refcoord(emit, target, &tmp_src);
5250 }
5251 end_emit_instruction(emit);
5252
5253 end_tex_swizzle(emit, &swz_info);
5254
5255 free_temp_indexes(emit);
5256
5257 return TRUE;
5258 }
5259
5260
5261 /*
5262 * Emit code for TGSI_OPCODE_XPD instruction.
5263 */
5264 static boolean
emit_xpd(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5265 emit_xpd(struct svga_shader_emitter_v10 *emit,
5266 const struct tgsi_full_instruction *inst)
5267 {
5268 /* dst.x = src0.y * src1.z - src1.y * src0.z
5269 * dst.y = src0.z * src1.x - src1.z * src0.x
5270 * dst.z = src0.x * src1.y - src1.x * src0.y
5271 * dst.w = 1
5272 */
5273 struct tgsi_full_src_register s0_xxxx =
5274 scalar_src(&inst->Src[0], TGSI_SWIZZLE_X);
5275 struct tgsi_full_src_register s0_yyyy =
5276 scalar_src(&inst->Src[0], TGSI_SWIZZLE_Y);
5277 struct tgsi_full_src_register s0_zzzz =
5278 scalar_src(&inst->Src[0], TGSI_SWIZZLE_Z);
5279
5280 struct tgsi_full_src_register s1_xxxx =
5281 scalar_src(&inst->Src[1], TGSI_SWIZZLE_X);
5282 struct tgsi_full_src_register s1_yyyy =
5283 scalar_src(&inst->Src[1], TGSI_SWIZZLE_Y);
5284 struct tgsi_full_src_register s1_zzzz =
5285 scalar_src(&inst->Src[1], TGSI_SWIZZLE_Z);
5286
5287 unsigned tmp1 = get_temp_index(emit);
5288 struct tgsi_full_src_register tmp1_src = make_src_temp_reg(tmp1);
5289 struct tgsi_full_dst_register tmp1_dst = make_dst_temp_reg(tmp1);
5290
5291 unsigned tmp2 = get_temp_index(emit);
5292 struct tgsi_full_src_register tmp2_src = make_src_temp_reg(tmp2);
5293 struct tgsi_full_dst_register tmp2_dst = make_dst_temp_reg(tmp2);
5294 struct tgsi_full_src_register neg_tmp2_src = negate_src(&tmp2_src);
5295
5296 unsigned tmp3 = get_temp_index(emit);
5297 struct tgsi_full_src_register tmp3_src = make_src_temp_reg(tmp3);
5298 struct tgsi_full_dst_register tmp3_dst = make_dst_temp_reg(tmp3);
5299 struct tgsi_full_dst_register tmp3_dst_x =
5300 writemask_dst(&tmp3_dst, TGSI_WRITEMASK_X);
5301 struct tgsi_full_dst_register tmp3_dst_y =
5302 writemask_dst(&tmp3_dst, TGSI_WRITEMASK_Y);
5303 struct tgsi_full_dst_register tmp3_dst_z =
5304 writemask_dst(&tmp3_dst, TGSI_WRITEMASK_Z);
5305 struct tgsi_full_dst_register tmp3_dst_w =
5306 writemask_dst(&tmp3_dst, TGSI_WRITEMASK_W);
5307
5308 /* Note: we put all the intermediate computations into tmp3 in case
5309 * the XPD dest register is that same as one of the src regs (in which
5310 * case we could clobber a src reg before we're done with it) .
5311 *
5312 * Note: we could get by with just one temp register instead of three
5313 * since we're doing scalar operations and there's enough room in one
5314 * temp for everything.
5315 */
5316
5317 /* MUL tmp1, src0.y, src1.z */
5318 /* MUL tmp2, src1.y, src0.z */
5319 /* ADD tmp3.x, tmp1, -tmp2 */
5320 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
5321 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst,
5322 &s0_yyyy, &s1_zzzz, FALSE);
5323 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp2_dst,
5324 &s1_yyyy, &s0_zzzz, FALSE);
5325 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp3_dst_x,
5326 &tmp1_src, &neg_tmp2_src, FALSE);
5327 }
5328
5329 /* MUL tmp1, src0.z, src1.x */
5330 /* MUL tmp2, src1.z, src0.x */
5331 /* ADD tmp3.y, tmp1, -tmp2 */
5332 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
5333 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst, &s0_zzzz,
5334 &s1_xxxx, FALSE);
5335 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp2_dst, &s1_zzzz,
5336 &s0_xxxx, FALSE);
5337 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp3_dst_y,
5338 &tmp1_src, &neg_tmp2_src, FALSE);
5339 }
5340
5341 /* MUL tmp1, src0.x, src1.y */
5342 /* MUL tmp2, src1.x, src0.y */
5343 /* ADD tmp3.z, tmp1, -tmp2 */
5344 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
5345 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp1_dst, &s0_xxxx,
5346 &s1_yyyy, FALSE);
5347 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp2_dst, &s1_xxxx,
5348 &s0_yyyy, FALSE);
5349 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp3_dst_z,
5350 &tmp1_src, &neg_tmp2_src, FALSE);
5351 }
5352
5353 /* MOV tmp3.w, 1.0 */
5354 if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
5355 struct tgsi_full_src_register one =
5356 make_immediate_reg_float(emit, 1.0f);
5357
5358 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &tmp3_dst_w, &one, FALSE);
5359 }
5360
5361 /* MOV dst, tmp3 */
5362 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &tmp3_src,
5363 inst->Instruction.Saturate);
5364
5365
5366 free_temp_indexes(emit);
5367
5368 return TRUE;
5369 }
5370
5371
5372 /**
5373 * Emit code for TGSI_OPCODE_TXD (explicit derivatives)
5374 */
5375 static boolean
emit_txd(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5376 emit_txd(struct svga_shader_emitter_v10 *emit,
5377 const struct tgsi_full_instruction *inst)
5378 {
5379 const uint unit = inst->Src[3].Register.Index;
5380 unsigned target = inst->Texture.Texture;
5381 int offsets[3];
5382 struct tgsi_full_src_register coord;
5383 struct tex_swizzle_info swz_info;
5384
5385 begin_tex_swizzle(emit, unit, inst, tgsi_is_shadow_target(target),
5386 &swz_info);
5387
5388 get_texel_offsets(emit, inst, offsets);
5389
5390 coord = setup_texcoord(emit, unit, &inst->Src[0]);
5391
5392 /* SAMPLE_D dst, coord(s0), resource, sampler, Xderiv(s1), Yderiv(s2) */
5393 begin_emit_instruction(emit);
5394 emit_sample_opcode(emit, VGPU10_OPCODE_SAMPLE_D,
5395 inst->Instruction.Saturate, offsets);
5396 emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
5397 emit_src_register(emit, &coord);
5398 emit_resource_register(emit, unit);
5399 emit_sampler_register(emit, unit);
5400 emit_src_register(emit, &inst->Src[1]); /* Xderiv */
5401 emit_src_register(emit, &inst->Src[2]); /* Yderiv */
5402 end_emit_instruction(emit);
5403
5404 end_tex_swizzle(emit, &swz_info);
5405
5406 free_temp_indexes(emit);
5407
5408 return TRUE;
5409 }
5410
5411
5412 /**
5413 * Emit code for TGSI_OPCODE_TXF (texel fetch)
5414 */
5415 static boolean
emit_txf(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5416 emit_txf(struct svga_shader_emitter_v10 *emit,
5417 const struct tgsi_full_instruction *inst)
5418 {
5419 const uint unit = inst->Src[1].Register.Index;
5420 const boolean msaa = tgsi_is_msaa_target(inst->Texture.Texture);
5421 int offsets[3];
5422 struct tex_swizzle_info swz_info;
5423
5424 begin_tex_swizzle(emit, unit, inst, FALSE, &swz_info);
5425
5426 get_texel_offsets(emit, inst, offsets);
5427
5428 if (msaa) {
5429 /* Fetch one sample from an MSAA texture */
5430 struct tgsi_full_src_register sampleIndex =
5431 scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
5432 /* LD_MS dst, coord(s0), resource, sampleIndex */
5433 begin_emit_instruction(emit);
5434 emit_sample_opcode(emit, VGPU10_OPCODE_LD_MS,
5435 inst->Instruction.Saturate, offsets);
5436 emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
5437 emit_src_register(emit, &inst->Src[0]);
5438 emit_resource_register(emit, unit);
5439 emit_src_register(emit, &sampleIndex);
5440 end_emit_instruction(emit);
5441 }
5442 else {
5443 /* Fetch one texel specified by integer coordinate */
5444 /* LD dst, coord(s0), resource */
5445 begin_emit_instruction(emit);
5446 emit_sample_opcode(emit, VGPU10_OPCODE_LD,
5447 inst->Instruction.Saturate, offsets);
5448 emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
5449 emit_src_register(emit, &inst->Src[0]);
5450 emit_resource_register(emit, unit);
5451 end_emit_instruction(emit);
5452 }
5453
5454 end_tex_swizzle(emit, &swz_info);
5455
5456 free_temp_indexes(emit);
5457
5458 return TRUE;
5459 }
5460
5461
5462 /**
5463 * Emit code for TGSI_OPCODE_TXL (explicit LOD) or TGSI_OPCODE_TXB (LOD bias)
5464 * or TGSI_OPCODE_TXB2 (for cube shadow maps).
5465 */
5466 static boolean
emit_txl_txb(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5467 emit_txl_txb(struct svga_shader_emitter_v10 *emit,
5468 const struct tgsi_full_instruction *inst)
5469 {
5470 unsigned target = inst->Texture.Texture;
5471 unsigned opcode, unit;
5472 int offsets[3];
5473 struct tgsi_full_src_register coord, lod_bias;
5474 struct tex_swizzle_info swz_info;
5475
5476 assert(inst->Instruction.Opcode == TGSI_OPCODE_TXL ||
5477 inst->Instruction.Opcode == TGSI_OPCODE_TXB ||
5478 inst->Instruction.Opcode == TGSI_OPCODE_TXB2);
5479
5480 if (inst->Instruction.Opcode == TGSI_OPCODE_TXB2) {
5481 lod_bias = scalar_src(&inst->Src[1], TGSI_SWIZZLE_X);
5482 unit = inst->Src[2].Register.Index;
5483 }
5484 else {
5485 lod_bias = scalar_src(&inst->Src[0], TGSI_SWIZZLE_W);
5486 unit = inst->Src[1].Register.Index;
5487 }
5488
5489 begin_tex_swizzle(emit, unit, inst, tgsi_is_shadow_target(target),
5490 &swz_info);
5491
5492 get_texel_offsets(emit, inst, offsets);
5493
5494 coord = setup_texcoord(emit, unit, &inst->Src[0]);
5495
5496 /* SAMPLE_L/B dst, coord(s0), resource, sampler, lod(s3) */
5497 begin_emit_instruction(emit);
5498 if (inst->Instruction.Opcode == TGSI_OPCODE_TXL) {
5499 opcode = VGPU10_OPCODE_SAMPLE_L;
5500 }
5501 else {
5502 opcode = VGPU10_OPCODE_SAMPLE_B;
5503 }
5504 emit_sample_opcode(emit, opcode, inst->Instruction.Saturate, offsets);
5505 emit_dst_register(emit, get_tex_swizzle_dst(&swz_info));
5506 emit_src_register(emit, &coord);
5507 emit_resource_register(emit, unit);
5508 emit_sampler_register(emit, unit);
5509 emit_src_register(emit, &lod_bias);
5510 end_emit_instruction(emit);
5511
5512 end_tex_swizzle(emit, &swz_info);
5513
5514 free_temp_indexes(emit);
5515
5516 return TRUE;
5517 }
5518
5519
5520 /**
5521 * Emit code for TGSI_OPCODE_TXQ (texture query) instruction.
5522 */
5523 static boolean
emit_txq(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5524 emit_txq(struct svga_shader_emitter_v10 *emit,
5525 const struct tgsi_full_instruction *inst)
5526 {
5527 const uint unit = inst->Src[1].Register.Index;
5528
5529 if (emit->sampler_target[unit] == TGSI_TEXTURE_BUFFER) {
5530 /* RESINFO does not support querying texture buffers, so we instead
5531 * store texture buffer sizes in shader constants, then copy them to
5532 * implement TXQ instead of emitting RESINFO.
5533 * MOV dst, const[texture_buffer_size_index[unit]]
5534 */
5535 struct tgsi_full_src_register size_src =
5536 make_src_const_reg(emit->texture_buffer_size_index[unit]);
5537 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &inst->Dst[0], &size_src,
5538 FALSE);
5539 } else {
5540 /* RESINFO dst, srcMipLevel, resource */
5541 begin_emit_instruction(emit);
5542 emit_opcode_resinfo(emit, VGPU10_RESINFO_RETURN_UINT);
5543 emit_dst_register(emit, &inst->Dst[0]);
5544 emit_src_register(emit, &inst->Src[0]);
5545 emit_resource_register(emit, unit);
5546 end_emit_instruction(emit);
5547 }
5548
5549 free_temp_indexes(emit);
5550
5551 return TRUE;
5552 }
5553
5554
5555 /**
5556 * Emit a simple instruction (like ADD, MUL, MIN, etc).
5557 */
5558 static boolean
emit_simple(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5559 emit_simple(struct svga_shader_emitter_v10 *emit,
5560 const struct tgsi_full_instruction *inst)
5561 {
5562 const unsigned opcode = inst->Instruction.Opcode;
5563 const struct tgsi_opcode_info *op = tgsi_get_opcode_info(opcode);
5564 unsigned i;
5565
5566 begin_emit_instruction(emit);
5567 emit_opcode(emit, translate_opcode(inst->Instruction.Opcode),
5568 inst->Instruction.Saturate);
5569 for (i = 0; i < op->num_dst; i++) {
5570 emit_dst_register(emit, &inst->Dst[i]);
5571 }
5572 for (i = 0; i < op->num_src; i++) {
5573 emit_src_register(emit, &inst->Src[i]);
5574 }
5575 end_emit_instruction(emit);
5576
5577 return TRUE;
5578 }
5579
5580
5581 /**
5582 * We only special case the MOV instruction to try to detect constant
5583 * color writes in the fragment shader.
5584 */
5585 static boolean
emit_mov(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)5586 emit_mov(struct svga_shader_emitter_v10 *emit,
5587 const struct tgsi_full_instruction *inst)
5588 {
5589 const struct tgsi_full_src_register *src = &inst->Src[0];
5590 const struct tgsi_full_dst_register *dst = &inst->Dst[0];
5591
5592 if (emit->unit == PIPE_SHADER_FRAGMENT &&
5593 dst->Register.File == TGSI_FILE_OUTPUT &&
5594 dst->Register.Index == 0 &&
5595 src->Register.File == TGSI_FILE_CONSTANT &&
5596 !src->Register.Indirect) {
5597 emit->constant_color_output = TRUE;
5598 }
5599
5600 return emit_simple(emit, inst);
5601 }
5602
5603
5604 /**
5605 * Emit a simple VGPU10 instruction which writes to multiple dest registers,
5606 * where TGSI only uses one dest register.
5607 */
5608 static boolean
emit_simple_1dst(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst,unsigned dst_count,unsigned dst_index)5609 emit_simple_1dst(struct svga_shader_emitter_v10 *emit,
5610 const struct tgsi_full_instruction *inst,
5611 unsigned dst_count,
5612 unsigned dst_index)
5613 {
5614 const unsigned opcode = inst->Instruction.Opcode;
5615 const struct tgsi_opcode_info *op = tgsi_get_opcode_info(opcode);
5616 unsigned i;
5617
5618 begin_emit_instruction(emit);
5619 emit_opcode(emit, translate_opcode(inst->Instruction.Opcode),
5620 inst->Instruction.Saturate);
5621
5622 for (i = 0; i < dst_count; i++) {
5623 if (i == dst_index) {
5624 emit_dst_register(emit, &inst->Dst[0]);
5625 } else {
5626 emit_null_dst_register(emit);
5627 }
5628 }
5629
5630 for (i = 0; i < op->num_src; i++) {
5631 emit_src_register(emit, &inst->Src[i]);
5632 }
5633 end_emit_instruction(emit);
5634
5635 return TRUE;
5636 }
5637
5638
5639 /**
5640 * Translate a single TGSI instruction to VGPU10.
5641 */
5642 static boolean
emit_vgpu10_instruction(struct svga_shader_emitter_v10 * emit,unsigned inst_number,const struct tgsi_full_instruction * inst)5643 emit_vgpu10_instruction(struct svga_shader_emitter_v10 *emit,
5644 unsigned inst_number,
5645 const struct tgsi_full_instruction *inst)
5646 {
5647 const unsigned opcode = inst->Instruction.Opcode;
5648
5649 switch (opcode) {
5650 case TGSI_OPCODE_ADD:
5651 case TGSI_OPCODE_AND:
5652 case TGSI_OPCODE_BGNLOOP:
5653 case TGSI_OPCODE_BRK:
5654 case TGSI_OPCODE_CEIL:
5655 case TGSI_OPCODE_CONT:
5656 case TGSI_OPCODE_DDX:
5657 case TGSI_OPCODE_DDY:
5658 case TGSI_OPCODE_DIV:
5659 case TGSI_OPCODE_DP2:
5660 case TGSI_OPCODE_DP3:
5661 case TGSI_OPCODE_DP4:
5662 case TGSI_OPCODE_ELSE:
5663 case TGSI_OPCODE_ENDIF:
5664 case TGSI_OPCODE_ENDLOOP:
5665 case TGSI_OPCODE_ENDSUB:
5666 case TGSI_OPCODE_F2I:
5667 case TGSI_OPCODE_F2U:
5668 case TGSI_OPCODE_FLR:
5669 case TGSI_OPCODE_FRC:
5670 case TGSI_OPCODE_FSEQ:
5671 case TGSI_OPCODE_FSGE:
5672 case TGSI_OPCODE_FSLT:
5673 case TGSI_OPCODE_FSNE:
5674 case TGSI_OPCODE_I2F:
5675 case TGSI_OPCODE_IMAX:
5676 case TGSI_OPCODE_IMIN:
5677 case TGSI_OPCODE_INEG:
5678 case TGSI_OPCODE_ISGE:
5679 case TGSI_OPCODE_ISHR:
5680 case TGSI_OPCODE_ISLT:
5681 case TGSI_OPCODE_MAD:
5682 case TGSI_OPCODE_MAX:
5683 case TGSI_OPCODE_MIN:
5684 case TGSI_OPCODE_MUL:
5685 case TGSI_OPCODE_NOP:
5686 case TGSI_OPCODE_NOT:
5687 case TGSI_OPCODE_OR:
5688 case TGSI_OPCODE_RET:
5689 case TGSI_OPCODE_UADD:
5690 case TGSI_OPCODE_USEQ:
5691 case TGSI_OPCODE_USGE:
5692 case TGSI_OPCODE_USLT:
5693 case TGSI_OPCODE_UMIN:
5694 case TGSI_OPCODE_UMAD:
5695 case TGSI_OPCODE_UMAX:
5696 case TGSI_OPCODE_ROUND:
5697 case TGSI_OPCODE_SQRT:
5698 case TGSI_OPCODE_SHL:
5699 case TGSI_OPCODE_TRUNC:
5700 case TGSI_OPCODE_U2F:
5701 case TGSI_OPCODE_UCMP:
5702 case TGSI_OPCODE_USHR:
5703 case TGSI_OPCODE_USNE:
5704 case TGSI_OPCODE_XOR:
5705 /* simple instructions */
5706 return emit_simple(emit, inst);
5707
5708 case TGSI_OPCODE_MOV:
5709 return emit_mov(emit, inst);
5710 case TGSI_OPCODE_EMIT:
5711 return emit_vertex(emit, inst);
5712 case TGSI_OPCODE_ENDPRIM:
5713 return emit_endprim(emit, inst);
5714 case TGSI_OPCODE_IABS:
5715 return emit_iabs(emit, inst);
5716 case TGSI_OPCODE_ARL:
5717 /* fall-through */
5718 case TGSI_OPCODE_UARL:
5719 return emit_arl_uarl(emit, inst);
5720 case TGSI_OPCODE_BGNSUB:
5721 /* no-op */
5722 return TRUE;
5723 case TGSI_OPCODE_CAL:
5724 return emit_cal(emit, inst);
5725 case TGSI_OPCODE_CMP:
5726 return emit_cmp(emit, inst);
5727 case TGSI_OPCODE_COS:
5728 return emit_sincos(emit, inst);
5729 case TGSI_OPCODE_DP2A:
5730 return emit_dp2a(emit, inst);
5731 case TGSI_OPCODE_DPH:
5732 return emit_dph(emit, inst);
5733 case TGSI_OPCODE_DST:
5734 return emit_dst(emit, inst);
5735 case TGSI_OPCODE_EX2:
5736 return emit_ex2(emit, inst);
5737 case TGSI_OPCODE_EXP:
5738 return emit_exp(emit, inst);
5739 case TGSI_OPCODE_IF:
5740 return emit_if(emit, inst);
5741 case TGSI_OPCODE_KILL:
5742 return emit_kill(emit, inst);
5743 case TGSI_OPCODE_KILL_IF:
5744 return emit_kill_if(emit, inst);
5745 case TGSI_OPCODE_LG2:
5746 return emit_lg2(emit, inst);
5747 case TGSI_OPCODE_LIT:
5748 return emit_lit(emit, inst);
5749 case TGSI_OPCODE_LOG:
5750 return emit_log(emit, inst);
5751 case TGSI_OPCODE_LRP:
5752 return emit_lrp(emit, inst);
5753 case TGSI_OPCODE_POW:
5754 return emit_pow(emit, inst);
5755 case TGSI_OPCODE_RCP:
5756 return emit_rcp(emit, inst);
5757 case TGSI_OPCODE_RSQ:
5758 return emit_rsq(emit, inst);
5759 case TGSI_OPCODE_SAMPLE:
5760 return emit_sample(emit, inst);
5761 case TGSI_OPCODE_SCS:
5762 return emit_scs(emit, inst);
5763 case TGSI_OPCODE_SEQ:
5764 return emit_seq(emit, inst);
5765 case TGSI_OPCODE_SGE:
5766 return emit_sge(emit, inst);
5767 case TGSI_OPCODE_SGT:
5768 return emit_sgt(emit, inst);
5769 case TGSI_OPCODE_SIN:
5770 return emit_sincos(emit, inst);
5771 case TGSI_OPCODE_SLE:
5772 return emit_sle(emit, inst);
5773 case TGSI_OPCODE_SLT:
5774 return emit_slt(emit, inst);
5775 case TGSI_OPCODE_SNE:
5776 return emit_sne(emit, inst);
5777 case TGSI_OPCODE_SSG:
5778 return emit_ssg(emit, inst);
5779 case TGSI_OPCODE_ISSG:
5780 return emit_issg(emit, inst);
5781 case TGSI_OPCODE_TEX:
5782 return emit_tex(emit, inst);
5783 case TGSI_OPCODE_TXP:
5784 return emit_txp(emit, inst);
5785 case TGSI_OPCODE_TXB:
5786 case TGSI_OPCODE_TXB2:
5787 case TGSI_OPCODE_TXL:
5788 return emit_txl_txb(emit, inst);
5789 case TGSI_OPCODE_TXD:
5790 return emit_txd(emit, inst);
5791 case TGSI_OPCODE_TXF:
5792 return emit_txf(emit, inst);
5793 case TGSI_OPCODE_TXQ:
5794 return emit_txq(emit, inst);
5795 case TGSI_OPCODE_UIF:
5796 return emit_if(emit, inst);
5797 case TGSI_OPCODE_XPD:
5798 return emit_xpd(emit, inst);
5799 case TGSI_OPCODE_UMUL_HI:
5800 case TGSI_OPCODE_IMUL_HI:
5801 case TGSI_OPCODE_UDIV:
5802 case TGSI_OPCODE_IDIV:
5803 /* These cases use only the FIRST of two destination registers */
5804 return emit_simple_1dst(emit, inst, 2, 0);
5805 case TGSI_OPCODE_UMUL:
5806 case TGSI_OPCODE_UMOD:
5807 case TGSI_OPCODE_MOD:
5808 /* These cases use only the SECOND of two destination registers */
5809 return emit_simple_1dst(emit, inst, 2, 1);
5810 case TGSI_OPCODE_END:
5811 if (!emit_post_helpers(emit))
5812 return FALSE;
5813 return emit_simple(emit, inst);
5814
5815 default:
5816 debug_printf("Unimplemented tgsi instruction %s\n",
5817 tgsi_get_opcode_name(opcode));
5818 return FALSE;
5819 }
5820
5821 return TRUE;
5822 }
5823
5824
5825 /**
5826 * Emit the extra instructions to adjust the vertex position.
5827 * There are two possible adjustments:
5828 * 1. Converting from Gallium to VGPU10 coordinate space by applying the
5829 * "prescale" and "pretranslate" values.
5830 * 2. Undoing the viewport transformation when we use the swtnl/draw path.
5831 * \param vs_pos_tmp_index which temporary register contains the vertex pos.
5832 */
5833 static void
emit_vpos_instructions(struct svga_shader_emitter_v10 * emit,unsigned vs_pos_tmp_index)5834 emit_vpos_instructions(struct svga_shader_emitter_v10 *emit,
5835 unsigned vs_pos_tmp_index)
5836 {
5837 struct tgsi_full_src_register tmp_pos_src;
5838 struct tgsi_full_dst_register pos_dst;
5839
5840 /* Don't bother to emit any extra vertex instructions if vertex position is
5841 * not written out
5842 */
5843 if (emit->vposition.out_index == INVALID_INDEX)
5844 return;
5845
5846 tmp_pos_src = make_src_temp_reg(vs_pos_tmp_index);
5847 pos_dst = make_dst_output_reg(emit->vposition.out_index);
5848
5849 /* If non-adjusted vertex position register index
5850 * is valid, copy the vertex position from the temporary
5851 * vertex position register before it is modified by the
5852 * prescale computation.
5853 */
5854 if (emit->vposition.so_index != INVALID_INDEX) {
5855 struct tgsi_full_dst_register pos_so_dst =
5856 make_dst_output_reg(emit->vposition.so_index);
5857
5858 /* MOV pos_so, tmp_pos */
5859 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &pos_so_dst,
5860 &tmp_pos_src, FALSE);
5861 }
5862
5863 if (emit->vposition.need_prescale) {
5864 /* This code adjusts the vertex position to match the VGPU10 convention.
5865 * If p is the position computed by the shader (usually by applying the
5866 * modelview and projection matrices), the new position q is computed by:
5867 *
5868 * q.x = p.w * trans.x + p.x * scale.x
5869 * q.y = p.w * trans.y + p.y * scale.y
5870 * q.z = p.w * trans.z + p.z * scale.z;
5871 * q.w = p.w * trans.w + p.w;
5872 */
5873 struct tgsi_full_src_register tmp_pos_src_w =
5874 scalar_src(&tmp_pos_src, TGSI_SWIZZLE_W);
5875 struct tgsi_full_dst_register tmp_pos_dst =
5876 make_dst_temp_reg(vs_pos_tmp_index);
5877 struct tgsi_full_dst_register tmp_pos_dst_xyz =
5878 writemask_dst(&tmp_pos_dst, TGSI_WRITEMASK_XYZ);
5879
5880 struct tgsi_full_src_register prescale_scale =
5881 make_src_const_reg(emit->vposition.prescale_scale_index);
5882 struct tgsi_full_src_register prescale_trans =
5883 make_src_const_reg(emit->vposition.prescale_trans_index);
5884
5885 /* MUL tmp_pos.xyz, tmp_pos, prescale.scale */
5886 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_pos_dst_xyz,
5887 &tmp_pos_src, &prescale_scale, FALSE);
5888
5889 /* MAD pos, tmp_pos.wwww, prescale.trans, tmp_pos */
5890 emit_instruction_op3(emit, VGPU10_OPCODE_MAD, &pos_dst, &tmp_pos_src_w,
5891 &prescale_trans, &tmp_pos_src, FALSE);
5892 }
5893 else if (emit->key.vs.undo_viewport) {
5894 /* This code computes the final vertex position from the temporary
5895 * vertex position by undoing the viewport transformation and the
5896 * divide-by-W operation (we convert window coords back to clip coords).
5897 * This is needed when we use the 'draw' module for fallbacks.
5898 * If p is the temp pos in window coords, then the NDC coord q is:
5899 * q.x = (p.x - vp.x_trans) / vp.x_scale * p.w
5900 * q.y = (p.y - vp.y_trans) / vp.y_scale * p.w
5901 * q.z = p.z * p.w
5902 * q.w = p.w
5903 * CONST[vs_viewport_index] contains:
5904 * { 1/vp.x_scale, 1/vp.y_scale, -vp.x_trans, -vp.y_trans }
5905 */
5906 struct tgsi_full_dst_register tmp_pos_dst =
5907 make_dst_temp_reg(vs_pos_tmp_index);
5908 struct tgsi_full_dst_register tmp_pos_dst_xy =
5909 writemask_dst(&tmp_pos_dst, TGSI_WRITEMASK_XY);
5910 struct tgsi_full_src_register tmp_pos_src_wwww =
5911 scalar_src(&tmp_pos_src, TGSI_SWIZZLE_W);
5912
5913 struct tgsi_full_dst_register pos_dst_xyz =
5914 writemask_dst(&pos_dst, TGSI_WRITEMASK_XYZ);
5915 struct tgsi_full_dst_register pos_dst_w =
5916 writemask_dst(&pos_dst, TGSI_WRITEMASK_W);
5917
5918 struct tgsi_full_src_register vp_xyzw =
5919 make_src_const_reg(emit->vs.viewport_index);
5920 struct tgsi_full_src_register vp_zwww =
5921 swizzle_src(&vp_xyzw, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W,
5922 TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);
5923
5924 /* ADD tmp_pos.xy, tmp_pos.xy, viewport.zwww */
5925 emit_instruction_op2(emit, VGPU10_OPCODE_ADD, &tmp_pos_dst_xy,
5926 &tmp_pos_src, &vp_zwww, FALSE);
5927
5928 /* MUL tmp_pos.xy, tmp_pos.xyzw, viewport.xyzy */
5929 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &tmp_pos_dst_xy,
5930 &tmp_pos_src, &vp_xyzw, FALSE);
5931
5932 /* MUL pos.xyz, tmp_pos.xyz, tmp_pos.www */
5933 emit_instruction_op2(emit, VGPU10_OPCODE_MUL, &pos_dst_xyz,
5934 &tmp_pos_src, &tmp_pos_src_wwww, FALSE);
5935
5936 /* MOV pos.w, tmp_pos.w */
5937 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &pos_dst_w,
5938 &tmp_pos_src, FALSE);
5939 }
5940 else if (vs_pos_tmp_index != INVALID_INDEX) {
5941 /* This code is to handle the case where the temporary vertex
5942 * position register is created when the vertex shader has stream
5943 * output and prescale is disabled because rasterization is to be
5944 * discarded.
5945 */
5946 struct tgsi_full_dst_register pos_dst =
5947 make_dst_output_reg(emit->vposition.out_index);
5948
5949 /* MOV pos, tmp_pos */
5950 begin_emit_instruction(emit);
5951 emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
5952 emit_dst_register(emit, &pos_dst);
5953 emit_src_register(emit, &tmp_pos_src);
5954 end_emit_instruction(emit);
5955 }
5956 }
5957
5958 static void
emit_clipping_instructions(struct svga_shader_emitter_v10 * emit)5959 emit_clipping_instructions(struct svga_shader_emitter_v10 *emit)
5960 {
5961 if (emit->clip_mode == CLIP_DISTANCE) {
5962 /* Copy from copy distance temporary to CLIPDIST & the shadow copy */
5963 emit_clip_distance_instructions(emit);
5964
5965 } else if (emit->clip_mode == CLIP_VERTEX) {
5966 /* Convert TGSI CLIPVERTEX to CLIPDIST */
5967 emit_clip_vertex_instructions(emit);
5968 }
5969
5970 /**
5971 * Emit vertex position and take care of legacy user planes only if
5972 * there is a valid vertex position register index.
5973 * This is to take care of the case
5974 * where the shader doesn't output vertex position. Then in
5975 * this case, don't bother to emit more vertex instructions.
5976 */
5977 if (emit->vposition.out_index == INVALID_INDEX)
5978 return;
5979
5980 /**
5981 * Emit per-vertex clipping instructions for legacy user defined clip planes.
5982 * NOTE: we must emit the clip distance instructions before the
5983 * emit_vpos_instructions() call since the later function will change
5984 * the TEMP[vs_pos_tmp_index] value.
5985 */
5986 if (emit->clip_mode == CLIP_LEGACY) {
5987 /* Emit CLIPDIST for legacy user defined clip planes */
5988 emit_clip_distance_from_vpos(emit, emit->vposition.tmp_index);
5989 }
5990 }
5991
5992
5993 /**
5994 * Emit extra per-vertex instructions. This includes clip-coordinate
5995 * space conversion and computing clip distances. This is called for
5996 * each GS emit-vertex instruction and at the end of VS translation.
5997 */
5998 static void
emit_vertex_instructions(struct svga_shader_emitter_v10 * emit)5999 emit_vertex_instructions(struct svga_shader_emitter_v10 *emit)
6000 {
6001 const unsigned vs_pos_tmp_index = emit->vposition.tmp_index;
6002
6003 /* Emit clipping instructions based on clipping mode */
6004 emit_clipping_instructions(emit);
6005
6006 /**
6007 * Reset the temporary vertex position register index
6008 * so that emit_dst_register() will use the real vertex position output
6009 */
6010 emit->vposition.tmp_index = INVALID_INDEX;
6011
6012 /* Emit vertex position instructions */
6013 emit_vpos_instructions(emit, vs_pos_tmp_index);
6014
6015 /* Restore original vposition.tmp_index value for the next GS vertex.
6016 * It doesn't matter for VS.
6017 */
6018 emit->vposition.tmp_index = vs_pos_tmp_index;
6019 }
6020
6021 /**
6022 * Translate the TGSI_OPCODE_EMIT GS instruction.
6023 */
6024 static boolean
emit_vertex(struct svga_shader_emitter_v10 * emit,const struct tgsi_full_instruction * inst)6025 emit_vertex(struct svga_shader_emitter_v10 *emit,
6026 const struct tgsi_full_instruction *inst)
6027 {
6028 unsigned ret = TRUE;
6029
6030 assert(emit->unit == PIPE_SHADER_GEOMETRY);
6031
6032 emit_vertex_instructions(emit);
6033
6034 /* We can't use emit_simple() because the TGSI instruction has one
6035 * operand (vertex stream number) which we must ignore for VGPU10.
6036 */
6037 begin_emit_instruction(emit);
6038 emit_opcode(emit, VGPU10_OPCODE_EMIT, FALSE);
6039 end_emit_instruction(emit);
6040
6041 return ret;
6042 }
6043
6044
6045 /**
6046 * Emit the extra code to convert from VGPU10's boolean front-face
6047 * register to TGSI's signed front-face register.
6048 *
6049 * TODO: Make temporary front-face register a scalar.
6050 */
6051 static void
emit_frontface_instructions(struct svga_shader_emitter_v10 * emit)6052 emit_frontface_instructions(struct svga_shader_emitter_v10 *emit)
6053 {
6054 assert(emit->unit == PIPE_SHADER_FRAGMENT);
6055
6056 if (emit->fs.face_input_index != INVALID_INDEX) {
6057 /* convert vgpu10 boolean face register to gallium +/-1 value */
6058 struct tgsi_full_dst_register tmp_dst =
6059 make_dst_temp_reg(emit->fs.face_tmp_index);
6060 struct tgsi_full_src_register one =
6061 make_immediate_reg_float(emit, 1.0f);
6062 struct tgsi_full_src_register neg_one =
6063 make_immediate_reg_float(emit, -1.0f);
6064
6065 /* MOVC face_tmp, IS_FRONT_FACE.x, 1.0, -1.0 */
6066 begin_emit_instruction(emit);
6067 emit_opcode(emit, VGPU10_OPCODE_MOVC, FALSE);
6068 emit_dst_register(emit, &tmp_dst);
6069 emit_face_register(emit);
6070 emit_src_register(emit, &one);
6071 emit_src_register(emit, &neg_one);
6072 end_emit_instruction(emit);
6073 }
6074 }
6075
6076
6077 /**
6078 * Emit the extra code to convert from VGPU10's fragcoord.w value to 1/w.
6079 */
6080 static void
emit_fragcoord_instructions(struct svga_shader_emitter_v10 * emit)6081 emit_fragcoord_instructions(struct svga_shader_emitter_v10 *emit)
6082 {
6083 assert(emit->unit == PIPE_SHADER_FRAGMENT);
6084
6085 if (emit->fs.fragcoord_input_index != INVALID_INDEX) {
6086 struct tgsi_full_dst_register tmp_dst =
6087 make_dst_temp_reg(emit->fs.fragcoord_tmp_index);
6088 struct tgsi_full_dst_register tmp_dst_xyz =
6089 writemask_dst(&tmp_dst, TGSI_WRITEMASK_XYZ);
6090 struct tgsi_full_dst_register tmp_dst_w =
6091 writemask_dst(&tmp_dst, TGSI_WRITEMASK_W);
6092 struct tgsi_full_src_register one =
6093 make_immediate_reg_float(emit, 1.0f);
6094 struct tgsi_full_src_register fragcoord =
6095 make_src_reg(TGSI_FILE_INPUT, emit->fs.fragcoord_input_index);
6096
6097 /* save the input index */
6098 unsigned fragcoord_input_index = emit->fs.fragcoord_input_index;
6099 /* set to invalid to prevent substitution in emit_src_register() */
6100 emit->fs.fragcoord_input_index = INVALID_INDEX;
6101
6102 /* MOV fragcoord_tmp.xyz, fragcoord.xyz */
6103 begin_emit_instruction(emit);
6104 emit_opcode(emit, VGPU10_OPCODE_MOV, FALSE);
6105 emit_dst_register(emit, &tmp_dst_xyz);
6106 emit_src_register(emit, &fragcoord);
6107 end_emit_instruction(emit);
6108
6109 /* DIV fragcoord_tmp.w, 1.0, fragcoord.w */
6110 begin_emit_instruction(emit);
6111 emit_opcode(emit, VGPU10_OPCODE_DIV, FALSE);
6112 emit_dst_register(emit, &tmp_dst_w);
6113 emit_src_register(emit, &one);
6114 emit_src_register(emit, &fragcoord);
6115 end_emit_instruction(emit);
6116
6117 /* restore saved value */
6118 emit->fs.fragcoord_input_index = fragcoord_input_index;
6119 }
6120 }
6121
6122
6123 /**
6124 * Emit extra instructions to adjust VS inputs/attributes. This can
6125 * mean casting a vertex attribute from int to float or setting the
6126 * W component to 1, or both.
6127 */
6128 static void
emit_vertex_attrib_instructions(struct svga_shader_emitter_v10 * emit)6129 emit_vertex_attrib_instructions(struct svga_shader_emitter_v10 *emit)
6130 {
6131 const unsigned save_w_1_mask = emit->key.vs.adjust_attrib_w_1;
6132 const unsigned save_itof_mask = emit->key.vs.adjust_attrib_itof;
6133 const unsigned save_utof_mask = emit->key.vs.adjust_attrib_utof;
6134 const unsigned save_is_bgra_mask = emit->key.vs.attrib_is_bgra;
6135 const unsigned save_puint_to_snorm_mask = emit->key.vs.attrib_puint_to_snorm;
6136 const unsigned save_puint_to_uscaled_mask = emit->key.vs.attrib_puint_to_uscaled;
6137 const unsigned save_puint_to_sscaled_mask = emit->key.vs.attrib_puint_to_sscaled;
6138
6139 unsigned adjust_mask = (save_w_1_mask |
6140 save_itof_mask |
6141 save_utof_mask |
6142 save_is_bgra_mask |
6143 save_puint_to_snorm_mask |
6144 save_puint_to_uscaled_mask |
6145 save_puint_to_sscaled_mask);
6146
6147 assert(emit->unit == PIPE_SHADER_VERTEX);
6148
6149 if (adjust_mask) {
6150 struct tgsi_full_src_register one =
6151 make_immediate_reg_float(emit, 1.0f);
6152
6153 struct tgsi_full_src_register one_int =
6154 make_immediate_reg_int(emit, 1);
6155
6156 /* We need to turn off these bitmasks while emitting the
6157 * instructions below, then restore them afterward.
6158 */
6159 emit->key.vs.adjust_attrib_w_1 = 0;
6160 emit->key.vs.adjust_attrib_itof = 0;
6161 emit->key.vs.adjust_attrib_utof = 0;
6162 emit->key.vs.attrib_is_bgra = 0;
6163 emit->key.vs.attrib_puint_to_snorm = 0;
6164 emit->key.vs.attrib_puint_to_uscaled = 0;
6165 emit->key.vs.attrib_puint_to_sscaled = 0;
6166
6167 while (adjust_mask) {
6168 unsigned index = u_bit_scan(&adjust_mask);
6169
6170 /* skip the instruction if this vertex attribute is not being used */
6171 if (emit->info.input_usage_mask[index] == 0)
6172 continue;
6173
6174 unsigned tmp = emit->vs.adjusted_input[index];
6175 struct tgsi_full_src_register input_src =
6176 make_src_reg(TGSI_FILE_INPUT, index);
6177
6178 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
6179 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
6180 struct tgsi_full_dst_register tmp_dst_w =
6181 writemask_dst(&tmp_dst, TGSI_WRITEMASK_W);
6182
6183 /* ITOF/UTOF/MOV tmp, input[index] */
6184 if (save_itof_mask & (1 << index)) {
6185 emit_instruction_op1(emit, VGPU10_OPCODE_ITOF,
6186 &tmp_dst, &input_src, FALSE);
6187 }
6188 else if (save_utof_mask & (1 << index)) {
6189 emit_instruction_op1(emit, VGPU10_OPCODE_UTOF,
6190 &tmp_dst, &input_src, FALSE);
6191 }
6192 else if (save_puint_to_snorm_mask & (1 << index)) {
6193 emit_puint_to_snorm(emit, &tmp_dst, &input_src);
6194 }
6195 else if (save_puint_to_uscaled_mask & (1 << index)) {
6196 emit_puint_to_uscaled(emit, &tmp_dst, &input_src);
6197 }
6198 else if (save_puint_to_sscaled_mask & (1 << index)) {
6199 emit_puint_to_sscaled(emit, &tmp_dst, &input_src);
6200 }
6201 else {
6202 assert((save_w_1_mask | save_is_bgra_mask) & (1 << index));
6203 emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
6204 &tmp_dst, &input_src, FALSE);
6205 }
6206
6207 if (save_is_bgra_mask & (1 << index)) {
6208 emit_swap_r_b(emit, &tmp_dst, &tmp_src);
6209 }
6210
6211 if (save_w_1_mask & (1 << index)) {
6212 /* MOV tmp.w, 1.0 */
6213 if (emit->key.vs.attrib_is_pure_int & (1 << index)) {
6214 emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
6215 &tmp_dst_w, &one_int, FALSE);
6216 }
6217 else {
6218 emit_instruction_op1(emit, VGPU10_OPCODE_MOV,
6219 &tmp_dst_w, &one, FALSE);
6220 }
6221 }
6222 }
6223
6224 emit->key.vs.adjust_attrib_w_1 = save_w_1_mask;
6225 emit->key.vs.adjust_attrib_itof = save_itof_mask;
6226 emit->key.vs.adjust_attrib_utof = save_utof_mask;
6227 emit->key.vs.attrib_is_bgra = save_is_bgra_mask;
6228 emit->key.vs.attrib_puint_to_snorm = save_puint_to_snorm_mask;
6229 emit->key.vs.attrib_puint_to_uscaled = save_puint_to_uscaled_mask;
6230 emit->key.vs.attrib_puint_to_sscaled = save_puint_to_sscaled_mask;
6231 }
6232 }
6233
6234
6235 /**
6236 * Some common values like 0.0, 1.0, 0.5, etc. are frequently needed
6237 * to implement some instructions. We pre-allocate those values here
6238 * in the immediate constant buffer.
6239 */
6240 static void
alloc_common_immediates(struct svga_shader_emitter_v10 * emit)6241 alloc_common_immediates(struct svga_shader_emitter_v10 *emit)
6242 {
6243 unsigned n = 0;
6244
6245 emit->common_immediate_pos[n++] =
6246 alloc_immediate_float4(emit, 0.0f, 1.0f, 0.5f, -1.0f);
6247
6248 emit->common_immediate_pos[n++] =
6249 alloc_immediate_float4(emit, 128.0f, -128.0f, 2.0f, 3.0f);
6250
6251 emit->common_immediate_pos[n++] =
6252 alloc_immediate_int4(emit, 0, 1, 0, -1);
6253
6254 if (emit->key.vs.attrib_puint_to_snorm) {
6255 emit->common_immediate_pos[n++] =
6256 alloc_immediate_float4(emit, -2.0f, -2.0f, -2.0f, -1.66666f);
6257 }
6258
6259 if (emit->key.vs.attrib_puint_to_uscaled) {
6260 emit->common_immediate_pos[n++] =
6261 alloc_immediate_float4(emit, 1023.0f, 3.0f, 0.0f, 0.0f);
6262 }
6263
6264 if (emit->key.vs.attrib_puint_to_sscaled) {
6265 emit->common_immediate_pos[n++] =
6266 alloc_immediate_int4(emit, 22, 12, 2, 0);
6267
6268 emit->common_immediate_pos[n++] =
6269 alloc_immediate_int4(emit, 22, 30, 0, 0);
6270 }
6271
6272 assert(n <= ARRAY_SIZE(emit->common_immediate_pos));
6273 emit->num_common_immediates = n;
6274 }
6275
6276
6277 /**
6278 * Emit any extra/helper declarations/code that we might need between
6279 * the declaration section and code section.
6280 */
6281 static boolean
emit_pre_helpers(struct svga_shader_emitter_v10 * emit)6282 emit_pre_helpers(struct svga_shader_emitter_v10 *emit)
6283 {
6284 /* Properties */
6285 if (emit->unit == PIPE_SHADER_GEOMETRY)
6286 emit_property_instructions(emit);
6287
6288 /* Declare inputs */
6289 if (!emit_input_declarations(emit))
6290 return FALSE;
6291
6292 /* Declare outputs */
6293 if (!emit_output_declarations(emit))
6294 return FALSE;
6295
6296 /* Declare temporary registers */
6297 emit_temporaries_declaration(emit);
6298
6299 /* Declare constant registers */
6300 emit_constant_declaration(emit);
6301
6302 /* Declare samplers and resources */
6303 emit_sampler_declarations(emit);
6304 emit_resource_declarations(emit);
6305
6306 /* Declare clip distance output registers */
6307 if (emit->unit == PIPE_SHADER_VERTEX ||
6308 emit->unit == PIPE_SHADER_GEOMETRY) {
6309 emit_clip_distance_declarations(emit);
6310 }
6311
6312 alloc_common_immediates(emit);
6313
6314 if (emit->unit == PIPE_SHADER_FRAGMENT &&
6315 emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS) {
6316 float alpha = emit->key.fs.alpha_ref;
6317 emit->fs.alpha_ref_index =
6318 alloc_immediate_float4(emit, alpha, alpha, alpha, alpha);
6319 }
6320
6321 /* Now, emit the constant block containing all the immediates
6322 * declared by shader, as well as the extra ones seen above.
6323 */
6324 emit_vgpu10_immediates_block(emit);
6325
6326 if (emit->unit == PIPE_SHADER_FRAGMENT) {
6327 emit_frontface_instructions(emit);
6328 emit_fragcoord_instructions(emit);
6329 }
6330 else if (emit->unit == PIPE_SHADER_VERTEX) {
6331 emit_vertex_attrib_instructions(emit);
6332 }
6333
6334 return TRUE;
6335 }
6336
6337
6338 /**
6339 * Emit alpha test code. This compares TEMP[fs_color_tmp_index].w
6340 * against the alpha reference value and discards the fragment if the
6341 * comparison fails.
6342 */
6343 static void
emit_alpha_test_instructions(struct svga_shader_emitter_v10 * emit,unsigned fs_color_tmp_index)6344 emit_alpha_test_instructions(struct svga_shader_emitter_v10 *emit,
6345 unsigned fs_color_tmp_index)
6346 {
6347 /* compare output color's alpha to alpha ref and kill */
6348 unsigned tmp = get_temp_index(emit);
6349 struct tgsi_full_src_register tmp_src = make_src_temp_reg(tmp);
6350 struct tgsi_full_src_register tmp_src_x =
6351 scalar_src(&tmp_src, TGSI_SWIZZLE_X);
6352 struct tgsi_full_dst_register tmp_dst = make_dst_temp_reg(tmp);
6353 struct tgsi_full_src_register color_src =
6354 make_src_temp_reg(fs_color_tmp_index);
6355 struct tgsi_full_src_register color_src_w =
6356 scalar_src(&color_src, TGSI_SWIZZLE_W);
6357 struct tgsi_full_src_register ref_src =
6358 make_src_immediate_reg(emit->fs.alpha_ref_index);
6359 struct tgsi_full_dst_register color_dst =
6360 make_dst_output_reg(emit->fs.color_out_index[0]);
6361
6362 assert(emit->unit == PIPE_SHADER_FRAGMENT);
6363
6364 /* dst = src0 'alpha_func' src1 */
6365 emit_comparison(emit, emit->key.fs.alpha_func, &tmp_dst,
6366 &color_src_w, &ref_src);
6367
6368 /* DISCARD if dst.x == 0 */
6369 begin_emit_instruction(emit);
6370 emit_discard_opcode(emit, FALSE); /* discard if src0.x is zero */
6371 emit_src_register(emit, &tmp_src_x);
6372 end_emit_instruction(emit);
6373
6374 /* If we don't need to broadcast the color below or set fragments to
6375 * white, emit final color here.
6376 */
6377 if (emit->key.fs.write_color0_to_n_cbufs <= 1 &&
6378 !emit->key.fs.white_fragments) {
6379 /* MOV output.color, tempcolor */
6380 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst,
6381 &color_src, FALSE); /* XXX saturate? */
6382 }
6383
6384 free_temp_indexes(emit);
6385 }
6386
6387
6388 /**
6389 * When we need to emit white for all fragments (for emulating XOR logicop
6390 * mode), this function copies white into the temporary color output register.
6391 */
6392 static void
emit_set_color_white(struct svga_shader_emitter_v10 * emit,unsigned fs_color_tmp_index)6393 emit_set_color_white(struct svga_shader_emitter_v10 *emit,
6394 unsigned fs_color_tmp_index)
6395 {
6396 struct tgsi_full_dst_register color_dst =
6397 make_dst_temp_reg(fs_color_tmp_index);
6398 struct tgsi_full_src_register white =
6399 make_immediate_reg_float(emit, 1.0f);
6400
6401 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst, &white, FALSE);
6402 }
6403
6404
6405 /**
6406 * Emit instructions for writing a single color output to multiple
6407 * color buffers.
6408 * This is used when the TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS (or
6409 * when key.fs.white_fragments is true).
6410 * property is set and the number of render targets is greater than one.
6411 * \param fs_color_tmp_index index of the temp register that holds the
6412 * color to broadcast.
6413 */
6414 static void
emit_broadcast_color_instructions(struct svga_shader_emitter_v10 * emit,unsigned fs_color_tmp_index)6415 emit_broadcast_color_instructions(struct svga_shader_emitter_v10 *emit,
6416 unsigned fs_color_tmp_index)
6417 {
6418 const unsigned n = emit->key.fs.write_color0_to_n_cbufs;
6419 unsigned i;
6420 struct tgsi_full_src_register color_src =
6421 make_src_temp_reg(fs_color_tmp_index);
6422
6423 assert(emit->unit == PIPE_SHADER_FRAGMENT);
6424
6425 for (i = 0; i < n; i++) {
6426 unsigned output_reg = emit->fs.color_out_index[i];
6427 struct tgsi_full_dst_register color_dst =
6428 make_dst_output_reg(output_reg);
6429
6430 /* Fill in this semantic here since we'll use it later in
6431 * emit_dst_register().
6432 */
6433 emit->info.output_semantic_name[output_reg] = TGSI_SEMANTIC_COLOR;
6434
6435 /* MOV output.color[i], tempcolor */
6436 emit_instruction_op1(emit, VGPU10_OPCODE_MOV, &color_dst,
6437 &color_src, FALSE); /* XXX saturate? */
6438 }
6439 }
6440
6441
6442 /**
6443 * Emit extra helper code after the original shader code, but before the
6444 * last END/RET instruction.
6445 * For vertex shaders this means emitting the extra code to apply the
6446 * prescale scale/translation.
6447 */
6448 static boolean
emit_post_helpers(struct svga_shader_emitter_v10 * emit)6449 emit_post_helpers(struct svga_shader_emitter_v10 *emit)
6450 {
6451 if (emit->unit == PIPE_SHADER_VERTEX) {
6452 emit_vertex_instructions(emit);
6453 }
6454 else if (emit->unit == PIPE_SHADER_FRAGMENT) {
6455 const unsigned fs_color_tmp_index = emit->fs.color_tmp_index;
6456
6457 /* We no longer want emit_dst_register() to substitute the
6458 * temporary fragment color register for the real color output.
6459 */
6460 emit->fs.color_tmp_index = INVALID_INDEX;
6461
6462 if (emit->key.fs.alpha_func != SVGA3D_CMP_ALWAYS) {
6463 emit_alpha_test_instructions(emit, fs_color_tmp_index);
6464 }
6465 if (emit->key.fs.white_fragments) {
6466 emit_set_color_white(emit, fs_color_tmp_index);
6467 }
6468 if (emit->key.fs.write_color0_to_n_cbufs > 1 ||
6469 emit->key.fs.white_fragments) {
6470 emit_broadcast_color_instructions(emit, fs_color_tmp_index);
6471 }
6472 }
6473
6474 return TRUE;
6475 }
6476
6477
6478 /**
6479 * Translate the TGSI tokens into VGPU10 tokens.
6480 */
6481 static boolean
emit_vgpu10_instructions(struct svga_shader_emitter_v10 * emit,const struct tgsi_token * tokens)6482 emit_vgpu10_instructions(struct svga_shader_emitter_v10 *emit,
6483 const struct tgsi_token *tokens)
6484 {
6485 struct tgsi_parse_context parse;
6486 boolean ret = TRUE;
6487 boolean pre_helpers_emitted = FALSE;
6488 unsigned inst_number = 0;
6489
6490 tgsi_parse_init(&parse, tokens);
6491
6492 while (!tgsi_parse_end_of_tokens(&parse)) {
6493 tgsi_parse_token(&parse);
6494
6495 switch (parse.FullToken.Token.Type) {
6496 case TGSI_TOKEN_TYPE_IMMEDIATE:
6497 ret = emit_vgpu10_immediate(emit, &parse.FullToken.FullImmediate);
6498 if (!ret)
6499 goto done;
6500 break;
6501
6502 case TGSI_TOKEN_TYPE_DECLARATION:
6503 ret = emit_vgpu10_declaration(emit, &parse.FullToken.FullDeclaration);
6504 if (!ret)
6505 goto done;
6506 break;
6507
6508 case TGSI_TOKEN_TYPE_INSTRUCTION:
6509 if (!pre_helpers_emitted) {
6510 ret = emit_pre_helpers(emit);
6511 if (!ret)
6512 goto done;
6513 pre_helpers_emitted = TRUE;
6514 }
6515 ret = emit_vgpu10_instruction(emit, inst_number++,
6516 &parse.FullToken.FullInstruction);
6517 if (!ret)
6518 goto done;
6519 break;
6520
6521 case TGSI_TOKEN_TYPE_PROPERTY:
6522 ret = emit_vgpu10_property(emit, &parse.FullToken.FullProperty);
6523 if (!ret)
6524 goto done;
6525 break;
6526
6527 default:
6528 break;
6529 }
6530 }
6531
6532 done:
6533 tgsi_parse_free(&parse);
6534 return ret;
6535 }
6536
6537
6538 /**
6539 * Emit the first VGPU10 shader tokens.
6540 */
6541 static boolean
emit_vgpu10_header(struct svga_shader_emitter_v10 * emit)6542 emit_vgpu10_header(struct svga_shader_emitter_v10 *emit)
6543 {
6544 VGPU10ProgramToken ptoken;
6545
6546 /* First token: VGPU10ProgramToken (version info, program type (VS,GS,PS)) */
6547 ptoken.majorVersion = 4;
6548 ptoken.minorVersion = 0;
6549 ptoken.programType = translate_shader_type(emit->unit);
6550 if (!emit_dword(emit, ptoken.value))
6551 return FALSE;
6552
6553 /* Second token: total length of shader, in tokens. We can't fill this
6554 * in until we're all done. Emit zero for now.
6555 */
6556 return emit_dword(emit, 0);
6557 }
6558
6559
6560 static boolean
emit_vgpu10_tail(struct svga_shader_emitter_v10 * emit)6561 emit_vgpu10_tail(struct svga_shader_emitter_v10 *emit)
6562 {
6563 VGPU10ProgramToken *tokens;
6564
6565 /* Replace the second token with total shader length */
6566 tokens = (VGPU10ProgramToken *) emit->buf;
6567 tokens[1].value = emit_get_num_tokens(emit);
6568
6569 return TRUE;
6570 }
6571
6572
6573 /**
6574 * Modify the FS to read the BCOLORs and use the FACE register
6575 * to choose between the front/back colors.
6576 */
6577 static const struct tgsi_token *
transform_fs_twoside(const struct tgsi_token * tokens)6578 transform_fs_twoside(const struct tgsi_token *tokens)
6579 {
6580 if (0) {
6581 debug_printf("Before tgsi_add_two_side ------------------\n");
6582 tgsi_dump(tokens,0);
6583 }
6584 tokens = tgsi_add_two_side(tokens);
6585 if (0) {
6586 debug_printf("After tgsi_add_two_side ------------------\n");
6587 tgsi_dump(tokens, 0);
6588 }
6589 return tokens;
6590 }
6591
6592
6593 /**
6594 * Modify the FS to do polygon stipple.
6595 */
6596 static const struct tgsi_token *
transform_fs_pstipple(struct svga_shader_emitter_v10 * emit,const struct tgsi_token * tokens)6597 transform_fs_pstipple(struct svga_shader_emitter_v10 *emit,
6598 const struct tgsi_token *tokens)
6599 {
6600 const struct tgsi_token *new_tokens;
6601 unsigned unit;
6602
6603 if (0) {
6604 debug_printf("Before pstipple ------------------\n");
6605 tgsi_dump(tokens,0);
6606 }
6607
6608 new_tokens = util_pstipple_create_fragment_shader(tokens, &unit, 0,
6609 TGSI_FILE_INPUT);
6610
6611 emit->fs.pstipple_sampler_unit = unit;
6612
6613 /* Setup texture state for stipple */
6614 emit->sampler_target[unit] = TGSI_TEXTURE_2D;
6615 emit->key.tex[unit].swizzle_r = TGSI_SWIZZLE_X;
6616 emit->key.tex[unit].swizzle_g = TGSI_SWIZZLE_Y;
6617 emit->key.tex[unit].swizzle_b = TGSI_SWIZZLE_Z;
6618 emit->key.tex[unit].swizzle_a = TGSI_SWIZZLE_W;
6619
6620 if (0) {
6621 debug_printf("After pstipple ------------------\n");
6622 tgsi_dump(new_tokens, 0);
6623 }
6624
6625 return new_tokens;
6626 }
6627
6628 /**
6629 * Modify the FS to support anti-aliasing point.
6630 */
6631 static const struct tgsi_token *
transform_fs_aapoint(const struct tgsi_token * tokens,int aa_coord_index)6632 transform_fs_aapoint(const struct tgsi_token *tokens,
6633 int aa_coord_index)
6634 {
6635 if (0) {
6636 debug_printf("Before tgsi_add_aa_point ------------------\n");
6637 tgsi_dump(tokens,0);
6638 }
6639 tokens = tgsi_add_aa_point(tokens, aa_coord_index);
6640 if (0) {
6641 debug_printf("After tgsi_add_aa_point ------------------\n");
6642 tgsi_dump(tokens, 0);
6643 }
6644 return tokens;
6645 }
6646
6647 /**
6648 * This is the main entrypoint for the TGSI -> VPGU10 translator.
6649 */
6650 struct svga_shader_variant *
svga_tgsi_vgpu10_translate(struct svga_context * svga,const struct svga_shader * shader,const struct svga_compile_key * key,unsigned unit)6651 svga_tgsi_vgpu10_translate(struct svga_context *svga,
6652 const struct svga_shader *shader,
6653 const struct svga_compile_key *key,
6654 unsigned unit)
6655 {
6656 struct svga_shader_variant *variant = NULL;
6657 struct svga_shader_emitter_v10 *emit;
6658 const struct tgsi_token *tokens = shader->tokens;
6659 struct svga_vertex_shader *vs = svga->curr.vs;
6660 struct svga_geometry_shader *gs = svga->curr.gs;
6661
6662 assert(unit == PIPE_SHADER_VERTEX ||
6663 unit == PIPE_SHADER_GEOMETRY ||
6664 unit == PIPE_SHADER_FRAGMENT);
6665
6666 /* These two flags cannot be used together */
6667 assert(key->vs.need_prescale + key->vs.undo_viewport <= 1);
6668
6669 SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_TGSIVGPU10TRANSLATE);
6670 /*
6671 * Setup the code emitter
6672 */
6673 emit = alloc_emitter();
6674 if (!emit)
6675 goto done;
6676
6677 emit->unit = unit;
6678 emit->key = *key;
6679
6680 emit->vposition.need_prescale = (emit->key.vs.need_prescale ||
6681 emit->key.gs.need_prescale);
6682 emit->vposition.tmp_index = INVALID_INDEX;
6683 emit->vposition.so_index = INVALID_INDEX;
6684 emit->vposition.out_index = INVALID_INDEX;
6685
6686 emit->fs.color_tmp_index = INVALID_INDEX;
6687 emit->fs.face_input_index = INVALID_INDEX;
6688 emit->fs.fragcoord_input_index = INVALID_INDEX;
6689
6690 emit->gs.prim_id_index = INVALID_INDEX;
6691
6692 emit->clip_dist_out_index = INVALID_INDEX;
6693 emit->clip_dist_tmp_index = INVALID_INDEX;
6694 emit->clip_dist_so_index = INVALID_INDEX;
6695 emit->clip_vertex_out_index = INVALID_INDEX;
6696
6697 if (emit->key.fs.alpha_func == SVGA3D_CMP_INVALID) {
6698 emit->key.fs.alpha_func = SVGA3D_CMP_ALWAYS;
6699 }
6700
6701 if (unit == PIPE_SHADER_FRAGMENT) {
6702 if (key->fs.light_twoside) {
6703 tokens = transform_fs_twoside(tokens);
6704 }
6705 if (key->fs.pstipple) {
6706 const struct tgsi_token *new_tokens =
6707 transform_fs_pstipple(emit, tokens);
6708 if (tokens != shader->tokens) {
6709 /* free the two-sided shader tokens */
6710 tgsi_free_tokens(tokens);
6711 }
6712 tokens = new_tokens;
6713 }
6714 if (key->fs.aa_point) {
6715 tokens = transform_fs_aapoint(tokens, key->fs.aa_point_coord_index);
6716 }
6717 }
6718
6719 if (SVGA_DEBUG & DEBUG_TGSI) {
6720 debug_printf("#####################################\n");
6721 debug_printf("### TGSI Shader %u\n", shader->id);
6722 tgsi_dump(tokens, 0);
6723 }
6724
6725 /**
6726 * Rescan the header if the token string is different from the one
6727 * included in the shader; otherwise, the header info is already up-to-date
6728 */
6729 if (tokens != shader->tokens) {
6730 tgsi_scan_shader(tokens, &emit->info);
6731 } else {
6732 emit->info = shader->info;
6733 }
6734
6735 emit->num_outputs = emit->info.num_outputs;
6736
6737 if (unit == PIPE_SHADER_FRAGMENT) {
6738 /* Compute FS input remapping to match the output from VS/GS */
6739 if (gs) {
6740 svga_link_shaders(&gs->base.info, &emit->info, &emit->linkage);
6741 } else {
6742 assert(vs);
6743 svga_link_shaders(&vs->base.info, &emit->info, &emit->linkage);
6744 }
6745 } else if (unit == PIPE_SHADER_GEOMETRY) {
6746 assert(vs);
6747 svga_link_shaders(&vs->base.info, &emit->info, &emit->linkage);
6748 }
6749
6750 determine_clipping_mode(emit);
6751
6752 if (unit == PIPE_SHADER_GEOMETRY || unit == PIPE_SHADER_VERTEX) {
6753 if (shader->stream_output != NULL || emit->clip_mode == CLIP_DISTANCE) {
6754 /* if there is stream output declarations associated
6755 * with this shader or the shader writes to ClipDistance
6756 * then reserve extra registers for the non-adjusted vertex position
6757 * and the ClipDistance shadow copy
6758 */
6759 emit->vposition.so_index = emit->num_outputs++;
6760
6761 if (emit->clip_mode == CLIP_DISTANCE) {
6762 emit->clip_dist_so_index = emit->num_outputs++;
6763 if (emit->info.num_written_clipdistance > 4)
6764 emit->num_outputs++;
6765 }
6766 }
6767 }
6768
6769 /*
6770 * Do actual shader translation.
6771 */
6772 if (!emit_vgpu10_header(emit)) {
6773 debug_printf("svga: emit VGPU10 header failed\n");
6774 goto cleanup;
6775 }
6776
6777 if (!emit_vgpu10_instructions(emit, tokens)) {
6778 debug_printf("svga: emit VGPU10 instructions failed\n");
6779 goto cleanup;
6780 }
6781
6782 if (!emit_vgpu10_tail(emit)) {
6783 debug_printf("svga: emit VGPU10 tail failed\n");
6784 goto cleanup;
6785 }
6786
6787 if (emit->register_overflow) {
6788 goto cleanup;
6789 }
6790
6791 /*
6792 * Create, initialize the 'variant' object.
6793 */
6794 variant = svga_new_shader_variant(svga);
6795 if (!variant)
6796 goto cleanup;
6797
6798 variant->shader = shader;
6799 variant->nr_tokens = emit_get_num_tokens(emit);
6800 variant->tokens = (const unsigned *)emit->buf;
6801 emit->buf = NULL; /* buffer is no longer owed by emitter context */
6802 memcpy(&variant->key, key, sizeof(*key));
6803 variant->id = UTIL_BITMASK_INVALID_INDEX;
6804
6805 /* The extra constant starting offset starts with the number of
6806 * shader constants declared in the shader.
6807 */
6808 variant->extra_const_start = emit->num_shader_consts[0];
6809 if (key->gs.wide_point) {
6810 /**
6811 * The extra constant added in the transformed shader
6812 * for inverse viewport scale is to be supplied by the driver.
6813 * So the extra constant starting offset needs to be reduced by 1.
6814 */
6815 assert(variant->extra_const_start > 0);
6816 variant->extra_const_start--;
6817 }
6818
6819 variant->pstipple_sampler_unit = emit->fs.pstipple_sampler_unit;
6820
6821 /* If there was exactly one write to a fragment shader output register
6822 * and it came from a constant buffer, we know all fragments will have
6823 * the same color (except for blending).
6824 */
6825 variant->constant_color_output =
6826 emit->constant_color_output && emit->num_output_writes == 1;
6827
6828 /** keep track in the variant if flat interpolation is used
6829 * for any of the varyings.
6830 */
6831 variant->uses_flat_interp = emit->uses_flat_interp;
6832
6833 if (tokens != shader->tokens) {
6834 tgsi_free_tokens(tokens);
6835 }
6836
6837 cleanup:
6838 free_emitter(emit);
6839
6840 done:
6841 SVGA_STATS_TIME_POP(svga_sws(svga));
6842 return variant;
6843 }
6844