From c40eddd294abfe8af3619d08ccd7e9c8f1660fcb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 25 Aug 2009 08:05:31 +0100 Subject: [PATCH] llvmpipe: Isolate sampling from TGSI translation. --- src/gallium/drivers/llvmpipe/lp_bld_tgsi.h | 17 ++- .../drivers/llvmpipe/lp_bld_tgsi_soa.c | 102 +++------------- src/gallium/drivers/llvmpipe/lp_jit.c | 3 +- src/gallium/drivers/llvmpipe/lp_jit.h | 5 + src/gallium/drivers/llvmpipe/lp_state_fs.c | 112 +++++++++++++++++- 5 files changed, 145 insertions(+), 94 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h index d42ab99cf82..912db24aecb 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h @@ -39,15 +39,19 @@ struct tgsi_token; -struct tgsi_sampler; union lp_type; struct lp_build_context; struct lp_build_mask_context; -void PIPE_CDECL -lp_build_tgsi_fetch_texel_soa( struct tgsi_sampler **samplers, - uint32_t unit, - float *store ); + +typedef void +(*lp_emit_fetch_texel_soa_callback)( LLVMBuilderRef builder, + void *context, + unsigned unit, + unsigned num_coords, + const LLVMValueRef *coords, + LLVMValueRef lodbias, + LLVMValueRef *texel); void lp_build_tgsi_soa(LLVMBuilderRef builder, @@ -58,7 +62,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[4], LLVMValueRef (*outputs)[4], - LLVMValueRef samplers_ptr); + lp_emit_fetch_texel_soa_callback emit_fetch_texel, + void *emit_fetch_texel_context); #endif /* LP_BLD_TGSI_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c index 1335ba862eb..0c837188cac 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c @@ -87,15 +87,14 @@ struct lp_build_tgsi_soa_context const LLVMValueRef *pos; const LLVMValueRef (*inputs)[NUM_CHANNELS]; LLVMValueRef (*outputs)[NUM_CHANNELS]; - LLVMValueRef samplers_ptr; + + lp_emit_fetch_texel_soa_callback emit_fetch_texel; + void *emit_fetch_texel_context; LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS]; LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS]; struct lp_build_mask_context *mask; - - /** Coords/texels store */ - LLVMValueRef store_ptr; }; @@ -236,52 +235,6 @@ emit_store( } -void PIPE_CDECL -lp_build_tgsi_fetch_texel_soa( struct tgsi_sampler **samplers, - uint32_t unit, - float *store ) -{ - struct tgsi_sampler *sampler = samplers[unit]; - -#if 0 - uint j; - - debug_printf("%s sampler: %p (%p) store: %p\n", - __FUNCTION__, - sampler, *sampler, - store ); - - debug_printf("lodbias %f\n", store[12]); - - for (j = 0; j < 4; j++) - debug_printf("sample %d texcoord %f %f\n", - j, - store[0+j], - store[4+j]); -#endif - - { - float rgba[NUM_CHANNELS][QUAD_SIZE]; - sampler->get_samples(sampler, - &store[0], - &store[4], - &store[8], - 0.0f, /*store[12], lodbias */ - rgba); - memcpy(store, rgba, sizeof rgba); - } - -#if 0 - for (j = 0; j < 4; j++) - debug_printf("sample %d result %f %f %f %f\n", - j, - store[0+j], - store[4+j], - store[8+j], - store[12+j]); -#endif -} - /** * High-level instruction translators. */ @@ -292,28 +245,28 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, boolean apply_lodbias, boolean projected) { - LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type); const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index; LLVMValueRef lodbias; LLVMValueRef oow; - LLVMValueRef args[3]; - unsigned count; + LLVMValueRef coords[3]; + LLVMValueRef texel[4]; + unsigned num_coords; unsigned i; switch (inst->InstructionExtTexture.Texture) { case TGSI_TEXTURE_1D: case TGSI_TEXTURE_SHADOW1D: - count = 1; + num_coords = 1; break; case TGSI_TEXTURE_2D: case TGSI_TEXTURE_RECT: case TGSI_TEXTURE_SHADOW2D: case TGSI_TEXTURE_SHADOWRECT: - count = 2; + num_coords = 2; break; case TGSI_TEXTURE_3D: case TGSI_TEXTURE_CUBE: - count = 3; + num_coords = 3; break; default: assert(0); @@ -325,41 +278,22 @@ emit_tex( struct lp_build_tgsi_soa_context *bld, else lodbias = bld->base.zero; - if(!bld->store_ptr) - bld->store_ptr = LLVMBuildArrayAlloca(bld->base.builder, - vec_type, - LLVMConstInt(LLVMInt32Type(), 4, 0), - "store"); - if (projected) { oow = emit_fetch( bld, inst, 0, 3 ); oow = lp_build_rcp(&bld->base, oow); } - for (i = 0; i < count; i++) { - LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); - LLVMValueRef coord_ptr = LLVMBuildGEP(bld->base.builder, bld->store_ptr, &index, 1, ""); - LLVMValueRef coord; - - coord = emit_fetch( bld, inst, 0, i ); - + for (i = 0; i < num_coords; i++) { + coords[i] = emit_fetch( bld, inst, 0, i ); if (projected) - coord = lp_build_mul(&bld->base, coord, oow); - - LLVMBuildStore(bld->base.builder, coord, coord_ptr); + coords[i] = lp_build_mul(&bld->base, coords[i], oow); } - args[0] = bld->samplers_ptr; - args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0); - args[2] = bld->store_ptr; - - lp_build_intrinsic(bld->base.builder, "fetch_texel", LLVMVoidType(), args, 3); + bld->emit_fetch_texel(bld->base.builder, bld->emit_fetch_texel_context, + unit, num_coords, coords, lodbias, texel); FOR_EACH_DST0_ENABLED_CHANNEL( inst, i ) { - LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); - LLVMValueRef res_ptr = LLVMBuildGEP(bld->base.builder, bld->store_ptr, &index, 1, ""); - LLVMValueRef res = LLVMBuildLoad(bld->base.builder, res_ptr, ""); - emit_store( bld, inst, 0, i, res ); + emit_store( bld, inst, 0, i, texel[i] ); } } @@ -1353,7 +1287,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[NUM_CHANNELS], LLVMValueRef (*outputs)[NUM_CHANNELS], - LLVMValueRef samplers_ptr) + lp_emit_fetch_texel_soa_callback emit_fetch_texel, + void *emit_fetch_texel_context) { struct lp_build_tgsi_soa_context bld; struct tgsi_parse_context parse; @@ -1368,7 +1303,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, bld.inputs = inputs; bld.outputs = outputs; bld.consts_ptr = consts_ptr; - bld.samplers_ptr = samplers_ptr; + bld.emit_fetch_texel = emit_fetch_texel; + bld.emit_fetch_texel_context = emit_fetch_texel_context; tgsi_parse_init( &parse, tokens ); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index 39c4df83633..d288460a1b8 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -38,7 +38,6 @@ #include "util/u_memory.h" #include "lp_screen.h" #include "lp_bld_intr.h" -#include "lp_bld_tgsi.h" /* for lp_build_tgsi_fetch_texel_soa */ #include "lp_jit.h" @@ -88,7 +87,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen) fetch_texel = lp_declare_intrinsic(screen->module, "fetch_texel", ret_type, arg_types, Elements(arg_types)); - LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_build_tgsi_fetch_texel_soa); + LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_fetch_texel_soa); } #ifdef DEBUG diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 33010ad5fb8..a7fb60f9f5c 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -92,6 +92,11 @@ typedef void void *color, void *depth); +void PIPE_CDECL +lp_fetch_texel_soa( struct tgsi_sampler **samplers, + uint32_t unit, + float *store ); + void lp_jit_screen_cleanup(struct llvmpipe_screen *screen); diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 4981432eb38..94170bd7161 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -71,6 +71,7 @@ #include "lp_bld_type.h" #include "lp_bld_const.h" #include "lp_bld_conv.h" +#include "lp_bld_intr.h" #include "lp_bld_logic.h" #include "lp_bld_depth.h" #include "lp_bld_interp.h" @@ -172,6 +173,107 @@ generate_depth(struct llvmpipe_context *lp, } +struct build_fetch_texel_context +{ + LLVMValueRef context_ptr; + + LLVMValueRef samplers_ptr; + + /** Coords/texels store */ + LLVMValueRef store_ptr; +}; + + +void PIPE_CDECL +lp_fetch_texel_soa( struct tgsi_sampler **samplers, + uint32_t unit, + float *store ) +{ + struct tgsi_sampler *sampler = samplers[unit]; + +#if 0 + uint j; + + debug_printf("%s sampler: %p (%p) store: %p\n", + __FUNCTION__, + sampler, *sampler, + store ); + + debug_printf("lodbias %f\n", store[12]); + + for (j = 0; j < 4; j++) + debug_printf("sample %d texcoord %f %f\n", + j, + store[0+j], + store[4+j]); +#endif + + { + float rgba[NUM_CHANNELS][QUAD_SIZE]; + sampler->get_samples(sampler, + &store[0], + &store[4], + &store[8], + 0.0f, /*store[12], lodbias */ + rgba); + memcpy(store, rgba, sizeof rgba); + } + +#if 0 + for (j = 0; j < 4; j++) + debug_printf("sample %d result %f %f %f %f\n", + j, + store[0+j], + store[4+j], + store[8+j], + store[12+j]); +#endif +} + + +static void +emit_fetch_texel( LLVMBuilderRef builder, + void *context, + unsigned unit, + unsigned num_coords, + const LLVMValueRef *coords, + LLVMValueRef lodbias, + LLVMValueRef *texel) +{ + struct build_fetch_texel_context *bld = context; + LLVMTypeRef vec_type = LLVMTypeOf(coords[0]); + LLVMValueRef args[3]; + unsigned i; + + if(!bld->samplers_ptr) + bld->samplers_ptr = lp_jit_context_samplers(builder, bld->context_ptr); + + if(!bld->store_ptr) + bld->store_ptr = LLVMBuildArrayAlloca(builder, + vec_type, + LLVMConstInt(LLVMInt32Type(), 4, 0), + "texel_store"); + + for (i = 0; i < num_coords; i++) { + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); + LLVMValueRef coord_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, ""); + LLVMBuildStore(builder, coords[i], coord_ptr); + } + + args[0] = bld->samplers_ptr; + args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0); + args[2] = bld->store_ptr; + + lp_build_intrinsic(builder, "fetch_texel", LLVMVoidType(), args, 3); + + for (i = 0; i < NUM_CHANNELS; ++i) { + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); + LLVMValueRef texel_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, ""); + texel[i] = LLVMBuildLoad(builder, texel_ptr, ""); + } +} + + /** * Generate the fragment shader, depth/stencil test, and alpha tests. */ @@ -184,6 +286,7 @@ generate_fs(struct llvmpipe_context *lp, LLVMValueRef context_ptr, unsigned i, const struct lp_build_interp_soa_context *interp, + struct build_fetch_texel_context *sampler, LLVMValueRef *pmask, LLVMValueRef *color, LLVMValueRef depth_ptr) @@ -193,7 +296,6 @@ generate_fs(struct llvmpipe_context *lp, LLVMTypeRef vec_type; LLVMTypeRef int_vec_type; LLVMValueRef consts_ptr; - LLVMValueRef samplers_ptr; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; LLVMValueRef z = interp->pos[2]; struct lp_build_mask_context mask; @@ -206,7 +308,6 @@ generate_fs(struct llvmpipe_context *lp, 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); lp_build_mask_begin(&mask, builder, type, *pmask); @@ -226,7 +327,7 @@ generate_fs(struct llvmpipe_context *lp, lp_build_tgsi_soa(builder, tokens, type, &mask, consts_ptr, interp->pos, interp->inputs, - outputs, samplers_ptr); + outputs, emit_fetch_texel, sampler); for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) { for(chan = 0; chan < NUM_CHANNELS; ++chan) { @@ -361,6 +462,7 @@ generate_fragment(struct llvmpipe_context *lp, LLVMBuilderRef builder; LLVMValueRef x0; LLVMValueRef y0; + struct build_fetch_texel_context sampler; struct lp_build_interp_soa_context interp; LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH]; LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH]; @@ -484,6 +586,9 @@ generate_fragment(struct llvmpipe_context *lp, a0_ptr, dadx_ptr, dady_ptr, x0, y0, 2, 0); + memset(&sampler, 0, sizeof sampler); + sampler.context_ptr = context_ptr; + for(i = 0; i < num_fs; ++i) { LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); LLVMValueRef out_color[NUM_CHANNELS]; @@ -501,6 +606,7 @@ generate_fragment(struct llvmpipe_context *lp, context_ptr, i, &interp, + &sampler, &fs_mask[i], out_color, depth_ptr_i); -- 2.30.2