diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_state_fs.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 232 |
1 files changed, 134 insertions, 98 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 5f861d6ca4..9ef78e6bad 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -87,7 +87,6 @@ #include "lp_bld_depth.h" #include "lp_bld_interp.h" #include "lp_context.h" -#include "lp_debug.h" #include "lp_perf.h" #include "lp_screen.h" #include "lp_setup.h" @@ -148,7 +147,8 @@ generate_depth_stencil(LLVMBuilderRef builder, LLVMValueRef stencil_refs[2], LLVMValueRef src, LLVMValueRef dst_ptr, - LLVMValueRef facing) + LLVMValueRef facing, + LLVMValueRef counter) { const struct util_format_description *format_desc; struct lp_type dst_type; @@ -195,7 +195,8 @@ generate_depth_stencil(LLVMBuilderRef builder, stencil_refs, src, dst_ptr, - facing); + facing, + counter); } @@ -400,7 +401,8 @@ generate_fs(struct llvmpipe_context *lp, LLVMValueRef c2, LLVMValueRef step0_ptr, LLVMValueRef step1_ptr, - LLVMValueRef step2_ptr) + LLVMValueRef step2_ptr, + LLVMValueRef counter) { const struct tgsi_token *tokens = shader->base.tokens; LLVMTypeRef vec_type; @@ -466,12 +468,13 @@ generate_fs(struct llvmpipe_context *lp, if (early_depth_stencil_test) generate_depth_stencil(builder, key, type, &mask, - stencil_refs, z, depth_ptr, facing); + stencil_refs, z, depth_ptr, facing, counter); lp_build_tgsi_soa(builder, tokens, type, &mask, consts_ptr, interp->pos, interp->inputs, outputs, sampler, &shader->info); + /* loop over fragment shader outputs/results */ for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) { for(chan = 0; chan < NUM_CHANNELS; ++chan) { if(outputs[attrib][chan]) { @@ -513,7 +516,7 @@ generate_fs(struct llvmpipe_context *lp, if (!early_depth_stencil_test) generate_depth_stencil(builder, key, type, &mask, - stencil_refs, z, depth_ptr, facing); + stencil_refs, z, depth_ptr, facing, counter); lp_build_mask_end(&mask); @@ -528,9 +531,16 @@ generate_fs(struct llvmpipe_context *lp, /** * Generate color blending and color output. + * \param rt the render target index (to index blend, colormask state) + * \param type the pixel color type + * \param context_ptr pointer to the runtime JIT context + * \param mask execution mask (active fragment/pixel mask) + * \param src colors from the fragment shader + * \param dst_ptr the destination color buffer pointer */ static void generate_blend(const struct pipe_blend_state *blend, + unsigned rt, LLVMBuilderRef builder, struct lp_type type, LLVMValueRef context_ptr, @@ -561,6 +571,7 @@ generate_blend(const struct pipe_blend_state *blend, const_ptr = LLVMBuildBitCast(builder, const_ptr, LLVMPointerType(vec_type, 0), ""); + /* load constant blend color and colors from the dest color buffer */ for(chan = 0; chan < 4; ++chan) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0); con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), ""); @@ -571,10 +582,12 @@ generate_blend(const struct pipe_blend_state *blend, lp_build_name(dst[chan], "dst.%c", "rgba"[chan]); } - lp_build_blend_soa(builder, blend, type, src, dst, con, res); + /* do blend */ + lp_build_blend_soa(builder, blend, type, rt, src, dst, con, res); + /* store results to color buffer */ for(chan = 0; chan < 4; ++chan) { - if(blend->rt[0].colormask & (1 << chan)) { + if(blend->rt[rt].colormask & (1 << chan)) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0); lp_build_name(res[chan], "res.%c", "rgba"[chan]); res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]); @@ -587,20 +600,6 @@ generate_blend(const struct pipe_blend_state *blend, } -/** casting function to avoid compiler warnings */ -static lp_jit_frag_func -cast_voidptr_to_lp_jit_frag_func(void *p) -{ - union { - void *v; - lp_jit_frag_func f; - } tmp; - assert(sizeof(tmp.v) == sizeof(tmp.f)); - tmp.v = p; - return tmp.f; -} - - /** * Generate the runtime callable function for the whole fragment pipeline. * Note that the function which we generate operates on a block of 16 @@ -620,7 +619,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMTypeRef fs_elem_type; LLVMTypeRef fs_int_vec_type; LLVMTypeRef blend_vec_type; - LLVMTypeRef arg_types[15]; + LLVMTypeRef arg_types[16]; LLVMTypeRef func_type; LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type(); LLVMValueRef context_ptr; @@ -631,7 +630,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMValueRef dady_ptr; LLVMValueRef color_ptr_ptr; LLVMValueRef depth_ptr; - LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr; + LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr, counter = NULL; LLVMBasicBlockRef block; LLVMBuilderRef builder; LLVMValueRef x0; @@ -641,7 +640,6 @@ generate_fragment(struct llvmpipe_context *lp, LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH]; LLVMValueRef fs_out_color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][LP_MAX_VECTOR_LENGTH]; LLVMValueRef blend_mask; - LLVMValueRef blend_in_color[NUM_CHANNELS]; LLVMValueRef function; LLVMValueRef facing; unsigned num_fs; @@ -696,6 +694,7 @@ generate_fragment(struct llvmpipe_context *lp, arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */ arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */ arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */ + arg_types[15] = LLVMPointerType(LLVMInt32Type(), 0);/* counter */ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); @@ -734,7 +733,7 @@ generate_fragment(struct llvmpipe_context *lp, lp_build_name(a0_ptr, "a0"); lp_build_name(dadx_ptr, "dadx"); lp_build_name(dady_ptr, "dady"); - lp_build_name(color_ptr_ptr, "color_ptr"); + lp_build_name(color_ptr_ptr, "color_ptr_ptr"); lp_build_name(depth_ptr, "depth"); lp_build_name(c0, "c0"); lp_build_name(c1, "c1"); @@ -743,6 +742,11 @@ generate_fragment(struct llvmpipe_context *lp, lp_build_name(step1_ptr, "step1"); lp_build_name(step2_ptr, "step2"); + if (key->occlusion_count) { + counter = LLVMGetParam(function, 15); + lp_build_name(counter, "counter"); + } + /* * Function body */ @@ -787,7 +791,7 @@ generate_fragment(struct llvmpipe_context *lp, facing, do_tri_test, c0, c1, c2, - step0_ptr, step1_ptr, step2_ptr); + step0_ptr, step1_ptr, step2_ptr, counter); for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) for(chan = 0; chan < NUM_CHANNELS; ++chan) @@ -801,6 +805,8 @@ generate_fragment(struct llvmpipe_context *lp, for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++) { LLVMValueRef color_ptr; LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), cbuf, 0); + LLVMValueRef blend_in_color[NUM_CHANNELS]; + unsigned rt; /* * Convert the fs's output color and mask to fit to the blending type. @@ -821,10 +827,14 @@ generate_fragment(struct llvmpipe_context *lp, ""); lp_build_name(color_ptr, "color_ptr%d", cbuf); + /* which blend/colormask state to use */ + rt = key->blend.independent_blend_enable ? cbuf : 0; + /* * Blending. */ generate_blend(&key->blend, + rt, builder, blend_type, context_ptr, @@ -842,7 +852,7 @@ generate_fragment(struct llvmpipe_context *lp, #ifdef DEBUG if(LLVMVerifyFunction(function, LLVMPrintMessageAction)) { if (1) - LLVMDumpValue(function); + lp_debug_dump_value(function); abort(); } #endif @@ -851,9 +861,9 @@ generate_fragment(struct llvmpipe_context *lp, if (1) LLVMRunFunctionPassManager(screen->pass, function); - if (LP_DEBUG & DEBUG_JIT) { + if (gallivm_debug & GALLIVM_DEBUG_IR) { /* Print the LLVM IR to stderr */ - LLVMDumpValue(function); + lp_debug_dump_value(function); debug_printf("\n"); } @@ -865,12 +875,84 @@ generate_fragment(struct llvmpipe_context *lp, variant->jit_function[do_tri_test] = cast_voidptr_to_lp_jit_frag_func(f); - if (LP_DEBUG & DEBUG_ASM) + if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(f); + } } } +static void +dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key) +{ + unsigned i; + + debug_printf("fs variant %p:\n", (void *) key); + + if (key->depth.enabled) { + debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format)); + debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE)); + debug_printf("depth.writemask = %u\n", key->depth.writemask); + } + + for (i = 0; i < 2; ++i) { + if (key->stencil[i].enabled) { + debug_printf("stencil[%u].func = %s\n", i, util_dump_func(key->stencil[i].func, TRUE)); + debug_printf("stencil[%u].fail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].fail_op, TRUE)); + debug_printf("stencil[%u].zpass_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zpass_op, TRUE)); + debug_printf("stencil[%u].zfail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zfail_op, TRUE)); + debug_printf("stencil[%u].valuemask = 0x%x\n", i, key->stencil[i].valuemask); + debug_printf("stencil[%u].writemask = 0x%x\n", i, key->stencil[i].writemask); + } + } + + if (key->alpha.enabled) { + debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE)); + debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); + } + + if (key->blend.logicop_enable) { + debug_printf("blend.logicop_func = %s\n", util_dump_logicop(key->blend.logicop_func, TRUE)); + } + else if (key->blend.rt[0].blend_enable) { + debug_printf("blend.rgb_func = %s\n", util_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); + debug_printf("blend.rgb_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); + debug_printf("blend.rgb_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); + debug_printf("blend.alpha_func = %s\n", util_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); + debug_printf("blend.alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); + debug_printf("blend.alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); + } + debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); + for (i = 0; i < PIPE_MAX_SAMPLERS; ++i) { + if (key->sampler[i].format) { + debug_printf("sampler[%u] = \n", i); + debug_printf(" .format = %s\n", + util_format_name(key->sampler[i].format)); + debug_printf(" .target = %s\n", + util_dump_tex_target(key->sampler[i].target, TRUE)); + debug_printf(" .pot = %u %u %u\n", + key->sampler[i].pot_width, + key->sampler[i].pot_height, + key->sampler[i].pot_depth); + debug_printf(" .wrap = %s %s %s\n", + util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), + util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), + util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); + debug_printf(" .min_img_filter = %s\n", + util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); + debug_printf(" .min_mip_filter = %s\n", + util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); + debug_printf(" .mag_img_filter = %s\n", + util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); + if (key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) + debug_printf(" .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE)); + debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); + } + } +} + + + static struct lp_fragment_shader_variant * generate_variant(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, @@ -878,57 +960,9 @@ generate_variant(struct llvmpipe_context *lp, { struct lp_fragment_shader_variant *variant; - if (LP_DEBUG & DEBUG_JIT) { - unsigned i; - + if (gallivm_debug & GALLIVM_DEBUG_IR) { tgsi_dump(shader->base.tokens, 0); - if(key->depth.enabled) { - debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format)); - debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE)); - debug_printf("depth.writemask = %u\n", key->depth.writemask); - } - if(key->alpha.enabled) { - debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE)); - debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); - } - if(key->blend.logicop_enable) { - debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); - } - else if(key->blend.rt[0].blend_enable) { - debug_printf("blend.rgb_func = %s\n", util_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); - debug_printf("rgb_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); - debug_printf("rgb_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); - debug_printf("alpha_func = %s\n", util_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); - debug_printf("alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); - debug_printf("alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); - } - debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); - for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { - if(key->sampler[i].format) { - debug_printf("sampler[%u] = \n", i); - debug_printf(" .format = %s\n", - util_format_name(key->sampler[i].format)); - debug_printf(" .target = %s\n", - util_dump_tex_target(key->sampler[i].target, TRUE)); - debug_printf(" .pot = %u %u %u\n", - key->sampler[i].pot_width, - key->sampler[i].pot_height, - key->sampler[i].pot_depth); - debug_printf(" .wrap = %s %s %s\n", - util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), - util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), - util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); - debug_printf(" .min_img_filter = %s\n", - util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); - debug_printf(" .min_mip_filter = %s\n", - util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); - debug_printf(" .mag_img_filter = %s\n", - util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); - if(key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) - debug_printf(" .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE)); - debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); - } - } + dump_fs_variant_key(key); } variant = CALLOC_STRUCT(lp_fragment_shader_variant); @@ -937,8 +971,20 @@ generate_variant(struct llvmpipe_context *lp, memcpy(&variant->key, key, sizeof *key); - generate_fragment(lp, shader, variant, 0); - generate_fragment(lp, shader, variant, 1); + generate_fragment(lp, shader, variant, RAST_WHOLE); + generate_fragment(lp, shader, variant, RAST_EDGE_TEST); + + /* TODO: most of these can be relaxed, in particular the colormask */ + variant->opaque = + !key->blend.logicop_enable && + !key->blend.rt[0].blend_enable && + key->blend.rt[0].colormask == 0xf && + !key->stencil[0].enabled && + !key->alpha.enabled && + !key->depth.enabled && + !key->scissor && + !shader->info.uses_kill + ? TRUE : FALSE; /* insert new variant into linked list */ variant->next = shader->variants; @@ -964,7 +1010,7 @@ llvmpipe_create_fs_state(struct pipe_context *pipe, /* we need to keep a local copy of the tokens */ shader->base.tokens = tgsi_dup_tokens(templ->tokens); - if (LP_DEBUG & DEBUG_TGSI) { + if (gallivm_debug & GALLIVM_DEBUG_TGSI) { debug_printf("llvmpipe: Create fragment shader %p:\n", (void *) shader); tgsi_dump(templ->tokens, 0); } @@ -1123,6 +1169,9 @@ make_variant_key(struct llvmpipe_context *lp, key->flatshade = lp->rasterizer->flatshade; key->scissor = lp->rasterizer->scissor; + if (lp->active_query_count) { + key->occlusion_count = TRUE; + } if (lp->framebuffer.nr_cbufs) { memcpy(&key->blend, lp->blend, sizeof key->blend); @@ -1187,7 +1236,6 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) struct lp_fragment_shader *shader = lp->fs; struct lp_fragment_shader_variant_key key; struct lp_fragment_shader_variant *variant; - boolean opaque; make_variant_key(lp, shader, &key); @@ -1212,22 +1260,10 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) LP_COUNT_ADD(nr_llvm_compiles, 2); /* emit vs. omit in/out test */ } - /* TODO: put this in the variant */ - /* TODO: most of these can be relaxed, in particular the colormask */ - opaque = !key.blend.logicop_enable && - !key.blend.rt[0].blend_enable && - key.blend.rt[0].colormask == 0xf && - !key.stencil[0].enabled && - !key.alpha.enabled && - !key.depth.enabled && - !key.scissor && - !shader->info.uses_kill - ? TRUE : FALSE; - lp_setup_set_fs_functions(lp->setup, variant->jit_function[RAST_WHOLE], variant->jit_function[RAST_EDGE_TEST], - opaque); + variant->opaque); } |