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 **************************************************************************/
30 * @author Jose Fonseca <jfonseca@vmware.com>
31 * @author Keith Whitwell <keith@tungstengraphics.com>
34 #include "util/u_memory.h"
35 #include "util/u_math.h"
36 #include "util/u_debug_dump.h"
37 #include "lp_screen.h"
38 #include "lp_context.h"
41 #include "lp_bld_type.h"
42 #include "lp_bld_arit.h"
43 #include "lp_bld_blend.h"
47 blend_generate(struct llvmpipe_screen
*screen
,
48 struct lp_blend_state
*blend
)
55 LLVMValueRef const_ptr
;
57 LLVMBasicBlockRef block
;
58 LLVMBuilderRef builder
;
63 char src_name
[5] = "src?";
64 char dst_name
[5] = "dst?";
65 char con_name
[5] = "con?";
66 char res_name
[5] = "res?";
70 type
.floating
= FALSE
;
76 vec_type
= lp_build_vec_type(type
);
78 args
[3] = args
[2] = args
[1] = args
[0] = LLVMPointerType(vec_type
, 0);
79 blend
->function
= LLVMAddFunction(screen
->module
, "blend", LLVMFunctionType(LLVMVoidType(), args
, 4, 0));
80 LLVMSetFunctionCallConv(blend
->function
, LLVMCCallConv
);
81 src_ptr
= LLVMGetParam(blend
->function
, 0);
82 dst_ptr
= LLVMGetParam(blend
->function
, 1);
83 const_ptr
= LLVMGetParam(blend
->function
, 2);
84 res_ptr
= LLVMGetParam(blend
->function
, 3);
86 block
= LLVMAppendBasicBlock(blend
->function
, "entry");
87 builder
= LLVMCreateBuilder();
88 LLVMPositionBuilderAtEnd(builder
, block
);
90 for(i
= 0; i
< 4; ++i
) {
91 LLVMValueRef index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
92 con_name
[3] = dst_name
[3] = src_name
[3] = "rgba"[i
];
93 src
[i
] = LLVMBuildLoad(builder
, LLVMBuildGEP(builder
, src_ptr
, &index
, 1, ""), src_name
);
94 dst
[i
] = LLVMBuildLoad(builder
, LLVMBuildGEP(builder
, dst_ptr
, &index
, 1, ""), dst_name
);
95 con
[i
] = LLVMBuildLoad(builder
, LLVMBuildGEP(builder
, const_ptr
, &index
, 1, ""), con_name
);
98 lp_build_blend_soa(builder
, &blend
->base
, type
, src
, dst
, con
, res
);
100 for(i
= 0; i
< 4; ++i
) {
101 LLVMValueRef index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
102 res_name
[3] = "rgba"[i
];
103 LLVMSetValueName(res
[i
], res_name
);
104 LLVMBuildStore(builder
, res
[i
], LLVMBuildGEP(builder
, res_ptr
, &index
, 1, ""));
107 LLVMBuildRetVoid(builder
);;
109 LLVMDisposeBuilder(builder
);
114 llvmpipe_create_blend_state(struct pipe_context
*pipe
,
115 const struct pipe_blend_state
*base
)
117 struct llvmpipe_screen
*screen
= llvmpipe_screen(pipe
->screen
);
118 struct lp_blend_state
*blend
;
120 blend
= CALLOC_STRUCT(lp_blend_state
);
126 blend_generate(screen
, blend
);
128 LLVMRunFunctionPassManager(screen
->pass
, blend
->function
);
131 debug_printf("%s=%s %s=%s %s=%s %s=%s %s=%s %s=%s\n",
132 "rgb_func", debug_dump_blend_func (blend
->base
.rgb_func
, TRUE
),
133 "rgb_src_factor", debug_dump_blend_factor(blend
->base
.rgb_src_factor
, TRUE
),
134 "rgb_dst_factor", debug_dump_blend_factor(blend
->base
.rgb_dst_factor
, TRUE
),
135 "alpha_func", debug_dump_blend_func (blend
->base
.alpha_func
, TRUE
),
136 "alpha_src_factor", debug_dump_blend_factor(blend
->base
.alpha_src_factor
, TRUE
),
137 "alpha_dst_factor", debug_dump_blend_factor(blend
->base
.alpha_dst_factor
, TRUE
));
138 LLVMDumpModule(screen
->module
);
142 if(LLVMVerifyFunction(blend
->function
, LLVMPrintMessageAction
)) {
143 LLVMDumpModule(screen
->module
);
147 blend
->jit_function
= (lp_blend_func
)LLVMGetPointerToGlobal(screen
->engine
, blend
->function
);
152 void llvmpipe_bind_blend_state( struct pipe_context
*pipe
,
155 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
157 llvmpipe
->blend
= (struct lp_blend_state
*)blend
;
159 llvmpipe
->dirty
|= LP_NEW_BLEND
;
162 void llvmpipe_delete_blend_state(struct pipe_context
*pipe
,
165 struct llvmpipe_screen
*screen
= llvmpipe_screen(pipe
->screen
);
166 struct lp_blend_state
*blend
= (struct lp_blend_state
*)_blend
;
168 if(blend
->function
) {
169 if(blend
->jit_function
)
170 LLVMFreeMachineCodeForFunction(screen
->engine
, blend
->function
);
171 LLVMDeleteFunction(blend
->function
);
178 void llvmpipe_set_blend_color( struct pipe_context
*pipe
,
179 const struct pipe_blend_color
*blend_color
)
181 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
184 for (i
= 0; i
< 4; ++i
)
185 for (j
= 0; j
< 16; ++j
)
186 llvmpipe
->blend_color
[i
][j
] = float_to_ubyte(blend_color
->color
[i
]);
188 llvmpipe
->dirty
|= LP_NEW_BLEND
;
192 /** XXX move someday? Or consolidate all these simple state setters
198 llvmpipe_create_depth_stencil_state(struct pipe_context
*pipe
,
199 const struct pipe_depth_stencil_alpha_state
*depth_stencil
)
201 return mem_dup(depth_stencil
, sizeof(*depth_stencil
));
205 llvmpipe_bind_depth_stencil_state(struct pipe_context
*pipe
,
208 struct llvmpipe_context
*llvmpipe
= llvmpipe_context(pipe
);
210 llvmpipe
->depth_stencil
= (const struct pipe_depth_stencil_alpha_state
*)depth_stencil
;
212 llvmpipe
->dirty
|= LP_NEW_DEPTH_STENCIL_ALPHA
;
216 llvmpipe_delete_depth_stencil_state(struct pipe_context
*pipe
, void *depth
)