diff options
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_alpha.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_alpha.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.h | 9 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_blend.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 93 |
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) { |