Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 1 | /* |
2 | * Copyright 2011 Advanced Micro Devices, Inc. |
||
3 | * |
||
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
5 | * copy of this software and associated documentation files (the "Software"), |
||
6 | * to deal in the Software without restriction, including without limitation |
||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
8 | * and/or sell copies of the Software, and to permit persons to whom the |
||
9 | * Software is furnished to do so, subject to the following conditions: |
||
10 | * |
||
11 | * The above copyright notice and this permission notice (including the next |
||
12 | * paragraph) shall be included in all copies or substantial portions of the |
||
13 | * Software. |
||
14 | * |
||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||
21 | * SOFTWARE. |
||
22 | * |
||
23 | * Authors: Tom Stellard |
||
24 | * |
||
25 | */ |
||
26 | |||
27 | #ifndef RADEON_LLVM_H |
||
28 | #define RADEON_LLVM_H |
||
29 | |||
30 | #include |
||
31 | #include "gallivm/lp_bld_init.h" |
||
32 | #include "gallivm/lp_bld_tgsi.h" |
||
33 | |||
34 | #define RADEON_LLVM_MAX_INPUTS 32 * 4 |
||
35 | #define RADEON_LLVM_MAX_OUTPUTS 32 * 4 |
||
36 | #define RADEON_LLVM_MAX_ARRAYS 16 |
||
37 | |||
38 | #define RADEON_LLVM_INITIAL_CF_DEPTH 4 |
||
39 | |||
40 | #define RADEON_LLVM_MAX_SYSTEM_VALUES 4 |
||
41 | |||
42 | struct radeon_llvm_branch { |
||
43 | LLVMBasicBlockRef endif_block; |
||
44 | LLVMBasicBlockRef if_block; |
||
45 | LLVMBasicBlockRef else_block; |
||
46 | unsigned has_else; |
||
47 | }; |
||
48 | |||
49 | struct radeon_llvm_loop { |
||
50 | LLVMBasicBlockRef loop_block; |
||
51 | LLVMBasicBlockRef endloop_block; |
||
52 | }; |
||
53 | |||
54 | struct radeon_llvm_context { |
||
55 | |||
56 | struct lp_build_tgsi_soa_context soa; |
||
57 | |||
58 | unsigned chip_class; |
||
59 | unsigned type; |
||
60 | unsigned face_gpr; |
||
61 | unsigned two_side; |
||
62 | unsigned clip_vertex; |
||
63 | unsigned inputs_count; |
||
64 | struct r600_shader_io * r600_inputs; |
||
65 | struct r600_shader_io * r600_outputs; |
||
66 | struct pipe_stream_output_info *stream_outputs; |
||
67 | unsigned color_buffer_count; |
||
68 | unsigned fs_color_all; |
||
69 | unsigned alpha_to_one; |
||
70 | unsigned has_txq_cube_array_z_comp; |
||
71 | unsigned uses_tex_buffers; |
||
72 | unsigned has_compressed_msaa_texturing; |
||
73 | |||
74 | /*=== Front end configuration ===*/ |
||
75 | |||
76 | /* Special Intrinsics */ |
||
77 | |||
78 | /** Write to an output register: float store_output(float, i32) */ |
||
79 | const char * store_output_intr; |
||
80 | |||
81 | /** Swizzle a vector value: <4 x float> swizzle(<4 x float>, i32) |
||
82 | * The swizzle is an unsigned integer that encodes a TGSI_SWIZZLE_* value |
||
83 | * in 2-bits. |
||
84 | * Swizzle{0-1} = X Channel |
||
85 | * Swizzle{2-3} = Y Channel |
||
86 | * Swizzle{4-5} = Z Channel |
||
87 | * Swizzle{6-7} = W Channel |
||
88 | */ |
||
89 | const char * swizzle_intr; |
||
90 | |||
91 | /* Instructions that are not described by any of the TGSI opcodes. */ |
||
92 | |||
93 | /** This function is responsible for initilizing the inputs array and will be |
||
94 | * called once for each input declared in the TGSI shader. |
||
95 | */ |
||
96 | void (*load_input)(struct radeon_llvm_context *, |
||
97 | unsigned input_index, |
||
98 | const struct tgsi_full_declaration *decl); |
||
99 | |||
100 | void (*load_system_value)(struct radeon_llvm_context *, |
||
101 | unsigned index, |
||
102 | const struct tgsi_full_declaration *decl); |
||
103 | |||
104 | /** User data to use with the callbacks */ |
||
105 | void * userdata; |
||
106 | |||
107 | /** This array contains the input values for the shader. Typically these |
||
108 | * values will be in the form of a target intrinsic that will inform the |
||
109 | * backend how to load the actual inputs to the shader. |
||
110 | */ |
||
111 | LLVMValueRef inputs[RADEON_LLVM_MAX_INPUTS]; |
||
112 | LLVMValueRef outputs[RADEON_LLVM_MAX_OUTPUTS][TGSI_NUM_CHANNELS]; |
||
113 | unsigned output_reg_count; |
||
114 | |||
115 | /** This pointer is used to contain the temporary values. |
||
116 | * The amount of temporary used in tgsi can't be bound to a max value and |
||
117 | * thus we must allocate this array at runtime. |
||
118 | */ |
||
119 | LLVMValueRef *temps; |
||
120 | unsigned temps_count; |
||
121 | LLVMValueRef system_values[RADEON_LLVM_MAX_SYSTEM_VALUES]; |
||
122 | |||
123 | /*=== Private Members ===*/ |
||
124 | |||
125 | struct radeon_llvm_branch *branch; |
||
126 | struct radeon_llvm_loop *loop; |
||
127 | |||
128 | unsigned branch_depth; |
||
129 | unsigned branch_depth_max; |
||
130 | unsigned loop_depth; |
||
131 | unsigned loop_depth_max; |
||
132 | |||
133 | struct tgsi_declaration_range arrays[RADEON_LLVM_MAX_ARRAYS]; |
||
134 | unsigned num_arrays; |
||
135 | |||
136 | LLVMValueRef main_fn; |
||
137 | |||
138 | struct gallivm_state gallivm; |
||
139 | }; |
||
140 | |||
141 | static inline LLVMTypeRef tgsi2llvmtype( |
||
142 | struct lp_build_tgsi_context * bld_base, |
||
143 | enum tgsi_opcode_type type) |
||
144 | { |
||
145 | LLVMContextRef ctx = bld_base->base.gallivm->context; |
||
146 | |||
147 | switch (type) { |
||
148 | case TGSI_TYPE_UNSIGNED: |
||
149 | case TGSI_TYPE_SIGNED: |
||
150 | return LLVMInt32TypeInContext(ctx); |
||
151 | case TGSI_TYPE_UNTYPED: |
||
152 | case TGSI_TYPE_FLOAT: |
||
153 | return LLVMFloatTypeInContext(ctx); |
||
154 | default: break; |
||
155 | } |
||
156 | return 0; |
||
157 | } |
||
158 | |||
159 | static inline LLVMValueRef bitcast( |
||
160 | struct lp_build_tgsi_context * bld_base, |
||
161 | enum tgsi_opcode_type type, |
||
162 | LLVMValueRef value |
||
163 | ) |
||
164 | { |
||
165 | LLVMBuilderRef builder = bld_base->base.gallivm->builder; |
||
166 | LLVMTypeRef dst_type = tgsi2llvmtype(bld_base, type); |
||
167 | |||
168 | if (dst_type) |
||
169 | return LLVMBuildBitCast(builder, value, dst_type, ""); |
||
170 | else |
||
171 | return value; |
||
172 | } |
||
173 | |||
174 | |||
175 | void radeon_llvm_emit_prepare_cube_coords(struct lp_build_tgsi_context * bld_base, |
||
176 | struct lp_build_emit_data * emit_data, |
||
177 | LLVMValueRef *coords_arg); |
||
178 | |||
179 | void radeon_llvm_context_init(struct radeon_llvm_context * ctx); |
||
180 | |||
181 | void radeon_llvm_create_func(struct radeon_llvm_context * ctx, |
||
182 | LLVMTypeRef *ParamTypes, unsigned ParamCount); |
||
183 | |||
184 | void radeon_llvm_dispose(struct radeon_llvm_context * ctx); |
||
185 | |||
186 | inline static struct radeon_llvm_context * radeon_llvm_context( |
||
187 | struct lp_build_tgsi_context * bld_base) |
||
188 | { |
||
189 | return (struct radeon_llvm_context*)bld_base; |
||
190 | } |
||
191 | |||
192 | unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan); |
||
193 | |||
194 | void radeon_llvm_finalize_module(struct radeon_llvm_context * ctx); |
||
195 | |||
196 | LLVMValueRef |
||
197 | build_intrinsic(LLVMBuilderRef builder, |
||
198 | const char *name, |
||
199 | LLVMTypeRef ret_type, |
||
200 | LLVMValueRef *args, |
||
201 | unsigned num_args, |
||
202 | LLVMAttribute attr); |
||
203 | |||
204 | void |
||
205 | build_tgsi_intrinsic_nomem( |
||
206 | const struct lp_build_tgsi_action * action, |
||
207 | struct lp_build_tgsi_context * bld_base, |
||
208 | struct lp_build_emit_data * emit_data); |
||
209 | |||
210 | |||
211 | |||
212 | #endif /* RADEON_LLVM_H */4>4> |