llvmpipe: Code generate the position interpolation.
[mesa.git] / src / gallium / drivers / llvmpipe / lp_state_fs.c
1 /**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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 #include "pipe/p_defines.h"
30 #include "util/u_memory.h"
31 #include "pipe/internal/p_winsys_screen.h"
32 #include "pipe/p_shader_tokens.h"
33 #include "draw/draw_context.h"
34 #include "tgsi/tgsi_dump.h"
35 #include "tgsi/tgsi_scan.h"
36 #include "tgsi/tgsi_parse.h"
37 #include "lp_bld_type.h"
38 #include "lp_bld_tgsi.h"
39 #include "lp_bld_swizzle.h"
40 #include "lp_bld_debug.h"
41 #include "lp_screen.h"
42 #include "lp_context.h"
43 #include "lp_state.h"
44 #include "lp_quad.h"
45
46
47 static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
48 static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
49
50
51 static void
52 setup_pos_vector(LLVMBuilderRef builder,
53 LLVMValueRef x,
54 LLVMValueRef y,
55 LLVMValueRef a0_ptr,
56 LLVMValueRef dadx_ptr,
57 LLVMValueRef dady_ptr,
58 LLVMValueRef *pos)
59 {
60 LLVMTypeRef int_elem_type = LLVMInt32Type();
61 LLVMTypeRef int_vec_type = LLVMVectorType(int_elem_type, QUAD_SIZE);
62 LLVMTypeRef elem_type = LLVMFloatType();
63 LLVMTypeRef vec_type = LLVMVectorType(elem_type, QUAD_SIZE);
64 LLVMValueRef x_offsets[QUAD_SIZE];
65 LLVMValueRef y_offsets[QUAD_SIZE];
66 unsigned chan;
67 unsigned i;
68
69 x = lp_build_broadcast(builder, int_vec_type, x);
70 y = lp_build_broadcast(builder, int_vec_type, y);
71
72 for(i = 0; i < QUAD_SIZE; ++i) {
73 x_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_x[i], 0);
74 y_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_y[i], 0);
75 }
76
77 x = LLVMBuildAdd(builder, x, LLVMConstVector(x_offsets, QUAD_SIZE), "");
78 y = LLVMBuildAdd(builder, y, LLVMConstVector(y_offsets, QUAD_SIZE), "");
79
80 x = LLVMBuildSIToFP(builder, x, vec_type, "");
81 y = LLVMBuildSIToFP(builder, y, vec_type, "");
82
83 pos[0] = x;
84 pos[1] = y;
85
86 for(chan = 2; chan < NUM_CHANNELS; ++chan) {
87 LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
88 LLVMValueRef a0 = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr, &index, 1, ""), "");
89 LLVMValueRef dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), "");
90 LLVMValueRef dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), "");
91 LLVMValueRef res;
92 a0 = lp_build_broadcast(builder, vec_type, a0);
93 dadx = lp_build_broadcast(builder, vec_type, dadx);
94 dady = lp_build_broadcast(builder, vec_type, dady);
95 res = a0;
96 res = LLVMBuildAdd(builder, res, LLVMBuildMul(builder, dadx, x, ""), "");
97 res = LLVMBuildAdd(builder, res, LLVMBuildMul(builder, dady, y, ""), "");
98 pos[chan] = res;
99 }
100
101 for(chan = 0; chan < NUM_CHANNELS; ++chan)
102 lp_build_name(pos[chan], "pos.%c", "xyzw"[chan]);
103 }
104
105
106 static void
107 shader_generate(struct llvmpipe_screen *screen,
108 struct lp_fragment_shader *shader)
109 {
110 const struct tgsi_token *tokens = shader->base.tokens;
111 union lp_type type;
112 LLVMTypeRef elem_type;
113 LLVMTypeRef vec_type;
114 LLVMTypeRef int_vec_type;
115 LLVMTypeRef arg_types[10];
116 LLVMTypeRef func_type;
117 LLVMValueRef x;
118 LLVMValueRef y;
119 LLVMValueRef a0_ptr;
120 LLVMValueRef dadx_ptr;
121 LLVMValueRef dady_ptr;
122 LLVMValueRef consts_ptr;
123 LLVMValueRef mask_ptr;
124 LLVMValueRef color_ptr;
125 LLVMValueRef depth_ptr;
126 LLVMValueRef samplers_ptr;
127 LLVMBasicBlockRef block;
128 LLVMBuilderRef builder;
129 LLVMValueRef pos[NUM_CHANNELS];
130 LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
131 LLVMValueRef mask;
132 unsigned i;
133 unsigned attrib;
134 unsigned chan;
135
136 type.value = 0;
137 type.floating = TRUE;
138 type.sign = TRUE;
139 type.norm = FALSE;
140 type.width = 32;
141 type.length = 4;
142
143 elem_type = lp_build_elem_type(type);
144 vec_type = lp_build_vec_type(type);
145 int_vec_type = lp_build_int_vec_type(type);
146
147 arg_types[0] = LLVMInt32Type(); /* x */
148 arg_types[1] = LLVMInt32Type(); /* y */
149 arg_types[2] = LLVMPointerType(elem_type, 0); /* a0 */
150 arg_types[3] = LLVMPointerType(elem_type, 0); /* dadx */
151 arg_types[4] = LLVMPointerType(elem_type, 0); /* dady */
152 arg_types[5] = LLVMPointerType(elem_type, 0); /* consts */
153 arg_types[6] = LLVMPointerType(int_vec_type, 0); /* mask */
154 arg_types[7] = LLVMPointerType(vec_type, 0); /* color */
155 arg_types[8] = LLVMPointerType(vec_type, 0); /* depth */
156 arg_types[9] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */
157
158 func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
159
160 shader->function = LLVMAddFunction(screen->module, "shader", func_type);
161 LLVMSetFunctionCallConv(shader->function, LLVMCCallConv);
162 for(i = 0; i < Elements(arg_types); ++i)
163 if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
164 LLVMAddAttribute(LLVMGetParam(shader->function, i), LLVMNoAliasAttribute);
165
166 x = LLVMGetParam(shader->function, 0);
167 y = LLVMGetParam(shader->function, 1);
168 a0_ptr = LLVMGetParam(shader->function, 2);
169 dadx_ptr = LLVMGetParam(shader->function, 3);
170 dady_ptr = LLVMGetParam(shader->function, 4);
171 consts_ptr = LLVMGetParam(shader->function, 5);
172 mask_ptr = LLVMGetParam(shader->function, 6);
173 color_ptr = LLVMGetParam(shader->function, 7);
174 depth_ptr = LLVMGetParam(shader->function, 8);
175 samplers_ptr = LLVMGetParam(shader->function, 9);
176
177 lp_build_name(x, "x");
178 lp_build_name(y, "y");
179 lp_build_name(a0_ptr, "a0");
180 lp_build_name(dadx_ptr, "dadx");
181 lp_build_name(dady_ptr, "dady");
182 lp_build_name(consts_ptr, "consts");
183 lp_build_name(mask_ptr, "mask");
184 lp_build_name(color_ptr, "color");
185 lp_build_name(depth_ptr, "depth");
186 lp_build_name(samplers_ptr, "samplers");
187
188 block = LLVMAppendBasicBlock(shader->function, "entry");
189 builder = LLVMCreateBuilder();
190 LLVMPositionBuilderAtEnd(builder, block);
191
192 setup_pos_vector(builder, x, y, a0_ptr, dadx_ptr, dady_ptr, pos);
193
194 memset(outputs, 0, sizeof outputs);
195
196 mask = lp_build_tgsi_soa(builder, tokens, type,
197 pos, a0_ptr, dadx_ptr, dady_ptr,
198 consts_ptr, outputs, samplers_ptr);
199
200 for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
201 for(chan = 0; chan < NUM_CHANNELS; ++chan) {
202 if(outputs[attrib][chan]) {
203 lp_build_name(outputs[attrib][chan], "output%u.%c", attrib, "xyzw"[chan]);
204
205 switch (shader->info.output_semantic_name[attrib]) {
206 case TGSI_SEMANTIC_COLOR:
207 {
208 unsigned cbuf = shader->info.output_semantic_index[attrib];
209 LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), cbuf*NUM_CHANNELS + chan, 0);
210 LLVMValueRef output_ptr = LLVMBuildGEP(builder, color_ptr, &index, 1, "");
211 lp_build_name(outputs[attrib][chan], "color%u.%c", attrib, "rgba"[chan]);
212 LLVMBuildStore(builder, outputs[attrib][chan], output_ptr);
213 break;
214 }
215
216 case TGSI_SEMANTIC_POSITION:
217 if(chan == 3)
218 LLVMBuildStore(builder, outputs[attrib][chan], depth_ptr);
219 break;
220 }
221 }
222 }
223 }
224
225 if(mask)
226 LLVMBuildStore(builder, mask, mask_ptr);
227
228 LLVMBuildRetVoid(builder);;
229
230 LLVMDisposeBuilder(builder);
231 }
232
233
234 void *
235 llvmpipe_create_fs_state(struct pipe_context *pipe,
236 const struct pipe_shader_state *templ)
237 {
238 struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
239 struct lp_fragment_shader *shader;
240 LLVMValueRef fetch_texel;
241
242 shader = CALLOC_STRUCT(lp_fragment_shader);
243 if (!shader)
244 return NULL;
245
246 /* get/save the summary info for this shader */
247 tgsi_scan_shader(templ->tokens, &shader->info);
248
249 /* we need to keep a local copy of the tokens */
250 shader->base.tokens = tgsi_dup_tokens(templ->tokens);
251
252 shader->screen = screen;
253
254 #ifdef DEBUG
255 tgsi_dump(templ->tokens, 0);
256 #endif
257
258 shader_generate(screen, shader);
259
260 LLVMRunFunctionPassManager(screen->pass, shader->function);
261
262 #ifdef DEBUG
263 LLVMDumpValue(shader->function);
264 debug_printf("\n");
265 #endif
266
267 if(LLVMVerifyFunction(shader->function, LLVMPrintMessageAction)) {
268 LLVMDumpValue(shader->function);
269 abort();
270 }
271
272 fetch_texel = LLVMGetNamedFunction(screen->module, "fetch_texel");
273 if(fetch_texel) {
274 static boolean first_time = TRUE;
275 if(first_time) {
276 LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_build_tgsi_fetch_texel_soa);
277 first_time = FALSE;
278 }
279 }
280
281 shader->jit_function = (lp_shader_fs_func)LLVMGetPointerToGlobal(screen->engine, shader->function);
282
283 #ifdef DEBUG
284 lp_disassemble(shader->jit_function);
285 #endif
286
287 return shader;
288 }
289
290
291 void
292 llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
293 {
294 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
295
296 llvmpipe->fs = (struct lp_fragment_shader *) fs;
297
298 llvmpipe->dirty |= LP_NEW_FS;
299 }
300
301
302 void
303 llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
304 {
305 struct lp_fragment_shader *shader = fs;
306 struct llvmpipe_screen *screen = shader->screen;
307
308 assert(fs != llvmpipe_context(pipe)->fs);
309
310 if(shader->function) {
311 if(shader->jit_function)
312 LLVMFreeMachineCodeForFunction(screen->engine, shader->function);
313 LLVMDeleteFunction(shader->function);
314 }
315
316 FREE((void *) shader->base.tokens);
317 FREE(shader);
318 }
319
320
321 void *
322 llvmpipe_create_vs_state(struct pipe_context *pipe,
323 const struct pipe_shader_state *templ)
324 {
325 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
326 struct lp_vertex_shader *state;
327
328 state = CALLOC_STRUCT(lp_vertex_shader);
329 if (state == NULL )
330 goto fail;
331
332 /* copy shader tokens, the ones passed in will go away.
333 */
334 state->shader.tokens = tgsi_dup_tokens(templ->tokens);
335 if (state->shader.tokens == NULL)
336 goto fail;
337
338 state->draw_data = draw_create_vertex_shader(llvmpipe->draw, templ);
339 if (state->draw_data == NULL)
340 goto fail;
341
342 return state;
343
344 fail:
345 if (state) {
346 FREE( (void *)state->shader.tokens );
347 FREE( state->draw_data );
348 FREE( state );
349 }
350 return NULL;
351 }
352
353
354 void
355 llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
356 {
357 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
358
359 llvmpipe->vs = (const struct lp_vertex_shader *)vs;
360
361 draw_bind_vertex_shader(llvmpipe->draw,
362 (llvmpipe->vs ? llvmpipe->vs->draw_data : NULL));
363
364 llvmpipe->dirty |= LP_NEW_VS;
365 }
366
367
368 void
369 llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
370 {
371 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
372
373 struct lp_vertex_shader *state =
374 (struct lp_vertex_shader *)vs;
375
376 draw_delete_vertex_shader(llvmpipe->draw, state->draw_data);
377 FREE( state );
378 }
379
380
381
382 void
383 llvmpipe_set_constant_buffer(struct pipe_context *pipe,
384 uint shader, uint index,
385 const struct pipe_constant_buffer *buf)
386 {
387 struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
388
389 assert(shader < PIPE_SHADER_TYPES);
390 assert(index == 0);
391
392 /* note: reference counting */
393 pipe_buffer_reference(&llvmpipe->constants[shader].buffer,
394 buf ? buf->buffer : NULL);
395
396 llvmpipe->dirty |= LP_NEW_CONSTANTS;
397 }