diff options
Diffstat (limited to 'src/gallium/drivers/softpipe')
-rw-r--r-- | src/gallium/drivers/softpipe/sp_context.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_context.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_flush.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_quad_depth_test.c | 259 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h | 147 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state.h | 21 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state_fs.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state_sampler.c | 89 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_tile_cache.c | 33 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_tile_cache.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_texture.c | 54 |
12 files changed, 401 insertions, 245 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index de92a0cd2c..937a573092 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -104,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++) { @@ -257,8 +257,10 @@ 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; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 9a8158e6a2..75e03c8ae6 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -70,15 +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]; unsigned num_samplers; - unsigned num_textures; + unsigned num_sampler_views; unsigned num_vertex_samplers; - unsigned num_vertex_textures; + unsigned num_vertex_sampler_views; unsigned num_vertex_buffers; unsigned dirty; /**< Mask of SP_NEW_x flags */ diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 3d76af4d8c..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]); } } diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index 4815a0d49f..17cd5b8207 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -1,6 +1,7 @@ /************************************************************************** * * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +19,7 @@ * 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 THE 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. @@ -26,7 +27,7 @@ **************************************************************************/ /** - * \brief Quad depth testing + * \brief Quad depth / stencil testing */ #include "pipe/p_defines.h" @@ -96,7 +97,9 @@ get_depth_stencil_values( struct depth_data *data, } } -/* If the shader has not been run, interpolate the depth values + +/** + * If the shader has not been run, interpolate the depth values * ourselves. */ static void @@ -115,6 +118,9 @@ interpolate_quad_depth( struct quad_header *quad ) } +/** + * Compute the depth_data::qzzzz[] values from the float fragment Z values. + */ static void convert_quad_depth( struct depth_data *data, const struct quad_header *quad ) @@ -173,6 +179,9 @@ convert_quad_depth( struct depth_data *data, +/** + * Write data->bzzzz[] values and data->stencilVals into the Z/stencil buffer. + */ static void write_depth_stencil_values( struct depth_data *data, struct quad_header *quad ) @@ -225,7 +234,6 @@ write_depth_stencil_values( struct depth_data *data, - /** Only 8-bit stencil supported */ #define STENCIL_MAX 0xff @@ -408,12 +416,11 @@ apply_stencil_op(struct depth_data *data, -/* +/** * To increase efficiency, we should probably have multiple versions * of this function that are specifically for Z16, Z32 and FP Z buffers. * Try to effectively do that with codegen... */ - static boolean depth_test_quad(struct quad_stage *qs, struct depth_data *data, @@ -523,7 +530,6 @@ depth_stencil_test_quad(struct quad_stage *qs, wrtMask = softpipe->depth_stencil->stencil[face].writemask; valMask = softpipe->depth_stencil->stencil[face].valuemask; - /* do the stencil test first */ { unsigned passMask, failMask; @@ -563,7 +569,7 @@ depth_stencil_test_quad(struct quad_stage *qs, #define ALPHATEST( FUNC, COMP ) \ - static int \ + static int \ alpha_test_quads_##FUNC( struct quad_stage *qs, \ struct quad_header *quads[], \ unsigned nr ) \ @@ -629,6 +635,7 @@ alpha_test_quads(struct quad_stage *qs, } } + static unsigned mask_count[16] = { 0, /* 0x0 */ @@ -665,6 +672,9 @@ get_depth_bits(struct quad_stage *qs) +/** + * General depth/stencil test function. Used when there's no fast-path. + */ static void depth_test_quads_fallback(struct quad_stage *qs, struct quad_header *quads[], @@ -712,7 +722,6 @@ depth_test_quads_fallback(struct quad_stage *qs, write_depth_stencil_values(&data, quads[i]); } - quads[pass++] = quads[i]; } @@ -730,169 +739,36 @@ depth_test_quads_fallback(struct quad_stage *qs, /** - * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LESS and - * Z buffer writes enabled. - * - * NOTE: there's no guarantee that the quads are sequentially side by - * side. The fragment shader may have culled some quads, etc. Sliver - * triangles may generate non-sequential quads. - */ -static void -depth_interp_z16_less_write(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) -{ - unsigned i, pass = 0; - const unsigned ix = quads[0]->input.x0; - const unsigned iy = quads[0]->input.y0; - const float fx = (float) ix; - const float fy = (float) iy; - const float dzdx = quads[0]->posCoef->dadx[2]; - const float dzdy = quads[0]->posCoef->dady[2]; - const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy; - struct softpipe_cached_tile *tile; - ushort (*depth16)[TILE_SIZE]; - ushort init_idepth[4], idepth[4], depth_step; - const float scale = 65535.0; - - /* compute scaled depth of the four pixels in first quad */ - init_idepth[0] = (ushort)((z0) * scale); - init_idepth[1] = (ushort)((z0 + dzdx) * scale); - init_idepth[2] = (ushort)((z0 + dzdy) * scale); - init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale); - - depth_step = (ushort)(dzdx * scale); - - tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy); - - for (i = 0; i < nr; i++) { - const unsigned outmask = quads[i]->inout.mask; - const int dx = quads[i]->input.x0 - ix; - unsigned mask = 0; - - /* compute depth for this quad */ - idepth[0] = init_idepth[0] + dx * depth_step; - idepth[1] = init_idepth[1] + dx * depth_step; - idepth[2] = init_idepth[2] + dx * depth_step; - idepth[3] = init_idepth[3] + dx * depth_step; - - depth16 = (ushort (*)[TILE_SIZE]) - &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE]; - - if ((outmask & 1) && idepth[0] < depth16[0][0]) { - depth16[0][0] = idepth[0]; - mask |= (1 << 0); - } - - if ((outmask & 2) && idepth[1] < depth16[0][1]) { - depth16[0][1] = idepth[1]; - mask |= (1 << 1); - } - - if ((outmask & 4) && idepth[2] < depth16[1][0]) { - depth16[1][0] = idepth[2]; - mask |= (1 << 2); - } - - if ((outmask & 8) && idepth[3] < depth16[1][1]) { - depth16[1][1] = idepth[3]; - mask |= (1 << 3); - } - - quads[i]->inout.mask = mask; - if (quads[i]->inout.mask) - quads[pass++] = quads[i]; - } - - if (pass) - qs->next->run(qs->next, quads, pass); - -} - - -/** - * Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LEQUAL and - * Z buffer writes enabled. - * - * NOTE: there's no guarantee that the quads are sequentially side by - * side. The fragment shader may have culled some quads, etc. Sliver - * triangles may generate non-sequential quads. + * Special-case Z testing for 16-bit Zbuffer and Z buffer writes enabled. */ -static void -depth_interp_z16_lequal_write(struct quad_stage *qs, - struct quad_header *quads[], - unsigned nr) -{ - unsigned i, pass = 0; - const unsigned ix = quads[0]->input.x0; - const unsigned iy = quads[0]->input.y0; - const float fx = (float) ix; - const float fy = (float) iy; - const float dzdx = quads[0]->posCoef->dadx[2]; - const float dzdy = quads[0]->posCoef->dady[2]; - const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy; - struct softpipe_cached_tile *tile; - ushort (*depth16)[TILE_SIZE]; - ushort init_idepth[4], idepth[4], depth_step; - const float scale = 65535.0; - - /* compute scaled depth of the four pixels in first quad */ - init_idepth[0] = (ushort)((z0) * scale); - init_idepth[1] = (ushort)((z0 + dzdx) * scale); - init_idepth[2] = (ushort)((z0 + dzdy) * scale); - init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale); - - depth_step = (ushort)(dzdx * scale); - tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy); - - for (i = 0; i < nr; i++) { - const unsigned outmask = quads[i]->inout.mask; - const int dx = quads[i]->input.x0 - ix; - unsigned mask = 0; - - /* compute depth for this quad */ - idepth[0] = init_idepth[0] + dx * depth_step; - idepth[1] = init_idepth[1] + dx * depth_step; - idepth[2] = init_idepth[2] + dx * depth_step; - idepth[3] = init_idepth[3] + dx * depth_step; - - depth16 = (ushort (*)[TILE_SIZE]) - &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE]; - - if ((outmask & 1) && idepth[0] <= depth16[0][0]) { - depth16[0][0] = idepth[0]; - mask |= (1 << 0); - } - - if ((outmask & 2) && idepth[1] <= depth16[0][1]) { - depth16[0][1] = idepth[1]; - mask |= (1 << 1); - } - - if ((outmask & 4) && idepth[2] <= depth16[1][0]) { - depth16[1][0] = idepth[2]; - mask |= (1 << 2); - } - - if ((outmask & 8) && idepth[3] <= depth16[1][1]) { - depth16[1][1] = idepth[3]; - mask |= (1 << 3); - } +#define NAME depth_interp_z16_less_write +#define OPERATOR < +#include "sp_quad_depth_test_tmp.h" - depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2]; +#define NAME depth_interp_z16_equal_write +#define OPERATOR == +#include "sp_quad_depth_test_tmp.h" - quads[i]->inout.mask = mask; - if (quads[i]->inout.mask) - quads[pass++] = quads[i]; - } +#define NAME depth_interp_z16_lequal_write +#define OPERATOR <= +#include "sp_quad_depth_test_tmp.h" - if (pass) - qs->next->run(qs->next, quads, pass); +#define NAME depth_interp_z16_greater_write +#define OPERATOR > +#include "sp_quad_depth_test_tmp.h" -} +#define NAME depth_interp_z16_notequal_write +#define OPERATOR != +#include "sp_quad_depth_test_tmp.h" +#define NAME depth_interp_z16_gequal_write +#define OPERATOR >= +#include "sp_quad_depth_test_tmp.h" +#define NAME depth_interp_z16_always_write +#define ALWAYS 1 +#include "sp_quad_depth_test_tmp.h" @@ -926,6 +802,10 @@ choose_depth_test(struct quad_stage *qs, boolean occlusion = qs->softpipe->active_query_count; + /* default */ + qs->run = depth_test_quads_fallback; + + /* look for special cases */ if (!alpha && !depth && !stencil) { @@ -938,57 +818,62 @@ choose_depth_test(struct quad_stage *qs, !occlusion && !stencil) { - switch (depthfunc) { - case PIPE_FUNC_LESS: - switch (qs->softpipe->framebuffer.zsbuf->format) { - case PIPE_FORMAT_Z16_UNORM: + if (qs->softpipe->framebuffer.zsbuf->format == PIPE_FORMAT_Z16_UNORM) { + switch (depthfunc) { + case PIPE_FUNC_NEVER: + qs->run = depth_test_quads_fallback; + break; + case PIPE_FUNC_LESS: qs->run = depth_interp_z16_less_write; break; - default: - qs->run = depth_test_quads_fallback; + case PIPE_FUNC_EQUAL: + qs->run = depth_interp_z16_equal_write; break; - } - break; - case PIPE_FUNC_LEQUAL: - switch (qs->softpipe->framebuffer.zsbuf->format) { - case PIPE_FORMAT_Z16_UNORM: + case PIPE_FUNC_LEQUAL: qs->run = depth_interp_z16_lequal_write; break; + case PIPE_FUNC_GREATER: + qs->run = depth_interp_z16_greater_write; + break; + case PIPE_FUNC_NOTEQUAL: + qs->run = depth_interp_z16_notequal_write; + break; + case PIPE_FUNC_GEQUAL: + qs->run = depth_interp_z16_gequal_write; + break; + case PIPE_FUNC_ALWAYS: + qs->run = depth_interp_z16_always_write; + break; default: qs->run = depth_test_quads_fallback; break; } - break; - default: - qs->run = depth_test_quads_fallback; } } - else { - qs->run = depth_test_quads_fallback; - } - + /* next quad/fragment stage */ qs->run( qs, quads, nr ); } - - -static void depth_test_begin(struct quad_stage *qs) +static void +depth_test_begin(struct quad_stage *qs) { qs->run = choose_depth_test; qs->next->begin(qs->next); } -static void depth_test_destroy(struct quad_stage *qs) +static void +depth_test_destroy(struct quad_stage *qs) { FREE( qs ); } -struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ) +struct quad_stage * +sp_quad_depth_test_stage(struct softpipe_context *softpipe) { struct quad_stage *stage = CALLOC_STRUCT(quad_stage); diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h b/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h new file mode 100644 index 0000000000..25af415c25 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test_tmp.h @@ -0,0 +1,147 @@ +/************************************************************************** + * + * 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 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 THE 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. + * + **************************************************************************/ + + +/* + * Template for generating Z test functions + * Only PIPE_FORMAT_Z16_UNORM supported at this time. + */ + + +#ifndef NAME +#error "NAME is not defined!" +#endif + +#if !defined(OPERATOR) && !defined(ALWAYS) +#error "neither OPERATOR nor ALWAYS is defined!" +#endif + + +/* + * NOTE: there's no guarantee that the quads are sequentially side by + * side. The fragment shader may have culled some quads, etc. Sliver + * triangles may generate non-sequential quads. + */ +static void +NAME(struct quad_stage *qs, + struct quad_header *quads[], + unsigned nr) +{ + unsigned i, pass = 0; + const unsigned ix = quads[0]->input.x0; + const unsigned iy = quads[0]->input.y0; + const float fx = (float) ix; + const float fy = (float) iy; + const float dzdx = quads[0]->posCoef->dadx[2]; + const float dzdy = quads[0]->posCoef->dady[2]; + const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy; + struct softpipe_cached_tile *tile; + ushort (*depth16)[TILE_SIZE]; + ushort init_idepth[4], idepth[4], depth_step; + const float scale = 65535.0; + + /* compute scaled depth of the four pixels in first quad */ + init_idepth[0] = (ushort)((z0) * scale); + init_idepth[1] = (ushort)((z0 + dzdx) * scale); + init_idepth[2] = (ushort)((z0 + dzdy) * scale); + init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale); + + depth_step = (ushort)(dzdx * scale); + + tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy); + + for (i = 0; i < nr; i++) { + const unsigned outmask = quads[i]->inout.mask; + const int dx = quads[i]->input.x0 - ix; + unsigned mask = 0; + + /* compute depth for this quad */ + idepth[0] = init_idepth[0] + dx * depth_step; + idepth[1] = init_idepth[1] + dx * depth_step; + idepth[2] = init_idepth[2] + dx * depth_step; + idepth[3] = init_idepth[3] + dx * depth_step; + + depth16 = (ushort (*)[TILE_SIZE]) + &tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE]; + +#ifdef ALWAYS + if (outmask & 1) { + depth16[0][0] = idepth[0]; + mask |= (1 << 0); + } + + if (outmask & 2) { + depth16[0][1] = idepth[1]; + mask |= (1 << 1); + } + + if (outmask & 4) { + depth16[1][0] = idepth[2]; + mask |= (1 << 2); + } + + if (outmask & 8) { + depth16[1][1] = idepth[3]; + mask |= (1 << 3); + } +#else + /* Note: OPERATOR appears here: */ + if ((outmask & 1) && (idepth[0] OPERATOR depth16[0][0])) { + depth16[0][0] = idepth[0]; + mask |= (1 << 0); + } + + if ((outmask & 2) && (idepth[1] OPERATOR depth16[0][1])) { + depth16[0][1] = idepth[1]; + mask |= (1 << 1); + } + + if ((outmask & 4) && (idepth[2] OPERATOR depth16[1][0])) { + depth16[1][0] = idepth[2]; + mask |= (1 << 2); + } + + if ((outmask & 8) && (idepth[3] OPERATOR depth16[1][1])) { + depth16[1][1] = idepth[3]; + mask |= (1 << 3); + } +#endif + + depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2]; + + quads[i]->inout.mask = mask; + if (quads[i]->inout.mask) + quads[pass++] = quads[i]; + } + + if (pass) + qs->next->run(qs->next, quads, pass); +} + + +#undef NAME +#undef OPERATOR +#undef ALWAYS diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index d62bfa3d63..757dc86128 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -173,8 +173,10 @@ softpipe_is_format_supported( struct pipe_screen *screen, break; } - if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { - if(!winsys->is_displaytarget_format_supported(winsys, format)) + if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { + if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format)) return FALSE; } diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 6b01c0f4d7..ade96b0fd4 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -177,14 +177,23 @@ void softpipe_set_polygon_stipple( struct pipe_context *, 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 * ); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 2b089c2831..d6f3229bed 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -181,9 +181,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, /* note: reference counting */ pipe_buffer_reference(&softpipe->constants[shader][index], constants); - if(shader == PIPE_SHADER_VERTEX) { - draw_set_mapped_constant_buffer(softpipe->draw, PIPE_SHADER_VERTEX, index, - data, size); + 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; 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_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index e3a5e37ce4..6594514c38 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -116,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); @@ -139,6 +140,14 @@ sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, 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++) { @@ -251,12 +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->pipe, - 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 b116397258..12ae7ba12d 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -83,6 +83,12 @@ 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 */ }; @@ -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 2aff6118f4..f4983b7c8e 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -91,6 +91,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, /* 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, @@ -139,8 +140,6 @@ softpipe_texture_create(struct pipe_screen *screen, } - - static void softpipe_texture_destroy(struct pipe_texture *pt) { @@ -161,6 +160,55 @@ softpipe_texture_destroy(struct pipe_texture *pt) } +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 = *template; + pipe_reference_init(&spt->base.reference, 1); + spt->base.screen = screen; + + 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 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); + + assert(spt->dt); + if (!spt->dt) + return FALSE; + + return winsys->displaytarget_get_handle(winsys, spt->dt, whandle); +} + + /** * Get a pipe_surface "view" into a texture. */ @@ -461,6 +509,8 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; 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; |