lp_bld_tgsi.h revision 5d10d757276a599a60a68b88b21087b5824a8df7
1/**************************************************************************
2 *
3 * Copyright 2011-2012 Advanced Micro Devices, Inc.
4 * Copyright 2009 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29/**
30 * @file
31 * TGSI to LLVM IR translation.
32 *
33 * @author Jose Fonseca <jfonseca@vmware.com>
34 * @author Tom Stellard <thomas.stellard@amd.com>
35 */
36
37#ifndef LP_BLD_TGSI_H
38#define LP_BLD_TGSI_H
39
40#include "gallivm/lp_bld.h"
41#include "gallivm/lp_bld_tgsi_action.h"
42#include "gallivm/lp_bld_limits.h"
43#include "lp_bld_type.h"
44#include "pipe/p_compiler.h"
45#include "pipe/p_state.h"
46#include "tgsi/tgsi_exec.h"
47#include "tgsi/tgsi_scan.h"
48#include "tgsi/tgsi_info.h"
49
50#define LP_CHAN_ALL ~0
51
52#define LP_MAX_INSTRUCTIONS 256
53
54struct tgsi_full_declaration;
55struct tgsi_full_immediate;
56struct tgsi_full_instruction;
57struct tgsi_full_src_register;
58struct tgsi_opcode_info;
59struct tgsi_token;
60struct tgsi_shader_info;
61struct lp_build_mask_context;
62struct gallivm_state;
63
64
65enum lp_build_tex_modifier {
66   LP_BLD_TEX_MODIFIER_NONE = 0,
67   LP_BLD_TEX_MODIFIER_PROJECTED,
68   LP_BLD_TEX_MODIFIER_LOD_BIAS,
69   LP_BLD_TEX_MODIFIER_EXPLICIT_LOD,
70   LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV
71};
72
73
74/**
75 * Describe a channel of a register.
76 *
77 * The value can be a:
78 * - immediate value (i.e. derived from a IMM register)
79 * - CONST[n].x/y/z/w
80 * - IN[n].x/y/z/w
81 * - undetermined (when .file == TGSI_FILE_NULL)
82 *
83 * This is one of the analysis results, and is used to described
84 * the output color in terms of inputs.
85 */
86struct lp_tgsi_channel_info
87{
88   unsigned file:4; /* TGSI_FILE_* */
89   unsigned swizzle:3; /* PIPE_SWIZZLE_x */
90   union {
91      uint32_t index;
92      float value; /* for TGSI_FILE_IMMEDIATE */
93   } u;
94};
95
96
97/**
98 * Describe a texture sampler interpolator.
99 *
100 * The interpolation is described in terms of regular inputs.
101 */
102struct lp_tgsi_texture_info
103{
104   struct lp_tgsi_channel_info coord[4];
105   unsigned target:8; /* TGSI_TEXTURE_* */
106   unsigned unit:8;  /* Sampler unit */
107   unsigned modifier:8; /* LP_BLD_TEX_MODIFIER_* */
108};
109
110
111struct lp_tgsi_info
112{
113   struct tgsi_shader_info base;
114
115   /*
116    * Whether any of the texture opcodes access a register file other than
117    * TGSI_FILE_INPUT.
118    *
119    * We could also handle TGSI_FILE_CONST/IMMEDIATE here, but there is little
120    * benefit.
121    */
122   unsigned indirect_textures:1;
123
124   /*
125    * Whether any immediate values are outside the range of 0 and 1
126    */
127   unsigned unclamped_immediates:1;
128
129   /*
130    * Texture opcode description. Aimed at detecting and described direct
131    * texture opcodes.
132    */
133   unsigned num_texs;
134   struct lp_tgsi_texture_info tex[PIPE_MAX_SAMPLERS];
135
136   /*
137    * Output description. Aimed at detecting and describing simple blit
138    * shaders.
139    */
140   struct lp_tgsi_channel_info output[PIPE_MAX_SHADER_OUTPUTS][4];
141
142   /*
143    * Shortcut pointers into the above (for fragment shaders).
144    */
145   const struct lp_tgsi_channel_info *cbuf[PIPE_MAX_COLOR_BUFS];
146};
147
148/**
149 * Sampler code generation interface.
150 *
151 * Although texture sampling is a requirement for TGSI translation, it is
152 * a very different problem with several different approaches to it. This
153 * structure establishes an interface for texture sampling code generation, so
154 * that we can easily use different texture sampling strategies.
155 */
156struct lp_build_sampler_soa
157{
158   void
159   (*destroy)( struct lp_build_sampler_soa *sampler );
160
161   void
162   (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler,
163                        struct gallivm_state *gallivm,
164                        struct lp_type type,
165                        unsigned unit,
166                        unsigned num_coords,
167                        const LLVMValueRef *coords,
168                        const LLVMValueRef *ddx,
169                        const LLVMValueRef *ddy,
170                        LLVMValueRef lod_bias, /* optional */
171                        LLVMValueRef explicit_lod, /* optional */
172                        LLVMValueRef *texel);
173
174   void
175   (*emit_size_query)( const struct lp_build_sampler_soa *sampler,
176                       struct gallivm_state *gallivm,
177                       unsigned unit,
178                       LLVMValueRef explicit_lod, /* optional */
179                       LLVMValueRef *sizes_out);
180};
181
182
183struct lp_build_sampler_aos
184{
185   LLVMValueRef
186   (*emit_fetch_texel)( struct lp_build_sampler_aos *sampler,
187                        struct lp_build_context *bld,
188                        unsigned target, /* TGSI_TEXTURE_* */
189                        unsigned unit,
190                        LLVMValueRef coords,
191                        LLVMValueRef ddx,
192                        LLVMValueRef ddy,
193                        enum lp_build_tex_modifier modifier);
194};
195
196
197void
198lp_build_tgsi_info(const struct tgsi_token *tokens,
199                   struct lp_tgsi_info *info);
200
201
202void
203lp_build_tgsi_soa(struct gallivm_state *gallivm,
204                  const struct tgsi_token *tokens,
205                  struct lp_type type,
206                  struct lp_build_mask_context *mask,
207                  LLVMValueRef consts_ptr,
208                  LLVMValueRef system_values_array,
209                  const LLVMValueRef *pos,
210                  const LLVMValueRef (*inputs)[4],
211                  LLVMValueRef (*outputs)[4],
212                  struct lp_build_sampler_soa *sampler,
213                  const struct tgsi_shader_info *info);
214
215
216void
217lp_build_tgsi_aos(struct gallivm_state *gallivm,
218                  const struct tgsi_token *tokens,
219                  struct lp_type type,
220                  const unsigned char swizzles[4],
221                  LLVMValueRef consts_ptr,
222                  const LLVMValueRef *inputs,
223                  LLVMValueRef *outputs,
224                  struct lp_build_sampler_aos *sampler,
225                  const struct tgsi_shader_info *info);
226
227
228LLVMValueRef
229lp_build_system_values_array(struct gallivm_state *gallivm,
230                             const struct tgsi_shader_info *info,
231                             LLVMValueRef instance_id,
232                             LLVMValueRef facing);
233
234
235struct lp_exec_mask {
236   struct lp_build_context *bld;
237
238   boolean has_mask;
239
240   LLVMTypeRef int_vec_type;
241
242   LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
243   int cond_stack_size;
244   LLVMValueRef cond_mask;
245
246   LLVMBasicBlockRef loop_block;
247   LLVMValueRef cont_mask;
248   LLVMValueRef break_mask;
249   LLVMValueRef break_var;
250   struct {
251      LLVMBasicBlockRef loop_block;
252      LLVMValueRef cont_mask;
253      LLVMValueRef break_mask;
254      LLVMValueRef break_var;
255   } loop_stack[LP_MAX_TGSI_NESTING];
256   int loop_stack_size;
257
258   LLVMValueRef ret_mask;
259   struct {
260      int pc;
261      LLVMValueRef ret_mask;
262   } call_stack[LP_MAX_TGSI_NESTING];
263   int call_stack_size;
264
265   LLVMValueRef exec_mask;
266   LLVMValueRef loop_limiter;
267};
268
269struct lp_build_tgsi_inst_list
270{
271   struct tgsi_full_instruction *instructions;
272   uint max_instructions;
273   uint num_instructions;
274};
275
276unsigned lp_bld_tgsi_list_init(struct lp_build_tgsi_context * bld_base);
277
278
279unsigned lp_bld_tgsi_add_instruction(
280   struct lp_build_tgsi_context * bld_base,
281   struct tgsi_full_instruction *inst_to_add);
282
283
284struct lp_build_tgsi_context;
285
286
287typedef LLVMValueRef (*lp_build_emit_fetch_fn)(struct lp_build_tgsi_context *,
288                                        const struct tgsi_full_src_register *,
289                                        enum tgsi_opcode_type,
290                                        unsigned);
291
292struct lp_build_tgsi_context
293{
294   struct lp_build_context base;
295
296   struct lp_build_context uint_bld;
297   struct lp_build_context int_bld;
298
299   /** This array stores functions that are used to transform TGSI opcodes to
300     * LLVM instructions.
301     */
302   struct lp_build_tgsi_action op_actions[TGSI_OPCODE_LAST];
303
304   /* TGSI_OPCODE_RSQ is defined as 1 / sqrt( abs(src0.x) ), rsq_action
305    * should compute 1 / sqrt (src0.x) */
306   struct lp_build_tgsi_action rsq_action;
307
308   const struct tgsi_shader_info *info;
309
310   lp_build_emit_fetch_fn emit_fetch_funcs[TGSI_FILE_COUNT];
311
312   LLVMValueRef (*emit_swizzle)(struct lp_build_tgsi_context *,
313                         LLVMValueRef, unsigned, unsigned, unsigned, unsigned);
314
315   void (*emit_store)(struct lp_build_tgsi_context *,
316                      const struct tgsi_full_instruction *,
317                      const struct tgsi_opcode_info *,
318                      LLVMValueRef dst[4]);
319
320   void (*emit_declaration)(struct lp_build_tgsi_context *,
321                             const struct tgsi_full_declaration *decl);
322
323   void (*emit_immediate)(struct lp_build_tgsi_context *,
324                          const struct tgsi_full_immediate *imm);
325
326
327   /* Allow the user to store data in this structure rather than passing it
328    * to every function. */
329   void * userdata;
330
331   boolean soa;
332
333   int pc;
334
335   struct tgsi_full_instruction *instructions;
336   uint max_instructions;
337   uint num_instructions;
338
339   /** This function allows the user to insert some instructions at the
340     * beginning of the program.  It is optional and does not need to be
341     * implemented.
342     */
343   void (*emit_prologue)(struct lp_build_tgsi_context*);
344
345   /** This function allows the user to insert some instructions at the end of
346     * the program.  This callback is intended to be used for emitting
347     * instructions to handle the export for the output registers, but it can
348     * be used for any purpose.  Implementing this function is optiona, but
349     * recommended.
350     */
351   void (*emit_epilogue)(struct lp_build_tgsi_context*);
352};
353
354struct lp_build_tgsi_soa_context
355{
356   struct lp_build_tgsi_context bld_base;
357
358   /* Builder for scalar elements of shader's data type (float) */
359   struct lp_build_context elem_bld;
360
361   LLVMValueRef consts_ptr;
362   const LLVMValueRef *pos;
363   const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS];
364   LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS];
365
366   const struct lp_build_sampler_soa *sampler;
367
368   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][TGSI_NUM_CHANNELS];
369   LLVMValueRef temps[LP_MAX_TGSI_TEMPS][TGSI_NUM_CHANNELS];
370   LLVMValueRef addr[LP_MAX_TGSI_ADDRS][TGSI_NUM_CHANNELS];
371   LLVMValueRef preds[LP_MAX_TGSI_PREDS][TGSI_NUM_CHANNELS];
372
373   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
374    * set in the indirect_files field.
375    * The temps[] array above is unused then.
376    */
377   LLVMValueRef temps_array;
378
379   /* We allocate/use this array of output if (1 << TGSI_FILE_OUTPUT) is
380    * set in the indirect_files field.
381    * The outputs[] array above is unused then.
382    */
383   LLVMValueRef outputs_array;
384
385   /* We allocate/use this array of inputs if (1 << TGSI_FILE_INPUT) is
386    * set in the indirect_files field.
387    * The inputs[] array above is unused then.
388    */
389   LLVMValueRef inputs_array;
390
391   LLVMValueRef system_values_array;
392
393   /** bitmask indicating which register files are accessed indirectly */
394   unsigned indirect_files;
395
396   struct lp_build_mask_context *mask;
397   struct lp_exec_mask exec_mask;
398
399   uint num_immediates;
400
401};
402
403void
404lp_emit_declaration_soa(
405   struct lp_build_tgsi_context *bld,
406   const struct tgsi_full_declaration *decl);
407
408void lp_emit_immediate_soa(
409   struct lp_build_tgsi_context *bld_base,
410   const struct tgsi_full_immediate *imm);
411
412boolean
413lp_emit_instruction_soa(
414   struct lp_build_tgsi_soa_context *bld,
415   const struct tgsi_full_instruction *inst,
416   const struct tgsi_opcode_info *info);
417
418
419LLVMValueRef
420lp_get_temp_ptr_soa(
421   struct lp_build_tgsi_soa_context *bld,
422   unsigned index,
423   unsigned chan);
424
425LLVMValueRef
426lp_get_output_ptr(
427   struct lp_build_tgsi_soa_context *bld,
428   unsigned index,
429   unsigned chan);
430
431struct lp_build_tgsi_aos_context
432{
433   struct lp_build_tgsi_context bld_base;
434
435   /* Builder for integer masks and indices */
436   struct lp_build_context int_bld;
437
438   /*
439    * AoS swizzle used:
440    * - swizzles[0] = red index
441    * - swizzles[1] = green index
442    * - swizzles[2] = blue index
443    * - swizzles[3] = alpha index
444    */
445   unsigned char swizzles[4];
446   unsigned char inv_swizzles[4];
447
448   LLVMValueRef consts_ptr;
449   const LLVMValueRef *inputs;
450   LLVMValueRef *outputs;
451
452   struct lp_build_sampler_aos *sampler;
453
454   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES];
455   LLVMValueRef temps[LP_MAX_TGSI_TEMPS];
456   LLVMValueRef addr[LP_MAX_TGSI_ADDRS];
457   LLVMValueRef preds[LP_MAX_TGSI_PREDS];
458
459   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
460    * set in the indirect_files field.
461    * The temps[] array above is unused then.
462    */
463   LLVMValueRef temps_array;
464
465   /** bitmask indicating which register files are accessed indirectly */
466   unsigned indirect_files;
467
468};
469
470static INLINE struct lp_build_tgsi_soa_context *
471lp_soa_context(struct lp_build_tgsi_context *bld_base)
472{
473   return (struct lp_build_tgsi_soa_context *)bld_base;
474}
475
476static INLINE struct lp_build_tgsi_aos_context *
477lp_aos_context(struct lp_build_tgsi_context *bld_base)
478{
479   return (struct lp_build_tgsi_aos_context *)bld_base;
480}
481
482void
483lp_emit_declaration_aos(
484   struct lp_build_tgsi_aos_context *bld,
485   const struct tgsi_full_declaration *decl);
486
487
488boolean
489lp_emit_instruction_aos(
490   struct lp_build_tgsi_aos_context *bld,
491   const struct tgsi_full_instruction *inst,
492   const struct tgsi_opcode_info *info,
493   int *pc);
494
495void
496lp_emit_store_aos(
497   struct lp_build_tgsi_aos_context *bld,
498   const struct tgsi_full_instruction *inst,
499   unsigned index,
500   LLVMValueRef value);
501
502void lp_build_fetch_args(
503   struct lp_build_tgsi_context * bld_base,
504   struct lp_build_emit_data * emit_data);
505
506LLVMValueRef
507lp_build_tgsi_inst_llvm_aos(
508   struct lp_build_tgsi_context * bld_base,
509   const struct tgsi_full_instruction *inst);
510
511void
512lp_build_tgsi_intrinsic(
513 const struct lp_build_tgsi_action * action,
514 struct lp_build_tgsi_context * bld_base,
515 struct lp_build_emit_data * emit_data);
516
517LLVMValueRef
518lp_build_emit_llvm(
519   struct lp_build_tgsi_context *bld_base,
520   unsigned tgsi_opcode,
521   struct lp_build_emit_data * emit_data);
522
523LLVMValueRef
524lp_build_emit_llvm_unary(
525   struct lp_build_tgsi_context *bld_base,
526   unsigned tgsi_opcode,
527   LLVMValueRef arg0);
528
529LLVMValueRef
530lp_build_emit_llvm_binary(
531   struct lp_build_tgsi_context *bld_base,
532   unsigned tgsi_opcode,
533   LLVMValueRef arg0,
534   LLVMValueRef arg1);
535
536LLVMValueRef
537lp_build_emit_llvm_ternary(
538   struct lp_build_tgsi_context *bld_base,
539   unsigned tgsi_opcode,
540   LLVMValueRef arg0,
541   LLVMValueRef arg1,
542   LLVMValueRef arg2);
543
544boolean
545lp_build_tgsi_inst_llvm(
546   struct lp_build_tgsi_context * bld_base,
547   const struct tgsi_full_instruction *inst);
548
549LLVMValueRef
550lp_build_emit_fetch(
551   struct lp_build_tgsi_context *bld_base,
552   const struct tgsi_full_instruction *inst,
553   unsigned src_op,
554   const unsigned chan_index);
555
556boolean
557lp_build_tgsi_llvm(
558   struct lp_build_tgsi_context * bld_base,
559   const struct tgsi_token *tokens);
560
561#endif /* LP_BLD_TGSI_H */
562