1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
4 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
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.
27 **************************************************************************/
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"
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};
52 setup_pos_vector(LLVMBuilderRef builder
,
56 LLVMValueRef dadx_ptr
,
57 LLVMValueRef dady_ptr
,
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
];
69 x
= lp_build_broadcast(builder
, int_vec_type
, x
);
70 y
= lp_build_broadcast(builder
, int_vec_type
, y
);
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);
77 x
= LLVMBuildAdd(builder
, x
, LLVMConstVector(x_offsets
, QUAD_SIZE
), "");
78 y
= LLVMBuildAdd(builder
, y
, LLVMConstVector(y_offsets
, QUAD_SIZE
), "");
80 x
= LLVMBuildSIToFP(builder
, x
, vec_type
, "");
81 y
= LLVMBuildSIToFP(builder
, y
, vec_type
, "");
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, ""), "");
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
);
96 res
= LLVMBuildAdd(builder
, res
, LLVMBuildMul(builder
, dadx
, x
, ""), "");
97 res
= LLVMBuildAdd(builder
, res
, LLVMBuildMul(builder
, dady
, y
, ""), "");
101 for(chan
= 0; chan
< NUM_CHANNELS
; ++chan
)
102 lp_build_name(pos
[chan
], "pos.%c", "xyzw"[chan
]);
107 shader_generate(struct llvmpipe_screen
*screen
,
108 struct lp_fragment_shader
*shader
)
110 const struct tgsi_token
*tokens
= shader
->base
.tokens
;
112 LLVMTypeRef elem_type
;
113 LLVMTypeRef vec_type
;
114 LLVMTypeRef int_vec_type
;
115 LLVMTypeRef arg_types
[10];
116 LLVMTypeRef func_type
;
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
];
137 type
.floating
= TRUE
;
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
);
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 */
158 func_type
= LLVMFunctionType(LLVMVoidType(), arg_types
, Elements(arg_types
), 0);
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
);
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);
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");
188 block
= LLVMAppendBasicBlock(shader
->function
, "entry");
189 builder
= LLVMCreateBuilder();
190 LLVMPositionBuilderAtEnd(builder
, block
);
192 setup_pos_vector(builder
, x
, y
, a0_ptr
, dadx_ptr
, dady_ptr
, pos
);
194 memset(outputs
, 0, sizeof outputs
);
196 mask
= lp_build_tgsi_soa(builder
, tokens
, type
,
197 pos
, a0_ptr
, dadx_ptr
, dady_ptr
,
198 consts_ptr
, outputs
, samplers_ptr
);
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
]);
205 switch (shader
->info
.output_semantic_name
[attrib
]) {
206 case TGSI_SEMANTIC_COLOR
:
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
);
216 case TGSI_SEMANTIC_POSITION
:
218 LLVMBuildStore(builder
, outputs
[attrib
][chan
], depth_ptr
);
226 LLVMBuildStore(builder
, mask
, mask_ptr
);
228 LLVMBuildRetVoid(builder
);;
230 LLVMDisposeBuilder(builder
);
235 llvmpipe_create_fs_state(struct pipe_context
*pipe
,
236 const struct pipe_shader_state
*templ
)
238 struct llvmpipe_screen
*screen
= llvmpipe_screen(pipe
->screen
);
239 struct lp_fragment_shader
*shader
;
240 LLVMValueRef fetch_texel
;
242 shader
= CALLOC_STRUCT(lp_fragment_shader
);
246 /* get/save the summary info for this shader */
247 tgsi_scan_shader(templ
->tokens
, &shader
->info
);
249 /* we need to keep a local copy of the tokens */
250 shader
->base
.tokens
= tgsi_dup_tokens(templ
->tokens
);
252 shader
->screen
= screen
;
255 tgsi_dump(templ
->tokens
, 0);
258 shader_generate(screen
, shader
);
260 LLVMRunFunctionPassManager(screen
->pass
, shader
->function
);
263 LLVMDumpValue(shader
->function
);
267 if(LLVMVerifyFunction(shader
->function
, LLVMPrintMessageAction
)) {
268 LLVMDumpValue(shader
->function
);
272 fetch_texel
= LLVMGetNamedFunction(screen
->module
, "fetch_texel");
274 static boolean first_time
= TRUE
;
276 LLVMAddGlobalMapping(screen
->engine
, fetch_texel
, lp_build_tgsi_fetch_texel_soa
);
281 shader
->jit_function
= (lp_shader_fs_func
)LLVMGetPointerToGlobal(screen
->engine
, shader
->function
);
284 lp_disassemble(shader
->jit_function
);
292 llvmpipe_bind_fs_state(struct pipe_context
*pipe
, void *fs
)
294 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
296 llvmpipe
->fs
= (struct lp_fragment_shader
*) fs
;
298 llvmpipe
->dirty
|= LP_NEW_FS
;
303 llvmpipe_delete_fs_state(struct pipe_context
*pipe
, void *fs
)
305 struct lp_fragment_shader
*shader
= fs
;
306 struct llvmpipe_screen
*screen
= shader
->screen
;
308 assert(fs
!= llvmpipe_context(pipe
)->fs
);
310 if(shader
->function
) {
311 if(shader
->jit_function
)
312 LLVMFreeMachineCodeForFunction(screen
->engine
, shader
->function
);
313 LLVMDeleteFunction(shader
->function
);
316 FREE((void *) shader
->base
.tokens
);
322 llvmpipe_create_vs_state(struct pipe_context
*pipe
,
323 const struct pipe_shader_state
*templ
)
325 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
326 struct lp_vertex_shader
*state
;
328 state
= CALLOC_STRUCT(lp_vertex_shader
);
332 /* copy shader tokens, the ones passed in will go away.
334 state
->shader
.tokens
= tgsi_dup_tokens(templ
->tokens
);
335 if (state
->shader
.tokens
== NULL
)
338 state
->draw_data
= draw_create_vertex_shader(llvmpipe
->draw
, templ
);
339 if (state
->draw_data
== NULL
)
346 FREE( (void *)state
->shader
.tokens
);
347 FREE( state
->draw_data
);
355 llvmpipe_bind_vs_state(struct pipe_context
*pipe
, void *vs
)
357 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
359 llvmpipe
->vs
= (const struct lp_vertex_shader
*)vs
;
361 draw_bind_vertex_shader(llvmpipe
->draw
,
362 (llvmpipe
->vs
? llvmpipe
->vs
->draw_data
: NULL
));
364 llvmpipe
->dirty
|= LP_NEW_VS
;
369 llvmpipe_delete_vs_state(struct pipe_context
*pipe
, void *vs
)
371 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
373 struct lp_vertex_shader
*state
=
374 (struct lp_vertex_shader
*)vs
;
376 draw_delete_vertex_shader(llvmpipe
->draw
, state
->draw_data
);
383 llvmpipe_set_constant_buffer(struct pipe_context
*pipe
,
384 uint shader
, uint index
,
385 const struct pipe_constant_buffer
*buf
)
387 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
389 assert(shader
< PIPE_SHADER_TYPES
);
392 /* note: reference counting */
393 pipe_buffer_reference(&llvmpipe
->constants
[shader
].buffer
,
394 buf
? buf
->buffer
: NULL
);
396 llvmpipe
->dirty
|= LP_NEW_CONSTANTS
;