1 /**************************************************************************
3 * Copyright 2010 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 * TGSI to LLVM IR translation -- AoS.
33 * - No control flow support: the existing control flow code should be factored
34 * out into from the SoA code into a common module and shared.
35 * - No derivatives. Derivate logic should be pluggable, just like the samplers.
37 * @author Jose Fonseca <jfonseca@vmware.com>
40 #include "pipe/p_config.h"
41 #include "pipe/p_shader_tokens.h"
42 #include "util/u_debug.h"
43 #include "util/u_math.h"
44 #include "util/u_memory.h"
45 #include "tgsi/tgsi_dump.h"
46 #include "tgsi/tgsi_info.h"
47 #include "tgsi/tgsi_parse.h"
48 #include "tgsi/tgsi_util.h"
49 #include "tgsi/tgsi_scan.h"
50 #include "lp_bld_type.h"
51 #include "lp_bld_const.h"
52 #include "lp_bld_arit.h"
53 #include "lp_bld_logic.h"
54 #include "lp_bld_swizzle.h"
55 #include "lp_bld_flow.h"
56 #include "lp_bld_quad.h"
57 #include "lp_bld_tgsi.h"
58 #include "lp_bld_debug.h"
59 #include "lp_bld_sample.h"
63 * Wrapper around lp_build_swizzle_aos which translates swizzles to another
67 swizzle_aos(struct lp_build_tgsi_context
*bld_base
,
74 unsigned char swizzles
[4];
75 struct lp_build_tgsi_aos_context
*bld
= lp_aos_context(bld_base
);
77 assert(swizzle_x
< 4);
78 assert(swizzle_y
< 4);
79 assert(swizzle_z
< 4);
80 assert(swizzle_w
< 4);
82 swizzles
[bld
->inv_swizzles
[0]] = bld
->swizzles
[swizzle_x
];
83 swizzles
[bld
->inv_swizzles
[1]] = bld
->swizzles
[swizzle_y
];
84 swizzles
[bld
->inv_swizzles
[2]] = bld
->swizzles
[swizzle_z
];
85 swizzles
[bld
->inv_swizzles
[3]] = bld
->swizzles
[swizzle_w
];
87 return lp_build_swizzle_aos(&bld
->bld_base
.base
, a
, swizzles
);
92 swizzle_scalar_aos(struct lp_build_tgsi_aos_context
*bld
,
96 chan
= bld
->swizzles
[chan
];
97 return lp_build_swizzle_scalar_aos(&bld
->bld_base
.base
, a
, chan
, 4);
103 struct lp_build_tgsi_context
* bld_base
,
104 const struct tgsi_full_src_register
* reg
,
105 enum tgsi_opcode_type stype
,
108 struct lp_build_tgsi_aos_context
* bld
= lp_aos_context(bld_base
);
109 LLVMBuilderRef builder
= bld_base
->base
.gallivm
->builder
;
110 struct lp_type type
= bld_base
->base
.type
;
114 assert(!reg
->Register
.Indirect
);
117 * Get the constants components
120 res
= bld
->bld_base
.base
.undef
;
121 for (chan
= 0; chan
< 4; ++chan
) {
123 LLVMValueRef scalar_ptr
;
125 LLVMValueRef swizzle
;
127 index
= lp_build_const_int32(bld
->bld_base
.base
.gallivm
,
128 reg
->Register
.Index
* 4 + chan
);
130 scalar_ptr
= LLVMBuildGEP(builder
, bld
->consts_ptr
, &index
, 1, "");
132 scalar
= LLVMBuildLoad(builder
, scalar_ptr
, "");
134 lp_build_name(scalar
, "const[%u].%c", reg
->Register
.Index
, "xyzw"[chan
]);
137 * NOTE: constants array is always assumed to be RGBA
140 swizzle
= lp_build_const_int32(bld
->bld_base
.base
.gallivm
,
141 bld
->swizzles
[chan
]);
143 res
= LLVMBuildInsertElement(builder
, res
, scalar
, swizzle
, "");
147 * Broadcast the first quaternion to all others.
149 * XXX: could be factored into a reusable function.
152 if (type
.length
> 4) {
153 LLVMValueRef shuffles
[LP_MAX_VECTOR_LENGTH
];
156 for (chan
= 0; chan
< 4; ++chan
) {
157 shuffles
[chan
] = lp_build_const_int32(bld
->bld_base
.base
.gallivm
, chan
);
160 for (i
= 4; i
< type
.length
; ++i
) {
161 shuffles
[i
] = shuffles
[i
% 4];
164 res
= LLVMBuildShuffleVector(builder
,
165 res
, bld
->bld_base
.base
.undef
,
166 LLVMConstVector(shuffles
, type
.length
),
173 emit_fetch_immediate(
174 struct lp_build_tgsi_context
* bld_base
,
175 const struct tgsi_full_src_register
* reg
,
176 enum tgsi_opcode_type stype
,
179 struct lp_build_tgsi_aos_context
* bld
= lp_aos_context(bld_base
);
180 LLVMValueRef res
= bld
->immediates
[reg
->Register
.Index
];
187 struct lp_build_tgsi_context
* bld_base
,
188 const struct tgsi_full_src_register
* reg
,
189 enum tgsi_opcode_type stype
,
192 struct lp_build_tgsi_aos_context
* bld
= lp_aos_context(bld_base
);
193 LLVMValueRef res
= bld
->inputs
[reg
->Register
.Index
];
194 assert(!reg
->Register
.Indirect
);
200 emit_fetch_temporary(
201 struct lp_build_tgsi_context
* bld_base
,
202 const struct tgsi_full_src_register
* reg
,
203 enum tgsi_opcode_type stype
,
206 struct lp_build_tgsi_aos_context
* bld
= lp_aos_context(bld_base
);
207 LLVMBuilderRef builder
= bld_base
->base
.gallivm
->builder
;
208 LLVMValueRef temp_ptr
= bld
->temps
[reg
->Register
.Index
];
209 LLVMValueRef res
= LLVMBuildLoad(builder
, temp_ptr
, "");
210 assert(!reg
->Register
.Indirect
);
212 return bld
->bld_base
.base
.undef
;
222 struct lp_build_tgsi_aos_context
*bld
,
223 const struct tgsi_full_instruction
*inst
,
227 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
228 const struct tgsi_full_dst_register
*reg
= &inst
->Dst
[index
];
229 LLVMValueRef mask
= NULL
;
235 if (inst
->Instruction
.Saturate
) {
236 value
= lp_build_max(&bld
->bld_base
.base
, value
, bld
->bld_base
.base
.zero
);
237 value
= lp_build_min(&bld
->bld_base
.base
, value
, bld
->bld_base
.base
.one
);
241 * Translate the register file
244 assert(!reg
->Register
.Indirect
);
246 switch (reg
->Register
.File
) {
247 case TGSI_FILE_OUTPUT
:
248 ptr
= bld
->outputs
[reg
->Register
.Index
];
251 case TGSI_FILE_TEMPORARY
:
252 ptr
= bld
->temps
[reg
->Register
.Index
];
255 case TGSI_FILE_ADDRESS
:
256 ptr
= bld
->addr
[reg
->Indirect
.Index
];
271 if (reg
->Register
.WriteMask
!= TGSI_WRITEMASK_XYZW
) {
272 LLVMValueRef writemask
;
274 writemask
= lp_build_const_mask_aos_swizzled(bld
->bld_base
.base
.gallivm
,
275 bld
->bld_base
.base
.type
,
276 reg
->Register
.WriteMask
,
281 mask
= LLVMBuildAnd(builder
, mask
, writemask
, "");
288 LLVMValueRef orig_value
;
290 orig_value
= LLVMBuildLoad(builder
, ptr
, "");
291 value
= lp_build_select(&bld
->bld_base
.base
,
292 mask
, value
, orig_value
);
295 LLVMBuildStore(builder
, value
, ptr
);
300 * High-level instruction translators.
304 emit_tex(struct lp_build_tgsi_aos_context
*bld
,
305 const struct tgsi_full_instruction
*inst
,
306 enum lp_build_tex_modifier modifier
)
311 struct lp_derivatives derivs
= { {NULL
}, {NULL
} };
314 _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
315 return bld
->bld_base
.base
.undef
;
318 target
= inst
->Texture
.Texture
;
320 coords
= lp_build_emit_fetch( &bld
->bld_base
, inst
, 0 , LP_CHAN_ALL
);
322 if (modifier
== LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV
) {
323 /* probably not going to work */
324 derivs
.ddx
[0] = lp_build_emit_fetch( &bld
->bld_base
, inst
, 1 , LP_CHAN_ALL
);
325 derivs
.ddy
[0] = lp_build_emit_fetch( &bld
->bld_base
, inst
, 2 , LP_CHAN_ALL
);
326 unit
= inst
->Src
[3].Register
.Index
;
329 unit
= inst
->Src
[1].Register
.Index
;
331 return bld
->sampler
->emit_fetch_texel(bld
->sampler
,
340 emit_sample(struct lp_build_tgsi_aos_context
*bld
,
341 const struct tgsi_full_instruction
*inst
,
342 enum lp_build_tex_modifier modifier
)
347 struct lp_derivatives derivs
= { {NULL
}, {NULL
} };
350 _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
351 return bld
->bld_base
.base
.undef
;
354 coords
= lp_build_emit_fetch( &bld
->bld_base
, inst
, 0 , LP_CHAN_ALL
);
356 /* ignore modifiers, can't handle different sampler / sampler view, etc... */
357 unit
= inst
->Src
[1].Register
.Index
;
358 assert(inst
->Src
[2].Register
.Index
== unit
);
360 target
= bld
->sv
[unit
].Resource
;
362 return bld
->sampler
->emit_fetch_texel(bld
->sampler
,
371 lp_emit_declaration_aos(
372 struct lp_build_tgsi_aos_context
*bld
,
373 const struct tgsi_full_declaration
*decl
)
375 struct gallivm_state
*gallivm
= bld
->bld_base
.base
.gallivm
;
376 LLVMTypeRef vec_type
= lp_build_vec_type(bld
->bld_base
.base
.gallivm
, bld
->bld_base
.base
.type
);
378 unsigned first
= decl
->Range
.First
;
379 unsigned last
= decl
->Range
.Last
;
382 for (idx
= first
; idx
<= last
; ++idx
) {
383 switch (decl
->Declaration
.File
) {
384 case TGSI_FILE_TEMPORARY
:
385 assert(idx
< LP_MAX_INLINED_TEMPS
);
386 if (bld
->indirect_files
& (1 << TGSI_FILE_TEMPORARY
)) {
387 LLVMValueRef array_size
= lp_build_const_int32(gallivm
, last
+ 1);
388 bld
->temps_array
= lp_build_array_alloca(bld
->bld_base
.base
.gallivm
,
389 vec_type
, array_size
, "");
391 bld
->temps
[idx
] = lp_build_alloca(gallivm
, vec_type
, "");
395 case TGSI_FILE_OUTPUT
:
396 bld
->outputs
[idx
] = lp_build_alloca(gallivm
, vec_type
, "");
399 case TGSI_FILE_ADDRESS
:
400 assert(idx
< LP_MAX_TGSI_ADDRS
);
401 bld
->addr
[idx
] = lp_build_alloca(gallivm
, vec_type
, "");
404 case TGSI_FILE_SAMPLER_VIEW
:
406 * The target stored here MUST match whatever there actually
407 * is in the set sampler views (what about return type?).
409 assert(last
< PIPE_MAX_SHADER_SAMPLER_VIEWS
);
410 for (idx
= first
; idx
<= last
; ++idx
) {
411 bld
->sv
[idx
] = decl
->SamplerView
;
416 /* don't need to declare other vars */
424 * Emit LLVM for one TGSI instruction.
425 * \param return TRUE for success, FALSE otherwise
428 lp_emit_instruction_aos(
429 struct lp_build_tgsi_aos_context
*bld
,
430 const struct tgsi_full_instruction
*inst
,
431 const struct tgsi_opcode_info
*info
,
434 LLVMValueRef src0
, src1
, src2
;
436 LLVMValueRef dst0
= NULL
;
439 * Stores and write masks are handled in a general fashion after the long
440 * instruction opcode switch statement.
442 * Although not stricitly necessary, we avoid generating instructions for
443 * channels which won't be stored, in cases where's that easy. For some
444 * complex instructions, like texture sampling, it is more convenient to
445 * assume a full writemask and then let LLVM optimization passes eliminate
451 assert(info
->num_dst
<= 1);
453 dst0
= bld
->bld_base
.base
.undef
;
456 switch (inst
->Instruction
.Opcode
) {
457 case TGSI_OPCODE_ARL
:
458 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
459 dst0
= lp_build_floor(&bld
->bld_base
.base
, src0
);
462 case TGSI_OPCODE_MOV
:
463 dst0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
466 case TGSI_OPCODE_LIT
:
469 case TGSI_OPCODE_RCP
:
470 /* TGSI_OPCODE_RECIP */
471 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
472 dst0
= lp_build_rcp(&bld
->bld_base
.base
, src0
);
475 case TGSI_OPCODE_RSQ
:
476 /* TGSI_OPCODE_RECIPSQRT */
477 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
478 tmp0
= lp_build_abs(&bld
->bld_base
.base
, src0
);
479 dst0
= lp_build_rsqrt(&bld
->bld_base
.base
, tmp0
);
482 case TGSI_OPCODE_EXP
:
485 case TGSI_OPCODE_LOG
:
488 case TGSI_OPCODE_MUL
:
489 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
490 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
491 dst0
= lp_build_mul(&bld
->bld_base
.base
, src0
, src1
);
494 case TGSI_OPCODE_ADD
:
495 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
496 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
497 dst0
= lp_build_add(&bld
->bld_base
.base
, src0
, src1
);
500 case TGSI_OPCODE_DP3
:
501 /* TGSI_OPCODE_DOT3 */
504 case TGSI_OPCODE_DP4
:
505 /* TGSI_OPCODE_DOT4 */
508 case TGSI_OPCODE_DST
:
511 case TGSI_OPCODE_MIN
:
512 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
513 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
514 dst0
= lp_build_min(&bld
->bld_base
.base
, src0
, src1
);
517 case TGSI_OPCODE_MAX
:
518 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
519 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
520 dst0
= lp_build_max(&bld
->bld_base
.base
, src0
, src1
);
523 case TGSI_OPCODE_SLT
:
524 /* TGSI_OPCODE_SETLT */
525 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
526 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
527 tmp0
= lp_build_cmp(&bld
->bld_base
.base
, PIPE_FUNC_LESS
, src0
, src1
);
528 dst0
= lp_build_select(&bld
->bld_base
.base
, tmp0
, bld
->bld_base
.base
.one
, bld
->bld_base
.base
.zero
);
531 case TGSI_OPCODE_SGE
:
532 /* TGSI_OPCODE_SETGE */
533 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
534 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
535 tmp0
= lp_build_cmp(&bld
->bld_base
.base
, PIPE_FUNC_GEQUAL
, src0
, src1
);
536 dst0
= lp_build_select(&bld
->bld_base
.base
, tmp0
, bld
->bld_base
.base
.one
, bld
->bld_base
.base
.zero
);
539 case TGSI_OPCODE_MAD
:
540 /* TGSI_OPCODE_MADD */
541 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
542 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
543 src2
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 2, LP_CHAN_ALL
);
544 tmp0
= lp_build_mul(&bld
->bld_base
.base
, src0
, src1
);
545 dst0
= lp_build_add(&bld
->bld_base
.base
, tmp0
, src2
);
548 case TGSI_OPCODE_LRP
:
549 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
550 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
551 src2
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 2, LP_CHAN_ALL
);
552 tmp0
= lp_build_sub(&bld
->bld_base
.base
, src1
, src2
);
553 tmp0
= lp_build_mul(&bld
->bld_base
.base
, src0
, tmp0
);
554 dst0
= lp_build_add(&bld
->bld_base
.base
, tmp0
, src2
);
557 case TGSI_OPCODE_DP2A
:
560 case TGSI_OPCODE_FRC
:
561 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
562 tmp0
= lp_build_floor(&bld
->bld_base
.base
, src0
);
563 dst0
= lp_build_sub(&bld
->bld_base
.base
, src0
, tmp0
);
566 case TGSI_OPCODE_FLR
:
567 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
568 dst0
= lp_build_floor(&bld
->bld_base
.base
, src0
);
571 case TGSI_OPCODE_ROUND
:
572 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
573 dst0
= lp_build_round(&bld
->bld_base
.base
, src0
);
576 case TGSI_OPCODE_EX2
:
577 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
578 tmp0
= lp_build_swizzle_scalar_aos(&bld
->bld_base
.base
, src0
, TGSI_SWIZZLE_X
, TGSI_NUM_CHANNELS
);
579 dst0
= lp_build_exp2(&bld
->bld_base
.base
, tmp0
);
582 case TGSI_OPCODE_LG2
:
583 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
584 tmp0
= swizzle_scalar_aos(bld
, src0
, TGSI_SWIZZLE_X
);
585 dst0
= lp_build_log2(&bld
->bld_base
.base
, tmp0
);
588 case TGSI_OPCODE_POW
:
589 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
590 src0
= swizzle_scalar_aos(bld
, src0
, TGSI_SWIZZLE_X
);
591 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
592 src1
= swizzle_scalar_aos(bld
, src1
, TGSI_SWIZZLE_X
);
593 dst0
= lp_build_pow(&bld
->bld_base
.base
, src0
, src1
);
596 case TGSI_OPCODE_XPD
:
599 case TGSI_OPCODE_DPH
:
602 case TGSI_OPCODE_COS
:
603 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
604 tmp0
= swizzle_scalar_aos(bld
, src0
, TGSI_SWIZZLE_X
);
605 dst0
= lp_build_cos(&bld
->bld_base
.base
, tmp0
);
608 case TGSI_OPCODE_DDX
:
611 case TGSI_OPCODE_DDY
:
614 case TGSI_OPCODE_KILL
:
617 case TGSI_OPCODE_KILL_IF
:
620 case TGSI_OPCODE_PK2H
:
624 case TGSI_OPCODE_PK2US
:
628 case TGSI_OPCODE_PK4B
:
632 case TGSI_OPCODE_PK4UB
:
635 case TGSI_OPCODE_SEQ
:
636 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
637 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
638 tmp0
= lp_build_cmp(&bld
->bld_base
.base
, PIPE_FUNC_EQUAL
, src0
, src1
);
639 dst0
= lp_build_select(&bld
->bld_base
.base
, tmp0
, bld
->bld_base
.base
.one
, bld
->bld_base
.base
.zero
);
642 case TGSI_OPCODE_SGT
:
643 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
644 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
645 tmp0
= lp_build_cmp(&bld
->bld_base
.base
, PIPE_FUNC_GREATER
, src0
, src1
);
646 dst0
= lp_build_select(&bld
->bld_base
.base
, tmp0
, bld
->bld_base
.base
.one
, bld
->bld_base
.base
.zero
);
649 case TGSI_OPCODE_SIN
:
650 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
651 tmp0
= swizzle_scalar_aos(bld
, src0
, TGSI_SWIZZLE_X
);
652 dst0
= lp_build_sin(&bld
->bld_base
.base
, tmp0
);
655 case TGSI_OPCODE_SLE
:
656 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
657 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
658 tmp0
= lp_build_cmp(&bld
->bld_base
.base
, PIPE_FUNC_LEQUAL
, src0
, src1
);
659 dst0
= lp_build_select(&bld
->bld_base
.base
, tmp0
, bld
->bld_base
.base
.one
, bld
->bld_base
.base
.zero
);
662 case TGSI_OPCODE_SNE
:
663 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
664 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
665 tmp0
= lp_build_cmp(&bld
->bld_base
.base
, PIPE_FUNC_NOTEQUAL
, src0
, src1
);
666 dst0
= lp_build_select(&bld
->bld_base
.base
, tmp0
, bld
->bld_base
.base
.one
, bld
->bld_base
.base
.zero
);
669 case TGSI_OPCODE_TEX
:
670 dst0
= emit_tex(bld
, inst
, LP_BLD_TEX_MODIFIER_NONE
);
673 case TGSI_OPCODE_TXD
:
674 dst0
= emit_tex(bld
, inst
, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV
);
677 case TGSI_OPCODE_UP2H
:
683 case TGSI_OPCODE_UP2US
:
689 case TGSI_OPCODE_UP4B
:
695 case TGSI_OPCODE_UP4UB
:
701 case TGSI_OPCODE_ARR
:
702 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
703 dst0
= lp_build_round(&bld
->bld_base
.base
, src0
);
706 case TGSI_OPCODE_CAL
:
709 case TGSI_OPCODE_RET
:
710 /* safe to ignore at end */
713 case TGSI_OPCODE_END
:
717 case TGSI_OPCODE_SSG
:
718 /* TGSI_OPCODE_SGN */
719 tmp0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
720 dst0
= lp_build_sgn(&bld
->bld_base
.base
, tmp0
);
723 case TGSI_OPCODE_CMP
:
724 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
725 src1
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 1, LP_CHAN_ALL
);
726 src2
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 2, LP_CHAN_ALL
);
727 tmp0
= lp_build_cmp(&bld
->bld_base
.base
, PIPE_FUNC_LESS
, src0
, bld
->bld_base
.base
.zero
);
728 dst0
= lp_build_select(&bld
->bld_base
.base
, tmp0
, src1
, src2
);
731 case TGSI_OPCODE_SCS
:
734 case TGSI_OPCODE_TXB
:
735 dst0
= emit_tex(bld
, inst
, LP_BLD_TEX_MODIFIER_LOD_BIAS
);
738 case TGSI_OPCODE_DIV
:
743 case TGSI_OPCODE_DP2
:
746 case TGSI_OPCODE_TXL
:
747 dst0
= emit_tex(bld
, inst
, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD
);
750 case TGSI_OPCODE_TXP
:
751 dst0
= emit_tex(bld
, inst
, LP_BLD_TEX_MODIFIER_PROJECTED
);
754 case TGSI_OPCODE_BRK
:
758 case TGSI_OPCODE_UIF
:
761 case TGSI_OPCODE_BGNLOOP
:
764 case TGSI_OPCODE_BGNSUB
:
767 case TGSI_OPCODE_ELSE
:
770 case TGSI_OPCODE_ENDIF
:
773 case TGSI_OPCODE_ENDLOOP
:
776 case TGSI_OPCODE_ENDSUB
:
779 case TGSI_OPCODE_CEIL
:
780 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
781 dst0
= lp_build_ceil(&bld
->bld_base
.base
, src0
);
784 case TGSI_OPCODE_I2F
:
789 case TGSI_OPCODE_NOT
:
794 case TGSI_OPCODE_TRUNC
:
795 src0
= lp_build_emit_fetch(&bld
->bld_base
, inst
, 0, LP_CHAN_ALL
);
796 dst0
= lp_build_trunc(&bld
->bld_base
.base
, src0
);
799 case TGSI_OPCODE_SHL
:
804 case TGSI_OPCODE_ISHR
:
809 case TGSI_OPCODE_AND
:
819 case TGSI_OPCODE_MOD
:
824 case TGSI_OPCODE_XOR
:
829 case TGSI_OPCODE_TXF
:
834 case TGSI_OPCODE_TXQ
:
839 case TGSI_OPCODE_CONT
:
842 case TGSI_OPCODE_EMIT
:
846 case TGSI_OPCODE_ENDPRIM
:
850 case TGSI_OPCODE_NOP
:
853 case TGSI_OPCODE_SAMPLE
:
854 dst0
= emit_sample(bld
, inst
, LP_BLD_TEX_MODIFIER_NONE
);
862 lp_emit_store_aos(bld
, inst
, 0, dst0
);
870 lp_build_tgsi_aos(struct gallivm_state
*gallivm
,
871 const struct tgsi_token
*tokens
,
873 const unsigned char swizzles
[4],
874 LLVMValueRef consts_ptr
,
875 const LLVMValueRef
*inputs
,
876 LLVMValueRef
*outputs
,
877 struct lp_build_sampler_aos
*sampler
,
878 const struct tgsi_shader_info
*info
)
880 struct lp_build_tgsi_aos_context bld
;
881 struct tgsi_parse_context parse
;
882 uint num_immediates
= 0;
886 /* Setup build context */
887 memset(&bld
, 0, sizeof bld
);
888 lp_build_context_init(&bld
.bld_base
.base
, gallivm
, type
);
889 lp_build_context_init(&bld
.bld_base
.uint_bld
, gallivm
, lp_uint_type(type
));
890 lp_build_context_init(&bld
.bld_base
.int_bld
, gallivm
, lp_int_type(type
));
891 lp_build_context_init(&bld
.int_bld
, gallivm
, lp_int_type(type
));
893 for (chan
= 0; chan
< 4; ++chan
) {
894 bld
.swizzles
[chan
] = swizzles
[chan
];
895 bld
.inv_swizzles
[swizzles
[chan
]] = chan
;
899 bld
.outputs
= outputs
;
900 bld
.consts_ptr
= consts_ptr
;
901 bld
.sampler
= sampler
;
902 bld
.indirect_files
= info
->indirect_files
;
903 bld
.bld_base
.emit_swizzle
= swizzle_aos
;
904 bld
.bld_base
.info
= info
;
906 bld
.bld_base
.emit_fetch_funcs
[TGSI_FILE_CONSTANT
] = emit_fetch_constant
;
907 bld
.bld_base
.emit_fetch_funcs
[TGSI_FILE_IMMEDIATE
] = emit_fetch_immediate
;
908 bld
.bld_base
.emit_fetch_funcs
[TGSI_FILE_INPUT
] = emit_fetch_input
;
909 bld
.bld_base
.emit_fetch_funcs
[TGSI_FILE_TEMPORARY
] = emit_fetch_temporary
;
911 /* Set opcode actions */
912 lp_set_default_actions_cpu(&bld
.bld_base
);
914 if (!lp_bld_tgsi_list_init(&bld
.bld_base
)) {
918 tgsi_parse_init(&parse
, tokens
);
920 while (!tgsi_parse_end_of_tokens(&parse
)) {
921 tgsi_parse_token(&parse
);
923 switch(parse
.FullToken
.Token
.Type
) {
924 case TGSI_TOKEN_TYPE_DECLARATION
:
925 /* Inputs already interpolated */
926 lp_emit_declaration_aos(&bld
, &parse
.FullToken
.FullDeclaration
);
929 case TGSI_TOKEN_TYPE_INSTRUCTION
:
930 /* save expanded instruction */
931 lp_bld_tgsi_add_instruction(&bld
.bld_base
,
932 &parse
.FullToken
.FullInstruction
);
935 case TGSI_TOKEN_TYPE_IMMEDIATE
:
936 /* simply copy the immediate values into the next immediates[] slot */
938 const uint size
= parse
.FullToken
.FullImmediate
.Immediate
.NrTokens
- 1;
941 assert(num_immediates
< LP_MAX_INLINED_IMMEDIATES
);
942 for (chan
= 0; chan
< 4; ++chan
) {
945 for (chan
= 0; chan
< size
; ++chan
) {
946 unsigned swizzle
= bld
.swizzles
[chan
];
947 imm
[swizzle
] = parse
.FullToken
.FullImmediate
.u
[chan
].Float
;
949 bld
.immediates
[num_immediates
] =
950 lp_build_const_aos(gallivm
, type
,
951 imm
[0], imm
[1], imm
[2], imm
[3],
957 case TGSI_TOKEN_TYPE_PROPERTY
:
966 struct tgsi_full_instruction
*instr
= bld
.bld_base
.instructions
+ pc
;
967 const struct tgsi_opcode_info
*opcode_info
=
968 tgsi_get_opcode_info(instr
->Instruction
.Opcode
);
969 if (!lp_emit_instruction_aos(&bld
, instr
, opcode_info
, &pc
))
970 _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
971 opcode_info
->mnemonic
);
975 LLVMBasicBlockRef block
= LLVMGetInsertBlock(gallivm
->builder
);
976 LLVMValueRef function
= LLVMGetBasicBlockParent(block
);
977 debug_printf("11111111111111111111111111111 \n");
978 tgsi_dump(tokens
, 0);
979 lp_debug_dump_value(function
);
980 debug_printf("2222222222222222222222222222 \n");
982 tgsi_parse_free(&parse
);
983 FREE(bld
.bld_base
.instructions
);
986 LLVMModuleRef module
= LLVMGetGlobalParent(
987 LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm
->builder
)));
988 LLVMDumpModule(module
);