lp_bld_tgsi.h revision bc2875aa483a0fef7f6e32c1886f6e2edaba7694
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
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    * Texture opcode description. Aimed at detecting and described direct
126    * texture opcodes.
127    */
128   unsigned num_texs;
129   struct lp_tgsi_texture_info tex[PIPE_MAX_SAMPLERS];
130
131   /*
132    * Output description. Aimed at detecting and describing simple blit
133    * shaders.
134    */
135   struct lp_tgsi_channel_info output[PIPE_MAX_SHADER_OUTPUTS][4];
136
137   /*
138    * Shortcut pointers into the above (for fragment shaders).
139    */
140   const struct lp_tgsi_channel_info *cbuf[PIPE_MAX_COLOR_BUFS];
141};
142
143/**
144 * Sampler code generation interface.
145 *
146 * Although texture sampling is a requirement for TGSI translation, it is
147 * a very different problem with several different approaches to it. This
148 * structure establishes an interface for texture sampling code generation, so
149 * that we can easily use different texture sampling strategies.
150 */
151struct lp_build_sampler_soa
152{
153   void
154   (*destroy)( struct lp_build_sampler_soa *sampler );
155
156   void
157   (*emit_fetch_texel)( const struct lp_build_sampler_soa *sampler,
158                        struct gallivm_state *gallivm,
159                        struct lp_type type,
160                        unsigned unit,
161                        unsigned num_coords,
162                        const LLVMValueRef *coords,
163                        const LLVMValueRef *ddx,
164                        const LLVMValueRef *ddy,
165                        LLVMValueRef lod_bias, /* optional */
166                        LLVMValueRef explicit_lod, /* optional */
167                        LLVMValueRef *texel);
168};
169
170
171struct lp_build_sampler_aos
172{
173   LLVMValueRef
174   (*emit_fetch_texel)( struct lp_build_sampler_aos *sampler,
175                        struct lp_build_context *bld,
176                        unsigned target, /* TGSI_TEXTURE_* */
177                        unsigned unit,
178                        LLVMValueRef coords,
179                        LLVMValueRef ddx,
180                        LLVMValueRef ddy,
181                        enum lp_build_tex_modifier modifier);
182};
183
184
185void
186lp_build_tgsi_info(const struct tgsi_token *tokens,
187                   struct lp_tgsi_info *info);
188
189
190void
191lp_build_tgsi_soa(struct gallivm_state *gallivm,
192                  const struct tgsi_token *tokens,
193                  struct lp_type type,
194                  struct lp_build_mask_context *mask,
195                  LLVMValueRef consts_ptr,
196                  LLVMValueRef system_values_array,
197                  const LLVMValueRef *pos,
198                  const LLVMValueRef (*inputs)[4],
199                  LLVMValueRef (*outputs)[4],
200                  struct lp_build_sampler_soa *sampler,
201                  const struct tgsi_shader_info *info);
202
203
204void
205lp_build_tgsi_aos(struct gallivm_state *gallivm,
206                  const struct tgsi_token *tokens,
207                  struct lp_type type,
208                  const unsigned char swizzles[4],
209                  LLVMValueRef consts_ptr,
210                  const LLVMValueRef *inputs,
211                  LLVMValueRef *outputs,
212                  struct lp_build_sampler_aos *sampler,
213                  const struct tgsi_shader_info *info);
214
215
216LLVMValueRef
217lp_build_system_values_array(struct gallivm_state *gallivm,
218                             const struct tgsi_shader_info *info,
219                             LLVMValueRef instance_id,
220                             LLVMValueRef facing);
221
222
223struct lp_exec_mask {
224   struct lp_build_context *bld;
225
226   boolean has_mask;
227
228   LLVMTypeRef int_vec_type;
229
230   LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
231   int cond_stack_size;
232   LLVMValueRef cond_mask;
233
234   LLVMBasicBlockRef loop_block;
235   LLVMValueRef cont_mask;
236   LLVMValueRef break_mask;
237   LLVMValueRef break_var;
238   struct {
239      LLVMBasicBlockRef loop_block;
240      LLVMValueRef cont_mask;
241      LLVMValueRef break_mask;
242      LLVMValueRef break_var;
243   } loop_stack[LP_MAX_TGSI_NESTING];
244   int loop_stack_size;
245
246   LLVMValueRef ret_mask;
247   struct {
248      int pc;
249      LLVMValueRef ret_mask;
250   } call_stack[LP_MAX_TGSI_NESTING];
251   int call_stack_size;
252
253   LLVMValueRef exec_mask;
254};
255
256struct lp_build_tgsi_inst_list
257{
258   struct tgsi_full_instruction *instructions;
259   uint max_instructions;
260   uint num_instructions;
261};
262
263unsigned lp_bld_tgsi_list_init(struct lp_build_tgsi_context * bld_base);
264
265
266unsigned lp_bld_tgsi_add_instruction(
267   struct lp_build_tgsi_context * bld_base,
268   struct tgsi_full_instruction *inst_to_add);
269
270
271struct lp_build_tgsi_context;
272
273
274typedef LLVMValueRef (*lp_build_emit_fetch_fn)(struct lp_build_tgsi_context *,
275                                        const struct tgsi_full_src_register *,
276                                        unsigned);
277
278struct lp_build_tgsi_context
279{
280   struct lp_build_context base;
281
282   /** This array stores functions that are used to transform TGSI opcodes to
283     * LLVM instructions.
284     */
285   struct lp_build_tgsi_action op_actions[TGSI_OPCODE_LAST];
286
287   /* TGSI_OPCODE_RSQ is defined as 1 / sqrt( abs(src0.x) ), rsq_action
288    * should compute 1 / sqrt (src0.x) */
289   struct lp_build_tgsi_action rsq_action;
290
291   const struct tgsi_shader_info *info;
292
293   lp_build_emit_fetch_fn emit_fetch_funcs[TGSI_FILE_COUNT];
294
295   LLVMValueRef (*emit_swizzle)(struct lp_build_tgsi_context *,
296                         LLVMValueRef, unsigned, unsigned, unsigned, unsigned);
297
298   void (*emit_store)(struct lp_build_tgsi_context *,
299                      const struct tgsi_full_instruction *,
300                      const struct tgsi_opcode_info *,
301                      LLVMValueRef dst[4]);
302
303   void (*emit_declaration)(struct lp_build_tgsi_context *,
304                             const struct tgsi_full_declaration *decl);
305
306   void (*emit_immediate)(struct lp_build_tgsi_context *,
307                          const struct tgsi_full_immediate *imm);
308
309
310   /* Allow the user to store data in this structure rather than passing it
311    * to every function. */
312   void * userdata;
313
314   boolean soa;
315
316   int pc;
317
318   struct tgsi_full_instruction *instructions;
319   uint max_instructions;
320   uint num_instructions;
321
322   /** This function allows the user to insert some instructions at the
323     * beginning of the program.  It is optional and does not need to be
324     * implemented.
325     */
326   void (*emit_prologue)(struct lp_build_tgsi_context*);
327
328   /** This function allows the user to insert some instructions at the end of
329     * the program.  This callback is intended to be used for emitting
330     * instructions to handle the export for the output registers, but it can
331     * be used for any purpose.  Implementing this function is optiona, but
332     * recommended.
333     */
334   void (*emit_epilogue)(struct lp_build_tgsi_context*);
335};
336
337struct lp_build_tgsi_soa_context
338{
339   struct lp_build_tgsi_context bld_base;
340
341   /* Builder for vector integer masks and indices */
342   struct lp_build_context uint_bld;
343
344   /* Builder for scalar elements of shader's data type (float) */
345   struct lp_build_context elem_bld;
346
347   LLVMValueRef consts_ptr;
348   const LLVMValueRef *pos;
349   const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS];
350   LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS];
351
352   const struct lp_build_sampler_soa *sampler;
353
354   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][TGSI_NUM_CHANNELS];
355   LLVMValueRef temps[LP_MAX_TGSI_TEMPS][TGSI_NUM_CHANNELS];
356   LLVMValueRef addr[LP_MAX_TGSI_ADDRS][TGSI_NUM_CHANNELS];
357   LLVMValueRef preds[LP_MAX_TGSI_PREDS][TGSI_NUM_CHANNELS];
358
359   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
360    * set in the indirect_files field.
361    * The temps[] array above is unused then.
362    */
363   LLVMValueRef temps_array;
364
365   /* We allocate/use this array of output if (1 << TGSI_FILE_OUTPUT) is
366    * set in the indirect_files field.
367    * The outputs[] array above is unused then.
368    */
369   LLVMValueRef outputs_array;
370
371   /* We allocate/use this array of inputs if (1 << TGSI_FILE_INPUT) is
372    * set in the indirect_files field.
373    * The inputs[] array above is unused then.
374    */
375   LLVMValueRef inputs_array;
376
377   LLVMValueRef system_values_array;
378
379   /** bitmask indicating which register files are accessed indirectly */
380   unsigned indirect_files;
381
382   struct lp_build_mask_context *mask;
383   struct lp_exec_mask exec_mask;
384
385   uint num_immediates;
386
387};
388
389void
390lp_emit_declaration_soa(
391   struct lp_build_tgsi_context *bld,
392   const struct tgsi_full_declaration *decl);
393
394void lp_emit_immediate_soa(
395   struct lp_build_tgsi_context *bld_base,
396   const struct tgsi_full_immediate *imm);
397
398boolean
399lp_emit_instruction_soa(
400   struct lp_build_tgsi_soa_context *bld,
401   const struct tgsi_full_instruction *inst,
402   const struct tgsi_opcode_info *info);
403
404
405LLVMValueRef
406lp_get_temp_ptr_soa(
407   struct lp_build_tgsi_soa_context *bld,
408   unsigned index,
409   unsigned chan);
410
411LLVMValueRef
412lp_get_output_ptr(
413   struct lp_build_tgsi_soa_context *bld,
414   unsigned index,
415   unsigned chan);
416
417struct lp_build_tgsi_aos_context
418{
419   struct lp_build_tgsi_context bld_base;
420
421   /* Builder for integer masks and indices */
422   struct lp_build_context int_bld;
423
424   /*
425    * AoS swizzle used:
426    * - swizzles[0] = red index
427    * - swizzles[1] = green index
428    * - swizzles[2] = blue index
429    * - swizzles[3] = alpha index
430    */
431   unsigned char swizzles[4];
432   unsigned char inv_swizzles[4];
433
434   LLVMValueRef consts_ptr;
435   const LLVMValueRef *inputs;
436   LLVMValueRef *outputs;
437
438   struct lp_build_sampler_aos *sampler;
439
440   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES];
441   LLVMValueRef temps[LP_MAX_TGSI_TEMPS];
442   LLVMValueRef addr[LP_MAX_TGSI_ADDRS];
443   LLVMValueRef preds[LP_MAX_TGSI_PREDS];
444
445   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
446    * set in the indirect_files field.
447    * The temps[] array above is unused then.
448    */
449   LLVMValueRef temps_array;
450
451   /** bitmask indicating which register files are accessed indirectly */
452   unsigned indirect_files;
453
454};
455
456static INLINE struct lp_build_tgsi_soa_context *
457lp_soa_context(struct lp_build_tgsi_context *bld_base)
458{
459   return (struct lp_build_tgsi_soa_context *)bld_base;
460}
461
462static INLINE struct lp_build_tgsi_aos_context *
463lp_aos_context(struct lp_build_tgsi_context *bld_base)
464{
465   return (struct lp_build_tgsi_aos_context *)bld_base;
466}
467
468void
469lp_emit_declaration_aos(
470   struct lp_build_tgsi_aos_context *bld,
471   const struct tgsi_full_declaration *decl);
472
473
474boolean
475lp_emit_instruction_aos(
476   struct lp_build_tgsi_aos_context *bld,
477   const struct tgsi_full_instruction *inst,
478   const struct tgsi_opcode_info *info,
479   int *pc);
480
481void
482lp_emit_store_aos(
483   struct lp_build_tgsi_aos_context *bld,
484   const struct tgsi_full_instruction *inst,
485   unsigned index,
486   LLVMValueRef value);
487
488void lp_build_fetch_args(
489   struct lp_build_tgsi_context * bld_base,
490   struct lp_build_emit_data * emit_data);
491
492LLVMValueRef
493lp_build_tgsi_inst_llvm_aos(
494   struct lp_build_tgsi_context * bld_base,
495   const struct tgsi_full_instruction *inst);
496
497void
498lp_build_tgsi_intrinsic(
499 const struct lp_build_tgsi_action * action,
500 struct lp_build_tgsi_context * bld_base,
501 struct lp_build_emit_data * emit_data);
502
503LLVMValueRef
504lp_build_emit_llvm(
505   struct lp_build_tgsi_context *bld_base,
506   unsigned tgsi_opcode,
507   struct lp_build_emit_data * emit_data);
508
509LLVMValueRef
510lp_build_emit_llvm_unary(
511   struct lp_build_tgsi_context *bld_base,
512   unsigned tgsi_opcode,
513   LLVMValueRef arg0);
514
515LLVMValueRef
516lp_build_emit_llvm_binary(
517   struct lp_build_tgsi_context *bld_base,
518   unsigned tgsi_opcode,
519   LLVMValueRef arg0,
520   LLVMValueRef arg1);
521
522LLVMValueRef
523lp_build_emit_llvm_ternary(
524   struct lp_build_tgsi_context *bld_base,
525   unsigned tgsi_opcode,
526   LLVMValueRef arg0,
527   LLVMValueRef arg1,
528   LLVMValueRef arg2);
529
530boolean
531lp_build_tgsi_inst_llvm(
532   struct lp_build_tgsi_context * bld_base,
533   const struct tgsi_full_instruction *inst);
534
535LLVMValueRef
536lp_build_emit_fetch(
537   struct lp_build_tgsi_context *bld_base,
538   const struct tgsi_full_instruction *inst,
539   unsigned src_op,
540   const unsigned chan_index);
541
542boolean
543lp_build_tgsi_llvm(
544   struct lp_build_tgsi_context * bld_base,
545   const struct tgsi_token *tokens);
546
547#endif /* LP_BLD_TGSI_H */
548