diff options
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
24 files changed, 406 insertions, 466 deletions
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 7bfce15c2e..a35a24f5b0 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -6,7 +6,6 @@ LIBNAME = llvmpipe DEFINES += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS C_SOURCES = \ - lp_buffer.c \ lp_clear.c \ lp_context.c \ lp_draw_arrays.c \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 07e6ccfce4..8e3267c843 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -1,12 +1,11 @@ Import('*') -env = env.Clone() - -env.Tool('llvm') -if not env.has_key('LLVM_VERSION'): - print 'warning: LLVM not found: not building llvmpipe' +if not env['llvm']: + print 'warning: LLVM disabled: not building llvmpipe' Return() +env = env.Clone() + env.Tool('udis86') env.Append(CPPPATH = ['.']) @@ -27,7 +26,6 @@ env.Depends('lp_tile_soa.c', [ llvmpipe = env.ConvenienceLibrary( target = 'llvmpipe', source = [ - 'lp_buffer.c', 'lp_clear.c', 'lp_context.c', 'lp_draw_arrays.c', diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c deleted file mode 100644 index 6e0f37393e..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_buffer.c +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * 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 VMWARE 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. - * - **************************************************************************/ - - -#include "util/u_inlines.h" -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "lp_screen.h" -#include "lp_buffer.h" - - -static void * -llvmpipe_buffer_map(struct pipe_screen *screen, - struct pipe_buffer *buf, - unsigned flags) -{ - struct llvmpipe_buffer *llvmpipe_buf = llvmpipe_buffer(buf); - return llvmpipe_buf->data; -} - - -static void -llvmpipe_buffer_unmap(struct pipe_screen *screen, - struct pipe_buffer *buf) -{ -} - - -static void -llvmpipe_buffer_destroy(struct pipe_buffer *buf) -{ - struct llvmpipe_buffer *sbuf = llvmpipe_buffer(buf); - - if (!sbuf->userBuffer) - align_free(sbuf->data); - - FREE(sbuf); -} - - -static struct pipe_buffer * -llvmpipe_buffer_create(struct pipe_screen *screen, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct llvmpipe_buffer *buffer = CALLOC_STRUCT(llvmpipe_buffer); - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.alignment = MAX2(alignment, 16); - buffer->base.usage = usage; - buffer->base.size = size; - - buffer->data = align_malloc(size, alignment); - - return &buffer->base; -} - - -/** - * Create buffer which wraps user-space data. - */ -static struct pipe_buffer * -llvmpipe_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes) -{ - struct llvmpipe_buffer *buffer; - - buffer = CALLOC_STRUCT(llvmpipe_buffer); - if(!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.screen = screen; - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - -void -llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen) -{ - screen->buffer_create = llvmpipe_buffer_create; - screen->user_buffer_create = llvmpipe_user_buffer_create; - screen->buffer_map = llvmpipe_buffer_map; - screen->buffer_unmap = llvmpipe_buffer_unmap; - screen->buffer_destroy = llvmpipe_buffer_destroy; -} diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.h b/src/gallium/drivers/llvmpipe/lp_buffer.h deleted file mode 100644 index d6b8184a0b..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_buffer.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * 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 VMWARE 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. - * - **************************************************************************/ - -#ifndef LP_BUFFER_H -#define LP_BUFFER_H - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - - -struct llvmpipe_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; -}; - - -/** Cast wrapper */ -static INLINE struct llvmpipe_buffer * -llvmpipe_buffer( struct pipe_buffer *buf ) -{ - return (struct llvmpipe_buffer *)buf; -} - - -void -llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen); - - -#endif /* LP_BUFFER_H */ diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 0786e409ae..e63720c99a 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -46,7 +46,7 @@ #include "lp_setup.h" - +#define USE_DRAW_LLVM 0 static void llvmpipe_destroy( struct pipe_context *pipe ) @@ -77,29 +77,13 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) for (i = 0; i < Elements(llvmpipe->constants); i++) { if (llvmpipe->constants[i]) { - pipe_buffer_reference(&llvmpipe->constants[i], NULL); + pipe_resource_reference(&llvmpipe->constants[i], NULL); } } align_free( llvmpipe ); } -static unsigned int -llvmpipe_is_texture_referenced( struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level) -{ - struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); - - return lp_setup_is_texture_referenced(llvmpipe->setup, texture); -} - -static unsigned int -llvmpipe_is_buffer_referenced( struct pipe_context *pipe, - struct pipe_buffer *buf) -{ - return PIPE_UNREFERENCED; -} struct pipe_context * llvmpipe_create_context( struct pipe_screen *screen, void *priv ) @@ -171,17 +155,19 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) llvmpipe->pipe.clear = llvmpipe_clear; llvmpipe->pipe.flush = llvmpipe_flush; - llvmpipe->pipe.is_texture_referenced = llvmpipe_is_texture_referenced; - llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced; llvmpipe_init_query_funcs( llvmpipe ); - llvmpipe_init_context_texture_funcs( &llvmpipe->pipe ); + llvmpipe_init_context_resource_funcs( &llvmpipe->pipe ); /* * Create drawing context and plug our rendering stage into it. */ +#if USE_DRAW_LLVM + llvmpipe->draw = draw_create_with_llvm(); +#else llvmpipe->draw = draw_create(); - if (!llvmpipe->draw) +#endif + if (!llvmpipe->draw) goto fail; /* FIXME: devise alternative to draw_texture_samplers */ diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 71f991049e..4848101ffb 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -65,7 +65,7 @@ struct llvmpipe_context { struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; - struct pipe_buffer *constants[PIPE_SHADER_TYPES]; + struct pipe_resource *constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 3dd68d5794..86525eea9e 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -35,7 +35,6 @@ #include "pipe/p_context.h" #include "util/u_prim.h" -#include "lp_buffer.h" #include "lp_context.h" #include "lp_state.h" @@ -58,7 +57,7 @@ llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, */ void llvmpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, @@ -75,13 +74,13 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, * Map vertex buffers */ for (i = 0; i < lp->num_vertex_buffers; i++) { - void *buf = llvmpipe_buffer(lp->vertex_buffer[i].buffer)->data; + void *buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer); draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes = llvmpipe_buffer(indexBuffer)->data; + void *mapped_indexes = llvmpipe_resource_data(indexBuffer); draw_set_mapped_element_buffer_range(draw, indexSize, min_index, max_index, @@ -117,7 +116,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe, void llvmpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count) { diff --git a/src/gallium/drivers/llvmpipe/lp_fence.c b/src/gallium/drivers/llvmpipe/lp_fence.c index 00dc3eab6b..75d8d2b825 100644 --- a/src/gallium/drivers/llvmpipe/lp_fence.c +++ b/src/gallium/drivers/llvmpipe/lp_fence.c @@ -33,6 +33,15 @@ #include "lp_fence.h" +/** + * Create a new fence object. + * + * The rank will be the number of bins in the scene. Whenever a rendering + * thread hits a fence command, it'll increment the fence counter. When + * the counter == the rank, the fence is finished. + * + * \param rank the expected finished value of the fence counter. + */ struct lp_fence * lp_fence_create(unsigned rank) { @@ -49,6 +58,7 @@ lp_fence_create(unsigned rank) } +/** Destroy a fence. Called when refcount hits zero. */ static void lp_fence_destroy(struct lp_fence *fence) { @@ -58,6 +68,10 @@ lp_fence_destroy(struct lp_fence *fence) } +/** + * For reference counting. + * This is a Gallium API function. + */ static void llvmpipe_fence_reference(struct pipe_screen *screen, struct pipe_fence_handle **ptr, @@ -72,6 +86,10 @@ llvmpipe_fence_reference(struct pipe_screen *screen, } +/** + * Has the fence been executed/finished? + * This is a Gallium API function. + */ static int llvmpipe_fence_signalled(struct pipe_screen *screen, struct pipe_fence_handle *fence, @@ -83,6 +101,10 @@ llvmpipe_fence_signalled(struct pipe_screen *screen, } +/** + * Wait for the fence to finish. + * This is a Gallium API function. + */ static int llvmpipe_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence_handle, @@ -100,6 +122,10 @@ llvmpipe_fence_finish(struct pipe_screen *screen, } +/** + * Called by the rendering threads to increment the fence counter. + * When the counter == the rank, the fence is finished. + */ void lp_fence_signal(struct lp_fence *fence) { diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 6aeb1a7977..a248142b1d 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -102,7 +102,7 @@ llvmpipe_flush( struct pipe_context *pipe, */ boolean llvmpipe_flush_texture(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, unsigned face, unsigned level, unsigned flush_flags, @@ -112,7 +112,7 @@ llvmpipe_flush_texture(struct pipe_context *pipe, { unsigned referenced; - referenced = pipe->is_texture_referenced(pipe, texture, face, level); + referenced = pipe->is_resource_referenced(pipe, texture, face, level); if ((referenced & PIPE_REFERENCED_FOR_WRITE) || ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h index e13f57ccec..2375d22b85 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.h +++ b/src/gallium/drivers/llvmpipe/lp_flush.h @@ -38,7 +38,7 @@ void llvmpipe_flush(struct pipe_context *pipe, unsigned flags, boolean llvmpipe_flush_texture(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, unsigned face, unsigned level, unsigned flush_flags, diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index d15a34c633..7e8a117cc8 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -166,8 +166,6 @@ lp_jit_screen_cleanup(struct llvmpipe_screen *screen) void lp_jit_screen_init(struct llvmpipe_screen *screen) { - char *error = NULL; - util_cpu_detect(); #if 0 @@ -179,17 +177,10 @@ lp_jit_screen_init(struct llvmpipe_screen *screen) lp_build_init(); - screen->module = LLVMModuleCreateWithName("llvmpipe"); - - screen->provider = LLVMCreateModuleProviderForExistingModule(screen->module); - - if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) { - _debug_printf("%s\n", error); - LLVMDisposeMessage(error); - assert(0); - } - - screen->target = LLVMGetExecutionEngineTargetData(screen->engine); + screen->module = lp_build_module; + screen->provider = lp_build_provider; + screen->engine = lp_build_engine; + screen->target = lp_build_target; screen->pass = LLVMCreateFunctionPassManager(screen->provider); LLVMAddTargetData(screen->target, screen->pass); diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index f3ac77a709..4574f41145 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -65,8 +65,7 @@ lp_rast_begin( struct lp_rasterizer *rast, rast->cbuf[i].tiles_per_row = align(cbuf->width, TILE_SIZE) / TILE_SIZE; rast->cbuf[i].blocksize = util_format_get_blocksize(cbuf->texture->format); - - rast->cbuf[i].map = llvmpipe_texture_map(cbuf->texture, + rast->cbuf[i].map = llvmpipe_resource_map(cbuf->texture, cbuf->face, cbuf->level, cbuf->zslice, @@ -76,12 +75,11 @@ lp_rast_begin( struct lp_rasterizer *rast, if (fb->zsbuf) { struct pipe_surface *zsbuf = scene->fb.zsbuf; - rast->zsbuf.stride = llvmpipe_texture_stride(zsbuf->texture, - zsbuf->level); + rast->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->level); rast->zsbuf.blocksize = util_format_get_blocksize(zsbuf->texture->format); - rast->zsbuf.map = llvmpipe_texture_map(zsbuf->texture, + rast->zsbuf.map = llvmpipe_resource_map(zsbuf->texture, zsbuf->face, zsbuf->level, zsbuf->zslice, @@ -103,7 +101,7 @@ lp_rast_end( struct lp_rasterizer *rast ) /* Unmap color buffers */ for (i = 0; i < rast->state.nr_cbufs; i++) { struct pipe_surface *cbuf = scene->fb.cbufs[i]; - llvmpipe_texture_unmap(cbuf->texture, + llvmpipe_resource_unmap(cbuf->texture, cbuf->face, cbuf->level, cbuf->zslice); @@ -113,7 +111,7 @@ lp_rast_end( struct lp_rasterizer *rast ) /* Unmap z/stencil buffer */ if (rast->zsbuf.map) { struct pipe_surface *zsbuf = scene->fb.zsbuf; - llvmpipe_texture_unmap(zsbuf->texture, + llvmpipe_resource_unmap(zsbuf->texture, zsbuf->face, zsbuf->level, zsbuf->zslice); @@ -160,9 +158,9 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task, /* get pointers to color tile(s) */ for (buf = 0; buf < rast->state.nr_cbufs; buf++) { struct pipe_surface *cbuf = rast->curr_scene->fb.cbufs[buf]; - struct llvmpipe_texture *lpt; + struct llvmpipe_resource *lpt; assert(cbuf); - lpt = llvmpipe_texture(cbuf->texture); + lpt = llvmpipe_resource(cbuf->texture); task->color_tiles[buf] = llvmpipe_get_texture_tile(lpt, cbuf->face, cbuf->level, @@ -175,7 +173,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task, { struct pipe_surface *zsbuf = rast->curr_scene->fb.zsbuf; if (zsbuf) { - struct llvmpipe_texture *lpt = llvmpipe_texture(zsbuf->texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture); if (scene->has_depth_clear) usage = LP_TEX_USAGE_WRITE_ALL; @@ -376,7 +374,7 @@ lp_rast_store_color( struct lp_rasterizer_task *task, for (buf = 0; buf < rast->state.nr_cbufs; buf++) { struct pipe_surface *cbuf = scene->fb.cbufs[buf]; const unsigned face = cbuf->face, level = cbuf->level; - struct llvmpipe_texture *lpt = llvmpipe_texture(cbuf->texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture); /* this will convert the tiled data to linear if needed */ (void) llvmpipe_get_texture_tile_linear(lpt, face,level, LP_TEX_USAGE_READ, diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c index 6d9ff4dac7..182e7cb230 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.c +++ b/src/gallium/drivers/llvmpipe/lp_scene.c @@ -181,7 +181,7 @@ lp_scene_reset(struct lp_scene *scene ) struct texture_ref *ref, *next, *ref_list = &scene->textures; for (ref = ref_list->next; ref != ref_list; ref = next) { next = next_elem(ref); - pipe_texture_reference(&ref->texture, NULL); + pipe_resource_reference(&ref->texture, NULL); FREE(ref); } make_empty_list(ref_list); @@ -251,12 +251,12 @@ lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ) */ void lp_scene_texture_reference( struct lp_scene *scene, - struct pipe_texture *texture ) + struct pipe_resource *texture ) { struct texture_ref *ref = CALLOC_STRUCT(texture_ref); if (ref) { struct texture_ref *ref_list = &scene->textures; - pipe_texture_reference(&ref->texture, texture); + pipe_resource_reference(&ref->texture, texture); insert_at_tail(ref_list, ref); } } @@ -266,8 +266,8 @@ lp_scene_texture_reference( struct lp_scene *scene, * Does this scene have a reference to the given texture? */ boolean -lp_scene_is_texture_referenced( const struct lp_scene *scene, - const struct pipe_texture *texture ) +lp_scene_is_resource_referenced( const struct lp_scene *scene, + const struct pipe_resource *texture ) { const struct texture_ref *ref_list = &scene->textures; const struct texture_ref *ref; @@ -426,7 +426,7 @@ lp_scene_unmap_buffers( struct lp_scene *scene ) for (i = 0; i < scene->fb.nr_cbufs; i++) { if (scene->cbuf_map[i]) { struct pipe_surface *cbuf = scene->fb.cbufs[i]; - llvmpipe_texture_unmap(cbuf->texture, + llvmpipe_resource_unmap(cbuf->texture, cbuf->face, cbuf->level, cbuf->zslice); @@ -436,7 +436,7 @@ lp_scene_unmap_buffers( struct lp_scene *scene ) if (scene->zsbuf_map) { struct pipe_surface *zsbuf = scene->fb.zsbuf; - llvmpipe_texture_unmap(zsbuf->texture, + llvmpipe_resource_unmap(zsbuf->texture, zsbuf->face, zsbuf->level, zsbuf->zslice); diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h index 421d685796..ac0717db6a 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene.h +++ b/src/gallium/drivers/llvmpipe/lp_scene.h @@ -99,7 +99,7 @@ struct data_block_list { /** List of texture references */ struct texture_ref { - struct pipe_texture *texture; + struct pipe_resource *texture; struct texture_ref *prev, *next; /**< linked list w/ u_simple_list.h */ }; @@ -165,10 +165,10 @@ unsigned lp_scene_data_size( const struct lp_scene *scene ); unsigned lp_scene_bin_size( const struct lp_scene *scene, unsigned x, unsigned y ); void lp_scene_texture_reference( struct lp_scene *scene, - struct pipe_texture *texture ); + struct pipe_resource *texture ); -boolean lp_scene_is_texture_referenced( const struct lp_scene *scene, - const struct pipe_texture *texture ); +boolean lp_scene_is_resource_referenced( const struct lp_scene *scene, + const struct pipe_resource *texture ); /** diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 625d4092db..a30f3c4e9f 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -28,11 +28,11 @@ #include "util/u_memory.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" #include "lp_texture.h" -#include "lp_buffer.h" #include "lp_fence.h" #include "lp_jit.h" #include "lp_screen.h" @@ -186,32 +186,37 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, case PIPE_FORMAT_DXT1_RGBA: case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: + return util_format_s3tc_enabled; + case PIPE_FORMAT_R16_FLOAT: + case PIPE_FORMAT_R16G16_FLOAT: + case PIPE_FORMAT_R16G16B16_FLOAT: + case PIPE_FORMAT_R16G16B16A16_FLOAT: return FALSE; default: break; } - if(format_desc->block.width != 1 || - format_desc->block.height != 1) - return FALSE; + if(tex_usage & PIPE_BIND_RENDER_TARGET) { + if(format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) + return FALSE; - if(format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) - return FALSE; + if(format_desc->block.width != 1 || + format_desc->block.height != 1) + return FALSE; - if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB && format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) return FALSE; } - if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + if(tex_usage & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) return FALSE; } - if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { + if(tex_usage & PIPE_BIND_DEPTH_STENCIL) { if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) return FALSE; @@ -220,17 +225,6 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, return FALSE; } - /* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */ - if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) { - if(!format_desc->is_bitmask && - format != PIPE_FORMAT_R32_FLOAT) - return FALSE; - - if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB && - format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) - return FALSE; - } - return TRUE; } @@ -244,7 +238,7 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen, { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; - struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture); + struct llvmpipe_resource *texture = llvmpipe_resource(surface->texture); assert(texture->dt); if (texture->dt) @@ -297,8 +291,9 @@ llvmpipe_create_screen(struct sw_winsys *winsys) screen->base.context_create = llvmpipe_create_context; screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer; - llvmpipe_init_screen_texture_funcs(&screen->base); - llvmpipe_init_screen_buffer_funcs(&screen->base); + util_format_s3tc_init(); + + llvmpipe_init_screen_resource_funcs(&screen->base); llvmpipe_init_screen_fence_funcs(&screen->base); lp_jit_screen_init(screen); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 8515242606..97a6b5422b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -39,7 +39,6 @@ #include "util/u_surface.h" #include "lp_scene.h" #include "lp_scene_queue.h" -#include "lp_buffer.h" #include "lp_texture.h" #include "lp_debug.h" #include "lp_fence.h" @@ -405,11 +404,11 @@ lp_setup_set_fs_functions( struct lp_setup_context *setup, void lp_setup_set_fs_constants(struct lp_setup_context *setup, - struct pipe_buffer *buffer) + struct pipe_resource *buffer) { LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer); - pipe_buffer_reference(&setup->constants.current, buffer); + pipe_resource_reference(&setup->constants.current, buffer); setup->dirty |= LP_SETUP_NEW_CONSTANTS; } @@ -507,8 +506,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, struct pipe_sampler_view *view = i < num ? views[i] : NULL; if(view) { - struct pipe_texture *tex = view->texture; - struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex); + struct pipe_resource *tex = view->texture; + struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex); struct lp_jit_texture *jit_tex; jit_tex = &setup->fs.current.jit_context.textures[i]; jit_tex->width = tex->width0; @@ -519,7 +518,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, /* We're referencing the texture's internal data, so save a * reference to it. */ - pipe_texture_reference(&setup->fs.current_tex[i], tex); + pipe_resource_reference(&setup->fs.current_tex[i], tex); if (!lp_tex->dt) { /* regular texture - setup array of mipmap level pointers */ @@ -545,7 +544,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen); struct sw_winsys *winsys = screen->winsys; jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ); jit_tex->row_stride[0] = lp_tex->stride[0]; assert(jit_tex->data[0]); } @@ -562,8 +561,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, * being rendered and the current scene being built. */ unsigned -lp_setup_is_texture_referenced( const struct lp_setup_context *setup, - const struct pipe_texture *texture ) +lp_setup_is_resource_referenced( const struct lp_setup_context *setup, + const struct pipe_resource *texture ) { unsigned i; @@ -578,7 +577,7 @@ lp_setup_is_texture_referenced( const struct lp_setup_context *setup, /* check textures referenced by the scene */ for (i = 0; i < Elements(setup->scenes); i++) { - if (lp_scene_is_texture_referenced(setup->scenes[i], texture)) { + if (lp_scene_is_resource_referenced(setup->scenes[i], texture)) { return PIPE_REFERENCED_FOR_READ; } } @@ -639,11 +638,11 @@ lp_setup_update_state( struct lp_setup_context *setup ) } if(setup->dirty & LP_SETUP_NEW_CONSTANTS) { - struct pipe_buffer *buffer = setup->constants.current; + struct pipe_resource *buffer = setup->constants.current; if(buffer) { - unsigned current_size = buffer->size; - const void *current_data = llvmpipe_buffer(buffer)->data; + unsigned current_size = buffer->width0; + const void *current_data = llvmpipe_resource_data(buffer); /* TODO: copy only the actually used constants? */ @@ -725,10 +724,10 @@ lp_setup_destroy( struct lp_setup_context *setup ) reset_context( setup ); for (i = 0; i < Elements(setup->fs.current_tex); i++) { - pipe_texture_reference(&setup->fs.current_tex[i], NULL); + pipe_resource_reference(&setup->fs.current_tex[i], NULL); } - pipe_buffer_reference(&setup->constants.current, NULL); + pipe_resource_reference(&setup->constants.current, NULL); /* free the scenes in the 'empty' queue */ while (1) { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index dbfc1bf8d4..e10d37d8d0 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -52,9 +52,8 @@ struct lp_shader_input { unsigned src_index; /* where to find values in incoming vertices */ }; -struct pipe_texture; +struct pipe_resource; struct pipe_surface; -struct pipe_buffer; struct pipe_blend_color; struct pipe_screen; struct pipe_framebuffer_state; @@ -105,7 +104,7 @@ lp_setup_set_fs_functions( struct lp_setup_context *setup, void lp_setup_set_fs_constants(struct lp_setup_context *setup, - struct pipe_buffer *buffer); + struct pipe_resource *buffer); void @@ -130,8 +129,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, struct pipe_sampler_view **views); unsigned -lp_setup_is_texture_referenced( const struct lp_setup_context *setup, - const struct pipe_texture *texture ); +lp_setup_is_resource_referenced( const struct lp_setup_context *setup, + const struct pipe_resource *texture ); void lp_setup_set_flatshade_first( struct lp_setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 3804adb6b8..4594f7597d 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -111,12 +111,12 @@ struct lp_setup_context const struct lp_rast_state *stored; /**< what's in the scene */ struct lp_rast_state current; /**< currently set state */ - struct pipe_texture *current_tex[PIPE_MAX_SAMPLERS]; + struct pipe_resource *current_tex[PIPE_MAX_SAMPLERS]; } fs; /** fragment shader constants */ struct { - struct pipe_buffer *current; + struct pipe_resource *current; unsigned stored_size; const void *stored_data; } constants; diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 74ebf90d58..d89c28a2af 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -170,7 +170,7 @@ void llvmpipe_set_clip_state( struct pipe_context *, void llvmpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, - struct pipe_buffer *buf); + struct pipe_resource *buf); void *llvmpipe_create_fs_state(struct pipe_context *, const struct pipe_shader_state *); @@ -204,7 +204,7 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *, struct pipe_sampler_view * llvmpipe_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ); void @@ -227,12 +227,12 @@ void llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count); void llvmpipe_draw_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned mode, unsigned start, unsigned count); void llvmpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, + struct pipe_resource *indexBuffer, unsigned indexSize, unsigned min_index, unsigned max_index, diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 7bbf348e0b..59ba0be2b9 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -85,7 +85,6 @@ #include "gallivm/lp_bld_swizzle.h" #include "gallivm/lp_bld_flow.h" #include "gallivm/lp_bld_debug.h" -#include "lp_buffer.h" #include "lp_context.h" #include "lp_debug.h" #include "lp_perf.h" @@ -1044,11 +1043,11 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs) void llvmpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *constants) + struct pipe_resource *constants) { struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); - unsigned size = constants ? constants->size : 0; - const void *data = constants ? llvmpipe_buffer(constants)->data : NULL; + unsigned size = constants ? constants->width0 : 0; + const void *data = constants ? llvmpipe_resource_data(constants) : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); @@ -1059,7 +1058,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe, draw_flush(llvmpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&llvmpipe->constants[shader], constants); + pipe_resource_reference(&llvmpipe->constants[shader], constants); if(shader == PIPE_SHADER_VERTEX) { draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0, @@ -1131,7 +1130,7 @@ make_variant_key(struct llvmpipe_context *lp, for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) - lp_sampler_static_state(&key->sampler[i], lp->fragment_sampler_views[i]->texture, lp->sampler[i]); + lp_sampler_static_state(&key->sampler[i], lp->fragment_sampler_views[i], lp->sampler[i]); } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index 2645441b58..3552ff50ce 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -165,7 +165,7 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe, struct pipe_sampler_view * llvmpipe_create_sampler_view(struct pipe_context *pipe, - struct pipe_texture *texture, + struct pipe_resource *texture, const struct pipe_sampler_view *templ) { struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); @@ -174,7 +174,7 @@ llvmpipe_create_sampler_view(struct pipe_context *pipe, *view = *templ; view->reference.count = 1; view->texture = NULL; - pipe_texture_reference(&view->texture, texture); + pipe_resource_reference(&view->texture, texture); view->context = pipe; } @@ -186,7 +186,7 @@ void llvmpipe_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) { - pipe_texture_reference(&view->texture, NULL); + pipe_resource_reference(&view->texture, NULL); FREE(view); } diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 0c4c64937c..381c58ecee 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -74,8 +74,8 @@ lp_surface_copy(struct pipe_context *pipe, * to a linear image. */ { - struct llvmpipe_texture *src_tex = llvmpipe_texture(src->texture); - struct llvmpipe_texture *dst_tex = llvmpipe_texture(dst->texture); + struct llvmpipe_resource *src_tex = llvmpipe_resource(src->texture); + struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst->texture); enum pipe_format format = src_tex->base.format; /* diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 8e8b81bcd8..7e4e4d5f0b 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -39,17 +39,34 @@ #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_transfer.h" #include "lp_context.h" #include "lp_flush.h" #include "lp_screen.h" #include "lp_tile_image.h" #include "lp_texture.h" +#include "lp_setup.h" #include "lp_tile_size.h" #include "state_tracker/sw_winsys.h" +static INLINE boolean +resource_is_texture(const struct pipe_resource *resource) +{ + const unsigned tex_binds = (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED | + PIPE_BIND_DEPTH_STENCIL | + PIPE_BIND_SAMPLER_VIEW); + const struct llvmpipe_resource *lpt = llvmpipe_resource_const(resource); + + return (lpt->base.bind & tex_binds) ? TRUE : FALSE; +} + + + /** * Allocate storage for llvmpipe_texture::layout array. * The number of elements is width_in_tiles * height_in_tiles. @@ -75,9 +92,9 @@ alloc_layout_array(unsigned width, unsigned height) */ static boolean llvmpipe_texture_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture *lpt) + struct llvmpipe_resource *lpt) { - struct pipe_texture *pt = &lpt->base; + struct pipe_resource *pt = &lpt->base; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; @@ -114,7 +131,7 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen, static boolean llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, - struct llvmpipe_texture *lpt) + struct llvmpipe_resource *lpt) { struct sw_winsys *winsys = screen->winsys; @@ -129,7 +146,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, lpt->layout[0][0] = alloc_layout_array(width, height); lpt->dt = winsys->displaytarget_create(winsys, - lpt->base.tex_usage, + lpt->base.bind, lpt->base.format, width, height, 16, @@ -139,13 +156,13 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, } -static struct pipe_texture * -llvmpipe_texture_create(struct pipe_screen *_screen, - const struct pipe_texture *templat) +static struct pipe_resource * +llvmpipe_resource_create(struct pipe_screen *_screen, + const struct pipe_resource *templat) { static unsigned id_counter = 0; struct llvmpipe_screen *screen = llvmpipe_screen(_screen); - struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + struct llvmpipe_resource *lpt = CALLOC_STRUCT(llvmpipe_resource); if (!lpt) return NULL; @@ -153,18 +170,35 @@ llvmpipe_texture_create(struct pipe_screen *_screen, pipe_reference_init(&lpt->base.reference, 1); lpt->base.screen = &screen->base; - if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_SCANOUT | - PIPE_TEXTURE_USAGE_SHARED)) { + assert(lpt->base.bind); + + if (lpt->base.bind & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) { + /* displayable surface */ if (!llvmpipe_displaytarget_layout(screen, lpt)) goto fail; + assert(lpt->layout[0][0][0] == LP_TEX_LAYOUT_NONE); } - else { + else if (lpt->base.bind & (PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_DEPTH_STENCIL)) { + /* texture map */ if (!llvmpipe_texture_layout(screen, lpt)) goto fail; + assert(lpt->layout[0][0][0] == LP_TEX_LAYOUT_NONE); + } + else { + /* other data (vertex buffer, const buffer, etc) */ + const enum pipe_format format = templat->format; + const uint w = templat->width0 / util_format_get_blockheight(format); + const uint h = templat->height0 / util_format_get_blockwidth(format); + const uint d = templat->depth0; + const uint bpp = util_format_get_blocksize(format); + const uint bytes = w * h * d * bpp; + lpt->data = align_malloc(bytes, 16); + if (!lpt->data) + goto fail; } - - assert(lpt->layout[0][0][0] == LP_TEX_LAYOUT_NONE); lpt->id = id_counter++; @@ -177,19 +211,21 @@ llvmpipe_texture_create(struct pipe_screen *_screen, static void -llvmpipe_texture_destroy(struct pipe_texture *pt) +llvmpipe_resource_destroy(struct pipe_screen *pscreen, + struct pipe_resource *pt) { - struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen); - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); + struct llvmpipe_resource *lpt = llvmpipe_resource(pt); if (lpt->dt) { /* display target */ struct sw_winsys *winsys = screen->winsys; winsys->displaytarget_destroy(winsys, lpt->dt); } - else { + else if (resource_is_texture(pt)) { /* regular texture */ - uint level; + const uint num_faces = pt->target == PIPE_TEXTURE_CUBE ? 6 : 1; + uint level, face; /* free linear image data */ for (level = 0; level < Elements(lpt->linear); level++) { @@ -206,6 +242,18 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) lpt->tiled[level].data = NULL; } } + + /* free layout flag arrays */ + for (level = 0; level < Elements(lpt->tiled); level++) { + for (face = 0; face < num_faces; face++) { + free(lpt->layout[face][level]); + lpt->layout[face][level] = NULL; + } + } + } + else if (!lpt->userBuffer) { + assert(lpt->data); + align_free(lpt->data); } FREE(lpt); @@ -216,16 +264,15 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) * Map a texture for read/write (rendering). Without any synchronization. */ void * -llvmpipe_texture_map(struct pipe_texture *texture, - unsigned face, - unsigned level, - unsigned zslice, - enum lp_texture_usage tex_usage, - enum lp_texture_layout layout) +llvmpipe_resource_map(struct pipe_resource *texture, + unsigned face, + unsigned level, + unsigned zslice, + enum lp_texture_usage tex_usage, + enum lp_texture_layout layout) { - struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(texture); uint8_t *map; - unsigned offset = 0; assert(face < 6); assert(level < LP_MAX_TEXTURE_LEVELS); @@ -245,10 +292,10 @@ llvmpipe_texture_map(struct pipe_texture *texture, unsigned dt_usage; if (tex_usage == LP_TEX_USAGE_READ) { - dt_usage = PIPE_BUFFER_USAGE_CPU_READ; + dt_usage = PIPE_TRANSFER_READ; } else { - dt_usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE; + dt_usage = PIPE_TRANSFER_READ_WRITE; } assert(face == 0); @@ -260,13 +307,19 @@ llvmpipe_texture_map(struct pipe_texture *texture, /* install this linear image in texture data structure */ lpt->linear[level].data = map; + + map = llvmpipe_get_texture_image(lpt, face, level, tex_usage, layout); + assert(map); + + return map; } - else { + else if (resource_is_texture(texture)) { /* regular texture */ - unsigned tex_height = u_minify(texture->height0, level); + const unsigned tex_height = u_minify(texture->height0, level); const unsigned nblocksy = util_format_get_nblocksy(texture->format, tex_height); const unsigned stride = lpt->stride[level]; + unsigned offset = 0; if (texture->target == PIPE_TEXTURE_CUBE) { /* XXX incorrect @@ -281,13 +334,15 @@ llvmpipe_texture_map(struct pipe_texture *texture, assert(zslice == 0); offset = 0; } - } - map = llvmpipe_get_texture_image(lpt, face, level, tex_usage, layout); - assert(map); - map += offset; - - return map; + map = llvmpipe_get_texture_image(lpt, face, level, tex_usage, layout); + assert(map); + map += offset; + return map; + } + else { + return lpt->data; + } } @@ -295,12 +350,12 @@ llvmpipe_texture_map(struct pipe_texture *texture, * Unmap a texture. Without any synchronization. */ void -llvmpipe_texture_unmap(struct pipe_texture *texture, +llvmpipe_resource_unmap(struct pipe_resource *texture, unsigned face, unsigned level, unsigned zslice) { - struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(texture); if (lpt->dt) { /* display target */ @@ -321,13 +376,27 @@ llvmpipe_texture_unmap(struct pipe_texture *texture, } -static struct pipe_texture * -llvmpipe_texture_from_handle(struct pipe_screen *screen, - const struct pipe_texture *template, - struct winsys_handle *whandle) +void * +llvmpipe_resource_data(struct pipe_resource *resource) +{ + struct llvmpipe_resource *lpt = llvmpipe_resource(resource); + + assert((lpt->base.bind & (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED | + PIPE_BIND_SAMPLER_VIEW)) == 0); + + return lpt->data; +} + + +static struct pipe_resource * +llvmpipe_resource_from_handle(struct pipe_screen *screen, + const struct pipe_resource *template, + struct winsys_handle *whandle) { struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; - struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); + struct llvmpipe_resource *lpt = CALLOC_STRUCT(llvmpipe_resource); if (!lpt) return NULL; @@ -351,12 +420,12 @@ llvmpipe_texture_from_handle(struct pipe_screen *screen, static boolean -llvmpipe_texture_get_handle(struct pipe_screen *screen, - struct pipe_texture *pt, +llvmpipe_resource_get_handle(struct pipe_screen *screen, + struct pipe_resource *pt, struct winsys_handle *whandle) { struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); + struct llvmpipe_resource *lpt = llvmpipe_resource(pt); assert(lpt->dt); if (!lpt->dt) @@ -368,11 +437,10 @@ llvmpipe_texture_get_handle(struct pipe_screen *screen, static struct pipe_surface * llvmpipe_get_tex_surface(struct pipe_screen *screen, - struct pipe_texture *pt, + struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, enum lp_texture_usage usage) { - struct llvmpipe_texture *lpt = llvmpipe_texture(pt); struct pipe_surface *ps; assert(level <= pt->last_level); @@ -380,32 +448,12 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen, ps = CALLOC_STRUCT(pipe_surface); if (ps) { pipe_reference_init(&ps->reference, 1); - pipe_texture_reference(&ps->texture, pt); + pipe_resource_reference(&ps->texture, pt); ps->format = pt->format; ps->width = u_minify(pt->width0, level); ps->height = u_minify(pt->height0, level); ps->usage = usage; - /* Because we are llvmpipe, anything that the state tracker - * thought was going to be done with the GPU will actually get - * done with the CPU. Let's adjust the flags to take that into - * account. - */ - if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) { - /* GPU_WRITE means "render" and that can involve reads (blending) */ - ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ; - } - - if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) - ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; - - if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_GPU_WRITE)) { - /* Mark the surface as dirty. */ - lpt->timestamp++; - llvmpipe_screen(screen)->timestamp++; - } - ps->face = face; ps->level = level; ps->zslice = zslice; @@ -422,37 +470,32 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf) * where it would happen. For llvmpipe, nothing to do. */ assert(surf->texture); - pipe_texture_reference(&surf->texture, NULL); + pipe_resource_reference(&surf->texture, NULL); FREE(surf); } static struct pipe_transfer * -llvmpipe_get_tex_transfer(struct pipe_context *pipe, - struct pipe_texture *texture, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) +llvmpipe_get_transfer(struct pipe_context *pipe, + struct pipe_resource *resource, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) { - struct llvmpipe_texture *lptex = llvmpipe_texture(texture); + struct llvmpipe_resource *lptex = llvmpipe_resource(resource); struct llvmpipe_transfer *lpt; - assert(texture); - assert(level <= texture->last_level); + assert(resource); + assert(sr.level <= resource->last_level); lpt = CALLOC_STRUCT(llvmpipe_transfer); if (lpt) { struct pipe_transfer *pt = &lpt->base; - pipe_texture_reference(&pt->texture, texture); - pt->x = x; - pt->y = y; - pt->width = align(w, TILE_SIZE); - pt->height = align(h, TILE_SIZE); - pt->stride = lptex->stride[level]; + pipe_resource_reference(&pt->resource, resource); + pt->box = *box; + pt->sr = sr; + pt->stride = lptex->stride[sr.level]; pt->usage = usage; - pt->face = face; - pt->level = level; - pt->zslice = zslice; return pt; } @@ -461,15 +504,15 @@ llvmpipe_get_tex_transfer(struct pipe_context *pipe, static void -llvmpipe_tex_transfer_destroy(struct pipe_context *pipe, +llvmpipe_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 * where it would happen. For llvmpipe, nothing to do. */ - assert (transfer->texture); - pipe_texture_reference(&transfer->texture, NULL); + assert (transfer->resource); + pipe_resource_reference(&transfer->resource, NULL); FREE(transfer); } @@ -480,12 +523,13 @@ llvmpipe_transfer_map( struct pipe_context *pipe, { struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); ubyte *map; + struct llvmpipe_resource *lpt; enum pipe_format format; enum lp_texture_usage tex_usage; const char *mode; - assert(transfer->face < 6); - assert(transfer->level < LP_MAX_TEXTURE_LEVELS); + assert(transfer->sr.face < 6); + assert(transfer->sr.level < LP_MAX_TEXTURE_LEVELS); /* printf("tex_transfer_map(%d, %d %d x %d of %d x %d, usage %d )\n", @@ -504,30 +548,35 @@ llvmpipe_transfer_map( struct pipe_context *pipe, mode = "read/write"; } - if(0){ - struct llvmpipe_texture *lpt = llvmpipe_texture(transfer->texture); + if (0) { + struct llvmpipe_resource *lpt = llvmpipe_resource(transfer->resource); printf("transfer map tex %u mode %s\n", lpt->id, mode); } - assert(transfer->texture); - format = transfer->texture->format; + assert(transfer->resource); + lpt = llvmpipe_resource(transfer->resource); + format = lpt->base.format; /* * 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, + transfer->resource, + transfer->sr.face, + transfer->sr.level, 0, /* flush_flags */ !(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */ TRUE, /* cpu_access */ FALSE); /* do_not_flush */ - /* get pointer to linear texture image */ - map = llvmpipe_texture_map(transfer->texture, transfer->face, - transfer->level, transfer->zslice, - tex_usage, LP_TEX_LAYOUT_LINEAR); + map = llvmpipe_resource_map(transfer->resource, + transfer->sr.face, + transfer->sr.level, + transfer->box.z, + tex_usage, LP_TEX_LAYOUT_LINEAR); + /* May want to do different things here depending on read/write nature * of the map: @@ -539,8 +588,8 @@ llvmpipe_transfer_map( struct pipe_context *pipe, } map += - transfer->y / util_format_get_blockheight(format) * transfer->stride + - transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + transfer->box.y / util_format_get_blockheight(format) * transfer->stride + + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); return map; } @@ -550,13 +599,57 @@ static void llvmpipe_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { - assert(transfer->texture); + assert(transfer->resource); - assert(transfer->face < 6); - assert(transfer->level < LP_MAX_TEXTURE_LEVELS); + llvmpipe_resource_unmap(transfer->resource, + transfer->sr.face, + transfer->sr.level, + transfer->box.z); +} + +static unsigned int +llvmpipe_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *presource, + unsigned face, unsigned level) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + + if (presource->target == PIPE_BUFFER) + return PIPE_UNREFERENCED; + + return lp_setup_is_resource_referenced(llvmpipe->setup, presource); +} + + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_resource * +llvmpipe_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes, + unsigned bind_flags) +{ + struct llvmpipe_resource *buffer; + + buffer = CALLOC_STRUCT(llvmpipe_resource); + if(!buffer) + return NULL; - llvmpipe_texture_unmap(transfer->texture, - transfer->face, transfer->level, transfer->zslice); + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = screen; + buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ + buffer->base.bind = bind_flags; + buffer->base._usage = PIPE_USAGE_IMMUTABLE; + buffer->base.flags = 0; + buffer->base.width0 = bytes; + buffer->base.height0 = 1; + buffer->base.depth0 = 1; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; } @@ -565,7 +658,7 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe, * for just one cube face. */ static unsigned -tex_image_face_size(const struct llvmpipe_texture *lpt, unsigned level, +tex_image_face_size(const struct llvmpipe_resource *lpt, unsigned level, enum lp_texture_layout layout) { /* for tiled layout, force a 32bpp format */ @@ -587,7 +680,7 @@ tex_image_face_size(const struct llvmpipe_texture *lpt, unsigned level, * including all cube faces. */ static unsigned -tex_image_size(const struct llvmpipe_texture *lpt, unsigned level, +tex_image_size(const struct llvmpipe_resource *lpt, unsigned level, enum lp_texture_layout layout) { const unsigned buf_size = tex_image_face_size(lpt, level, layout); @@ -659,7 +752,7 @@ layout_logic(enum lp_texture_layout cur_layout, * Return pointer to a texture image. No tiled/linear conversion is done. */ void * -llvmpipe_get_texture_image_address(struct llvmpipe_texture *lpt, +llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpt, unsigned face, unsigned level, enum lp_texture_layout layout) { @@ -690,7 +783,7 @@ llvmpipe_get_texture_image_address(struct llvmpipe_texture *lpt, * \param layout either LP_TEX_LAYOUT_LINEAR or LP_TEX_LAYOUT_TILED */ void * -llvmpipe_get_texture_image(struct llvmpipe_texture *lpt, +llvmpipe_get_texture_image(struct llvmpipe_resource *lpt, unsigned face, unsigned level, enum lp_texture_usage usage, enum lp_texture_layout layout) @@ -810,11 +903,12 @@ llvmpipe_get_texture_image(struct llvmpipe_texture *lpt, static INLINE enum lp_texture_layout -llvmpipe_get_texture_tile_layout(const struct llvmpipe_texture *lpt, +llvmpipe_get_texture_tile_layout(const struct llvmpipe_resource *lpt, unsigned face, unsigned level, unsigned x, unsigned y) { uint i; + assert(resource_is_texture(&lpt->base)); assert(x < lpt->tiles_per_row[level]); i = y * lpt->tiles_per_row[level] + x; return lpt->layout[face][level][i]; @@ -822,12 +916,13 @@ llvmpipe_get_texture_tile_layout(const struct llvmpipe_texture *lpt, static INLINE void -llvmpipe_set_texture_tile_layout(struct llvmpipe_texture *lpt, +llvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpt, unsigned face, unsigned level, unsigned x, unsigned y, enum lp_texture_layout layout) { uint i; + assert(resource_is_texture(&lpt->base)); assert(x < lpt->tiles_per_row[level]); i = y * lpt->tiles_per_row[level] + x; lpt->layout[face][level][i] = layout; @@ -841,7 +936,7 @@ llvmpipe_set_texture_tile_layout(struct llvmpipe_texture *lpt, * \return pointer to start of image/face (not the tile) */ ubyte * -llvmpipe_get_texture_tile_linear(struct llvmpipe_texture *lpt, +llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpt, unsigned face, unsigned level, enum lp_texture_usage usage, unsigned x, unsigned y) @@ -852,6 +947,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_texture *lpt, const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; boolean convert; + assert(resource_is_texture(&lpt->base)); assert(x % TILE_SIZE == 0); assert(y % TILE_SIZE == 0); @@ -891,7 +987,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_texture *lpt, * \return pointer to the tiled data at the given tile position */ ubyte * -llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, +llvmpipe_get_texture_tile(struct llvmpipe_resource *lpt, unsigned face, unsigned level, enum lp_texture_usage usage, unsigned x, unsigned y) @@ -947,12 +1043,13 @@ llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, void -llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) +llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) { - screen->texture_create = llvmpipe_texture_create; - screen->texture_destroy = llvmpipe_texture_destroy; - screen->texture_from_handle = llvmpipe_texture_from_handle; - screen->texture_get_handle = llvmpipe_texture_get_handle; + screen->resource_create = llvmpipe_resource_create; + screen->resource_destroy = llvmpipe_resource_destroy; + screen->resource_from_handle = llvmpipe_resource_from_handle; + screen->resource_get_handle = llvmpipe_resource_get_handle; + screen->user_buffer_create = llvmpipe_user_buffer_create; screen->get_tex_surface = llvmpipe_get_tex_surface; screen->tex_surface_destroy = llvmpipe_tex_surface_destroy; @@ -960,10 +1057,14 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) void -llvmpipe_init_context_texture_funcs(struct pipe_context *pipe) +llvmpipe_init_context_resource_funcs(struct pipe_context *pipe) { - pipe->get_tex_transfer = llvmpipe_get_tex_transfer; - pipe->tex_transfer_destroy = llvmpipe_tex_transfer_destroy; + pipe->get_transfer = llvmpipe_get_transfer; + pipe->transfer_destroy = llvmpipe_transfer_destroy; pipe->transfer_map = llvmpipe_transfer_map; pipe->transfer_unmap = llvmpipe_transfer_unmap; + pipe->is_resource_referenced = llvmpipe_is_resource_referenced; + + pipe->transfer_flush_region = u_default_transfer_flush_region; + pipe->transfer_inline_write = u_default_transfer_inline_write; } diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index bac4ff665d..8920209245 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -30,6 +30,7 @@ #include "pipe/p_state.h" +#include "util/u_debug.h" #define LP_MAX_TEXTURE_2D_LEVELS 12 /* 2K x 2K for now */ @@ -78,16 +79,24 @@ struct llvmpipe_texture_image }; -struct llvmpipe_texture +/** + * llvmpipe subclass of pipe_resource. A texture, drawing surface, + * vertex buffer, const buffer, etc. + * Textures are stored differently than othere types of objects such as + * vertex buffers and const buffers. + * The former are tiled and have per-tile layout flags. + * The later are simple malloc'd blocks of memory. + */ +struct llvmpipe_resource { - struct pipe_texture base; + struct pipe_resource base; /** Row stride in bytes */ unsigned stride[LP_MAX_TEXTURE_LEVELS]; unsigned tiles_per_row[LP_MAX_TEXTURE_LEVELS]; /** - * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET + * Display target, for textures with the PIPE_BIND_DISPLAY_TARGET * usage. */ struct sw_displaytarget *dt; @@ -98,9 +107,15 @@ struct llvmpipe_texture struct llvmpipe_texture_image tiled[LP_MAX_TEXTURE_LEVELS]; struct llvmpipe_texture_image linear[LP_MAX_TEXTURE_LEVELS]; + /** + * Data for non-texture resources. + */ + void *data; + /** per-tile layout info */ enum lp_texture_layout *layout[PIPE_TEX_FACE_MAX][LP_MAX_TEXTURE_LEVELS]; + boolean userBuffer; /** Is this a user-space buffer? */ unsigned timestamp; unsigned id; /**< temporary, for debugging */ @@ -116,17 +131,17 @@ struct llvmpipe_transfer /** cast wrappers */ -static INLINE struct llvmpipe_texture * -llvmpipe_texture(struct pipe_texture *pt) +static INLINE struct llvmpipe_resource * +llvmpipe_resource(struct pipe_resource *pt) { - return (struct llvmpipe_texture *) pt; + return (struct llvmpipe_resource *) pt; } -static INLINE const struct llvmpipe_texture * -llvmpipe_texture_const(const struct pipe_texture *pt) +static INLINE const struct llvmpipe_resource * +llvmpipe_resource_const(const struct pipe_resource *pt) { - return (const struct llvmpipe_texture *) pt; + return (const struct llvmpipe_resource *) pt; } @@ -137,53 +152,61 @@ llvmpipe_transfer(struct pipe_transfer *pt) } +void llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen); +void llvmpipe_init_context_resource_funcs(struct pipe_context *pipe); + static INLINE unsigned -llvmpipe_texture_stride(struct pipe_texture *texture, +llvmpipe_resource_stride(struct pipe_resource *texture, unsigned level) { - struct llvmpipe_texture *lpt = llvmpipe_texture(texture); + struct llvmpipe_resource *lpt = llvmpipe_resource(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, - enum lp_texture_usage usage, - enum lp_texture_layout layout); +llvmpipe_resource_map(struct pipe_resource *texture, + unsigned face, + unsigned level, + unsigned zslice, + enum lp_texture_usage tex_usage, + enum lp_texture_layout layout); void -llvmpipe_texture_unmap(struct pipe_texture *texture, +llvmpipe_resource_unmap(struct pipe_resource *texture, unsigned face, unsigned level, unsigned zslice); + void * -llvmpipe_get_texture_image_address(struct llvmpipe_texture *lpt, - unsigned face, unsigned level, - enum lp_texture_layout layout); +llvmpipe_resource_data(struct pipe_resource *resource); + void * -llvmpipe_get_texture_image(struct llvmpipe_texture *texture, - unsigned face, unsigned level, - enum lp_texture_usage usage, - enum lp_texture_layout layout); +llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpt, + unsigned face, unsigned level, + enum lp_texture_layout layout); + +void * +llvmpipe_get_texture_image(struct llvmpipe_resource *resource, + unsigned face, unsigned level, + enum lp_texture_usage usage, + enum lp_texture_layout layout); ubyte * -llvmpipe_get_texture_tile_linear(struct llvmpipe_texture *lpt, - unsigned face, unsigned level, - enum lp_texture_usage usage, - unsigned x, unsigned y); +llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpt, + unsigned face, unsigned level, + enum lp_texture_usage usage, + unsigned x, unsigned y); ubyte * -llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, - unsigned face, unsigned level, - enum lp_texture_usage usage, - unsigned x, unsigned y); +llvmpipe_get_texture_tile(struct llvmpipe_resource *lpt, + unsigned face, unsigned level, + enum lp_texture_usage usage, + unsigned x, unsigned y); |