From 946f432a08112148d743eb9faf6b27bb8cc7fa76 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 26 Jul 2009 23:44:38 +0100 Subject: llvmpipe: Fork softpipe for experimentation with llvm. --- src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 194 ++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 src/gallium/drivers/llvmpipe/lp_draw_arrays.c (limited to 'src/gallium/drivers/llvmpipe/lp_draw_arrays.c') diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c new file mode 100644 index 0000000000..87e8623c4f --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -0,0 +1,194 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Author: + * Brian Paul + * Keith Whitwell + */ + + +#include "pipe/p_defines.h" +#include "pipe/p_context.h" +#include "pipe/internal/p_winsys_screen.h" +#include "pipe/p_inlines.h" +#include "util/u_prim.h" + +#include "lp_context.h" +#include "lp_state.h" + +#include "draw/draw_context.h" + + + +static void +llvmpipe_map_constant_buffers(struct llvmpipe_context *lp) +{ + struct pipe_winsys *ws = lp->pipe.winsys; + uint i, size; + + for (i = 0; i < PIPE_SHADER_TYPES; i++) { + if (lp->constants[i].buffer && lp->constants[i].buffer->size) + lp->mapped_constants[i] = ws->buffer_map(ws, lp->constants[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + } + + if (lp->constants[PIPE_SHADER_VERTEX].buffer) + size = lp->constants[PIPE_SHADER_VERTEX].buffer->size; + else + size = 0; + + draw_set_mapped_constant_buffer(lp->draw, + lp->mapped_constants[PIPE_SHADER_VERTEX], + size); +} + + +static void +llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp) +{ + struct pipe_winsys *ws = lp->pipe.winsys; + uint i; + + /* really need to flush all prims since the vert/frag shaders const buffers + * are going away now. + */ + draw_flush(lp->draw); + + draw_set_mapped_constant_buffer(lp->draw, NULL, 0); + + for (i = 0; i < 2; i++) { + if (lp->constants[i].buffer && lp->constants[i].buffer->size) + ws->buffer_unmap(ws, lp->constants[i].buffer); + lp->mapped_constants[i] = NULL; + } +} + + +boolean +llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, + unsigned start, unsigned count) +{ + return llvmpipe_draw_elements(pipe, NULL, 0, mode, start, count); +} + + +/** + * Draw vertex arrays, with optional indexing. + * Basically, map the vertex buffers (and drawing surfaces), then hand off + * the drawing to the 'draw' module. + */ +boolean +llvmpipe_draw_range_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned min_index, + unsigned max_index, + unsigned mode, unsigned start, unsigned count) +{ + struct llvmpipe_context *lp = llvmpipe_context(pipe); + struct draw_context *draw = lp->draw; + unsigned i; + + lp->reduced_api_prim = u_reduced_prim(mode); + + if (lp->dirty) + llvmpipe_update_derived( lp ); + + llvmpipe_map_transfers(lp); + llvmpipe_map_constant_buffers(lp); + + /* + * Map vertex buffers + */ + for (i = 0; i < lp->num_vertex_buffers; i++) { + void *buf + = pipe_buffer_map(pipe->screen, + lp->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes + = pipe_buffer_map(pipe->screen, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer_range(draw, indexSize, + min_index, + max_index, + mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer_range(draw, 0, start, + start + count - 1, NULL); + } + + /* draw! */ + draw_arrays(draw, mode, start, count); + + /* + * unmap vertex/index buffers - will cause draw module to flush + */ + for (i = 0; i < lp->num_vertex_buffers; i++) { + draw_set_mapped_vertex_buffer(draw, i, NULL); + pipe_buffer_unmap(pipe->screen, lp->vertex_buffer[i].buffer); + } + if (indexBuffer) { + draw_set_mapped_element_buffer(draw, 0, NULL); + pipe_buffer_unmap(pipe->screen, indexBuffer); + } + + + /* Note: leave drawing surfaces mapped */ + llvmpipe_unmap_constant_buffers(lp); + + lp->dirty_render_cache = TRUE; + + return TRUE; +} + + +boolean +llvmpipe_draw_elements(struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned mode, unsigned start, unsigned count) +{ + return llvmpipe_draw_range_elements( pipe, indexBuffer, + indexSize, + 0, 0xffffffff, + mode, start, count ); +} + + +void +llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags) +{ + struct llvmpipe_context *lp = llvmpipe_context(pipe); + draw_set_edgeflags(lp->draw, edgeflags); +} -- cgit v1.2.3 From c022e15d1e56ba3a9c6b74eef6556d6063e2e322 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 23 Aug 2009 06:35:09 +0100 Subject: 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 ++------ src/gallium/drivers/llvmpipe/lp_state_derived.c | 2 ++ src/gallium/drivers/llvmpipe/lp_state_fs.c | 35 ++++++++++++----------- 8 files changed, 108 insertions(+), 33 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_draw_arrays.c') diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 77263e4029..8b4266b775 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 87e8623c4f..6a89b74e3a 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 c3ba03a5a1..92d5d43d0c 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 03ab268d0c..fe36b60921 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 c3ff1531d2..98d2789159 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 421cccd302..34bcb9912d 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 5f800eb17f..6fbb057937 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 f77b488e6d..15dbfe8483 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]; -- cgit v1.2.3 From e173a9bbd64dc38dba6b881ed7a9faea02861042 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 29 Aug 2009 20:02:25 +0100 Subject: llvmpipe: Define an winsys for LLVM. Drop pipe_winsys lp_winsys will eventually be unified with softpipe's eventually, but we are free to move quicker since we don't have the myriad of users yet. Will provide a pipe_winsys adaptor from Keith's softpipe-private-winsys soon. --- src/gallium/drivers/llvmpipe/SConscript | 1 + src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 10 +-- src/gallium/drivers/llvmpipe/lp_screen.c | 53 +++++++++++-- src/gallium/drivers/llvmpipe/lp_screen.h | 5 ++ src/gallium/drivers/llvmpipe/lp_texture.c | 106 +++++++++++++------------- src/gallium/drivers/llvmpipe/lp_texture.h | 13 +++- src/gallium/drivers/llvmpipe/lp_winsys.h | 87 ++++++++++++++++++--- 7 files changed, 196 insertions(+), 79 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_draw_arrays.c') diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 26bf8b08fb..6bceb84da4 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -26,6 +26,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_bld_swizzle.c', 'lp_bld_tgsi_soa.c', 'lp_bld_type.c', + 'lp_buffer.c', 'lp_clear.c', 'lp_context.c', 'lp_draw_arrays.c', diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 6a89b74e3a..0f75afc79b 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -47,13 +47,13 @@ static void llvmpipe_map_constant_buffers(struct llvmpipe_context *lp) { - struct pipe_winsys *ws = lp->pipe.winsys; + struct pipe_screen *screen = lp->pipe.screen; uint i, size; for (i = 0; i < PIPE_SHADER_TYPES; i++) { if (lp->constants[i].buffer && lp->constants[i].buffer->size) - lp->mapped_constants[i] = ws->buffer_map(ws, lp->constants[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + lp->mapped_constants[i] = screen->buffer_map(screen, lp->constants[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); } if (lp->constants[PIPE_SHADER_VERTEX].buffer) @@ -72,7 +72,7 @@ llvmpipe_map_constant_buffers(struct llvmpipe_context *lp) static void llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp) { - struct pipe_winsys *ws = lp->pipe.winsys; + struct pipe_screen *screen = lp->pipe.screen; uint i; /* really need to flush all prims since the vert/frag shaders const buffers @@ -86,7 +86,7 @@ llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp) for (i = 0; i < 2; i++) { if (lp->constants[i].buffer && lp->constants[i].buffer->size) - ws->buffer_unmap(ws, lp->constants[i].buffer); + screen->buffer_unmap(screen, lp->constants[i].buffer); lp->mapped_constants[i] = NULL; } } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index f302b99ad7..125035771e 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -33,6 +33,7 @@ #include "pipe/p_screen.h" #include "lp_texture.h" +#include "lp_buffer.h" #include "lp_winsys.h" #include "lp_jit.h" #include "lp_screen.h" @@ -41,7 +42,7 @@ static const char * llvmpipe_get_vendor(struct pipe_screen *screen) { - return "Tungsten Graphics, Inc."; + return "VMware, Inc."; } @@ -126,12 +127,15 @@ llvmpipe_get_paramf(struct pipe_screen *screen, int param) * \param type one of PIPE_TEXTURE, PIPE_SURFACE */ static boolean -llvmpipe_is_format_supported( struct pipe_screen *screen, +llvmpipe_is_format_supported( struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, unsigned tex_usage, unsigned geom_flags ) { + struct llvmpipe_screen *screen = llvmpipe_screen(_screen); + struct llvmpipe_winsys *winsys = screen->winsys; + assert(target == PIPE_TEXTURE_1D || target == PIPE_TEXTURE_2D || target == PIPE_TEXTURE_3D || @@ -149,8 +153,42 @@ llvmpipe_is_format_supported( struct pipe_screen *screen, case PIPE_FORMAT_DXT5_RGBA: return FALSE; default: - return TRUE; + break; } + + if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) + return winsys->is_displaytarget_format_supported(winsys, format); + + return TRUE; +} + + +static struct pipe_buffer * +llvmpipe_surface_buffer_create(struct pipe_screen *screen, + unsigned width, unsigned height, + enum pipe_format format, + unsigned tex_usage, + unsigned usage, + unsigned *stride) +{ + /* This function should never be used */ + assert(0); + return NULL; +} + + +static void +llvmpipe_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *surface, + void *context_private) +{ + struct llvmpipe_screen *screen = llvmpipe_screen(_screen); + struct llvmpipe_winsys *winsys = screen->winsys; + struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture); + + assert(texture->dt); + if (texture->dt) + winsys->displaytarget_display(winsys, texture->dt, context_private); } @@ -176,14 +214,14 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen ) * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen). */ struct pipe_screen * -llvmpipe_create_screen(struct pipe_winsys *winsys) +llvmpipe_create_screen(struct llvmpipe_winsys *winsys) { struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen); if (!screen) return NULL; - screen->base.winsys = winsys; + screen->winsys = winsys; screen->base.destroy = llvmpipe_destroy_screen; @@ -193,8 +231,11 @@ llvmpipe_create_screen(struct pipe_winsys *winsys) screen->base.get_paramf = llvmpipe_get_paramf; screen->base.is_format_supported = llvmpipe_is_format_supported; + screen->base.surface_buffer_create = llvmpipe_surface_buffer_create; + screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer; + llvmpipe_init_screen_texture_funcs(&screen->base); - u_simple_screen_init(&screen->base); + llvmpipe_init_screen_buffer_funcs(&screen->base); lp_jit_screen_init(screen); diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h index 98d2789159..4a1b4d6f3e 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.h +++ b/src/gallium/drivers/llvmpipe/lp_screen.h @@ -43,10 +43,15 @@ #include "pipe/p_defines.h" +struct llvmpipe_winsys; + + struct llvmpipe_screen { struct pipe_screen base; + struct llvmpipe_winsys *winsys; + LLVMModuleRef module; LLVMExecutionEngineRef engine; LLVMModuleProviderRef provider; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 18e348d69e..724d437833 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -52,7 +52,7 @@ /* Conventional allocation path for non-display textures: */ static boolean -llvmpipe_texture_layout(struct pipe_screen *screen, +llvmpipe_texture_layout(struct llvmpipe_screen *screen, struct llvmpipe_texture * lpt) { struct pipe_texture *pt = &lpt->base; @@ -84,34 +84,29 @@ llvmpipe_texture_layout(struct pipe_screen *screen, depth = minify(depth); } - lpt->buffer = screen->buffer_create(screen, 32, - PIPE_BUFFER_USAGE_PIXEL, - buffer_size); + lpt->data = align_malloc(buffer_size, 16); - return lpt->buffer != NULL; + return lpt->data != NULL; } static boolean -llvmpipe_displaytarget_layout(struct pipe_screen *screen, +llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, struct llvmpipe_texture * lpt) { - unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE | - PIPE_BUFFER_USAGE_GPU_READ_WRITE); - unsigned tex_usage = lpt->base.tex_usage; + struct llvmpipe_winsys *winsys = screen->winsys; pf_get_block(lpt->base.format, &lpt->base.block); lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]); lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]); - lpt->buffer = screen->surface_buffer_create( screen, - lpt->base.width[0], - lpt->base.height[0], - lpt->base.format, - usage, - tex_usage, - &lpt->stride[0]); + lpt->dt = winsys->displaytarget_create(winsys, + lpt->base.format, + lpt->base.width[0], + lpt->base.height[0], + 16, + &lpt->stride[0] ); - return lpt->buffer != NULL; + return lpt->dt != NULL; } @@ -119,16 +114,17 @@ llvmpipe_displaytarget_layout(struct pipe_screen *screen, static struct pipe_texture * -llvmpipe_texture_create(struct pipe_screen *screen, +llvmpipe_texture_create(struct pipe_screen *_screen, const struct pipe_texture *templat) { + struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); if (!lpt) return NULL; lpt->base = *templat; pipe_reference_init(&lpt->base.reference, 1); - lpt->base.screen = screen; + lpt->base.screen = &screen->base; /* XXX: The xlib state tracker is brain-dead and will request * PIPE_FORMAT_Z16_UNORM no matter how much we tell it we don't support it. @@ -160,6 +156,8 @@ llvmpipe_texture_blanket(struct pipe_screen * screen, const unsigned *stride, struct pipe_buffer *buffer) { + /* FIXME */ +#if 0 struct llvmpipe_texture *lpt; assert(screen); @@ -184,15 +182,25 @@ llvmpipe_texture_blanket(struct pipe_screen * screen, pipe_buffer_reference(&lpt->buffer, buffer); return &lpt->base; +#else + return NULL; +#endif } static void llvmpipe_texture_destroy(struct pipe_texture *pt) { + struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen); struct llvmpipe_texture *lpt = llvmpipe_texture(pt); - pipe_buffer_reference(&lpt->buffer, NULL); + if(lpt->dt) { + struct llvmpipe_winsys *winsys = screen->winsys; + winsys->displaytarget_destroy(winsys, lpt->dt); + } + else + align_free(lpt->data); + FREE(lpt); } @@ -333,27 +341,34 @@ llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer) static void * -llvmpipe_transfer_map( struct pipe_screen *screen, +llvmpipe_transfer_map( struct pipe_screen *_screen, struct pipe_transfer *transfer ) { + struct llvmpipe_screen *screen = llvmpipe_screen(_screen); ubyte *map, *xfer_map; struct llvmpipe_texture *lpt; - unsigned flags = 0; assert(transfer->texture); lpt = llvmpipe_texture(transfer->texture); - if (transfer->usage != PIPE_TRANSFER_READ) { - flags |= PIPE_BUFFER_USAGE_CPU_WRITE; - } + if(lpt->dt) { + struct llvmpipe_winsys *winsys = screen->winsys; + unsigned flags = 0; - if (transfer->usage != PIPE_TRANSFER_WRITE) { - flags |= PIPE_BUFFER_USAGE_CPU_READ; - } + if (transfer->usage != PIPE_TRANSFER_READ) { + flags |= PIPE_BUFFER_USAGE_CPU_WRITE; + } - map = pipe_buffer_map(screen, lpt->buffer, flags); - if (map == NULL) - return NULL; + if (transfer->usage != PIPE_TRANSFER_WRITE) { + flags |= PIPE_BUFFER_USAGE_CPU_READ; + } + + map = winsys->displaytarget_map(winsys, lpt->dt, flags); + if (map == NULL) + return NULL; + } + else + map = lpt->data; /* May want to different things here depending on read/write nature * of the map: @@ -363,7 +378,7 @@ llvmpipe_transfer_map( struct pipe_screen *screen, /* Do something to notify sharing contexts of a texture change. * In llvmpipe, that would mean flushing the texture cache. */ - llvmpipe_screen(screen)->timestamp++; + screen->timestamp++; } xfer_map = map + llvmpipe_transfer(transfer)->offset + @@ -375,15 +390,19 @@ llvmpipe_transfer_map( struct pipe_screen *screen, static void -llvmpipe_transfer_unmap(struct pipe_screen *screen, +llvmpipe_transfer_unmap(struct pipe_screen *_screen, struct pipe_transfer *transfer) { + struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct llvmpipe_texture *lpt; assert(transfer->texture); lpt = llvmpipe_texture(transfer->texture); - pipe_buffer_unmap( screen, lpt->buffer ); + if(lpt->dt) { + struct llvmpipe_winsys *winsys = screen->winsys; + winsys->displaytarget_unmap(winsys, lpt->dt); + } } @@ -408,22 +427,3 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) screen->transfer_map = llvmpipe_transfer_map; screen->transfer_unmap = llvmpipe_transfer_unmap; } - - -boolean -llvmpipe_get_texture_buffer( struct pipe_texture *texture, - struct pipe_buffer **buf, - unsigned *stride ) -{ - struct llvmpipe_texture *tex = (struct llvmpipe_texture *)texture; - - if (!tex) - return FALSE; - - pipe_buffer_reference(buf, tex->buffer); - - if (stride) - *stride = tex->stride[0]; - - return TRUE; -} diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index a1ed6b0ac2..00a20763e4 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -35,7 +35,7 @@ struct pipe_context; struct pipe_screen; struct llvmpipe_context; - +struct llvmpipe_displaytarget; struct llvmpipe_texture { @@ -44,9 +44,16 @@ struct llvmpipe_texture unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; unsigned stride[PIPE_MAX_TEXTURE_LEVELS]; - /* The data is held here: + /** + * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET + * usage. + */ + struct llvmpipe_displaytarget *dt; + + /** + * Malloc'ed data for regular textures, or a mapping to dt above. */ - struct pipe_buffer *buffer; + void *data; unsigned timestamp; }; diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h index 268336b690..595481c2cb 100644 --- a/src/gallium/drivers/llvmpipe/lp_winsys.h +++ b/src/gallium/drivers/llvmpipe/lp_winsys.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2007-2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,9 +25,9 @@ * **************************************************************************/ -/* This is the interface that llvmpipe requires any window system - * hosting it to implement. This is the only include file in llvmpipe - * which is public. +/** + * @file + * llvmpipe public interface. */ @@ -35,27 +35,90 @@ #define LP_WINSYS_H +#include "pipe/p_compiler.h" // for boolean +#include "pipe/p_format.h" + + #ifdef __cplusplus extern "C" { #endif struct pipe_screen; -struct pipe_winsys; struct pipe_context; -struct pipe_context *llvmpipe_create( struct pipe_screen * ); +/** + * Opaque pointer. + */ +struct llvmpipe_displaytarget; -struct pipe_screen * -llvmpipe_create_screen(struct pipe_winsys *); +/** + * This is the interface that llvmpipe expects any window system + * hosting it to implement. + * + * llvmpipe is for the most part a self sufficient driver. The only thing it + * does not know is how to display a surface. + */ +struct llvmpipe_winsys +{ + void + (*destroy)( struct llvmpipe_winsys *ws ); + + boolean + (*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws, + enum pipe_format format ); + + /** + * Allocate storage for a render target. + * + * Often surfaces which are meant to be blitted to the front screen (i.e., + * display targets) must be allocated with special characteristics, memory + * pools, or obtained directly from the windowing system. + * + * This callback is invoked by the pipe_screen when creating a texture marked + * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying + * storage. + */ + struct llvmpipe_displaytarget * + (*displaytarget_create)( struct llvmpipe_winsys *ws, + enum pipe_format format, + unsigned width, unsigned height, + unsigned alignment, + unsigned *stride ); + + void * + (*displaytarget_map)( struct llvmpipe_winsys *ws, + struct llvmpipe_displaytarget *dt, + unsigned flags ); + + void + (*displaytarget_unmap)( struct llvmpipe_winsys *ws, + struct llvmpipe_displaytarget *dt ); + + /** + * @sa pipe_screen:flush_frontbuffer. + * + * This call will likely become asynchronous eventually. + */ + void + (*displaytarget_display)( struct llvmpipe_winsys *ws, + struct llvmpipe_displaytarget *dt, + void *context_private ); + + void + (*displaytarget_destroy)( struct llvmpipe_winsys *ws, + struct llvmpipe_displaytarget *dt ); +}; + + +struct pipe_context * +llvmpipe_create( struct pipe_screen * ); -boolean -llvmpipe_get_texture_buffer( struct pipe_texture *texture, - struct pipe_buffer **buf, - unsigned *stride ); +struct pipe_screen * +llvmpipe_create_screen( struct llvmpipe_winsys * ); #ifdef __cplusplus -- cgit v1.2.3 From 379304a72cf332e2d570b13663bb447ec7a12940 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sat, 29 Aug 2009 20:34:01 +0100 Subject: llvmpipe: Eliminate internal pipe_buffer_map/unmap usage. --- src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'src/gallium/drivers/llvmpipe/lp_draw_arrays.c') diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 0f75afc79b..89772e62d3 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -37,6 +37,7 @@ #include "pipe/p_inlines.h" #include "util/u_prim.h" +#include "lp_buffer.h" #include "lp_context.h" #include "lp_state.h" @@ -129,18 +130,13 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, * Map vertex buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { - void *buf - = pipe_buffer_map(pipe->screen, - lp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *buf = llvmpipe_buffer(lp->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes - = pipe_buffer_map(pipe->screen, indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *mapped_indexes = llvmpipe_buffer(indexBuffer)->data; draw_set_mapped_element_buffer_range(draw, indexSize, min_index, max_index, @@ -160,11 +156,9 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, */ for (i = 0; i < lp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); - pipe_buffer_unmap(pipe->screen, lp->vertex_buffer[i].buffer); } if (indexBuffer) { draw_set_mapped_element_buffer(draw, 0, NULL); - pipe_buffer_unmap(pipe->screen, indexBuffer); } -- cgit v1.2.3