diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
29 files changed, 469 insertions, 259 deletions
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 41ac1cee72..89c06ea3ad 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -55,7 +55,7 @@ testprogs := lp_test_format \ LIBS += $(GL_LIB_DEPS) -L. -lllvmpipe -L../../auxiliary/ -lgallium -$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a - $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group +#$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a +# $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group -default: $(testprogs) +#default: $(testprogs) diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index bf4c9a5727..3c3fd386b5 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -12,7 +12,11 @@ Done so far is: - depth testing - - texture sampling (not all state/formats are supported) + - texture sampling + - 1D/2D/3D/cube maps supported + - all texture wrap modes supported + - all texture filtering modes supported + - perhaps not all texture formats yet supported - fragment shader TGSI translation - same level of support as the TGSI SSE2 exec machine, with the exception @@ -37,8 +41,6 @@ To do (probably by this order): - code generate stipple and stencil testing - - translate the remaining bits of texture sampling state - - translate TGSI control flow instructions, and all other remaining opcodes - integrate with the draw module for VS code generation @@ -57,7 +59,7 @@ Requirements See /proc/cpuinfo to know what your CPU supports. - - LLVM 2.6. + - LLVM 2.6 (or later) For Linux, on a recent Debian based distribution do: @@ -67,6 +69,9 @@ Requirements http://people.freedesktop.org/~jrfonseca/llvm/ and set the LLVM environment variable to the extracted path. + The version of LLVM from SVN ("2.7svn") from mid-March 2010 seems pretty + stable and has some features not in version 2.6. + - scons (optional) - udis86, http://udis86.sourceforge.net/ (optional): @@ -140,11 +145,13 @@ Development Notes then skim through the lp_bld_* functions called in there, and the comments at the top of the lp_bld_*.c functions. -- All lp_bld_*.[ch] are isolated from the rest of the driver, and could/may be - put in a stand-alone Gallium state -> LLVM IR translation module. +- The driver-independent parts of the LLVM / Gallium code are found in + src/gallium/auxiliary/gallivm/. The filenames and function prefixes + need to be renamed from "lp_bld_" to something else though. - We use LLVM-C bindings for now. They are not documented, but follow the C++ interfaces very closely, and appear to be complete enough for code generation. See http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html for a stand-alone example. + See the llvm-c/Core.h file for reference. diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c index dab20cb639..6e0f37393e 100644 --- a/src/gallium/drivers/llvmpipe/lp_buffer.c +++ b/src/gallium/drivers/llvmpipe/lp_buffer.c @@ -33,7 +33,6 @@ #include "lp_screen.h" #include "lp_buffer.h" -#include "state_tracker/sw_winsys.h" static void * llvmpipe_buffer_map(struct pipe_screen *screen, diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index d94efec16a..945e3e0558 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -173,6 +173,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced; llvmpipe_init_query_funcs( llvmpipe ); + llvmpipe_init_context_texture_funcs( &llvmpipe->pipe ); /* * Create drawing context and plug our rendering stage into it. diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 217ec59b68..f391871b0e 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -45,7 +45,7 @@ struct draw_stage; struct lp_fragment_shader; struct lp_vertex_shader; struct lp_blend_state; -struct setup_context; +struct lp_setup_context; struct lp_velems_state; struct llvmpipe_context { @@ -98,7 +98,7 @@ struct llvmpipe_context { int psize_slot; /** The tiling engine */ - struct setup_context *setup; + struct lp_setup_context *setup; /** The primitive drawing context */ struct draw_context *draw; diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index bf832433be..636d72a9bb 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -79,12 +79,12 @@ llvmpipe_flush( struct pipe_context *pipe, for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); - debug_dump_surface(filename, llvmpipe->framebuffer.cbufs[i]); + debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[0]); } if (0) { util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); - debug_dump_surface(filename, llvmpipe->framebuffer.zsbuf); + debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf); } ++frame_no; @@ -92,3 +92,68 @@ llvmpipe_flush( struct pipe_context *pipe, #endif } + +/** + * Flush context if necessary. + * + * TODO: move this logic to an auxiliary library? + * + * FIXME: We must implement DISCARD/DONTBLOCK/UNSYNCHRONIZED/etc for + * textures to avoid blocking. + */ +boolean +llvmpipe_flush_texture(struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, + unsigned level, + unsigned flush_flags, + boolean read_only, + boolean cpu_access, + boolean do_not_flush) +{ + struct pipe_fence_handle *last_fence = NULL; + unsigned referenced; + + referenced = pipe->is_texture_referenced(pipe, texture, face, level); + + if ((referenced & PIPE_REFERENCED_FOR_WRITE) || + ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { + + if (do_not_flush) + return FALSE; + + /* + * TODO: The semantics of these flush flags are too obtuse. They should + * disappear and the pipe driver should just ensure that all visible + * side-effects happen when they need to happen. + */ + if (referenced & PIPE_REFERENCED_FOR_WRITE) + flush_flags |= PIPE_FLUSH_RENDER_CACHE; + + if (referenced & PIPE_REFERENCED_FOR_READ) + flush_flags |= PIPE_FLUSH_TEXTURE_CACHE; + + if (cpu_access) { + /* + * Flush and wait. + */ + + struct pipe_fence_handle *fence = NULL; + + pipe->flush(pipe, flush_flags, &fence); + + if (last_fence) { + pipe->screen->fence_finish(pipe->screen, fence, 0); + pipe->screen->fence_reference(pipe->screen, &fence, NULL); + } + } else { + /* + * Just flush. + */ + + pipe->flush(pipe, flush_flags, NULL); + } + } + + return TRUE; +} diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h index 10b2b52583..e13f57ccec 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.h +++ b/src/gallium/drivers/llvmpipe/lp_flush.h @@ -28,10 +28,22 @@ #ifndef LP_FLUSH_H #define LP_FLUSH_H +#include "pipe/p_compiler.h" + struct pipe_context; struct pipe_fence_handle; void llvmpipe_flush(struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence); +boolean +llvmpipe_flush_texture(struct pipe_context *pipe, + struct pipe_texture *texture, + unsigned face, + unsigned level, + unsigned flush_flags, + boolean read_only, + boolean cpu_access, + boolean do_not_flush); + #endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index dd9a8e8856..81ea11a16b 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -62,18 +62,20 @@ lp_rast_begin( struct lp_rasterizer *rast, rast->state.write_color = write_color; for (i = 0; i < rast->state.nr_cbufs; i++) { + struct pipe_surface *cbuf = scene->fb.cbufs[i]; rast->cbuf[i].map = scene->cbuf_map[i]; - rast->cbuf[i].format = scene->cbuf_transfer[i]->texture->format; - rast->cbuf[i].width = scene->cbuf_transfer[i]->width; - rast->cbuf[i].height = scene->cbuf_transfer[i]->height; - rast->cbuf[i].stride = scene->cbuf_transfer[i]->stride; + rast->cbuf[i].format = cbuf->texture->format; + rast->cbuf[i].width = cbuf->width; + rast->cbuf[i].height = cbuf->height; + rast->cbuf[i].stride = llvmpipe_texture_stride(cbuf->texture, cbuf->level); } if (write_zstencil) { + struct pipe_surface *zsbuf = scene->fb.zsbuf; rast->zsbuf.map = scene->zsbuf_map; - rast->zsbuf.stride = scene->zsbuf_transfer->stride; + rast->zsbuf.stride = llvmpipe_texture_stride(zsbuf->texture, zsbuf->level); rast->zsbuf.blocksize = - util_format_get_blocksize(scene->zsbuf_transfer->texture->format); + util_format_get_blocksize(zsbuf->texture->format); } lp_scene_bin_iter_begin( scene ); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index dc5fc5fc7d..303f6e3f7e 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -95,7 +95,7 @@ struct lp_rast_shader_inputs { * Rasterization information for a triangle known to be in this bin, * plus inputs to run the shader: * These fields are tile- and bin-independent. - * Objects of this type are put into the setup_context::data buffer. + * Objects of this type are put into the lp_setup_context::data buffer. */ struct lp_rast_triangle { #ifdef DEBUG diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 72492c0f0c..681ce674d4 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -397,7 +397,6 @@ end: static boolean lp_scene_map_buffers( struct lp_scene *scene ) { - struct pipe_screen *screen = scene->pipe->screen; struct pipe_surface *cbuf, *zsbuf; int i; @@ -409,20 +408,10 @@ lp_scene_map_buffers( struct lp_scene *scene ) for (i = 0; i < scene->fb.nr_cbufs; i++) { cbuf = scene->fb.cbufs[i]; if (cbuf) { - scene->cbuf_transfer[i] = screen->get_tex_transfer(screen, - cbuf->texture, - cbuf->face, - cbuf->level, - cbuf->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, - cbuf->width, - cbuf->height); - if (!scene->cbuf_transfer[i]) - goto fail; - - scene->cbuf_map[i] = screen->transfer_map(screen, - scene->cbuf_transfer[i]); + scene->cbuf_map[i] = llvmpipe_texture_map(cbuf->texture, + cbuf->face, + cbuf->level, + cbuf->zslice); if (!scene->cbuf_map[i]) goto fail; } @@ -432,20 +421,10 @@ lp_scene_map_buffers( struct lp_scene *scene ) */ zsbuf = scene->fb.zsbuf; if (zsbuf) { - scene->zsbuf_transfer = screen->get_tex_transfer(screen, - zsbuf->texture, - zsbuf->face, - zsbuf->level, - zsbuf->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, - zsbuf->width, - zsbuf->height); - if (!scene->zsbuf_transfer) - goto fail; - - scene->zsbuf_map = screen->transfer_map(screen, - scene->zsbuf_transfer); + scene->zsbuf_map = llvmpipe_texture_map(zsbuf->texture, + zsbuf->face, + zsbuf->level, + zsbuf->zslice); if (!scene->zsbuf_map) goto fail; } @@ -469,28 +448,27 @@ fail: static void lp_scene_unmap_buffers( struct lp_scene *scene ) { - struct pipe_screen *screen = scene->pipe->screen; unsigned i; for (i = 0; i < scene->fb.nr_cbufs; i++) { - if (scene->cbuf_map[i]) - screen->transfer_unmap(screen, scene->cbuf_transfer[i]); - - if (scene->cbuf_transfer[i]) - screen->tex_transfer_destroy(scene->cbuf_transfer[i]); - - scene->cbuf_transfer[i] = NULL; - scene->cbuf_map[i] = NULL; + if (scene->cbuf_map[i]) { + struct pipe_surface *cbuf = scene->fb.cbufs[i]; + llvmpipe_texture_unmap(cbuf->texture, + cbuf->face, + cbuf->level, + cbuf->zslice); + scene->cbuf_map[i] = NULL; + } } - if (scene->zsbuf_map) - screen->transfer_unmap(screen, scene->zsbuf_transfer); - - if (scene->zsbuf_transfer) - screen->tex_transfer_destroy(scene->zsbuf_transfer); - - scene->zsbuf_transfer = NULL; - scene->zsbuf_map = NULL; + if (scene->zsbuf_map) { + struct pipe_surface *zsbuf = scene->fb.zsbuf; + llvmpipe_texture_unmap(zsbuf->texture, + zsbuf->face, + zsbuf->level, + zsbuf->zslice); + scene->zsbuf_map = NULL; + } util_unreference_framebuffer_state( &scene->fb ); } diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index 739ac22908..b602b1e8a0 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -114,8 +114,6 @@ struct texture_ref { */ struct lp_scene { struct pipe_context *pipe; - struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS]; - struct pipe_transfer *zsbuf_transfer; /* Scene's buffers are mapped at the time the scene is enqueued: */ diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 5093f58bb1..f1bbc2092c 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -204,8 +204,10 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, return FALSE; } - if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { - if(!winsys->is_displaytarget_format_supported(winsys, format)) + if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { + if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) return FALSE; } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h index d977f98cfa..af25e043cc 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.h +++ b/src/gallium/drivers/llvmpipe/lp_screen.h @@ -34,7 +34,7 @@ #ifndef LP_SCREEN_H #define LP_SCREEN_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include <llvm-c/ExecutionEngine.h> #include "pipe/p_screen.h" diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index c870f89d01..16128c34c8 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -52,11 +52,11 @@ #include "draw/draw_vbuf.h" -static void set_scene_state( struct setup_context *, unsigned ); +static void set_scene_state( struct lp_setup_context *, unsigned ); struct lp_scene * -lp_setup_get_current_scene(struct setup_context *setup) +lp_setup_get_current_scene(struct lp_setup_context *setup) { if (!setup->scene) { @@ -74,7 +74,7 @@ lp_setup_get_current_scene(struct setup_context *setup) static void -first_triangle( struct setup_context *setup, +first_triangle( struct lp_setup_context *setup, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4]) @@ -85,7 +85,7 @@ first_triangle( struct setup_context *setup, } static void -first_line( struct setup_context *setup, +first_line( struct lp_setup_context *setup, const float (*v0)[4], const float (*v1)[4]) { @@ -95,7 +95,7 @@ first_line( struct setup_context *setup, } static void -first_point( struct setup_context *setup, +first_point( struct lp_setup_context *setup, const float (*v0)[4]) { set_scene_state( setup, SETUP_ACTIVE ); @@ -103,7 +103,7 @@ first_point( struct setup_context *setup, setup->point( setup, v0 ); } -static void reset_context( struct setup_context *setup ) +static void reset_context( struct lp_setup_context *setup ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -131,7 +131,7 @@ static void reset_context( struct setup_context *setup ) /** Rasterize all scene's bins */ static void -lp_setup_rasterize_scene( struct setup_context *setup, +lp_setup_rasterize_scene( struct lp_setup_context *setup, boolean write_depth ) { struct lp_scene *scene = lp_setup_get_current_scene(setup); @@ -148,7 +148,7 @@ lp_setup_rasterize_scene( struct setup_context *setup, static void -begin_binning( struct setup_context *setup ) +begin_binning( struct lp_setup_context *setup ) { struct lp_scene *scene = lp_setup_get_current_scene(setup); @@ -184,7 +184,7 @@ begin_binning( struct setup_context *setup ) * TODO: fast path for fullscreen clears and no triangles. */ static void -execute_clears( struct setup_context *setup ) +execute_clears( struct lp_setup_context *setup ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -194,7 +194,7 @@ execute_clears( struct setup_context *setup ) static void -set_scene_state( struct setup_context *setup, +set_scene_state( struct lp_setup_context *setup, unsigned new_state ) { unsigned old_state = setup->state; @@ -229,7 +229,7 @@ set_scene_state( struct setup_context *setup, void -lp_setup_flush( struct setup_context *setup, +lp_setup_flush( struct lp_setup_context *setup, unsigned flags ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -239,7 +239,7 @@ lp_setup_flush( struct setup_context *setup, void -lp_setup_bind_framebuffer( struct setup_context *setup, +lp_setup_bind_framebuffer( struct lp_setup_context *setup, const struct pipe_framebuffer_state *fb ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -256,7 +256,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, void -lp_setup_clear( struct setup_context *setup, +lp_setup_clear( struct lp_setup_context *setup, const float *color, double depth, unsigned stencil, @@ -314,7 +314,7 @@ lp_setup_clear( struct setup_context *setup, * Emit a fence. */ struct pipe_fence_handle * -lp_setup_fence( struct setup_context *setup ) +lp_setup_fence( struct lp_setup_context *setup ) { struct lp_scene *scene = lp_setup_get_current_scene(setup); const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */ @@ -334,10 +334,11 @@ lp_setup_fence( struct setup_context *setup ) void -lp_setup_set_triangle_state( struct setup_context *setup, +lp_setup_set_triangle_state( struct lp_setup_context *setup, unsigned cull_mode, boolean ccw_is_frontface, - boolean scissor ) + boolean scissor, + boolean gl_rasterization_rules) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -345,12 +346,13 @@ lp_setup_set_triangle_state( struct setup_context *setup, setup->cullmode = cull_mode; setup->triangle = first_triangle; setup->scissor_test = scissor; + setup->pixel_offset = gl_rasterization_rules ? 0.5f : 0.0f; } void -lp_setup_set_fs_inputs( struct setup_context *setup, +lp_setup_set_fs_inputs( struct lp_setup_context *setup, const struct lp_shader_input *input, unsigned nr ) { @@ -361,7 +363,7 @@ lp_setup_set_fs_inputs( struct setup_context *setup, } void -lp_setup_set_fs_functions( struct setup_context *setup, +lp_setup_set_fs_functions( struct lp_setup_context *setup, lp_jit_frag_func jit_function0, lp_jit_frag_func jit_function1, boolean opaque ) @@ -376,7 +378,7 @@ lp_setup_set_fs_functions( struct setup_context *setup, } void -lp_setup_set_fs_constants(struct setup_context *setup, +lp_setup_set_fs_constants(struct lp_setup_context *setup, struct pipe_buffer *buffer) { LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer); @@ -388,7 +390,7 @@ lp_setup_set_fs_constants(struct setup_context *setup, void -lp_setup_set_alpha_ref_value( struct setup_context *setup, +lp_setup_set_alpha_ref_value( struct lp_setup_context *setup, float alpha_ref_value ) { LP_DBG(DEBUG_SETUP, "%s %f\n", __FUNCTION__, alpha_ref_value); @@ -400,7 +402,7 @@ lp_setup_set_alpha_ref_value( struct setup_context *setup, } void -lp_setup_set_blend_color( struct setup_context *setup, +lp_setup_set_blend_color( struct lp_setup_context *setup, const struct pipe_blend_color *blend_color ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -415,7 +417,7 @@ lp_setup_set_blend_color( struct setup_context *setup, void -lp_setup_set_scissor( struct setup_context *setup, +lp_setup_set_scissor( struct lp_setup_context *setup, const struct pipe_scissor_state *scissor ) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); @@ -430,7 +432,7 @@ lp_setup_set_scissor( struct setup_context *setup, void -lp_setup_set_flatshade_first( struct setup_context *setup, +lp_setup_set_flatshade_first( struct lp_setup_context *setup, boolean flatshade_first ) { setup->flatshade_first = flatshade_first; @@ -438,7 +440,7 @@ lp_setup_set_flatshade_first( struct setup_context *setup, void -lp_setup_set_vertex_info( struct setup_context *setup, +lp_setup_set_vertex_info( struct lp_setup_context *setup, struct vertex_info *vertex_info ) { /* XXX: just silently holding onto the pointer: @@ -451,7 +453,7 @@ lp_setup_set_vertex_info( struct setup_context *setup, * Called during state validation when LP_NEW_TEXTURE is set. */ void -lp_setup_set_sampler_textures( struct setup_context *setup, +lp_setup_set_sampler_textures( struct lp_setup_context *setup, unsigned num, struct pipe_texture **texture) { unsigned i; @@ -512,7 +514,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup, * being rendered and the current scene being built. */ unsigned -lp_setup_is_texture_referenced( const struct setup_context *setup, +lp_setup_is_texture_referenced( const struct lp_setup_context *setup, const struct pipe_texture *texture ) { unsigned i; @@ -541,7 +543,7 @@ lp_setup_is_texture_referenced( const struct setup_context *setup, * Called by vbuf code when we're about to draw something. */ void -lp_setup_update_state( struct setup_context *setup ) +lp_setup_update_state( struct lp_setup_context *setup ) { struct lp_scene *scene = lp_setup_get_current_scene(setup); @@ -659,7 +661,7 @@ lp_setup_update_state( struct setup_context *setup ) /* Only caller is lp_setup_vbuf_destroy() */ void -lp_setup_destroy( struct setup_context *setup ) +lp_setup_destroy( struct lp_setup_context *setup ) { reset_context( setup ); @@ -684,12 +686,12 @@ lp_setup_destroy( struct setup_context *setup ) * the draw module. Currently also creates a rasterizer to use with * it. */ -struct setup_context * +struct lp_setup_context * lp_setup_create( struct pipe_context *pipe, struct draw_context *draw ) { unsigned i; - struct setup_context *setup = CALLOC_STRUCT(setup_context); + struct lp_setup_context *setup = CALLOC_STRUCT(lp_setup_context); if (!setup) return NULL; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 17c112b528..be1bf96f12 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -61,78 +61,79 @@ struct pipe_framebuffer_state; struct lp_fragment_shader; struct lp_jit_context; -struct setup_context * +struct lp_setup_context * lp_setup_create( struct pipe_context *pipe, struct draw_context *draw ); void -lp_setup_clear(struct setup_context *setup, +lp_setup_clear(struct lp_setup_context *setup, const float *clear_color, double clear_depth, unsigned clear_stencil, unsigned flags); struct pipe_fence_handle * -lp_setup_fence( struct setup_context *setup ); +lp_setup_fence( struct lp_setup_context *setup ); void -lp_setup_flush( struct setup_context *setup, +lp_setup_flush( struct lp_setup_context *setup, unsigned flags ); void -lp_setup_bind_framebuffer( struct setup_context *setup, +lp_setup_bind_framebuffer( struct lp_setup_context *setup, const struct pipe_framebuffer_state *fb ); void -lp_setup_set_triangle_state( struct setup_context *setup, +lp_setup_set_triangle_state( struct lp_setup_context *setup, unsigned cullmode, boolean front_is_ccw, - boolean scissor ); + boolean scissor, + boolean gl_rasterization_rules ); void -lp_setup_set_fs_inputs( struct setup_context *setup, +lp_setup_set_fs_inputs( struct lp_setup_context *setup, const struct lp_shader_input *interp, unsigned nr ); void -lp_setup_set_fs_functions( struct setup_context *setup, +lp_setup_set_fs_functions( struct lp_setup_context *setup, lp_jit_frag_func jit_function0, lp_jit_frag_func jit_function1, boolean opaque ); void -lp_setup_set_fs_constants(struct setup_context *setup, +lp_setup_set_fs_constants(struct lp_setup_context *setup, struct pipe_buffer *buffer); void -lp_setup_set_alpha_ref_value( struct setup_context *setup, +lp_setup_set_alpha_ref_value( struct lp_setup_context *setup, float alpha_ref_value ); void -lp_setup_set_blend_color( struct setup_context *setup, +lp_setup_set_blend_color( struct lp_setup_context *setup, const struct pipe_blend_color *blend_color ); void -lp_setup_set_scissor( struct setup_context *setup, +lp_setup_set_scissor( struct lp_setup_context *setup, const struct pipe_scissor_state *scissor ); void -lp_setup_set_sampler_textures( struct setup_context *setup, +lp_setup_set_sampler_textures( struct lp_setup_context *setup, unsigned num, struct pipe_texture **texture); unsigned -lp_setup_is_texture_referenced( const struct setup_context *setup, +lp_setup_is_texture_referenced( const struct lp_setup_context *setup, const struct pipe_texture *texture ); void -lp_setup_set_flatshade_first( struct setup_context *setup, +lp_setup_set_flatshade_first( struct lp_setup_context *setup, boolean flatshade_first ); void -lp_setup_set_vertex_info( struct setup_context *setup, +lp_setup_set_vertex_info( struct lp_setup_context *setup, struct vertex_info *info ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index a5fc34e54a..464fb36984 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -65,7 +65,7 @@ struct lp_scene_queue; * Subclass of vbuf_render, plugged directly into the draw module as * the rendering backend. */ -struct setup_context +struct lp_setup_context { struct vbuf_render base; @@ -89,6 +89,7 @@ struct setup_context boolean ccw_is_frontface; boolean scissor_test; unsigned cullmode; + float pixel_offset; struct pipe_framebuffer_state fb; @@ -131,29 +132,29 @@ struct setup_context unsigned dirty; /**< bitmask of LP_SETUP_NEW_x bits */ - void (*point)( struct setup_context *, + void (*point)( struct lp_setup_context *, const float (*v0)[4]); - void (*line)( struct setup_context *, + void (*line)( struct lp_setup_context *, const float (*v0)[4], const float (*v1)[4]); - void (*triangle)( struct setup_context *, + void (*triangle)( struct lp_setup_context *, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4]); }; -void lp_setup_choose_triangle( struct setup_context *setup ); -void lp_setup_choose_line( struct setup_context *setup ); -void lp_setup_choose_point( struct setup_context *setup ); +void lp_setup_choose_triangle( struct lp_setup_context *setup ); +void lp_setup_choose_line( struct lp_setup_context *setup ); +void lp_setup_choose_point( struct lp_setup_context *setup ); -struct lp_scene *lp_setup_get_current_scene(struct setup_context *setup); +struct lp_scene *lp_setup_get_current_scene(struct lp_setup_context *setup); -void lp_setup_init_vbuf(struct setup_context *setup); +void lp_setup_init_vbuf(struct lp_setup_context *setup); -void lp_setup_update_state( struct setup_context *setup ); +void lp_setup_update_state( struct lp_setup_context *setup ); -void lp_setup_destroy( struct setup_context *setup ); +void lp_setup_destroy( struct lp_setup_context *setup ); #endif diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index feea79d394..be41c44e6f 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -31,7 +31,7 @@ #include "lp_setup_context.h" -static void line_nop( struct setup_context *setup, +static void line_nop( struct lp_setup_context *setup, const float (*v0)[4], const float (*v1)[4] ) { @@ -39,7 +39,7 @@ static void line_nop( struct setup_context *setup, void -lp_setup_choose_line( struct setup_context *setup ) +lp_setup_choose_line( struct lp_setup_context *setup ) { setup->line = line_nop; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c index f03ca729b2..9f69e6c5ce 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_point.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c @@ -31,14 +31,14 @@ #include "lp_setup_context.h" -static void point_nop( struct setup_context *setup, +static void point_nop( struct lp_setup_context *setup, const float (*v0)[4] ) { } void -lp_setup_choose_point( struct setup_context *setup ) +lp_setup_choose_point( struct lp_setup_context *setup ) { setup->point = point_nop; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index e75412ac9a..ac6264dc73 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -41,7 +41,8 @@ /** * Compute a0 for a constant-valued coefficient (GL_FLAT shading). */ -static void constant_coef( struct lp_rast_triangle *tri, +static void constant_coef( struct lp_setup_context *setup, + struct lp_rast_triangle *tri, unsigned slot, const float value, unsigned i ) @@ -56,7 +57,8 @@ static void constant_coef( struct lp_rast_triangle *tri, * Compute a0, dadx and dady for a linearly interpolated coefficient, * for a triangle. */ -static void linear_coef( struct lp_rast_triangle *tri, +static void linear_coef( struct lp_setup_context *setup, + struct lp_rast_triangle *tri, float oneoverarea, unsigned slot, const float (*v1)[4], @@ -90,8 +92,8 @@ static void linear_coef( struct lp_rast_triangle *tri, * instead - i'll switch to this later. */ tri->inputs.a0[slot][i] = (a1 - - (dadx * (v1[0][0] - 0.5f) + - dady * (v1[0][1] - 0.5f))); + (dadx * (v1[0][0] - setup->pixel_offset) + + dady * (v1[0][1] - setup->pixel_offset))); } @@ -103,7 +105,8 @@ static void linear_coef( struct lp_rast_triangle *tri, * Later, when we compute the value at a particular fragment position we'll * divide the interpolated value by the interpolated W at that fragment. */ -static void perspective_coef( struct lp_rast_triangle *tri, +static void perspective_coef( struct lp_setup_context *setup, + struct lp_rast_triangle *tri, float oneoverarea, unsigned slot, const float (*v1)[4], @@ -125,8 +128,8 @@ static void perspective_coef( struct lp_rast_triangle *tri, tri->inputs.dadx[slot][i] = dadx; tri->inputs.dady[slot][i] = dady; tri->inputs.a0[slot][i] = (a1 - - (dadx * (v1[0][0] - 0.5f) + - dady * (v1[0][1] - 0.5f))); + (dadx * (v1[0][0] - setup->pixel_offset) + + dady * (v1[0][1] - setup->pixel_offset))); } @@ -137,7 +140,8 @@ static void perspective_coef( struct lp_rast_triangle *tri, * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask. */ static void -setup_fragcoord_coef(struct lp_rast_triangle *tri, +setup_fragcoord_coef(struct lp_setup_context *setup, + struct lp_rast_triangle *tri, float oneoverarea, unsigned slot, const float (*v1)[4], @@ -153,27 +157,28 @@ setup_fragcoord_coef(struct lp_rast_triangle *tri, tri->inputs.dadx[slot][1] = 0.0; tri->inputs.dady[slot][1] = 1.0; /*Z*/ - linear_coef(tri, oneoverarea, slot, v1, v2, v3, 0, 2); + linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 2); /*W*/ - linear_coef(tri, oneoverarea, slot, v1, v2, v3, 0, 3); + linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 3); } -static void setup_facing_coef( struct lp_rast_triangle *tri, +static void setup_facing_coef( struct lp_setup_context *setup, + struct lp_rast_triangle *tri, unsigned slot, boolean frontface ) { - constant_coef( tri, slot, 1.0f - frontface, 0 ); - constant_coef( tri, slot, 0.0f, 1 ); /* wasted */ - constant_coef( tri, slot, 0.0f, 2 ); /* wasted */ - constant_coef( tri, slot, 0.0f, 3 ); /* wasted */ + constant_coef( setup, tri, slot, 1.0f - frontface, 0 ); + constant_coef( setup, tri, slot, 0.0f, 1 ); /* wasted */ + constant_coef( setup, tri, slot, 0.0f, 2 ); /* wasted */ + constant_coef( setup, tri, slot, 0.0f, 3 ); /* wasted */ } /** * Compute the tri->coef[] array dadx, dady, a0 values. */ -static void setup_tri_coefficients( struct setup_context *setup, +static void setup_tri_coefficients( struct lp_setup_context *setup, struct lp_rast_triangle *tri, float oneoverarea, const float (*v1)[4], @@ -185,7 +190,7 @@ static void setup_tri_coefficients( struct setup_context *setup, /* The internal position input is in slot zero: */ - setup_fragcoord_coef(tri, oneoverarea, 0, v1, v2, v3); + setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2, v3); /* setup interpolation for all the remaining attributes: */ @@ -196,27 +201,27 @@ static void setup_tri_coefficients( struct setup_context *setup, switch (setup->fs.input[slot].interp) { case LP_INTERP_CONSTANT: for (i = 0; i < NUM_CHANNELS; i++) - constant_coef(tri, slot+1, v3[vert_attr][i], i); + constant_coef(setup, tri, slot+1, v3[vert_attr][i], i); break; case LP_INTERP_LINEAR: for (i = 0; i < NUM_CHANNELS; i++) - linear_coef(tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); + linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); break; case LP_INTERP_PERSPECTIVE: for (i = 0; i < NUM_CHANNELS; i++) - perspective_coef(tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); + perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i); break; case LP_INTERP_POSITION: /* XXX: fix me - duplicates the values in slot zero. */ - setup_fragcoord_coef(tri, oneoverarea, slot+1, v1, v2, v3); + setup_fragcoord_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3); break; case LP_INTERP_FACING: - setup_facing_coef(tri, slot+1, frontface); + setup_facing_coef(setup, tri, slot+1, frontface); break; default: @@ -274,19 +279,19 @@ alloc_triangle(struct lp_scene *scene, unsigned nr_inputs, unsigned *tri_size) * bins for the tiles which we overlap. */ static void -do_triangle_ccw(struct setup_context *setup, +do_triangle_ccw(struct lp_setup_context *setup, const float (*v1)[4], const float (*v2)[4], const float (*v3)[4], boolean frontfacing ) { /* x/y positions in fixed point */ - const int x1 = subpixel_snap(v1[0][0]); - const int x2 = subpixel_snap(v2[0][0]); - const int x3 = subpixel_snap(v3[0][0]); - const int y1 = subpixel_snap(v1[0][1]); - const int y2 = subpixel_snap(v2[0][1]); - const int y3 = subpixel_snap(v3[0][1]); + const int x1 = subpixel_snap(v1[0][0] + 0.5 - setup->pixel_offset); + const int x2 = subpixel_snap(v2[0][0] + 0.5 - setup->pixel_offset); + const int x3 = subpixel_snap(v3[0][0] + 0.5 - setup->pixel_offset); + const int y1 = subpixel_snap(v1[0][1] + 0.5 - setup->pixel_offset); + const int y2 = subpixel_snap(v2[0][1] + 0.5 - setup->pixel_offset); + const int y3 = subpixel_snap(v3[0][1] + 0.5 - setup->pixel_offset); struct lp_scene *scene = lp_setup_get_current_scene(setup); struct lp_rast_triangle *tri; @@ -565,7 +570,7 @@ do_triangle_ccw(struct setup_context *setup, } -static void triangle_cw( struct setup_context *setup, +static void triangle_cw( struct lp_setup_context *setup, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4] ) @@ -574,7 +579,7 @@ static void triangle_cw( struct setup_context *setup, } -static void triangle_ccw( struct setup_context *setup, +static void triangle_ccw( struct lp_setup_context *setup, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4] ) @@ -583,7 +588,7 @@ static void triangle_ccw( struct setup_context *setup, } -static void triangle_both( struct setup_context *setup, +static void triangle_both( struct lp_setup_context *setup, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4] ) @@ -602,7 +607,7 @@ static void triangle_both( struct setup_context *setup, } -static void triangle_nop( struct setup_context *setup, +static void triangle_nop( struct lp_setup_context *setup, const float (*v0)[4], const float (*v1)[4], const float (*v2)[4] ) @@ -611,7 +616,7 @@ static void triangle_nop( struct setup_context *setup, void -lp_setup_choose_triangle( struct setup_context *setup ) +lp_setup_choose_triangle( struct lp_setup_context *setup ) { switch (setup->cullmode) { case PIPE_WINDING_NONE: diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c index 671e74465c..d7336d82b2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c @@ -48,10 +48,10 @@ /** cast wrapper */ -static struct setup_context * -setup_context(struct vbuf_render *vbr) +static struct lp_setup_context * +lp_setup_context(struct vbuf_render *vbr) { - return (struct setup_context *) vbr; + return (struct lp_setup_context *) vbr; } @@ -59,7 +59,7 @@ setup_context(struct vbuf_render *vbr) static const struct vertex_info * lp_setup_get_vertex_info(struct vbuf_render *vbr) { - struct setup_context *setup = setup_context(vbr); + struct lp_setup_context *setup = lp_setup_context(vbr); return setup->vertex_info; } @@ -68,7 +68,7 @@ static boolean lp_setup_allocate_vertices(struct vbuf_render *vbr, ushort vertex_size, ushort nr_vertices) { - struct setup_context *setup = setup_context(vbr); + struct lp_setup_context *setup = lp_setup_context(vbr); unsigned size = vertex_size * nr_vertices; if (setup->vertex_buffer_size < size) { @@ -92,7 +92,7 @@ lp_setup_release_vertices(struct vbuf_render *vbr) static void * lp_setup_map_vertices(struct vbuf_render *vbr) { - struct setup_context *setup = setup_context(vbr); + struct lp_setup_context *setup = lp_setup_context(vbr); return setup->vertex_buffer; } @@ -101,7 +101,7 @@ lp_setup_unmap_vertices(struct vbuf_render *vbr, ushort min_index, ushort max_index ) { - struct setup_context *setup = setup_context(vbr); + struct lp_setup_context *setup = lp_setup_context(vbr); assert( setup->vertex_buffer_size >= (max_index+1) * setup->vertex_size ); /* do nothing */ } @@ -110,7 +110,7 @@ lp_setup_unmap_vertices(struct vbuf_render *vbr, static boolean lp_setup_set_primitive(struct vbuf_render *vbr, unsigned prim) { - setup_context(vbr)->prim = prim; + lp_setup_context(vbr)->prim = prim; return TRUE; } @@ -129,7 +129,7 @@ static INLINE const_float4_ptr get_vert( const void *vertex_buffer, static void lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) { - struct setup_context *setup = setup_context(vbr); + struct lp_setup_context *setup = lp_setup_context(vbr); const unsigned stride = setup->vertex_info->size * sizeof(float); const void *vertex_buffer = setup->vertex_buffer; unsigned i; @@ -284,7 +284,7 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) static void lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) { - struct setup_context *setup = setup_context(vbr); + struct lp_setup_context *setup = lp_setup_context(vbr); const unsigned stride = setup->vertex_info->size * sizeof(float); const void *vertex_buffer = (void *) get_vert(setup->vertex_buffer, start, stride); @@ -436,7 +436,7 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) static void lp_setup_vbuf_destroy(struct vbuf_render *vbr) { - lp_setup_destroy(setup_context(vbr)); + lp_setup_destroy(lp_setup_context(vbr)); } @@ -444,7 +444,7 @@ lp_setup_vbuf_destroy(struct vbuf_render *vbr) * Create the post-transform vertex handler for the given context. */ void -lp_setup_init_vbuf(struct setup_context *setup) +lp_setup_init_vbuf(struct lp_setup_context *setup) { setup->base.max_indices = LP_MAX_VBUF_INDEXES; setup->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE; diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index a5a1a72074..34dd5234ce 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -31,7 +31,7 @@ #ifndef LP_STATE_H #define LP_STATE_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include "pipe/p_state.h" #include "tgsi/tgsi_scan.h" diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 9a8de0edfd..64f988d6d0 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -252,7 +252,7 @@ generate_tri_edge_mask(LLVMBuilderRef builder, LLVMConstInt(LLVMInt32Type(), INT_MIN, 0), ""); - in_out_mask = lp_build_int_const_scalar(i32_type, ~0); + in_out_mask = lp_build_const_int_vec(i32_type, ~0); lp_build_flow_scope_declare(flow, &in_out_mask); @@ -367,7 +367,7 @@ build_int32_vec_const(int value) i32_type.norm = FALSE; /* values are not normalized */ i32_type.width = 32; /* 32-bit int values */ i32_type.length = 4; /* 4 elements per vector */ - return lp_build_int_const_scalar(i32_type, value); + return lp_build_const_int_vec(i32_type, value); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c index feb012816c..6df3ef25b0 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c @@ -62,7 +62,8 @@ void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, lp_setup_set_triangle_state( llvmpipe->setup, llvmpipe->rasterizer->cull_mode, llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW, - llvmpipe->rasterizer->scissor); + llvmpipe->rasterizer->scissor, + llvmpipe->rasterizer->gl_rasterization_rules); } llvmpipe->dirty |= LP_NEW_RASTERIZER; diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 6110b0a193..ca3d62c361 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -27,6 +27,7 @@ #include "util/u_rect.h" #include "lp_context.h" +#include "lp_flush.h" #include "lp_surface.h" @@ -36,6 +37,20 @@ lp_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { + llvmpipe_flush_texture(pipe, + dest->texture, dest->face, dest->level, + 0, /* flush_flags */ + FALSE, /* read_only */ + FALSE, /* cpu_access */ + FALSE); /* do_not_flush */ + + llvmpipe_flush_texture(pipe, + src->texture, src->face, src->level, + 0, /* flush_flags */ + TRUE, /* read_only */ + FALSE, /* cpu_access */ + FALSE); /* do_not_flush */ + util_surface_copy(pipe, FALSE, dest, destx, desty, src, srcx, srcy, diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h index 1df9897898..338a04a487 100644 --- a/src/gallium/drivers/llvmpipe/lp_test.h +++ b/src/gallium/drivers/llvmpipe/lp_test.h @@ -41,7 +41,7 @@ #include <stdio.h> #include <float.h> -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include <llvm-c/Analysis.h> #include <llvm-c/ExecutionEngine.h> #include <llvm-c/Target.h> diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c index 2c4d7fb6e1..fb595893bd 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_format.c +++ b/src/gallium/drivers/llvmpipe/lp_test_format.c @@ -29,7 +29,7 @@ #include <stdlib.h> #include <stdio.h> -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" #include <llvm-c/Analysis.h> #include <llvm-c/ExecutionEngine.h> #include <llvm-c/Target.h> diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h index 799df182b6..1228a831f3 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h @@ -29,7 +29,7 @@ #define LP_TEX_SAMPLE_H -#include "os/os_llvm.h" +#include "gallivm/lp_bld.h" struct lp_sampler_static_state; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 74b7b4ec5e..93ad789c35 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -40,6 +40,7 @@ #include "lp_context.h" #include "lp_screen.h" +#include "lp_flush.h" #include "lp_texture.h" #include "lp_tile_size.h" #include "state_tracker/sw_winsys.h" @@ -102,6 +103,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, unsigned height = align(lpt->base.height0, TILE_SIZE); lpt->dt = winsys->displaytarget_create(winsys, + lpt->base.tex_usage, lpt->base.format, width, height, 16, @@ -163,6 +165,137 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) } +/** + * Map a texture. Without any synchronization. + */ +void * +llvmpipe_texture_map(struct pipe_texture *texture, + unsigned face, + unsigned level, + unsigned zslice) +{ + struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + uint8_t *map; + + if (lpt->dt) { + /* display target */ + struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen); + struct sw_winsys *winsys = screen->winsys; + const unsigned usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE; + + assert(face == 0); + assert(level == 0); + assert(zslice == 0); + + /* FIXME: keep map count? */ + map = winsys->displaytarget_map(winsys, lpt->dt, usage); + } + else { + /* regular texture */ + unsigned offset; + unsigned stride; + + map = lpt->data; + + assert(level < LP_MAX_TEXTURE_2D_LEVELS); + + offset = lpt->level_offset[level]; + stride = lpt->stride[level]; + + /* XXX shouldn't that rather be + tex_height = align(u_minify(texture->height0, level), 2) + to account for alignment done in llvmpipe_texture_layout ? + */ + if (texture->target == PIPE_TEXTURE_CUBE) { + unsigned tex_height = u_minify(texture->height0, level); + offset += face * util_format_get_nblocksy(texture->format, tex_height) * stride; + } + else if (texture->target == PIPE_TEXTURE_3D) { + unsigned tex_height = u_minify(texture->height0, level); + offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * stride; + } + else { + assert(face == 0); + assert(zslice == 0); + } + + map += offset; + } + + return map; +} + + +/** + * Unmap a texture. Without any synchronization. + */ +void +llvmpipe_texture_unmap(struct pipe_texture *texture, + unsigned face, + unsigned level, + unsigned zslice) +{ + struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + + if (lpt->dt) { + /* display target */ + struct llvmpipe_screen *lp_screen = llvmpipe_screen(texture->screen); + struct sw_winsys *winsys = lp_screen->winsys; + + assert(face == 0); + assert(level == 0); + assert(zslice == 0); + + winsys->displaytarget_unmap(winsys, lpt->dt); + } +} + + +static struct pipe_texture * +llvmpipe_texture_from_handle(struct pipe_screen *screen, + const struct pipe_texture *template, + struct winsys_handle *whandle) +{ + struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; + struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + if (!lpt) + return NULL; + + lpt->base = *template; + pipe_reference_init(&lpt->base.reference, 1); + lpt->base.screen = screen; + + lpt->dt = winsys->displaytarget_from_handle(winsys, + template, + whandle, + &lpt->stride[0]); + if (!lpt->dt) + goto fail; + + return &lpt->base; + + fail: + FREE(lpt); + return NULL; +} + + +static boolean +llvmpipe_texture_get_handle(struct pipe_screen *screen, + struct pipe_texture *pt, + struct winsys_handle *whandle) +{ + struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; + struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + + assert(lpt->dt); + if (!lpt->dt) + return FALSE; + + return winsys->displaytarget_get_handle(winsys, lpt->dt, whandle); +} + + static struct pipe_surface * llvmpipe_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, @@ -181,7 +314,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); - ps->offset = lpt->level_offset[level]; ps->usage = usage; /* Because we are llvmpipe, anything that the state tracker @@ -207,23 +339,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, ps->face = face; ps->level = level; ps->zslice = zslice; - - /* XXX shouldn't that rather be - tex_height = align(ps->height, 2); - to account for alignment done in llvmpipe_texture_layout ? - */ - if (pt->target == PIPE_TEXTURE_CUBE) { - unsigned tex_height = ps->height; - ps->offset += face * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level]; - } - else if (pt->target == PIPE_TEXTURE_3D) { - unsigned tex_height = ps->height; - ps->offset += zslice * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level]; - } - else { - assert(face == 0); - assert(zslice == 0); - } } return ps; } @@ -243,7 +358,7 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf) static struct pipe_transfer * -llvmpipe_get_tex_transfer(struct pipe_screen *screen, +llvmpipe_get_tex_transfer(struct pipe_context *pipe, struct pipe_texture *texture, unsigned face, unsigned level, unsigned zslice, enum pipe_transfer_usage usage, @@ -269,24 +384,6 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen, pt->level = level; pt->zslice = zslice; - lpt->offset = lptex->level_offset[level]; - - /* XXX shouldn't that rather be - tex_height = align(u_minify(texture->height0, level), 2) - to account for alignment done in llvmpipe_texture_layout ? - */ - if (texture->target == PIPE_TEXTURE_CUBE) { - unsigned tex_height = u_minify(texture->height0, level); - lpt->offset += face * util_format_get_nblocksy(texture->format, tex_height) * pt->stride; - } - else if (texture->target == PIPE_TEXTURE_3D) { - unsigned tex_height = u_minify(texture->height0, level); - lpt->offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * pt->stride; - } - else { - assert(face == 0); - assert(zslice == 0); - } return pt; } return NULL; @@ -294,7 +391,8 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen, static void -llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer) +llvmpipe_tex_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) { /* Effectively do the texture_update work here - if texture images * needed post-processing to put them into hardware layout, this is @@ -307,11 +405,11 @@ llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer) static void * -llvmpipe_transfer_map( struct pipe_screen *_screen, +llvmpipe_transfer_map( struct pipe_context *pipe, struct pipe_transfer *transfer ) { - struct llvmpipe_screen *screen = llvmpipe_screen(_screen); - ubyte *map, *xfer_map; + struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); + ubyte *map; struct llvmpipe_texture *lpt; enum pipe_format format; @@ -319,52 +417,45 @@ llvmpipe_transfer_map( struct pipe_screen *_screen, lpt = llvmpipe_texture(transfer->texture); format = lpt->base.format; - if (lpt->dt) { - /* display target */ - struct sw_winsys *winsys = screen->winsys; + /* + * Transfers, like other pipe operations, must happen in order, so flush the + * context if necessary. + */ + llvmpipe_flush_texture(pipe, + transfer->texture, transfer->face, transfer->level, + 0, /* flush_flags */ + !(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */ + TRUE, /* cpu_access */ + FALSE); /* do_not_flush */ - map = winsys->displaytarget_map(winsys, lpt->dt, - pipe_transfer_buffer_flags(transfer)); - if (map == NULL) - return NULL; - } - else { - /* regular texture */ - map = lpt->data; - } + map = llvmpipe_texture_map(transfer->texture, + transfer->face, transfer->level, transfer->zslice); /* May want to different things here depending on read/write nature * of the map: */ - if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) { + if (transfer->usage & PIPE_TRANSFER_WRITE) { /* Do something to notify sharing contexts of a texture change. */ screen->timestamp++; } - xfer_map = map + llvmpipe_transfer(transfer)->offset + + map += transfer->y / util_format_get_blockheight(format) * transfer->stride + transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); - /*printf("map = %p xfer map = %p\n", map, xfer_map);*/ - return xfer_map; + + return map; } static void -llvmpipe_transfer_unmap(struct pipe_screen *screen, - struct pipe_transfer *transfer) +llvmpipe_transfer_unmap(struct pipe_context *pipe, + struct pipe_transfer *transfer) { - struct llvmpipe_screen *lp_screen = llvmpipe_screen(screen); - struct llvmpipe_texture *lpt; - assert(transfer->texture); - lpt = llvmpipe_texture(transfer->texture); - if (lpt->dt) { - /* display target */ - struct sw_winsys *winsys = lp_screen->winsys; - winsys->displaytarget_unmap(winsys, lpt->dt); - } + llvmpipe_texture_unmap(transfer->texture, + transfer->face, transfer->level, transfer->zslice); } @@ -373,12 +464,18 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = llvmpipe_texture_create; screen->texture_destroy = llvmpipe_texture_destroy; + screen->texture_get_handle = llvmpipe_texture_get_handle; screen->get_tex_surface = llvmpipe_get_tex_surface; screen->tex_surface_destroy = llvmpipe_tex_surface_destroy; +} - screen->get_tex_transfer = llvmpipe_get_tex_transfer; - screen->tex_transfer_destroy = llvmpipe_tex_transfer_destroy; - screen->transfer_map = llvmpipe_transfer_map; - screen->transfer_unmap = llvmpipe_transfer_unmap; + +void +llvmpipe_init_context_texture_funcs(struct pipe_context *pipe) +{ + pipe->get_tex_transfer = llvmpipe_get_tex_transfer; + pipe->tex_transfer_destroy = llvmpipe_tex_transfer_destroy; + pipe->transfer_map = llvmpipe_transfer_map; + pipe->transfer_unmap = llvmpipe_transfer_unmap; } diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index b23f929b16..2350c26e4f 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -95,8 +95,32 @@ llvmpipe_transfer(struct pipe_transfer *pt) } +static INLINE unsigned +llvmpipe_texture_stride(struct pipe_texture *texture, + unsigned level) +{ + struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + assert(level < LP_MAX_TEXTURE_2D_LEVELS); + return lpt->stride[level]; +} + + +void * +llvmpipe_texture_map(struct pipe_texture *texture, + unsigned face, + unsigned level, + unsigned zslice); + +void +llvmpipe_texture_unmap(struct pipe_texture *texture, + unsigned face, + unsigned level, + unsigned zslice); + extern void llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen); +extern void +llvmpipe_init_context_texture_funcs(struct pipe_context *pipe); #endif /* LP_TEXTURE_H */ |