From c022e15d1e56ba3a9c6b74eef6556d6063e2e322 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Sun, 23 Aug 2009 06:35:09 +0100 Subject: [PATCH] llvmpipe: Pass fragment context to generated function in a single structure. --- src/gallium/drivers/llvmpipe/lp_context.h | 3 ++ src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 4 ++ src/gallium/drivers/llvmpipe/lp_jit.c | 38 ++++++++++++++++++- src/gallium/drivers/llvmpipe/lp_jit.h | 38 ++++++++++++++++--- src/gallium/drivers/llvmpipe/lp_screen.h | 9 ++++- src/gallium/drivers/llvmpipe/lp_setup.c | 12 ++---- .../drivers/llvmpipe/lp_state_derived.c | 2 + src/gallium/drivers/llvmpipe/lp_state_fs.c | 35 ++++++++--------- 8 files changed, 108 insertions(+), 33 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 77263e4029e..8b4266b775c 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -36,6 +36,7 @@ #include "draw/draw_vertex.h" #include "lp_tex_sample.h" +#include "lp_jit.h" struct llvmpipe_vbuf_render; @@ -139,6 +140,8 @@ struct llvmpipe_context { struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS]; unsigned no_rast : 1; + + struct lp_jit_context jit_context; }; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 87e8623c4f0..6a89b74e3a3 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -61,6 +61,8 @@ llvmpipe_map_constant_buffers(struct llvmpipe_context *lp) else size = 0; + lp->jit_context.constants = lp->mapped_constants[PIPE_SHADER_FRAGMENT]; + draw_set_mapped_constant_buffer(lp->draw, lp->mapped_constants[PIPE_SHADER_VERTEX], size); @@ -80,6 +82,8 @@ llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp) draw_set_mapped_constant_buffer(lp->draw, NULL, 0); + lp->jit_context.constants = NULL; + for (i = 0; i < 2; i++) { if (lp->constants[i].buffer && lp->constants[i].buffer->size) ws->buffer_unmap(ws, lp->constants[i].buffer); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index c3ba03a5a18..92d5d43d0cc 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -35,10 +35,42 @@ #include +#include "util/u_memory.h" #include "lp_screen.h" #include "lp_jit.h" +static void +lp_jit_init_types(struct llvmpipe_screen *screen) +{ + /* struct lp_jit_context */ + { + LLVMTypeRef elem_types[2]; + LLVMTypeRef context_type; + + elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */ + elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */ + + context_type = LLVMStructType(elem_types, Elements(elem_types), 0); + + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants, + screen->target, context_type, 0); + LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers, + screen->target, context_type, 1); + LP_CHECK_STRUCT_SIZE(struct lp_jit_context, + screen->target, context_type); + + LLVMAddTypeName(screen->module, "context", context_type); + + screen->context_ptr_type = LLVMPointerType(context_type, 0); + } + +#ifdef DEBUG + LLVMDumpModule(screen->module); +#endif +} + + void lp_jit_screen_cleanup(struct llvmpipe_screen *screen) { @@ -65,8 +97,10 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) abort(); } + screen->target = LLVMGetExecutionEngineTargetData(screen->engine); + screen->pass = LLVMCreateFunctionPassManager(screen->provider); - LLVMAddTargetData(LLVMGetExecutionEngineTargetData(screen->engine), screen->pass); + LLVMAddTargetData(screen->target, screen->pass); /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, * but there are more on SVN. */ LLVMAddConstantPropagationPass(screen->pass); @@ -74,4 +108,6 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) LLVMAddPromoteMemoryToRegisterPass(screen->pass); LLVMAddGVNPass(screen->pass); LLVMAddCFGSimplificationPass(screen->pass); + + lp_jit_init_types(screen); } diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 03ab268d0cf..fe36b609212 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -36,24 +36,52 @@ #define LP_JIT_H -#include +#include "lp_bld_struct.h" struct tgsi_sampler; struct llvmpipe_screen; +/** + * This structure is passed directly to the generated fragment shader. + * + * It contains the derived state. + * + * Changes here must be reflected in the lp_jit_context_* macros and + * lp_jit_init_types function. Changes to the ordering should be avoided. + * + * Only use types with a clear size and padding here, in particular prefer the + * stdint.h types to the basic integer types. + */ +struct lp_jit_context +{ + const float *constants; + + struct tgsi_sampler **samplers; + + /* TODO: alpha reference value */ + /* TODO: blend constant color */ +}; + + +#define lp_jit_context_constants(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 0, "context.constants") + +#define lp_jit_context_samplers(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 1, "context.samplers") + + typedef void -(*lp_jit_frag_func)(uint32_t x, +(*lp_jit_frag_func)(struct lp_jit_context *context, + uint32_t x, uint32_t y, const void *a0, const void *dadx, const void *dady, - const void *consts, uint32_t *mask, void *color, - void *depth, - struct tgsi_sampler **samplers); + void *depth); void diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h index c3ff1531d2f..98d27891596 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.h +++ b/src/gallium/drivers/llvmpipe/lp_screen.h @@ -1,5 +1,6 @@ /************************************************************************** * + * Copyright 2009 VMware, Inc. * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * @@ -25,7 +26,9 @@ * **************************************************************************/ -/* Authors: Keith Whitwell +/** + * @author Jose Fonseca + * @author Keith Whitwell */ #ifndef LP_SCREEN_H @@ -33,6 +36,7 @@ #include #include +#include #include #include "pipe/p_screen.h" @@ -46,8 +50,11 @@ struct llvmpipe_screen LLVMModuleRef module; LLVMExecutionEngineRef engine; LLVMModuleProviderRef provider; + LLVMTargetDataRef target; LLVMPassManagerRef pass; + LLVMTypeRef context_ptr_type; + /* Increments whenever textures are modified. Contexts can track * this. */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 421cccd302e..34bcb9912d4 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -120,8 +120,6 @@ shade_quads(struct llvmpipe_context *llvmpipe, unsigned nr) { struct lp_fragment_shader *fs = llvmpipe->fs; - void *constants; - struct tgsi_sampler **samplers; struct quad_header *quad = quads[0]; const unsigned x = quad->input.x0; const unsigned y = quad->input.y0; @@ -164,8 +162,6 @@ shade_quads(struct llvmpipe_context *llvmpipe, else depth = NULL; - constants = llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; - samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list; /* TODO: blend color */ assert((((uintptr_t)mask) & 0xf) == 0); @@ -174,16 +170,14 @@ shade_quads(struct llvmpipe_context *llvmpipe, assert((((uintptr_t)llvmpipe->blend_color) & 0xf) == 0); /* run shader */ - fs->current->jit_function( x, - y, + fs->current->jit_function( &llvmpipe->jit_context, + x, y, quad->coef->a0, quad->coef->dadx, quad->coef->dady, - constants, &mask[0][0], color, - depth, - samplers); + depth); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index 5f800eb17fa..6fbb057937e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -216,6 +216,8 @@ update_tgsi_samplers( struct llvmpipe_context *llvmpipe ) for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { lp_tex_tile_cache_validate_texture( llvmpipe->tex_cache[i] ); } + + llvmpipe->jit_context.samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list; } /* Hopefully this will remain quite simple, otherwise need to pull in diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index f77b488e6d1..15dbfe8483c 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -378,8 +378,9 @@ generate_fragment(struct llvmpipe_context *lp, LLVMTypeRef fs_int_vec_type; LLVMTypeRef blend_vec_type; LLVMTypeRef blend_int_vec_type; - LLVMTypeRef arg_types[10]; + LLVMTypeRef arg_types[9]; LLVMTypeRef func_type; + LLVMValueRef context_ptr; LLVMValueRef x; LLVMValueRef y; LLVMValueRef a0_ptr; @@ -463,16 +464,15 @@ generate_fragment(struct llvmpipe_context *lp, blend_vec_type = lp_build_vec_type(blend_type); blend_int_vec_type = lp_build_int_vec_type(blend_type); - arg_types[0] = LLVMInt32Type(); /* x */ - arg_types[1] = LLVMInt32Type(); /* y */ - arg_types[2] = LLVMPointerType(fs_elem_type, 0); /* a0 */ - arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* dadx */ - arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dady */ - arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* consts */ + arg_types[0] = screen->context_ptr_type; /* context */ + arg_types[1] = LLVMInt32Type(); /* x */ + arg_types[2] = LLVMInt32Type(); /* y */ + arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */ + arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */ + arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */ arg_types[6] = LLVMPointerType(fs_int_vec_type, 0); /* mask */ arg_types[7] = LLVMPointerType(blend_vec_type, 0); /* color */ arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */ - arg_types[9] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); @@ -482,27 +482,25 @@ generate_fragment(struct llvmpipe_context *lp, if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) LLVMAddAttribute(LLVMGetParam(variant->function, i), LLVMNoAliasAttribute); - x = LLVMGetParam(variant->function, 0); - y = LLVMGetParam(variant->function, 1); - a0_ptr = LLVMGetParam(variant->function, 2); - dadx_ptr = LLVMGetParam(variant->function, 3); - dady_ptr = LLVMGetParam(variant->function, 4); - consts_ptr = LLVMGetParam(variant->function, 5); + context_ptr = LLVMGetParam(variant->function, 0); + x = LLVMGetParam(variant->function, 1); + y = LLVMGetParam(variant->function, 2); + a0_ptr = LLVMGetParam(variant->function, 3); + dadx_ptr = LLVMGetParam(variant->function, 4); + dady_ptr = LLVMGetParam(variant->function, 5); mask_ptr = LLVMGetParam(variant->function, 6); color_ptr = LLVMGetParam(variant->function, 7); depth_ptr = LLVMGetParam(variant->function, 8); - samplers_ptr = LLVMGetParam(variant->function, 9); + lp_build_name(context_ptr, "context"); lp_build_name(x, "x"); lp_build_name(y, "y"); lp_build_name(a0_ptr, "a0"); lp_build_name(dadx_ptr, "dadx"); lp_build_name(dady_ptr, "dady"); - lp_build_name(consts_ptr, "consts"); lp_build_name(mask_ptr, "mask"); lp_build_name(color_ptr, "color"); lp_build_name(depth_ptr, "depth"); - lp_build_name(samplers_ptr, "samplers"); /* * Function body @@ -512,6 +510,9 @@ 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]; -- 2.30.2