diff options
Diffstat (limited to 'src/gallium/drivers/softpipe')
29 files changed, 740 insertions, 751 deletions
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile index e4ac49fa85..239655d628 100644 --- a/src/gallium/drivers/softpipe/Makefile +++ b/src/gallium/drivers/softpipe/Makefile @@ -6,7 +6,9 @@ LIBNAME = softpipe C_SOURCES = \ sp_fs_exec.c \ sp_fs_sse.c \ + sp_buffer.c \ sp_clear.c \ + sp_fence.c \ sp_flush.c \ sp_query.c \ sp_context.c \ @@ -32,7 +34,6 @@ C_SOURCES = \ sp_tex_tile_cache.c \ sp_tile_cache.c \ sp_surface.c \ - sp_video_context.c \ - sp_winsys.c + sp_video_context.c include ../../Makefile.template diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index 3042e556c6..9949a53adf 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -7,9 +7,11 @@ softpipe = env.ConvenienceLibrary( source = [ 'sp_fs_exec.c', 'sp_fs_sse.c', + 'sp_buffer.c', 'sp_clear.c', 'sp_context.c', 'sp_draw_arrays.c', + 'sp_fence.c', 'sp_flush.c', 'sp_prim_vbuf.c', 'sp_setup.c', @@ -33,8 +35,7 @@ softpipe = env.ConvenienceLibrary( 'sp_tex_tile_cache.c', 'sp_texture.c', 'sp_tile_cache.c', - 'sp_video_context.c', - 'sp_winsys.c' + 'sp_video_context.c' ]) Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_buffer.c b/src/gallium/drivers/softpipe/sp_buffer.c new file mode 100644 index 0000000000..8f39025086 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_buffer.c @@ -0,0 +1,118 @@ +/************************************************************************** + * + * 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 "sp_screen.h" +#include "sp_buffer.h" + + +static void * +softpipe_buffer_map(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned flags) +{ + struct softpipe_buffer *softpipe_buf = softpipe_buffer(buf); + return softpipe_buf->data; +} + + +static void +softpipe_buffer_unmap(struct pipe_screen *screen, + struct pipe_buffer *buf) +{ +} + + +static void +softpipe_buffer_destroy(struct pipe_buffer *buf) +{ + struct softpipe_buffer *sbuf = softpipe_buffer(buf); + + if (!sbuf->userBuffer) + align_free(sbuf->data); + + FREE(sbuf); +} + + +static struct pipe_buffer * +softpipe_buffer_create(struct pipe_screen *screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct softpipe_buffer *buffer = CALLOC_STRUCT(softpipe_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 * +softpipe_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes) +{ + struct softpipe_buffer *buffer; + + buffer = CALLOC_STRUCT(softpipe_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 +softpipe_init_screen_buffer_funcs(struct pipe_screen *screen) +{ + screen->buffer_create = softpipe_buffer_create; + screen->user_buffer_create = softpipe_user_buffer_create; + screen->buffer_map = softpipe_buffer_map; + screen->buffer_unmap = softpipe_buffer_unmap; + screen->buffer_destroy = softpipe_buffer_destroy; +} diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_buffer.h index 6e3920c49b..9d8e56a176 100644 --- a/src/gallium/drivers/softpipe/sp_winsys.h +++ b/src/gallium/drivers/softpipe/sp_buffer.h @@ -1,8 +1,8 @@ /************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * + * 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 @@ -10,64 +10,46 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * 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. - * + * **************************************************************************/ -/* This is the interface that softpipe requires any window system - * hosting it to implement. This is the only include file in softpipe - * which is public. - */ +#ifndef SP_BUFFER_H +#define SP_BUFFER_H +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" -#ifndef SP_WINSYS_H -#define SP_WINSYS_H -#ifdef __cplusplus -extern "C" { -#endif +struct softpipe_buffer +{ + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; +}; -#include "pipe/p_defines.h" -struct pipe_screen; -struct pipe_winsys; -struct pipe_context; -struct pipe_texture; -struct pipe_buffer; - - - -/** - * Create a softpipe screen that uses the - * given winsys for allocating buffers. - */ -struct pipe_screen *softpipe_create_screen( struct pipe_winsys * ); - -/** - * Create a softpipe screen that uses - * regular malloc to create all its buffers. - */ -struct pipe_screen *softpipe_create_screen_malloc(void); +/** Cast wrapper */ +static INLINE struct softpipe_buffer * +softpipe_buffer( struct pipe_buffer *buf ) +{ + return (struct softpipe_buffer *)buf; +} -boolean -softpipe_get_texture_buffer( struct pipe_texture *texture, - struct pipe_buffer **buf, - unsigned *stride ); +void +softpipe_init_screen_buffer_funcs(struct pipe_screen *screen); -#ifdef __cplusplus -} -#endif -#endif /* SP_WINSYS_H */ +#endif /* SP_BUFFER_H */ diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index ddc35bcd62..937a573092 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -44,6 +44,7 @@ #include "sp_surface.h" #include "sp_tile_cache.h" #include "sp_tex_tile_cache.h" +#include "sp_texture.h" #include "sp_query.h" @@ -103,12 +104,12 @@ softpipe_destroy( struct pipe_context *pipe ) for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { sp_destroy_tex_tile_cache(softpipe->tex_cache[i]); - pipe_texture_reference(&softpipe->texture[i], NULL); + pipe_sampler_view_reference(&softpipe->sampler_views[i], NULL); } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { sp_destroy_tex_tile_cache(softpipe->vertex_tex_cache[i]); - pipe_texture_reference(&softpipe->vertex_textures[i], NULL); + pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL); } for (i = 0; i < PIPE_SHADER_TYPES; i++) { @@ -210,7 +211,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE ); softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE ); - softpipe->pipe.winsys = screen->winsys; + softpipe->pipe.winsys = NULL; softpipe->pipe.screen = screen; softpipe->pipe.destroy = softpipe_destroy; softpipe->pipe.priv = priv; @@ -245,6 +246,10 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.bind_gs_state = softpipe_bind_gs_state; softpipe->pipe.delete_gs_state = softpipe_delete_gs_state; + softpipe->pipe.create_vertex_elements_state = softpipe_create_vertex_elements_state; + softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state; + softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state; + softpipe->pipe.set_blend_color = softpipe_set_blend_color; softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref; softpipe->pipe.set_clip_state = softpipe_set_clip_state; @@ -252,12 +257,13 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; - softpipe->pipe.set_fragment_sampler_textures = softpipe_set_sampler_textures; - softpipe->pipe.set_vertex_sampler_textures = softpipe_set_vertex_sampler_textures; + softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views; + softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_sampler_views; + softpipe->pipe.create_sampler_view = softpipe_create_sampler_view; + softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy; softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; - softpipe->pipe.set_vertex_elements = softpipe_set_vertex_elements; softpipe->pipe.draw_arrays = softpipe_draw_arrays; softpipe->pipe.draw_elements = softpipe_draw_elements; @@ -272,6 +278,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced; softpipe_init_query_funcs( softpipe ); + softpipe_init_texture_funcs( &softpipe->pipe ); softpipe->pipe.render_condition = softpipe_render_condition; @@ -280,13 +287,13 @@ softpipe_create_context( struct pipe_screen *screen, * Must be before quad stage setup! */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache( screen ); - softpipe->zsbuf_cache = sp_create_tile_cache( screen ); + softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe ); + softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen ); + softpipe->tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache(screen); + softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe ); } /* setup quad rendering stages */ diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 95def72c54..75e03c8ae6 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -45,6 +45,7 @@ struct softpipe_tile_cache; struct softpipe_tex_tile_cache; struct sp_fragment_shader; struct sp_vertex_shader; +struct sp_velems_state; struct softpipe_context { @@ -59,6 +60,7 @@ struct softpipe_context { struct sp_fragment_shader *fs; struct sp_vertex_shader *vs; struct sp_geometry_shader *gs; + struct sp_velems_state *velems; /** Other rendering state */ struct pipe_blend_color blend_color; @@ -68,17 +70,15 @@ struct softpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; - struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; + struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; unsigned num_samplers; - unsigned num_textures; + unsigned num_sampler_views; unsigned num_vertex_samplers; - unsigned num_vertex_textures; - unsigned num_vertex_elements; + unsigned num_vertex_sampler_views; unsigned num_vertex_buffers; unsigned dirty; /**< Mask of SP_NEW_x flags */ @@ -93,7 +93,7 @@ struct softpipe_context { ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS]; /** Mapped constant buffers */ - void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; + const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; /** Vertex format */ struct vertex_info vertex_info; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index b2acc36bf7..7b77eb239f 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -33,90 +33,19 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "util/u_simple_screen.h" #include "util/u_inlines.h" #include "util/u_prim.h" #include "sp_context.h" #include "sp_query.h" #include "sp_state.h" +#include "sp_buffer.h" #include "draw/draw_context.h" -static void -softpipe_map_constant_buffers(struct softpipe_context *sp) -{ - struct pipe_winsys *ws = sp->pipe.winsys; - uint i; - - for (i = 0; i < PIPE_SHADER_TYPES; i++) { - uint j; - - for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { - if (sp->constants[i][j] && sp->constants[i][j]->size) { - sp->mapped_constants[i][j] = ws->buffer_map(ws, - sp->constants[i][j], - PIPE_BUFFER_USAGE_CPU_READ); - } - } - } - - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - if (sp->constants[PIPE_SHADER_VERTEX][i]) { - draw_set_mapped_constant_buffer(sp->draw, - PIPE_SHADER_VERTEX, - i, - sp->mapped_constants[PIPE_SHADER_VERTEX][i], - sp->constants[PIPE_SHADER_VERTEX][i]->size); - } - if (sp->constants[PIPE_SHADER_GEOMETRY][i]) { - draw_set_mapped_constant_buffer(sp->draw, - PIPE_SHADER_GEOMETRY, - i, - sp->mapped_constants[PIPE_SHADER_GEOMETRY][i], - sp->constants[PIPE_SHADER_GEOMETRY][i]->size); - } - } -} - - -static void -softpipe_unmap_constant_buffers(struct softpipe_context *sp) -{ - struct pipe_winsys *ws = sp->pipe.winsys; - uint i; - /* really need to flush all prims since the vert/frag shaders const buffers - * are going away now. - */ - draw_flush(sp->draw); - - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - draw_set_mapped_constant_buffer(sp->draw, - PIPE_SHADER_VERTEX, - i, - NULL, - 0); - draw_set_mapped_constant_buffer(sp->draw, - PIPE_SHADER_GEOMETRY, - i, - NULL, - 0); - } - - for (i = 0; i < PIPE_SHADER_TYPES; i++) { - uint j; - - for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) { - if (sp->constants[i][j] && sp->constants[i][j]->size) { - ws->buffer_unmap(ws, sp->constants[i][j]); - } - sp->mapped_constants[i][j] = NULL; - } - } -} /** @@ -261,25 +190,16 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe, } softpipe_map_transfers(sp); - softpipe_map_constant_buffers(sp); /* Map vertex buffers */ for (i = 0; i < sp->num_vertex_buffers; i++) { - void *buf; - - buf = pipe_buffer_map(pipe->screen, - sp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *buf = softpipe_buffer(sp->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes; - - mapped_indexes = pipe_buffer_map(pipe->screen, - indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *mapped_indexes = softpipe_buffer(indexBuffer)->data; draw_set_mapped_element_buffer_range(draw, indexSize, minIndex, @@ -300,15 +220,18 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe, /* unmap vertex/index buffers - will cause draw module to flush */ for (i = 0; i < sp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); - pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer); } if (indexBuffer) { draw_set_mapped_element_buffer(draw, 0, NULL); - pipe_buffer_unmap(pipe->screen, indexBuffer); } - /* Note: leave drawing surfaces mapped */ - softpipe_unmap_constant_buffers(sp); + /* + * TODO: Flush only when a user vertex/index buffer is present + * (or even better, modify draw module to do this + * internally when this condition is seen?) + */ + draw_flush(draw); + /* Note: leave drawing surfaces mapped */ sp->dirty_render_cache = TRUE; } diff --git a/src/gallium/drivers/softpipe/sp_fence.c b/src/gallium/drivers/softpipe/sp_fence.c new file mode 100644 index 0000000000..66c5214113 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_fence.c @@ -0,0 +1,70 @@ +/************************************************************************** + * + * Copyright 2010 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + + +#include "pipe/p_screen.h" +#include "util/u_debug.h" +#include "sp_fence.h" + + +static void +softpipe_fence_reference(struct pipe_screen *screen, + struct pipe_fence_handle **ptr, + struct pipe_fence_handle *fence) +{ + assert(!*ptr); + assert(!fence); +} + + +static int +softpipe_fence_signalled(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + assert(!fence); + return 0; +} + + +static int +softpipe_fence_finish(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + unsigned flags) +{ + assert(!fence); + return 0; +} + + +void +softpipe_init_screen_fence_funcs(struct pipe_screen *screen) +{ + screen->fence_reference = softpipe_fence_reference; + screen->fence_finish = softpipe_fence_finish; + screen->fence_signalled = softpipe_fence_signalled; +} diff --git a/src/gallium/drivers/softpipe/sp_fence.h b/src/gallium/drivers/softpipe/sp_fence.h new file mode 100644 index 0000000000..39c33243bd --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_fence.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2010 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + + +#ifndef SP_FENCE_H_ +#define SP_FENCE_H_ + + +struct pipe_screen; + + +void +softpipe_init_screen_fence_funcs(struct pipe_screen *screen); + + +#endif /* SP_FENCE_H_ */ diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index e8952bf4fb..508fe8f764 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -50,10 +50,10 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - for (i = 0; i < softpipe->num_textures; i++) { + for (i = 0; i < softpipe->num_sampler_views; i++) { sp_flush_tex_tile_cache(softpipe->tex_cache[i]); } - for (i = 0; i < softpipe->num_vertex_textures; i++) { + for (i = 0; i < softpipe->num_vertex_sampler_views; i++) { sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]); } } @@ -93,9 +93,9 @@ softpipe_flush( struct pipe_context *pipe, static unsigned frame_no = 1; static char filename[256]; util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no); - debug_dump_surface_bmp(filename, softpipe->framebuffer.cbufs[0]); + debug_dump_surface_bmp(softpipe, filename, softpipe->framebuffer.cbufs[0]); util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no); - debug_dump_surface_bmp(filename, softpipe->framebuffer.zsbuf); + debug_dump_surface_bmp(softpipe, filename, softpipe->framebuffer.zsbuf); ++frame_no; } #endif diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c index 27fa126b7c..67e2c8f8bc 100644 --- a/src/gallium/drivers/softpipe/sp_fs_exec.c +++ b/src/gallium/drivers/softpipe/sp_fs_exec.c @@ -145,8 +145,13 @@ exec_run( const struct sp_fragment_shader *base, case TGSI_SEMANTIC_COLOR: { uint cbuf = sem_index[i]; + + assert(sizeof(quad->output.color[cbuf]) == + sizeof(machine->Outputs[i])); + + /* copy float[4][4] result */ memcpy(quad->output.color[cbuf], - &machine->Outputs[i].xyzw[0].f[0], + &machine->Outputs[i], sizeof(quad->output.color[0]) ); } break; diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index acee213670..daa158df7c 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -156,8 +156,13 @@ fs_sse_run( const struct sp_fragment_shader *base, case TGSI_SEMANTIC_COLOR: { uint cbuf = sem_index[i]; + + assert(sizeof(quad->output.color[cbuf]) == + sizeof(machine->Outputs[i])); + + /* copy float[4][4] result */ memcpy(quad->output.color[cbuf], - &machine->Outputs[i].xyzw[0].f[0], + &machine->Outputs[i], sizeof(quad->output.color[0]) ); } break; diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 98c08eaffa..6749243ab4 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -264,57 +264,29 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_QUADS: - if (softpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 4) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - } - } - else { - for (i = 3; i < nr; i += 4) { - sp_setup_tri( setup_ctx, + for (i = 3; i < nr; i += 4) { + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - sp_setup_tri( setup_ctx, + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - } } break; case PIPE_PRIM_QUAD_STRIP: - if (softpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 2) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride)); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-3], stride) ); - } - } - else { - for (i = 3; i < nr; i += 2) { - sp_setup_tri( setup_ctx, + for (i = 3; i < nr; i += 2) { + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - sp_setup_tri( setup_ctx, + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - } } break; @@ -448,56 +420,28 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_QUADS: - if (softpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 4) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride) ); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-3, stride) ); - } - } - else { - for (i = 3; i < nr; i += 4) { - sp_setup_tri( setup_ctx, + for (i = 3; i < nr; i += 4) { + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-0, stride) ); - sp_setup_tri( setup_ctx, + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride) ); - } } break; case PIPE_PRIM_QUAD_STRIP: - if (softpipe->rasterizer->flatshade_first) { - for (i = 3; i < nr; i += 2) { - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride) ); - sp_setup_tri( setup_ctx, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-3, stride) ); - } - } - else { - for (i = 3; i < nr; i += 2) { - sp_setup_tri( setup_ctx, + for (i = 3; i < nr; i += 2) { + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i-0, stride) ); - sp_setup_tri( setup_ctx, + sp_setup_tri( setup_ctx, get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-3, stride), get_vert(vertex_buffer, i-0, stride) ); - } } break; diff --git a/src/gallium/drivers/softpipe/sp_public.h b/src/gallium/drivers/softpipe/sp_public.h new file mode 100644 index 0000000000..62d0903d87 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_public.h @@ -0,0 +1,10 @@ +#ifndef SP_PUBLIC_H +#define SP_PUBLIC_H + +struct pipe_screen; +struct sw_winsys; + +struct pipe_screen * +softpipe_create_screen(struct sw_winsys *winsys); + +#endif diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 17cd5b8207..4ee31969e6 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -75,7 +75,7 @@ get_depth_stencil_values( struct depth_data *data, } break; case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->input.x0 % TILE_SIZE + (j & 1); int y = quad->input.y0 % TILE_SIZE + (j >> 1); @@ -84,7 +84,7 @@ get_depth_stencil_values( struct depth_data *data, } break; case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->input.x0 % TILE_SIZE + (j & 1); int y = quad->input.y0 % TILE_SIZE + (j >> 1); @@ -153,7 +153,7 @@ convert_quad_depth( struct depth_data *data, } break; case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: { float scale = (float) ((1 << 24) - 1); @@ -163,7 +163,7 @@ convert_quad_depth( struct depth_data *data, } break; case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: { float scale = (float) ((1 << 24) - 1); @@ -206,14 +206,14 @@ write_depth_stencil_values( struct depth_data *data, tile->data.depth32[y][x] = data->bzzzz[j]; } break; - case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->input.x0 % TILE_SIZE + (j & 1); int y = quad->input.y0 % TILE_SIZE + (j >> 1); tile->data.depth32[y][x] = (data->stencilVals[j] << 24) | data->bzzzz[j]; } break; - case PIPE_FORMAT_S8Z24_UNORM: + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->input.x0 % TILE_SIZE + (j & 1); int y = quad->input.y0 % TILE_SIZE + (j >> 1); diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 6ec63fe698..be64048abf 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -27,15 +27,18 @@ #include "util/u_memory.h" -#include "util/u_simple_screen.h" -#include "util/u_simple_screen.h" +#include "util/u_format_s3tc.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" +#include "state_tracker/sw_winsys.h" + #include "sp_texture.h" -#include "sp_winsys.h" #include "sp_screen.h" #include "sp_context.h" +#include "sp_buffer.h" +#include "sp_fence.h" +#include "sp_public.h" static const char * @@ -83,11 +86,11 @@ softpipe_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return 13; /* max 4Kx4K */ + return SP_MAX_TEXTURE_2D_LEVELS; case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 9; /* max 256x256x256 */ + return SP_MAX_TEXTURE_3D_LEVELS; case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return 13; /* max 4Kx4K */ + return SP_MAX_TEXTURE_2D_LEVELS; case PIPE_CAP_TGSI_CONT_SUPPORTED: return 1; case PIPE_CAP_BLEND_EQUATION_SEPARATE: @@ -145,36 +148,50 @@ softpipe_is_format_supported( struct pipe_screen *screen, unsigned tex_usage, unsigned geom_flags ) { + struct sw_winsys *winsys = softpipe_screen(screen)->winsys; + assert(target == PIPE_TEXTURE_1D || target == PIPE_TEXTURE_2D || target == PIPE_TEXTURE_3D || target == PIPE_TEXTURE_CUBE); switch(format) { - case PIPE_FORMAT_L16_UNORM: case PIPE_FORMAT_YUYV: case PIPE_FORMAT_UYVY: + return FALSE; + case PIPE_FORMAT_DXT1_RGB: case PIPE_FORMAT_DXT1_RGBA: case PIPE_FORMAT_DXT3_RGBA: case PIPE_FORMAT_DXT5_RGBA: + return util_format_s3tc_enabled; + case PIPE_FORMAT_Z32_FLOAT: - case PIPE_FORMAT_R8G8_SNORM: - case PIPE_FORMAT_R5SG5SB6U_NORM: - case PIPE_FORMAT_R8SG8SB8UX8U_NORM: - case PIPE_FORMAT_R8G8B8A8_SNORM: case PIPE_FORMAT_NONE: return FALSE; + default: - return TRUE; + break; + } + + 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; } + + /* XXX: this is often a lie. Pull in logic from llvmpipe to fix. + */ + return TRUE; } static void softpipe_destroy_screen( struct pipe_screen *screen ) { - struct pipe_winsys *winsys = screen->winsys; + struct softpipe_screen *sp_screen = softpipe_screen(screen); + struct sw_winsys *winsys = sp_screen->winsys; if(winsys->destroy) winsys->destroy(winsys); @@ -183,21 +200,37 @@ softpipe_destroy_screen( struct pipe_screen *screen ) } +/* This is often overriden by the co-state tracker. + */ +static void +softpipe_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *surface, + void *context_private) +{ + struct softpipe_screen *screen = softpipe_screen(_screen); + struct sw_winsys *winsys = screen->winsys; + struct softpipe_texture *texture = softpipe_texture(surface->texture); + + assert(texture->dt); + if (texture->dt) + winsys->displaytarget_display(winsys, texture->dt, context_private); +} /** * Create a new pipe_screen object * Note: we're not presently subclassing pipe_screen (no softpipe_screen). */ struct pipe_screen * -softpipe_create_screen(struct pipe_winsys *winsys) +softpipe_create_screen(struct sw_winsys *winsys) { struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen); if (!screen) return NULL; - screen->base.winsys = winsys; + screen->winsys = winsys; + screen->base.winsys = NULL; screen->base.destroy = softpipe_destroy_screen; screen->base.get_name = softpipe_get_name; @@ -206,9 +239,13 @@ softpipe_create_screen(struct pipe_winsys *winsys) screen->base.get_paramf = softpipe_get_paramf; screen->base.is_format_supported = softpipe_is_format_supported; screen->base.context_create = softpipe_create_context; + screen->base.flush_frontbuffer = softpipe_flush_frontbuffer; + + util_format_s3tc_init(); softpipe_init_screen_texture_funcs(&screen->base); - u_simple_screen_init(&screen->base); + softpipe_init_screen_buffer_funcs(&screen->base); + softpipe_init_screen_fence_funcs(&screen->base); return &screen->base; } diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h index 3d4bfd3e84..f741454c9e 100644 --- a/src/gallium/drivers/softpipe/sp_screen.h +++ b/src/gallium/drivers/softpipe/sp_screen.h @@ -35,10 +35,13 @@ #include "pipe/p_defines.h" +struct sw_winsys; struct softpipe_screen { struct pipe_screen base; + struct sw_winsys *winsys; + /* Increments whenever textures are modified. Contexts can track * this. */ @@ -55,4 +58,5 @@ softpipe_screen( struct pipe_screen *pipe ) } + #endif /* SP_SCREEN_H */ diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 4370bbeaee..ade96b0fd4 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -100,6 +100,11 @@ struct sp_geometry_shader { struct draw_geometry_shader *draw_data; }; +struct sp_velems_state { + unsigned count; + struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; +}; + void * softpipe_create_blend_state(struct pipe_context *, @@ -160,28 +165,39 @@ void *softpipe_create_gs_state(struct pipe_context *, void softpipe_bind_gs_state(struct pipe_context *, void *); void softpipe_delete_gs_state(struct pipe_context *, void *); +void *softpipe_create_vertex_elements_state(struct pipe_context *, + unsigned count, + const struct pipe_vertex_element *); +void softpipe_bind_vertex_elements_state(struct pipe_context *, void *); +void softpipe_delete_vertex_elements_state(struct pipe_context *, void *); + void softpipe_set_polygon_stipple( struct pipe_context *, - const struct pipe_poly_stipple * ); + const struct pipe_poly_stipple * ); void softpipe_set_scissor_state( struct pipe_context *, const struct pipe_scissor_state * ); -void softpipe_set_sampler_textures( struct pipe_context *, - unsigned num, - struct pipe_texture ** ); +void softpipe_set_sampler_views( struct pipe_context *, + unsigned num, + struct pipe_sampler_view ** ); void -softpipe_set_vertex_sampler_textures(struct pipe_context *, - unsigned num_textures, - struct pipe_texture **); +softpipe_set_vertex_sampler_views(struct pipe_context *, + unsigned num, + struct pipe_sampler_view **); + +struct pipe_sampler_view * +softpipe_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ); + +void +softpipe_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view); void softpipe_set_viewport_state( struct pipe_context *, const struct pipe_viewport_state * ); -void softpipe_set_vertex_elements(struct pipe_context *, - unsigned count, - const struct pipe_vertex_element *); - void softpipe_set_vertex_buffers(struct pipe_context *, unsigned count, const struct pipe_vertex_buffer *); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index c88e213751..d6f3229bed 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -28,6 +28,7 @@ #include "sp_context.h" #include "sp_state.h" #include "sp_fs.h" +#include "sp_buffer.h" #include "pipe/p_defines.h" #include "util/u_memory.h" @@ -163,26 +164,32 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) FREE( state ); } - - void softpipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf) + struct pipe_buffer *constants) { struct softpipe_context *softpipe = softpipe_context(pipe); + unsigned size = constants ? constants->size : 0; + const void *data = constants ? softpipe_buffer(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); - assert(index < PIPE_MAX_CONSTANT_BUFFERS); + assert(index == 0); draw_flush(softpipe->draw); /* note: reference counting */ - pipe_buffer_reference(&softpipe->constants[shader][index], buf); + pipe_buffer_reference(&softpipe->constants[shader][index], constants); + if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) { + draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size); + } + + softpipe->mapped_constants[shader][index] = data; softpipe->dirty |= SP_NEW_CONSTANTS; } + void * softpipe_create_gs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index ceb4e338f1..d501952bba 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -121,9 +121,38 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe, } +struct pipe_sampler_view * +softpipe_create_sampler_view(struct pipe_context *pipe, + struct pipe_texture *texture, + const struct pipe_sampler_view *templ) +{ + struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + + if (view) { + *view = *templ; + view->reference.count = 1; + view->texture = NULL; + pipe_texture_reference(&view->texture, texture); + view->context = pipe; + } + + return view; +} + + void -softpipe_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) +softpipe_sampler_view_destroy(struct pipe_context *pipe, + struct pipe_sampler_view *view) +{ + pipe_texture_reference(&view->texture, NULL); + FREE(view); +} + + +void +softpipe_set_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; @@ -131,51 +160,51 @@ softpipe_set_sampler_textures(struct pipe_context *pipe, assert(num <= PIPE_MAX_SAMPLERS); /* Check for no-op */ - if (num == softpipe->num_textures && - !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *))) + if (num == softpipe->num_sampler_views && + !memcmp(softpipe->sampler_views, views, num * sizeof(struct pipe_sampler_view *))) return; draw_flush(softpipe->draw); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - struct pipe_texture *tex = i < num ? texture[i] : NULL; + struct pipe_sampler_view *view = i < num ? views[i] : NULL; - pipe_texture_reference(&softpipe->texture[i], tex); - sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex); + pipe_sampler_view_reference(&softpipe->sampler_views[i], view); + sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[i], view); } - softpipe->num_textures = num; + softpipe->num_sampler_views = num; softpipe->dirty |= SP_NEW_TEXTURE; } void -softpipe_set_vertex_sampler_textures(struct pipe_context *pipe, - unsigned num_textures, - struct pipe_texture **textures) +softpipe_set_vertex_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) { struct softpipe_context *softpipe = softpipe_context(pipe); uint i; - assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); + assert(num <= PIPE_MAX_VERTEX_SAMPLERS); /* Check for no-op */ - if (num_textures == softpipe->num_vertex_textures && - !memcmp(softpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { + if (num == softpipe->num_vertex_sampler_views && + !memcmp(softpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { return; } draw_flush(softpipe->draw); for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { - struct pipe_texture *tex = i < num_textures ? textures[i] : NULL; + struct pipe_sampler_view *view = i < num ? views[i] : NULL; - pipe_texture_reference(&softpipe->vertex_textures[i], tex); - sp_tex_tile_cache_set_texture(softpipe->vertex_tex_cache[i], tex); + pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], view); + sp_tex_tile_cache_set_sampler_view(softpipe->vertex_tex_cache[i], view); } - softpipe->num_vertex_textures = num_textures; + softpipe->num_vertex_sampler_views = num; softpipe->dirty |= SP_NEW_TEXTURE; } @@ -245,29 +274,41 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe) */ for (i = 0; i <= softpipe->vs->max_sampler; i++) { if (softpipe->vertex_samplers[i]) { + struct pipe_texture *texture = NULL; + + if (softpipe->vertex_sampler_views[i]) { + texture = softpipe->vertex_sampler_views[i]->texture; + } + softpipe->tgsi.vert_samplers_list[i] = get_sampler_varient( i, - sp_sampler(softpipe->vertex_samplers[i]), - softpipe->vertex_textures[i], + sp_sampler(softpipe->vertex_samplers[i]), + texture, TGSI_PROCESSOR_VERTEX ); sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i], - softpipe->vertex_tex_cache[i], - softpipe->vertex_textures[i] ); + softpipe->vertex_tex_cache[i], + texture ); } } for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) { if (softpipe->sampler[i]) { + struct pipe_texture *texture = NULL; + + if (softpipe->sampler_views[i]) { + texture = softpipe->sampler_views[i]->texture; + } + softpipe->tgsi.frag_samplers_list[i] = get_sampler_varient( i, sp_sampler(softpipe->sampler[i]), - softpipe->texture[i], + texture, TGSI_PROCESSOR_FRAGMENT ); sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i], softpipe->tex_cache[i], - softpipe->texture[i] ); + texture ); } } } diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index b491d92ed1..462f4d2655 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -32,27 +32,45 @@ #include "sp_context.h" #include "sp_state.h" +#include "util/u_memory.h" #include "draw/draw_context.h" +void * +softpipe_create_vertex_elements_state(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *attribs) +{ + struct sp_velems_state *velems; + assert(count <= PIPE_MAX_ATTRIBS); + velems = (struct sp_velems_state *) MALLOC(sizeof(struct sp_velems_state)); + if (velems) { + velems->count = count; + memcpy(velems->velem, attribs, sizeof(*attribs) * count); + } + return velems; +} + void -softpipe_set_vertex_elements(struct pipe_context *pipe, - unsigned count, - const struct pipe_vertex_element *attribs) +softpipe_bind_vertex_elements_state(struct pipe_context *pipe, + void *velems) { struct softpipe_context *softpipe = softpipe_context(pipe); + struct sp_velems_state *sp_velems = (struct sp_velems_state *) velems; - assert(count <= PIPE_MAX_ATTRIBS); - - memcpy(softpipe->vertex_element, attribs, - count * sizeof(struct pipe_vertex_element)); - softpipe->num_vertex_elements = count; + softpipe->velems = sp_velems; softpipe->dirty |= SP_NEW_VERTEX; - draw_set_vertex_elements(softpipe->draw, count, attribs); + if (sp_velems) + draw_set_vertex_elements(softpipe->draw, sp_velems->count, sp_velems->velem); } +void +softpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) +{ + FREE( velems ); +} void softpipe_set_vertex_buffers(struct pipe_context *pipe, diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index ef7ccf4189..fa9e19b282 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1614,7 +1614,6 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; float ssss[4], tttt[4]; - unsigned face; /* major axis @@ -1628,7 +1627,8 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz */ - /* First choose the cube face. + /* Choose the cube face and compute new s/t coords for the 2D face. + * * Use the same cube face for all four pixels in the quad. * * This isn't ideal, but if we want to use a different cube face @@ -1647,85 +1647,37 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); if (arx >= ary && arx >= arz) { - if (rx >= 0.0F) { - face = PIPE_TEX_FACE_POS_X; - } - else { - face = PIPE_TEX_FACE_NEG_X; + float sign = (rx >= 0.0F) ? 1.0F : -1.0F; + uint face = (rx >= 0.0F) ? PIPE_TEX_FACE_POS_X : PIPE_TEX_FACE_NEG_X; + for (j = 0; j < QUAD_SIZE; j++) { + const float ima = -0.5F / fabsf(s[j]); + ssss[j] = sign * p[j] * ima + 0.5F; + tttt[j] = t[j] * ima + 0.5F; + samp->faces[j] = face; } } else if (ary >= arx && ary >= arz) { - if (ry >= 0.0F) { - face = PIPE_TEX_FACE_POS_Y; - } - else { - face = PIPE_TEX_FACE_NEG_Y; + float sign = (ry >= 0.0F) ? 1.0F : -1.0F; + uint face = (ry >= 0.0F) ? PIPE_TEX_FACE_POS_Y : PIPE_TEX_FACE_NEG_Y; + for (j = 0; j < QUAD_SIZE; j++) { + const float ima = -0.5F / fabsf(t[j]); + ssss[j] = -s[j] * ima + 0.5F; + tttt[j] = sign * -p[j] * ima + 0.5F; + samp->faces[j] = face; } } else { - if (rz > 0.0F) { - face = PIPE_TEX_FACE_POS_Z; - } - else { - face = PIPE_TEX_FACE_NEG_Z; + float sign = (rz >= 0.0F) ? 1.0F : -1.0F; + uint face = (rz >= 0.0F) ? PIPE_TEX_FACE_POS_Z : PIPE_TEX_FACE_NEG_Z; + for (j = 0; j < QUAD_SIZE; j++) { + const float ima = -0.5 / fabsf(p[j]); + ssss[j] = sign * -s[j] * ima + 0.5F; + tttt[j] = t[j] * ima + 0.5F; + samp->faces[j] = face; } } } - /* Now compute the 2D _face_ texture coords from the - * 3D _cube_ texture coords. - */ - for (j = 0; j < QUAD_SIZE; j++) { - const float rx = s[j], ry = t[j], rz = p[j]; - const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); - float sc, tc, ma; - - switch (face) { - case PIPE_TEX_FACE_POS_X: - sc = -rz; - tc = -ry; - ma = arx; - break; - case PIPE_TEX_FACE_NEG_X: - sc = rz; - tc = -ry; - ma = arx; - break; - case PIPE_TEX_FACE_POS_Y: - sc = rx; - tc = rz; - ma = ary; - break; - case PIPE_TEX_FACE_NEG_Y: - sc = rx; - tc = -rz; - ma = ary; - break; - case PIPE_TEX_FACE_POS_Z: - sc = rx; - tc = -ry; - ma = arz; - break; - case PIPE_TEX_FACE_NEG_Z: - sc = -rx; - tc = -ry; - ma = arz; - break; - default: - assert(0 && "bad cube face"); - sc = 0.0F; - tc = 0.0F; - ma = 0.0F; - } - - { - const float ima = 1.0 / ma; - ssss[j] = ( sc * ima + 1.0F ) * 0.5F; - tttt[j] = ( tc * ima + 1.0F ) * 0.5F; - samp->faces[j] = face; - } - } - /* In our little pipeline, the compare stage is next. If compare * is not active, this will point somewhere deeper into the * pipeline, eg. to mip_filter or even img_filter. diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index a0b95c8884..6594514c38 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -43,14 +43,14 @@ struct softpipe_tex_tile_cache * -sp_create_tex_tile_cache( struct pipe_screen *screen ) +sp_create_tex_tile_cache( struct pipe_context *pipe ) { struct softpipe_tex_tile_cache *tc; uint pos; tc = CALLOC_STRUCT( softpipe_tex_tile_cache ); if (tc) { - tc->screen = screen; + tc->pipe = pipe; for (pos = 0; pos < NUM_ENTRIES; pos++) { tc->entries[pos].addr.bits.invalid = 1; } @@ -63,19 +63,16 @@ sp_create_tex_tile_cache( struct pipe_screen *screen ) void sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc) { - struct pipe_screen *screen; uint pos; for (pos = 0; pos < NUM_ENTRIES; pos++) { /*assert(tc->entries[pos].x < 0);*/ } if (tc->transfer) { - screen = tc->transfer->texture->screen; - screen->tex_transfer_destroy(tc->transfer); + tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer); } if (tc->tex_trans) { - screen = tc->tex_trans->texture->screen; - screen->tex_transfer_destroy(tc->tex_trans); + tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans); } FREE( tc ); @@ -88,7 +85,7 @@ void sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc) { if (tc->tex_trans && !tc->tex_trans_map) - tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans); + tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans); } @@ -96,7 +93,7 @@ void sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc) { if (tc->tex_trans_map) { - tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans); tc->tex_trans_map = NULL; } } @@ -119,12 +116,13 @@ sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc) } /** - * Specify the texture to cache. + * Specify the sampler view to cache. */ void -sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, - struct pipe_texture *texture) +sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, + struct pipe_sampler_view *view) { + struct pipe_texture *texture = view ? view->texture : NULL; uint i; assert(!tc->transfer); @@ -133,17 +131,23 @@ sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, pipe_texture_reference(&tc->texture, texture); if (tc->tex_trans) { - struct pipe_screen *screen = tc->tex_trans->texture->screen; - if (tc->tex_trans_map) { - screen->transfer_unmap(screen, tc->tex_trans); + tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans); tc->tex_trans_map = NULL; } - screen->tex_transfer_destroy(tc->tex_trans); + tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans); tc->tex_trans = NULL; } + if (view) { + tc->swizzle_r = view->swizzle_r; + tc->swizzle_g = view->swizzle_g; + tc->swizzle_b = view->swizzle_b; + tc->swizzle_a = view->swizzle_a; + tc->format = view->format; + } + /* mark as entries as invalid/empty */ /* XXX we should try to avoid this when the teximage hasn't changed */ for (i = 0; i < NUM_ENTRIES; i++) { @@ -204,7 +208,6 @@ const struct softpipe_tex_cached_tile * sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, union tex_tile_address addr ) { - struct pipe_screen *screen = tc->screen; struct softpipe_tex_cached_tile *tile; tile = tc->entries + tex_cache_pos( addr ); @@ -232,16 +235,16 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, if (tc->tex_trans) { if (tc->tex_trans_map) { - tc->screen->transfer_unmap(tc->screen, tc->tex_trans); + tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans); tc->tex_trans_map = NULL; } - screen->tex_transfer_destroy(tc->tex_trans); + tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans); tc->tex_trans = NULL; } tc->tex_trans = - screen->get_tex_transfer(screen, tc->texture, + tc->pipe->get_tex_transfer(tc->pipe, tc->texture, addr.bits.face, addr.bits.level, addr.bits.z, @@ -249,7 +252,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, u_minify(tc->texture->width0, addr.bits.level), u_minify(tc->texture->height0, addr.bits.level)); - tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans); + tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans); tc->tex_face = addr.bits.face; tc->tex_level = addr.bits.level; @@ -257,11 +260,18 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc, } /* get tile from the transfer (view into texture) */ - pipe_get_tile_rgba(tc->tex_trans, - addr.bits.x * TILE_SIZE, - addr.bits.y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + pipe_get_tile_swizzle(tc->pipe, + tc->tex_trans, + addr.bits.x * TILE_SIZE, + addr.bits.y * TILE_SIZE, + TILE_SIZE, + TILE_SIZE, + tc->swizzle_r, + tc->swizzle_g, + tc->swizzle_b, + tc->swizzle_a, + tc->format, + (float *) tile->data.color); tile->addr = addr; } diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h index ac6886a3df..12ae7ba12d 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -70,7 +70,7 @@ struct softpipe_tex_cached_tile struct softpipe_tex_tile_cache { - struct pipe_screen *screen; + struct pipe_context *pipe; struct pipe_transfer *transfer; void *transfer_map; @@ -83,12 +83,18 @@ struct softpipe_tex_tile_cache void *tex_trans_map; int tex_face, tex_level, tex_z; + unsigned swizzle_r; + unsigned swizzle_g; + unsigned swizzle_b; + unsigned swizzle_a; + unsigned format; + struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */ }; extern struct softpipe_tex_tile_cache * -sp_create_tex_tile_cache( struct pipe_screen *screen ); +sp_create_tex_tile_cache( struct pipe_context *pipe ); extern void sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc); @@ -101,8 +107,8 @@ extern void sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc); extern void -sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, - struct pipe_texture *texture); +sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, + struct pipe_sampler_view *view); void sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 32d261b5ff..f4983b7c8e 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -40,7 +40,8 @@ #include "sp_context.h" #include "sp_texture.h" #include "sp_screen.h" -#include "sp_winsys.h" + +#include "state_tracker/sw_winsys.h" /** @@ -72,11 +73,9 @@ softpipe_texture_layout(struct pipe_screen *screen, depth = u_minify(depth, 1); } - spt->buffer = screen->buffer_create(screen, 32, - PIPE_BUFFER_USAGE_PIXEL, - buffer_size); + spt->data = align_malloc(buffer_size, 16); - return spt->buffer != NULL; + return spt->data != NULL; } @@ -87,19 +86,19 @@ static boolean softpipe_displaytarget_layout(struct pipe_screen *screen, struct softpipe_texture * spt) { - unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE | - PIPE_BUFFER_USAGE_GPU_READ_WRITE); - unsigned tex_usage = spt->base.tex_usage; - - spt->buffer = screen->surface_buffer_create( screen, - spt->base.width0, - spt->base.height0, - spt->base.format, - usage, - tex_usage, - &spt->stride[0]); - - return spt->buffer != NULL; + struct sw_winsys *winsys = softpipe_screen(screen)->winsys; + + /* Round up the surface size to a multiple of the tile size? + */ + spt->dt = winsys->displaytarget_create(winsys, + spt->base.tex_usage, + spt->base.format, + spt->base.width0, + spt->base.height0, + 16, + &spt->stride[0] ); + + return spt->dt != NULL; } @@ -123,7 +122,8 @@ softpipe_texture_create(struct pipe_screen *screen, util_is_power_of_two(template->depth0)); if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY)) { + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { if (!softpipe_displaytarget_layout(screen, spt)) goto fail; } @@ -140,47 +140,72 @@ softpipe_texture_create(struct pipe_screen *screen, } -/** - * Create a new pipe_texture which wraps an existing buffer. - */ -static struct pipe_texture * -softpipe_texture_blanket(struct pipe_screen * screen, - const struct pipe_texture *base, - const unsigned *stride, - struct pipe_buffer *buffer) +static void +softpipe_texture_destroy(struct pipe_texture *pt) { - struct softpipe_texture *spt; - assert(screen); + struct softpipe_screen *screen = softpipe_screen(pt->screen); + struct softpipe_texture *spt = softpipe_texture(pt); - /* Only supports one type */ - if (base->target != PIPE_TEXTURE_2D || - base->last_level != 0 || - base->depth0 != 1) { - return NULL; + if (spt->dt) { + /* display target */ + struct sw_winsys *winsys = screen->winsys; + winsys->displaytarget_destroy(winsys, spt->dt); + } + else { + /* regular texture */ + align_free(spt->data); } - spt = CALLOC_STRUCT(softpipe_texture); + FREE(spt); +} + + +static struct pipe_texture * +softpipe_texture_from_handle(struct pipe_screen *screen, + const struct pipe_texture *template, + struct winsys_handle *whandle) +{ + struct sw_winsys *winsys = softpipe_screen(screen)->winsys; + struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); if (!spt) return NULL; - spt->base = *base; + spt->base = *template; pipe_reference_init(&spt->base.reference, 1); spt->base.screen = screen; - spt->stride[0] = stride[0]; - pipe_buffer_reference(&spt->buffer, buffer); + spt->pot = (util_is_power_of_two(template->width0) && + util_is_power_of_two(template->height0) && + util_is_power_of_two(template->depth0)); + + spt->dt = winsys->displaytarget_from_handle(winsys, + template, + whandle, + &spt->stride[0]); + if (!spt->dt) + goto fail; return &spt->base; + + fail: + FREE(spt); + return NULL; } -static void -softpipe_texture_destroy(struct pipe_texture *pt) +static boolean +softpipe_texture_get_handle(struct pipe_screen *screen, + struct pipe_texture *pt, + struct winsys_handle *whandle) { + struct sw_winsys *winsys = softpipe_screen(screen)->winsys; struct softpipe_texture *spt = softpipe_texture(pt); - pipe_buffer_reference(&spt->buffer, NULL); - FREE(spt); + assert(spt->dt); + if (!spt->dt) + return FALSE; + + return winsys->displaytarget_get_handle(winsys, spt->dt, whandle); } @@ -278,7 +303,7 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf) * \param height height of region to read/write */ static struct pipe_transfer * -softpipe_get_tex_transfer(struct pipe_screen *screen, +softpipe_get_tex_transfer(struct pipe_context *pipe, struct pipe_texture *texture, unsigned face, unsigned level, unsigned zslice, enum pipe_transfer_usage usage, @@ -332,7 +357,8 @@ softpipe_get_tex_transfer(struct pipe_screen *screen, * softpipe_get_tex_transfer(). */ static void -softpipe_tex_transfer_destroy(struct pipe_transfer *transfer) +softpipe_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 @@ -348,7 +374,7 @@ softpipe_tex_transfer_destroy(struct pipe_transfer *transfer) * Create memory mapping for given pipe_transfer object. */ static void * -softpipe_transfer_map( struct pipe_screen *screen, +softpipe_transfer_map( struct pipe_context *pipe, struct pipe_transfer *transfer ) { ubyte *map, *xfer_map; @@ -359,9 +385,20 @@ softpipe_transfer_map( struct pipe_screen *screen, spt = softpipe_texture(transfer->texture); format = transfer->texture->format; - map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer)); - if (map == NULL) - return NULL; + if (spt->dt) { + /* display target */ + struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys; + + map = winsys->displaytarget_map(winsys, spt->dt, + pipe_transfer_buffer_flags(transfer)); + if (map == NULL) + return NULL; + } + else { + map = spt->data; + if (map == NULL) + return NULL; + } /* May want to different things here depending on read/write nature * of the map: @@ -370,7 +407,7 @@ softpipe_transfer_map( struct pipe_screen *screen, /* Do something to notify sharing contexts of a texture change. * In softpipe, that would mean flushing the texture cache. */ - softpipe_screen(screen)->timestamp++; + softpipe_screen(pipe->screen)->timestamp++; } xfer_map = map + softpipe_transfer(transfer)->offset + @@ -385,7 +422,7 @@ softpipe_transfer_map( struct pipe_screen *screen, * Unmap memory mapping for given pipe_transfer object. */ static void -softpipe_transfer_unmap(struct pipe_screen *screen, +softpipe_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct softpipe_texture *spt; @@ -393,7 +430,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen, assert(transfer->texture); spt = softpipe_texture(transfer->texture); - pipe_buffer_unmap( screen, spt->buffer ); + if (spt->dt) { + /* display target */ + struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys; + winsys->displaytarget_unmap(winsys, spt->dt); + } if (transfer->usage & PIPE_TRANSFER_WRITE) { /* Mark the texture as dirty to expire the tile caches. */ @@ -455,43 +496,28 @@ softpipe_video_surface_destroy(struct pipe_video_surface *vsfc) void +softpipe_init_texture_funcs(struct pipe_context *pipe) +{ + pipe->get_tex_transfer = softpipe_get_tex_transfer; + pipe->tex_transfer_destroy = softpipe_tex_transfer_destroy; + pipe->transfer_map = softpipe_transfer_map; + pipe->transfer_unmap = softpipe_transfer_unmap; +} + +void softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; - screen->texture_blanket = softpipe_texture_blanket; screen->texture_destroy = softpipe_texture_destroy; + screen->texture_from_handle = softpipe_texture_from_handle; + screen->texture_get_handle = softpipe_texture_get_handle; screen->get_tex_surface = softpipe_get_tex_surface; screen->tex_surface_destroy = softpipe_tex_surface_destroy; - screen->get_tex_transfer = softpipe_get_tex_transfer; - screen->tex_transfer_destroy = softpipe_tex_transfer_destroy; - screen->transfer_map = softpipe_transfer_map; - screen->transfer_unmap = softpipe_transfer_unmap; - screen->video_surface_create = softpipe_video_surface_create; screen->video_surface_destroy = softpipe_video_surface_destroy; } -/** - * Return pipe_buffer handle and stride for given texture object. - * XXX used for??? - */ -boolean -softpipe_get_texture_buffer( struct pipe_texture *texture, - struct pipe_buffer **buf, - unsigned *stride ) -{ - struct softpipe_texture *tex = (struct softpipe_texture *) texture; - - if (!tex) - return FALSE; - pipe_buffer_reference(buf, tex->buffer); - - if (stride) - *stride = tex->stride[0]; - - return TRUE; -} diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index 2ef64e1e7c..c0e6ba8a86 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -33,6 +33,10 @@ #include "pipe/p_video_state.h" +#define SP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K */ +#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */ + + struct pipe_context; struct pipe_screen; struct softpipe_context; @@ -42,12 +46,19 @@ struct softpipe_texture { struct pipe_texture base; - unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; - unsigned stride[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long level_offset[SP_MAX_TEXTURE_2D_LEVELS]; + unsigned stride[SP_MAX_TEXTURE_2D_LEVELS]; - /* The data is held here: + /** + * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET + * usage. */ - struct pipe_buffer *buffer; + struct sw_displaytarget *dt; + + /** + * Malloc'ed data for regular textures, or a mapping to dt above. + */ + void *data; /* True if texture images are power-of-two in all dimensions: */ @@ -96,5 +107,8 @@ softpipe_video_surface(struct pipe_video_surface *pvs) extern void softpipe_init_screen_texture_funcs(struct pipe_screen *screen); +void +softpipe_init_texture_funcs(struct pipe_context *pipe); + #endif /* SP_TEXTURE */ diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index aedfdf1b46..7551b923fb 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -79,20 +79,20 @@ clear_clear_flag(uint *bitvec, union tile_address addr) struct softpipe_tile_cache * -sp_create_tile_cache( struct pipe_screen *screen ) +sp_create_tile_cache( struct pipe_context *pipe ) { struct softpipe_tile_cache *tc; uint pos; int maxLevels, maxTexSize; /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */ - maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); + maxLevels = pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS); maxTexSize = 1 << (maxLevels - 1); assert(MAX_WIDTH >= maxTexSize); tc = CALLOC_STRUCT( softpipe_tile_cache ); if (tc) { - tc->screen = screen; + tc->pipe = pipe; for (pos = 0; pos < NUM_ENTRIES; pos++) { tc->entries[pos].addr.bits.invalid = 1; } @@ -115,15 +115,13 @@ sp_create_tile_cache( struct pipe_screen *screen ) void sp_destroy_tile_cache(struct softpipe_tile_cache *tc) { - struct pipe_screen *screen; uint pos; for (pos = 0; pos < NUM_ENTRIES; pos++) { /*assert(tc->entries[pos].x < 0);*/ } if (tc->transfer) { - screen = tc->transfer->texture->screen; - screen->tex_transfer_destroy(tc->transfer); + tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer); } FREE( tc ); @@ -137,38 +135,36 @@ void sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, struct pipe_surface *ps) { - if (tc->transfer) { - struct pipe_screen *screen = tc->transfer->texture->screen; + struct pipe_context *pipe = tc->pipe; + if (tc->transfer) { if (ps == tc->surface) return; if (tc->transfer_map) { - screen->transfer_unmap(screen, tc->transfer); + pipe->transfer_unmap(pipe, tc->transfer); tc->transfer_map = NULL; } - screen->tex_transfer_destroy(tc->transfer); + pipe->tex_transfer_destroy(pipe, tc->transfer); tc->transfer = NULL; } tc->surface = ps; if (ps) { - struct pipe_screen *screen = ps->texture->screen; - - tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face, + tc->transfer = pipe->get_tex_transfer(pipe, ps->texture, ps->face, ps->level, ps->zslice, PIPE_TRANSFER_READ_WRITE, 0, 0, ps->width, ps->height); - tc->depth_stencil = (ps->format == PIPE_FORMAT_Z24S8_UNORM || + tc->depth_stencil = (ps->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED || ps->format == PIPE_FORMAT_Z24X8_UNORM || - ps->format == PIPE_FORMAT_S8Z24_UNORM || + ps->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM || ps->format == PIPE_FORMAT_X8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || ps->format == PIPE_FORMAT_Z32_UNORM || - ps->format == PIPE_FORMAT_S8_UNORM); + ps->format == PIPE_FORMAT_S8_USCALED); } } @@ -187,7 +183,7 @@ void sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc) { if (tc->transfer && !tc->transfer_map) - tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer); + tc->transfer_map = tc->pipe->transfer_map(tc->pipe, tc->transfer); } @@ -195,7 +191,7 @@ void sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc) { if (tc->transfer_map) { - tc->screen->transfer_unmap(tc->screen, tc->transfer); + tc->pipe->transfer_unmap(tc->pipe, tc->transfer); tc->transfer_map = NULL; } } @@ -295,7 +291,8 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc) union tile_address addr = tile_address(x, y); if (is_clear_flag_set(tc->clear_flags, addr)) { - pipe_put_tile_raw(pt, + pipe_put_tile_raw(tc->pipe, + pt, x, y, TILE_SIZE, TILE_SIZE, tc->tile.data.color32, 0/*STRIDE*/); @@ -329,14 +326,14 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc) struct softpipe_cached_tile *tile = tc->entries + pos; if (!tile->addr.bits.invalid) { if (tc->depth_stencil) { - pipe_put_tile_raw(pt, + pipe_put_tile_raw(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(pt, + pipe_put_tile_rgba(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, @@ -379,14 +376,14 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, if (tile->addr.bits.invalid == 0) { /* put dirty tile back in framebuffer */ if (tc->depth_stencil) { - pipe_put_tile_raw(pt, + pipe_put_tile_raw(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_put_tile_rgba(pt, + pipe_put_tile_rgba(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, @@ -409,14 +406,14 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc, else { /* get new tile data from transfer */ if (tc->depth_stencil) { - pipe_get_tile_raw(pt, + pipe_get_tile_raw(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { - pipe_get_tile_rgba(pt, + pipe_get_tile_rgba(tc->pipe, pt, tile->addr.bits.x * TILE_SIZE, tile->addr.bits.y * TILE_SIZE, TILE_SIZE, TILE_SIZE, diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index a12092702a..753d8c0daa 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -80,7 +80,7 @@ struct softpipe_cached_tile struct softpipe_tile_cache { - struct pipe_screen *screen; + struct pipe_context *pipe; struct pipe_surface *surface; /**< the surface we're caching */ struct pipe_transfer *transfer; void *transfer_map; @@ -98,7 +98,7 @@ struct softpipe_tile_cache extern struct softpipe_tile_cache * -sp_create_tile_cache( struct pipe_screen *screen ); +sp_create_tile_cache( struct pipe_context *pipe ); extern void sp_destroy_tile_cache(struct softpipe_tile_cache *tc); diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c deleted file mode 100644 index 0a6245ed2c..0000000000 --- a/src/gallium/drivers/softpipe/sp_winsys.c +++ /dev/null @@ -1,245 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ - -/** - * @file - * Malloc softpipe winsys. Uses malloc for all memory allocations. - * - * @author Keith Whitwell - * @author Brian Paul - * @author Jose Fonseca - */ - - -#include "util/u_simple_screen.h"/* port to just p_screen */ -#include "util/u_format.h" -#include "util/u_math.h" -#include "util/u_memory.h" -#include "util/u_inlines.h" -#include "pipe/p_format.h" -#include "pipe/p_context.h" -#include "sp_winsys.h" - - -struct st_softpipe_buffer -{ - struct pipe_buffer base; - boolean userBuffer; /** Is this a user-space buffer? */ - void *data; - void *mapped; -}; - - -/** Cast wrapper */ -static INLINE struct st_softpipe_buffer * -st_softpipe_buffer( struct pipe_buffer *buf ) -{ - return (struct st_softpipe_buffer *)buf; -} - - -static void * -st_softpipe_buffer_map(struct pipe_winsys *winsys, - struct pipe_buffer *buf, - unsigned flags) -{ - struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); - st_softpipe_buf->mapped = st_softpipe_buf->data; - return st_softpipe_buf->mapped; -} - - -static void -st_softpipe_buffer_unmap(struct pipe_winsys *winsys, - struct pipe_buffer *buf) -{ - struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); - st_softpipe_buf->mapped = NULL; -} - - -static void -st_softpipe_buffer_destroy(struct pipe_buffer *buf) -{ - struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); - - if (oldBuf->data) { - if (!oldBuf->userBuffer) - align_free(oldBuf->data); - - oldBuf->data = NULL; - } - - FREE(oldBuf); -} - - -static void -st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, - struct pipe_surface *surf, - void *context_private) -{ -} - - - -static const char * -st_softpipe_get_name(struct pipe_winsys *winsys) -{ - return "softpipe"; -} - - -static struct pipe_buffer * -st_softpipe_buffer_create(struct pipe_winsys *winsys, - unsigned alignment, - unsigned usage, - unsigned size) -{ - struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.alignment = alignment; - 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 * -st_softpipe_user_buffer_create(struct pipe_winsys *winsys, - void *ptr, - unsigned bytes) -{ - struct st_softpipe_buffer *buffer; - - buffer = CALLOC_STRUCT(st_softpipe_buffer); - if(!buffer) - return NULL; - - pipe_reference_init(&buffer->base.reference, 1); - buffer->base.size = bytes; - buffer->userBuffer = TRUE; - buffer->data = ptr; - - return &buffer->base; -} - - -static struct pipe_buffer * -st_softpipe_surface_buffer_create(struct pipe_winsys *winsys, - unsigned width, unsigned height, - enum pipe_format format, - unsigned usage, - unsigned tex_usage, - unsigned *stride) -{ - const unsigned alignment = 64; - unsigned nblocksy; - - nblocksy = util_format_get_nblocksy(format, height); - *stride = align(util_format_get_stride(format, width), alignment); - - return winsys->buffer_create(winsys, alignment, - usage, - *stride * nblocksy); -} - - -static void -st_softpipe_fence_reference(struct pipe_winsys *winsys, - struct pipe_fence_handle **ptr, - struct pipe_fence_handle *fence) -{ -} - - -static int -st_softpipe_fence_signalled(struct pipe_winsys *winsys, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static int -st_softpipe_fence_finish(struct pipe_winsys *winsys, - struct pipe_fence_handle *fence, - unsigned flag) -{ - return 0; -} - - -static void -st_softpipe_destroy(struct pipe_winsys *winsys) -{ - FREE(winsys); -} - - -struct pipe_screen * -softpipe_create_screen_malloc(void) -{ - static struct pipe_winsys *winsys; - struct pipe_screen *screen; - - winsys = CALLOC_STRUCT(pipe_winsys); - if(!winsys) - return NULL; - - winsys->destroy = st_softpipe_destroy; - - winsys->buffer_create = st_softpipe_buffer_create; - winsys->user_buffer_create = st_softpipe_user_buffer_create; - winsys->buffer_map = st_softpipe_buffer_map; - winsys->buffer_unmap = st_softpipe_buffer_unmap; - winsys->buffer_destroy = st_softpipe_buffer_destroy; - - winsys->surface_buffer_create = st_softpipe_surface_buffer_create; - - winsys->fence_reference = st_softpipe_fence_reference; - winsys->fence_signalled = st_softpipe_fence_signalled; - winsys->fence_finish = st_softpipe_fence_finish; - - winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; - winsys->get_name = st_softpipe_get_name; - - screen = softpipe_create_screen(winsys); - if(!screen) - st_softpipe_destroy(winsys); - - return screen; -} |