summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_alpha.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_alpha.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_blend.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c93
8 files changed, 86 insertions, 50 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
index 8d9af4cf6d9..49c2f911af7 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
@@ -47,14 +47,14 @@ lp_build_alpha_test(LLVMBuilderRef builder,
const struct pipe_alpha_state *state,
union lp_type type,
struct lp_build_mask_context *mask,
- LLVMValueRef alpha)
+ LLVMValueRef alpha,
+ LLVMValueRef ref)
{
struct lp_build_context bld;
lp_build_context_init(&bld, builder, type);
if(state->enabled) {
- LLVMValueRef ref = lp_build_const_scalar(type, state->ref_value);
LLVMValueRef test = lp_build_cmp(&bld, state->func, alpha, ref);
lp_build_name(test, "alpha_mask");
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
index 962ea9fafab..9dbcdb4daab 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
@@ -47,7 +47,8 @@ lp_build_alpha_test(LLVMBuilderRef builder,
const struct pipe_alpha_state *state,
union lp_type type,
struct lp_build_mask_context *mask,
- LLVMValueRef alpha);
+ LLVMValueRef alpha,
+ LLVMValueRef ref);
#endif /* !LP_BLD_ALPHA_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 8b4266b775c..8d5a0d4f1fc 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -61,7 +61,7 @@ struct llvmpipe_context {
const struct lp_vertex_shader *vs;
/** Other rendering state */
- uint8_t ALIGN16_ATTRIB blend_color[4][16];
+ struct pipe_blend_color blend_color[4][16];
struct pipe_clip_state clip;
struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 92d5d43d0cc..0a32c41a6fa 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -45,11 +45,13 @@ lp_jit_init_types(struct llvmpipe_screen *screen)
{
/* struct lp_jit_context */
{
- LLVMTypeRef elem_types[2];
+ LLVMTypeRef elem_types[4];
LLVMTypeRef context_type;
elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */
+ elem_types[2] = LLVMFloatType(); /* alpha_ref_value */
+ elem_types[3] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */
context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
@@ -57,6 +59,10 @@ lp_jit_init_types(struct llvmpipe_screen *screen)
screen->target, context_type, 0);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers,
screen->target, context_type, 1);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
+ screen->target, context_type, 2);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
+ screen->target, context_type, 3);
LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
screen->target, context_type);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index fe36b609212..e7e887fb64f 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -61,7 +61,10 @@ struct lp_jit_context
struct tgsi_sampler **samplers;
/* TODO: alpha reference value */
+ float alpha_ref_value;
+
/* TODO: blend constant color */
+ uint8_t *blend_color;
};
@@ -71,6 +74,12 @@ struct lp_jit_context
#define lp_jit_context_samplers(_builder, _ptr) \
lp_build_struct_get(_builder, _ptr, 1, "context.samplers")
+#define lp_jit_context_alpha_ref_value(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, 2, "context.alpha")
+
+#define lp_jit_context_blend_color(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, 3, "context.blend")
+
typedef void
(*lp_jit_frag_func)(struct lp_jit_context *context,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 34bcb9912d4..d145f6d6bbc 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -167,7 +167,7 @@ shade_quads(struct llvmpipe_context *llvmpipe,
assert((((uintptr_t)mask) & 0xf) == 0);
assert((((uintptr_t)depth) & 0xf) == 0);
assert((((uintptr_t)color) & 0xf) == 0);
- assert((((uintptr_t)llvmpipe->blend_color) & 0xf) == 0);
+ assert((((uintptr_t)llvmpipe->jit_context.blend_color) & 0xf) == 0);
/* run shader */
fs->current->jit_function( &llvmpipe->jit_context,
diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c
index ebde41c0998..3f03bd00571 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c
@@ -69,11 +69,15 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe,
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
unsigned i, j;
- for (i = 0; i < 4; ++i)
- for (j = 0; j < 16; ++j)
- llvmpipe->blend_color[i][j] = float_to_ubyte(blend_color->color[i]);
+ memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color);
- llvmpipe->dirty |= LP_NEW_BLEND;
+ if(!llvmpipe->jit_context.blend_color)
+ llvmpipe->jit_context.blend_color = align_malloc(4 * 16, 16);
+ for (i = 0; i < 4; ++i) {
+ uint8_t c = float_to_ubyte(blend_color->color[i]);
+ for (j = 0; j < 16; ++j)
+ llvmpipe->jit_context.blend_color[i*4 + j] = c;
+ }
}
@@ -97,6 +101,9 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
+ if(llvmpipe->depth_stencil)
+ llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value;
+
llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 15dbfe8483c..eea332e3e48 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -216,22 +216,23 @@ generate_fs(struct llvmpipe_context *lp,
const struct lp_fragment_shader_variant_key *key,
LLVMBuilderRef builder,
union lp_type type,
+ LLVMValueRef context_ptr,
unsigned i,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
LLVMValueRef dady_ptr,
- LLVMValueRef consts_ptr,
LLVMValueRef *pmask,
LLVMValueRef *color,
- LLVMValueRef depth_ptr,
- LLVMValueRef samplers_ptr)
+ LLVMValueRef depth_ptr)
{
const struct tgsi_token *tokens = shader->base.tokens;
LLVMTypeRef elem_type;
LLVMTypeRef vec_type;
LLVMTypeRef int_vec_type;
+ LLVMValueRef consts_ptr;
+ LLVMValueRef samplers_ptr;
LLVMValueRef pos[NUM_CHANNELS];
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
struct lp_build_mask_context mask;
@@ -243,6 +244,9 @@ generate_fs(struct llvmpipe_context *lp,
vec_type = lp_build_vec_type(type);
int_vec_type = lp_build_int_vec_type(type);
+ consts_ptr = lp_jit_context_constants(builder, context_ptr);
+ samplers_ptr = lp_jit_context_samplers(builder, context_ptr);
+
generate_pos(builder, x, y, a0_ptr, dadx_ptr, dady_ptr, pos);
lp_build_mask_begin(&mask, builder, type, *pmask);
@@ -279,10 +283,14 @@ generate_fs(struct llvmpipe_context *lp,
/* Alpha test */
/* XXX: should the alpha reference value be passed separately? */
- if(cbuf == 0 && chan == 3)
+ if(cbuf == 0 && chan == 3) {
+ LLVMValueRef alpha = outputs[attrib][chan];
+ LLVMValueRef alpha_ref_value;
+ alpha_ref_value = lp_jit_context_alpha_ref_value(builder, context_ptr);
+ alpha_ref_value = lp_build_broadcast(builder, vec_type, alpha_ref_value);
lp_build_alpha_test(builder, &key->alpha, type,
- &mask,
- outputs[attrib][chan]);
+ &mask, alpha, alpha_ref_value);
+ }
if(cbuf == 0)
color[chan] = outputs[attrib][chan];
@@ -318,14 +326,15 @@ static void
generate_blend(const struct pipe_blend_state *blend,
LLVMBuilderRef builder,
union lp_type type,
+ LLVMValueRef context_ptr,
LLVMValueRef mask,
LLVMValueRef *src,
- LLVMValueRef const_ptr,
LLVMValueRef dst_ptr)
{
struct lp_build_context bld;
LLVMTypeRef vec_type;
LLVMTypeRef int_vec_type;
+ LLVMValueRef const_ptr;
LLVMValueRef con[4];
LLVMValueRef dst[4];
LLVMValueRef res[4];
@@ -336,13 +345,13 @@ generate_blend(const struct pipe_blend_state *blend,
lp_build_context_init(&bld, builder, type);
+ const_ptr = lp_jit_context_blend_color(builder, context_ptr);
+ const_ptr = LLVMBuildBitCast(builder, const_ptr,
+ LLVMPointerType(vec_type, 0), "");
+
for(chan = 0; chan < 4; ++chan) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
-
- if(const_ptr)
- con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
- else
- con[chan] = LLVMGetUndef(vec_type); /* FIXME */
+ con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
dst[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
@@ -386,11 +395,9 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMValueRef a0_ptr;
LLVMValueRef dadx_ptr;
LLVMValueRef dady_ptr;
- LLVMValueRef consts_ptr;
LLVMValueRef mask_ptr;
LLVMValueRef color_ptr;
LLVMValueRef depth_ptr;
- LLVMValueRef samplers_ptr;
LLVMBasicBlockRef block;
LLVMBuilderRef builder;
LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
@@ -510,9 +517,6 @@ generate_fragment(struct llvmpipe_context *lp,
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, block);
- consts_ptr = lp_jit_context_constants(builder, context_ptr);
- samplers_ptr = lp_jit_context_samplers(builder, context_ptr);
-
for(i = 0; i < num_fs; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef out_color[NUM_CHANNELS];
@@ -525,22 +529,16 @@ generate_fragment(struct llvmpipe_context *lp,
fs_mask[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, mask_ptr, &index, 1, ""), "");
depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, "");
- generate_fs(lp,
- shader,
- key,
+ generate_fs(lp, shader, key,
builder,
fs_type,
+ context_ptr,
i,
- x_i,
- y,
- a0_ptr,
- dadx_ptr,
- dady_ptr,
- consts_ptr,
+ x_i, y,
+ a0_ptr, dadx_ptr, dady_ptr,
&fs_mask[i],
out_color,
- depth_ptr_i,
- samplers_ptr);
+ depth_ptr_i);
for(chan = 0; chan < NUM_CHANNELS; ++chan)
fs_out_color[chan][i] = out_color[chan];
@@ -555,6 +553,7 @@ generate_fragment(struct llvmpipe_context *lp,
fs_out_color[chan], num_fs,
&blend_in_color[chan], 1);
lp_build_name(blend_in_color[chan], "color.%c", "rgba"[chan]);
+
}
lp_build_conv_mask(builder, fs_type, blend_type,
@@ -568,9 +567,9 @@ generate_fragment(struct llvmpipe_context *lp,
generate_blend(&key->blend,
builder,
blend_type,
+ context_ptr,
blend_mask,
blend_in_color,
- NULL /* FIXME: blend_const_color */,
color_ptr);
LLVMBuildRetVoid(builder);
@@ -698,6 +697,30 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
}
+/**
+ * We need to generate several variants of the fragment pipeline to match
+ * all the combinations of the contributing state atoms.
+ *
+ * TODO: there is actually no reason to tie this to context state -- the
+ * generated code could be cached globally in the screen.
+ */
+static void
+make_variant_key(struct llvmpipe_context *lp,
+ struct lp_fragment_shader_variant_key *key)
+{
+ memset(key, 0, sizeof *key);
+
+ memcpy(&key->depth, &lp->depth_stencil->depth, sizeof &key->depth);
+
+ key->alpha.enabled = lp->depth_stencil->alpha.enabled;
+ if(key->alpha.enabled)
+ key->alpha.func = lp->depth_stencil->alpha.func;
+ /* alpha.ref_value is passed in jit_context */
+
+ memcpy(&key->blend, lp->blend, sizeof &key->blend);
+}
+
+
void
llvmpipe_update_fs(struct llvmpipe_context *lp)
{
@@ -705,17 +728,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
struct lp_fragment_shader_variant_key key;
struct lp_fragment_shader_variant *variant;
- /* We need to generate several variants of the fragment pipeline to match
- * all the combinations of the contributing state atoms.
- *
- * TODO: there is actually no reason to tie this to context state -- the
- * generated code could be cached globally in the screen.
- */
-
- memset(&key, 0, sizeof key);
- memcpy(&key.depth, &lp->depth_stencil->depth, sizeof &key.depth);
- memcpy(&key.alpha, &lp->depth_stencil->alpha, sizeof &key.alpha);
- memcpy(&key.blend, lp->blend, sizeof &key.blend);
+ make_variant_key(lp, &key);
variant = shader->variants;
while(variant) {