diff options
Diffstat (limited to 'src/mesa/pipe/softpipe')
26 files changed, 901 insertions, 759 deletions
diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile index 59628531cc..647cc05373 100644 --- a/src/mesa/pipe/softpipe/Makefile +++ b/src/mesa/pipe/softpipe/Makefile @@ -24,7 +24,6 @@ DRIVER_SOURCES = \ sp_quad_output.c \ sp_quad_stencil.c \ sp_quad_stipple.c \ - sp_region.c \ sp_state_blend.c \ sp_state_clip.c \ sp_state_derived.c \ @@ -34,7 +33,7 @@ DRIVER_SOURCES = \ sp_state_rasterizer.c \ sp_state_surface.c \ sp_state_vertex.c \ - sp_tex_layout.c \ + sp_texture.c \ sp_tex_sample.c \ sp_tile_cache.c \ sp_surface.c diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c index 87f850b6fd..5b3857145d 100644 --- a/src/mesa/pipe/softpipe/sp_clear.c +++ b/src/mesa/pipe/softpipe/sp_clear.c @@ -47,39 +47,28 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, unsigned clearValue) { struct softpipe_context *softpipe = softpipe_context(pipe); - unsigned x, y, w, h; + uint i; +#if 0 softpipe_update_derived(softpipe); /* not needed?? */ +#endif - /* Use the X coord to trick region_fill() into filling at an offset - * from the start of the region. Perhaps pipe_region should have the - * 'offset' field, not pipe_surface??? - */ - assert(ps->offset % ps->region->cpp == 0); - x = ps->offset / ps->region->cpp; - y = 0; - w = ps->width; - h = ps->height; - - assert(w <= ps->region->pitch); - assert(h <= ps->region->height); - +#if TILE_CLEAR_OPTIMIZATION if (ps == sp_tile_cache_get_surface(softpipe->zbuf_cache)) { - float clear[4]; - clear[0] = 1.0; /* XXX hack */ - sp_tile_cache_clear(softpipe->zbuf_cache, clear); - } - else if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[0])) { - float clear[4]; - clear[0] = 0.2f; /* XXX hack */ - clear[1] = 0.2f; /* XXX hack */ - clear[2] = 0.2f; /* XXX hack */ - clear[3] = 0.2f; /* XXX hack */ - sp_tile_cache_clear(softpipe->cbuf_cache[0], clear); + sp_tile_cache_clear(softpipe->zbuf_cache, clearValue); + return; } - pipe->region_fill(pipe, ps->region, 0, x, y, w, h, clearValue); + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { + if (ps == sp_tile_cache_get_surface(softpipe->cbuf_cache[i])) { + sp_tile_cache_clear(softpipe->cbuf_cache[i], clearValue); + return; + } + } +#endif + /* non-cached surface */ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); #if 0 sp_clear_tile_cache(ps, clearValue); diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index d5e68c189d..df4e0cbd5a 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -31,16 +31,16 @@ #include "pipe/draw/draw_context.h" #include "pipe/p_defines.h" +#include "pipe/p_inlines.h" #include "pipe/p_util.h" #include "sp_clear.h" #include "sp_context.h" #include "sp_flush.h" #include "sp_prim_setup.h" -#include "sp_region.h" #include "sp_state.h" #include "sp_surface.h" #include "sp_tile_cache.h" -#include "sp_tex_layout.h" +#include "sp_texture.h" #include "sp_winsys.h" @@ -51,7 +51,8 @@ * parameter or another function. */ static boolean -softpipe_is_format_supported( struct pipe_context *pipe, uint format ) +softpipe_is_format_supported( struct pipe_context *pipe, + enum pipe_format format ) { struct softpipe_context *softpipe = softpipe_context( pipe ); /* ask winsys if the format is supported */ @@ -65,44 +66,22 @@ softpipe_is_format_supported( struct pipe_context *pipe, uint format ) void softpipe_map_surfaces(struct softpipe_context *sp) { - struct pipe_context *pipe = &sp->pipe; + struct pipe_surface *ps; unsigned i; for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - struct pipe_surface *ps = sp->framebuffer.cbufs[i]; - if (ps->region && !ps->region->map) { - pipe->region_map(pipe, ps->region); - } + ps = sp->framebuffer.cbufs[i]; + if (ps->buffer) + pipe_surface_map(ps); } - if (sp->framebuffer.zbuf) { - struct pipe_surface *ps = sp->framebuffer.zbuf; - if (ps->region && !ps->region->map) { - pipe->region_map(pipe, ps->region); - } - } - - if (sp->framebuffer.sbuf) { - struct pipe_surface *ps = sp->framebuffer.sbuf; - if (ps->region && !ps->region->map) { - pipe->region_map(pipe, ps->region); - } - } -} - - -void -softpipe_map_texture_surfaces(struct softpipe_context *sp) -{ - struct pipe_context *pipe = &sp->pipe; - uint i; + ps = sp->framebuffer.zbuf; + if (ps && ps->buffer) + pipe_surface_map(ps); - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - struct pipe_mipmap_tree *mt = sp->texture[i]; - if (mt) { - pipe->region_map(pipe, mt->region); - } - } + ps = sp->framebuffer.sbuf; + if (ps && ps->buffer) + pipe_surface_map(ps); } @@ -112,45 +91,27 @@ softpipe_map_texture_surfaces(struct softpipe_context *sp) void softpipe_unmap_surfaces(struct softpipe_context *sp) { - struct pipe_context *pipe = &sp->pipe; + struct pipe_surface *ps; uint i; - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + for (i = 0; i < sp->framebuffer.num_cbufs; i++) sp_flush_tile_cache(sp, sp->cbuf_cache[i]); sp_flush_tile_cache(sp, sp->zbuf_cache); sp_flush_tile_cache(sp, sp->sbuf_cache); for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - struct pipe_surface *ps = sp->framebuffer.cbufs[i]; - if (ps->region) - pipe->region_unmap(pipe, ps->region); - } - - if (sp->framebuffer.zbuf) { - struct pipe_surface *ps = sp->framebuffer.zbuf; - if (ps->region) - pipe->region_unmap(pipe, ps->region); - } - - if (sp->framebuffer.sbuf && sp->framebuffer.sbuf != sp->framebuffer.zbuf) { - struct pipe_surface *ps = sp->framebuffer.sbuf; - if (ps->region) - pipe->region_unmap(pipe, ps->region); + ps = sp->framebuffer.cbufs[i]; + if (ps->map) + pipe_surface_unmap(ps); } -} + ps = sp->framebuffer.zbuf; + if (ps && ps->map) + pipe_surface_unmap(ps); -void -softpipe_unmap_texture_surfaces(struct softpipe_context *sp) -{ - struct pipe_context *pipe = &sp->pipe; - uint i; - for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { - struct pipe_mipmap_tree *mt = sp->texture[i]; - if (mt) { - pipe->region_unmap(pipe, mt->region); - } - } + ps = sp->framebuffer.sbuf; + if (ps && ps->map) + pipe_surface_unmap(ps); } @@ -295,6 +256,8 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, /* queries */ softpipe->pipe.is_format_supported = softpipe_is_format_supported; + softpipe->pipe.get_name = softpipe_get_name; + softpipe->pipe.get_vendor = softpipe_get_vendor; softpipe->pipe.get_param = softpipe_get_param; softpipe->pipe.get_paramf = softpipe_get_paramf; @@ -302,21 +265,27 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.create_alpha_test_state = softpipe_create_alpha_test_state; softpipe->pipe.bind_alpha_test_state = softpipe_bind_alpha_test_state; softpipe->pipe.delete_alpha_test_state = softpipe_delete_alpha_test_state; + softpipe->pipe.create_blend_state = softpipe_create_blend_state; softpipe->pipe.bind_blend_state = softpipe_bind_blend_state; softpipe->pipe.delete_blend_state = softpipe_delete_blend_state; + softpipe->pipe.create_sampler_state = softpipe_create_sampler_state; softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state; softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state; + softpipe->pipe.create_depth_stencil_state = softpipe_create_depth_stencil_state; softpipe->pipe.bind_depth_stencil_state = softpipe_bind_depth_stencil_state; softpipe->pipe.delete_depth_stencil_state = softpipe_delete_depth_stencil_state; + softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state; softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state; softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state; + softpipe->pipe.create_fs_state = softpipe_create_fs_state; softpipe->pipe.bind_fs_state = softpipe_bind_fs_state; softpipe->pipe.delete_fs_state = softpipe_delete_fs_state; + softpipe->pipe.create_vs_state = softpipe_create_vs_state; softpipe->pipe.bind_vs_state = softpipe_bind_vs_state; softpipe->pipe.delete_vs_state = softpipe_delete_vs_state; @@ -347,11 +316,9 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, softpipe->pipe.end_query = softpipe_end_query; softpipe->pipe.wait_query = softpipe_wait_query; - softpipe->pipe.get_name = softpipe_get_name; - softpipe->pipe.get_vendor = softpipe_get_vendor; - /* textures */ - softpipe->pipe.mipmap_tree_layout = softpipe_mipmap_tree_layout; + softpipe->pipe.texture_create = softpipe_texture_create; + softpipe->pipe.texture_release = softpipe_texture_release; softpipe->pipe.get_tex_surface = softpipe_get_tex_surface; /* @@ -402,8 +369,6 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, draw_set_rasterize_stage(softpipe->draw, softpipe->setup); } - - sp_init_region_functions(softpipe); sp_init_surface_functions(softpipe); return &softpipe->pipe; diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 872766101d..d4763a98c6 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -89,7 +89,7 @@ struct softpipe_context { struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct pipe_mipmap_tree *texture[PIPE_MAX_SAMPLERS]; + struct softpipe_texture *texture[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX]; diff --git a/src/mesa/pipe/softpipe/sp_draw_arrays.c b/src/mesa/pipe/softpipe/sp_draw_arrays.c index 8a82cdfe1a..93eb68405d 100644 --- a/src/mesa/pipe/softpipe/sp_draw_arrays.c +++ b/src/mesa/pipe/softpipe/sp_draw_arrays.c @@ -112,7 +112,6 @@ softpipe_draw_elements(struct pipe_context *pipe, softpipe_update_derived( sp ); softpipe_map_surfaces(sp); - softpipe_map_texture_surfaces(sp); softpipe_map_constant_buffers(sp); /* @@ -184,7 +183,6 @@ softpipe_draw_elements(struct pipe_context *pipe, /* Note: leave drawing surfaces mapped */ - softpipe_unmap_texture_surfaces(sp); softpipe_unmap_constant_buffers(sp); return TRUE; diff --git a/src/mesa/pipe/softpipe/sp_flush.c b/src/mesa/pipe/softpipe/sp_flush.c index 1010924bf6..47b11803ce 100644 --- a/src/mesa/pipe/softpipe/sp_flush.c +++ b/src/mesa/pipe/softpipe/sp_flush.c @@ -55,7 +55,7 @@ softpipe_flush( struct pipe_context *pipe, * - flush the render cache */ - for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) if (softpipe->cbuf_cache[i]) sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); diff --git a/src/mesa/pipe/softpipe/sp_headers.h b/src/mesa/pipe/softpipe/sp_headers.h index e23742f803..b9f2b2205a 100644 --- a/src/mesa/pipe/softpipe/sp_headers.h +++ b/src/mesa/pipe/softpipe/sp_headers.h @@ -31,7 +31,7 @@ #ifndef SP_HEADERS_H #define SP_HEADERS_H -#include "../tgsi/exec/tgsi_core.h" +#include "pipe/tgsi/exec/tgsi_exec.h" #define PRIM_POINT 1 #define PRIM_LINE 2 diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c index 5a0df6de9d..e0327c4cf9 100644 --- a/src/mesa/pipe/softpipe/sp_quad.c +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -27,9 +27,8 @@ #include "sp_context.h" - #include "sp_state.h" -#include "pipe/tgsi/exec/tgsi_token.h" +#include "pipe/p_shader_tokens.h" static void sp_push_quad_first( diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c index 3318189621..93ea1196f9 100644 --- a/src/mesa/pipe/softpipe/sp_quad_depth_test.c +++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c @@ -54,7 +54,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) { struct softpipe_context *softpipe = qs->softpipe; struct pipe_surface *ps = softpipe->framebuffer.zbuf; - const uint format = ps->format; + const enum pipe_format format = ps->format; unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */ unsigned zmask = 0; @@ -74,7 +74,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) * Also, get the zbuffer values (bzzzz) from the cached tile. */ switch (format) { - case PIPE_FORMAT_U_Z16: + case PIPE_FORMAT_Z16_UNORM: { float scale = 65535.0; @@ -89,7 +89,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } } break; - case PIPE_FORMAT_U_Z32: + case PIPE_FORMAT_Z32_UNORM: { double scale = (double) (uint) ~0UL; @@ -104,7 +104,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } } break; - case PIPE_FORMAT_S8_Z24: + case PIPE_FORMAT_S8Z24_UNORM: { float scale = (float) ((1 << 24) - 1); @@ -119,7 +119,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) } } break; - case PIPE_FORMAT_Z24_S8: + case PIPE_FORMAT_Z24S8_UNORM: { float scale = (float) ((1 << 24) - 1); @@ -202,21 +202,21 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) /* put updated Z values back into cached tile */ switch (format) { - case PIPE_FORMAT_U_Z16: + case PIPE_FORMAT_Z16_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); tile->data.depth16[y][x] = (ushort) bzzzz[j]; } break; - case PIPE_FORMAT_U_Z32: + case PIPE_FORMAT_Z32_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); tile->data.depth32[y][x] = bzzzz[j]; } break; - case PIPE_FORMAT_S8_Z24: + case PIPE_FORMAT_S8Z24_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); @@ -225,7 +225,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) tile->data.depth32[y][x] = s8z24; } break; - case PIPE_FORMAT_Z24_S8: + case PIPE_FORMAT_Z24S8_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c index ed14dac18e..1aba54d12a 100644 --- a/src/mesa/pipe/softpipe/sp_quad_fs.c +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -37,6 +37,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" #include "x86/rtasm/x86sse.h" @@ -48,6 +49,7 @@ #include "sp_state.h" #include "sp_headers.h" #include "sp_quad.h" +#include "sp_texture.h" #include "sp_tex_sample.h" @@ -276,7 +278,7 @@ static void shade_begin(struct quad_stage *qs) /* set TGSI sampler state that varies */ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { qss->samplers[i].state = softpipe->sampler[i]; - qss->samplers[i].texture = softpipe->texture[i]; + qss->samplers[i].texture = &softpipe->texture[i]->base; } #ifdef MESA_LLVM diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c index 0149b20f48..b8c199204d 100644 --- a/src/mesa/pipe/softpipe/sp_quad_stencil.c +++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c @@ -234,14 +234,14 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) /* get stencil values from cached tile */ switch (ps->format) { - case PIPE_FORMAT_S8_Z24: + case PIPE_FORMAT_S8Z24_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); stencilVals[j] = tile->data.depth32[y][x] >> 24; } break; - case PIPE_FORMAT_Z24_S8: + case PIPE_FORMAT_Z24S8_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); @@ -298,7 +298,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) /* put new stencil values into cached tile */ switch (ps->format) { - case PIPE_FORMAT_S8_Z24: + case PIPE_FORMAT_S8Z24_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); @@ -307,7 +307,7 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) tile->data.depth32[y][x] = s8z24; } break; - case PIPE_FORMAT_Z24_S8: + case PIPE_FORMAT_Z24S8_UNORM: for (j = 0; j < QUAD_SIZE; j++) { int x = quad->x0 % TILE_SIZE + (j & 1); int y = quad->y0 % TILE_SIZE + (j >> 1); diff --git a/src/mesa/pipe/softpipe/sp_region.c b/src/mesa/pipe/softpipe/sp_region.c deleted file mode 100644 index fef63ef2f6..0000000000 --- a/src/mesa/pipe/softpipe/sp_region.c +++ /dev/null @@ -1,265 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Provide additional functionality on top of bufmgr buffers: - * - 2d semantics and blit operations (XXX: remove/simplify blits??) - * - refcounting of buffers for multiple images in a buffer. - * - refcounting of buffer mappings. - */ - -#include "sp_context.h" -#include "sp_region.h" -#include "pipe/p_util.h" -#include "pipe/p_winsys.h" -#include "pipe/p_defines.h" - - - -static ubyte * -sp_region_map(struct pipe_context *pipe, struct pipe_region *region) -{ - struct softpipe_context *sp = softpipe_context( pipe ); - - if (!region->map_refcount++) { - region->map = sp->pipe.winsys->buffer_map( sp->pipe.winsys, - region->buffer, - PIPE_BUFFER_FLAG_WRITE | - PIPE_BUFFER_FLAG_READ); - } - - return region->map; -} - -static void -sp_region_unmap(struct pipe_context *pipe, struct pipe_region *region) -{ - struct softpipe_context *sp = softpipe_context( pipe ); - - if (region->map_refcount > 0) { - assert(region->map); - if (!--region->map_refcount) { - sp->pipe.winsys->buffer_unmap( sp->pipe.winsys, - region->buffer ); - region->map = NULL; - } - } -} - - - -/** - * Copy 2D rect from one place to another. - * Position and sizes are in pixels. - */ -static void -copy_rect(ubyte * dst, - unsigned cpp, - unsigned dst_pitch, - unsigned dst_x, - unsigned dst_y, - unsigned width, - unsigned height, - const ubyte * src, - unsigned src_pitch, - unsigned src_x, - unsigned src_y) -{ - unsigned i; - - dst_pitch *= cpp; - src_pitch *= cpp; - dst += dst_x * cpp; - src += src_x * cpp; - dst += dst_y * dst_pitch; - src += src_y * src_pitch; - width *= cpp; - - if (width == dst_pitch && width == src_pitch) - memcpy(dst, src, height * width); - else { - for (i = 0; i < height; i++) { - memcpy(dst, src, width); - dst += dst_pitch; - src += src_pitch; - } - } -} - - -/* Upload data to a rectangular sub-region. Lots of choices how to do this: - * - * - memcpy by span to current destination - * - upload data as new buffer and blit - * - * Currently always memcpy. - */ -static void -sp_region_data(struct pipe_context *pipe, - struct pipe_region *dst, - unsigned dst_offset, - unsigned dstx, unsigned dsty, - const void *src, unsigned src_pitch, - unsigned srcx, unsigned srcy, unsigned width, unsigned height) -{ - copy_rect(pipe->region_map(pipe, dst) + dst_offset, - dst->cpp, - dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - pipe->region_unmap(pipe, dst); -} - -/* Assumes all values are within bounds -- no checking at this level - - * do it higher up if required. - */ -static void -sp_region_copy(struct pipe_context *pipe, - struct pipe_region *dst, - unsigned dst_offset, - unsigned dstx, unsigned dsty, - struct pipe_region *src, - unsigned src_offset, - unsigned srcx, unsigned srcy, unsigned width, unsigned height) -{ - ubyte *src_map, *dst_map; - assert( dst->cpp == src->cpp ); - - dst_map = pipe->region_map(pipe, dst); - src_map = pipe->region_map(pipe, src); - copy_rect(dst_map + dst_offset, - dst->cpp, - dst->pitch, - dstx, dsty, - width, height, - src_map + src_offset, - src->pitch, - srcx, srcy); - - pipe->region_unmap(pipe, src); - pipe->region_unmap(pipe, dst); -} - - -static ubyte * -get_pointer(struct pipe_region *dst, unsigned x, unsigned y) -{ - return dst->map + (y * dst->pitch + x) * dst->cpp; -} - - -#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8)) - - -/** - * Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -static void -sp_region_fill(struct pipe_context *pipe, - struct pipe_region *dst, - unsigned dst_offset, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, unsigned value) -{ - unsigned i, j; - - assert(dst->pitch > 0); - assert(width <= dst->pitch); - - (void)pipe->region_map(pipe, dst); - - switch (dst->cpp) { - case 1: - { - ubyte *row = get_pointer(dst, dstx, dsty); - for (i = 0; i < height; i++) { - memset(row, value, width); - row += dst->pitch; - } - } - break; - case 2: - { - ushort *row = (ushort *) get_pointer(dst, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = (ushort) value; - row += dst->pitch; - } - } - break; - case 4: - { - unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - row[j] = value; - row += dst->pitch; - } - } - break; - case 8: - { - /* expand the 4-byte clear value to an 8-byte value */ - ushort *row = (ushort *) get_pointer(dst, dstx, dsty); - ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff); - ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff); - ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff); - ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff); - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) { - row[j*4+0] = val0; - row[j*4+1] = val1; - row[j*4+2] = val2; - row[j*4+3] = val3; - } - row += dst->pitch * 4; - } - } - break; - default: - assert(0); - break; - } - - pipe->region_unmap( pipe, dst ); -} - - - - - -void -sp_init_region_functions(struct softpipe_context *sp) -{ - sp->pipe.region_map = sp_region_map; - sp->pipe.region_unmap = sp_region_unmap; - sp->pipe.region_data = sp_region_data; - sp->pipe.region_copy = sp_region_copy; - sp->pipe.region_fill = sp_region_fill; -} - diff --git a/src/mesa/pipe/softpipe/sp_region.h b/src/mesa/pipe/softpipe/sp_region.h deleted file mode 100644 index 432746b27f..0000000000 --- a/src/mesa/pipe/softpipe/sp_region.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef SP_REGION_H -#define SP_REGION_H - - -struct softpipe_context; - - -extern void -sp_init_region_functions(struct softpipe_context *sp); - - -#endif /* SP_REGION_H */ diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index 2f096a9cc9..ea9d2e62be 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -125,7 +125,7 @@ void softpipe_set_scissor_state( struct pipe_context *, void softpipe_set_texture_state( struct pipe_context *, unsigned unit, - struct pipe_mipmap_tree * ); + struct pipe_texture * ); void softpipe_set_viewport_state( struct pipe_context *, const struct pipe_viewport_state * ); diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 81f70f0f24..c4f1a0a01a 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -26,15 +26,12 @@ **************************************************************************/ #include "pipe/p_util.h" - +#include "pipe/p_shader_tokens.h" #include "pipe/draw/draw_context.h" #include "pipe/draw/draw_vertex.h" - #include "sp_context.h" #include "sp_state.h" -#include "pipe/tgsi/exec/tgsi_token.h" - /** * Determine which post-transform / pre-rasterization vertex attributes @@ -156,10 +153,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) if (1/*vinfo->attr_mask != softpipe->attr_mask*/) { /*softpipe->attr_mask = vinfo->attr_mask;*/ - draw_set_vertex_attributes( softpipe->draw, - NULL,/*vinfo->slot_to_attrib,*/ - vinfo->interp_mode, - vinfo->num_attribs); + draw_set_vertex_info( softpipe->draw, vinfo); draw_set_twoside_attributes(softpipe->draw, front0, back0, front1, back1); diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index ba564b16e6..a360b4f02b 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -32,8 +32,10 @@ #include "pipe/p_util.h" #include "pipe/p_winsys.h" #include "pipe/draw/draw_context.h" -#include "pipe/tgsi/exec/tgsi_core.h" +#include "pipe/p_shader_tokens.h" #include "pipe/llvm/gallivm.h" +#include "pipe/tgsi/util/tgsi_dump.h" +#include "pipe/tgsi/exec/tgsi_sse2.h" void * softpipe_create_fs_state(struct pipe_context *pipe, diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c index 246a7d6eda..173901f04e 100644 --- a/src/mesa/pipe/softpipe/sp_state_sampler.c +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -32,6 +32,7 @@ #include "pipe/p_util.h" #include "sp_context.h" #include "sp_state.h" +#include "sp_texture.h" #include "sp_tile_cache.h" @@ -68,12 +69,12 @@ softpipe_delete_sampler_state(struct pipe_context *pipe, void softpipe_set_texture_state(struct pipe_context *pipe, unsigned unit, - struct pipe_mipmap_tree *texture) + struct pipe_texture *texture) { struct softpipe_context *softpipe = softpipe_context(pipe); assert(unit < PIPE_MAX_SAMPLERS); - softpipe->texture[unit] = texture; /* ptr, not struct */ + softpipe->texture[unit] = softpipe_texture(texture); /* ptr, not struct */ sp_tile_cache_set_texture(softpipe->tex_cache[unit], texture); diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c index d4e0bd1e15..30bedc74bc 100644 --- a/src/mesa/pipe/softpipe/sp_state_surface.c +++ b/src/mesa/pipe/softpipe/sp_state_surface.c @@ -27,6 +27,8 @@ /* Authors: Keith Whitwell <keith@tungstengraphics.com> */ +#include "p_inlines.h" + #include "sp_context.h" #include "sp_state.h" #include "sp_surface.h" @@ -54,12 +56,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_flush_tile_cache(sp, sp->cbuf_cache[i]); /* unmap old */ ps = sp->framebuffer.cbufs[i]; - if (ps && ps->region) - pipe->region_unmap(pipe, ps->region); + if (ps && ps->map) + pipe_surface_unmap(ps); /* map new */ ps = fb->cbufs[i]; if (ps) - pipe->region_map(pipe, ps->region); + pipe_surface_map(ps); /* assign new */ sp->framebuffer.cbufs[i] = fb->cbufs[i]; @@ -76,8 +78,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_flush_tile_cache(sp, sp->zbuf_cache); /* unmap old */ ps = sp->framebuffer.zbuf; - if (ps && ps->region) - pipe->region_unmap(pipe, ps->region); + if (ps && ps->map) + pipe_surface_unmap(ps); if (sp->framebuffer.sbuf == sp->framebuffer.zbuf) { /* combined z/stencil */ sp->framebuffer.sbuf = NULL; @@ -85,7 +87,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, /* map new */ ps = fb->zbuf; if (ps) - pipe->region_map(pipe, ps->region); + pipe_surface_map(ps); /* assign new */ sp->framebuffer.zbuf = fb->zbuf; @@ -101,12 +103,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, sp_flush_tile_cache(sp, sp->sbuf_cache_sep); /* unmap old */ ps = sp->framebuffer.sbuf; - if (ps && ps->region) - pipe->region_unmap(pipe, ps->region); + if (ps && ps->map) + pipe_surface_unmap(ps); /* map new */ ps = fb->sbuf; if (ps && fb->sbuf != fb->zbuf) - pipe->region_map(pipe, ps->region); + pipe_surface_map(ps); /* assign new */ sp->framebuffer.sbuf = fb->sbuf; diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index b7c9d4f004..55b8b85ef2 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -30,9 +30,9 @@ #include "pipe/p_inlines.h" #include "pipe/p_winsys.h" #include "sp_context.h" -#include "sp_state.h" #include "sp_surface.h" -#include "sp_tile_cache.h" +#include "sp_texture.h" + /** * Softpipe surface functions. @@ -47,14 +47,6 @@ -#if 0 -#define CLIP_TILE \ - do { \ - assert(x + w <= ps->width); \ - assert(y + h <= ps->height); \ - } while(0) - -#else #define CLIP_TILE \ do { \ if (x >= ps->width) \ @@ -64,24 +56,23 @@ if (x + w > ps->width) \ w = ps->width - x; \ if (y + h > ps->height) \ - h = ps->height -y; \ + h = ps->height - y; \ } while(0) -#endif -/*** PIPE_FORMAT_U_A8_R8_G8_B8 ***/ +/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/ static void a8r8g8b8_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const unsigned *src - = ((const unsigned *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const unsigned *) (ps->map)) + + y * ps->pitch + x; unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8); + assert(ps->format == PIPE_FORMAT_A8R8G8B8_UNORM); CLIP_TILE; @@ -95,7 +86,7 @@ a8r8g8b8_get_tile(struct pipe_surface *ps, pRow[3] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); pRow += 4; } - src += ps->region->pitch; + src += ps->pitch; p += w0 * 4; } } @@ -107,12 +98,12 @@ a8r8g8b8_put_tile(struct pipe_surface *ps, const float *p) { unsigned *dst - = ((unsigned *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((unsigned *) (ps->map)) + + y * ps->pitch + x; unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8); + assert(ps->format == PIPE_FORMAT_A8R8G8B8_UNORM); CLIP_TILE; @@ -127,24 +118,88 @@ a8r8g8b8_put_tile(struct pipe_surface *ps, dst[j] = (a << 24) | (r << 16) | (g << 8) | b; pRow += 4; } - dst += ps->region->pitch; + dst += ps->pitch; p += w0 * 4; } } -/*** PIPE_FORMAT_U_A1_R5_G5_B5 ***/ +/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/ + +static void +b8g8r8a8_get_tile(struct pipe_surface *ps, + unsigned x, unsigned y, unsigned w, unsigned h, float *p) +{ + const unsigned *src + = ((const unsigned *) (ps->map)) + + y * ps->pitch + x; + unsigned i, j; + unsigned w0 = w; + + assert(ps->format == PIPE_FORMAT_B8G8R8A8_UNORM); + + CLIP_TILE; + + for (i = 0; i < h; i++) { + float *pRow = p; + for (j = 0; j < w; j++) { + const unsigned pixel = src[j]; + pRow[0] = UBYTE_TO_FLOAT((pixel >> 8) & 0xff); + pRow[1] = UBYTE_TO_FLOAT((pixel >> 16) & 0xff); + pRow[2] = UBYTE_TO_FLOAT((pixel >> 24) & 0xff); + pRow[3] = UBYTE_TO_FLOAT((pixel >> 0) & 0xff); + pRow += 4; + } + src += ps->pitch; + p += w0 * 4; + } +} + + +static void +b8g8r8a8_put_tile(struct pipe_surface *ps, + unsigned x, unsigned y, unsigned w, unsigned h, + const float *p) +{ + unsigned *dst + = ((unsigned *) (ps->map)) + + y * ps->pitch + x; + unsigned i, j; + unsigned w0 = w; + + assert(ps->format == PIPE_FORMAT_B8G8R8A8_UNORM); + + CLIP_TILE; + + for (i = 0; i < h; i++) { + const float *pRow = p; + for (j = 0; j < w; j++) { + unsigned r, g, b, a; + UNCLAMPED_FLOAT_TO_UBYTE(r, pRow[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, pRow[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, pRow[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, pRow[3]); + dst[j] = (b << 24) | (g << 16) | (r << 8) | a; + pRow += 4; + } + dst += ps->pitch; + p += w0 * 4; + } +} + + +/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/ static void a1r5g5b5_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const ushort *src - = ((const ushort *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const ushort *) (ps->map)) + + y * ps->pitch + x; unsigned i, j; - assert(ps->format == PIPE_FORMAT_U_A1_R5_G5_B5); + assert(ps->format == PIPE_FORMAT_A1R5G5B5_UNORM); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { @@ -155,13 +210,13 @@ a1r5g5b5_get_tile(struct pipe_surface *ps, p[3] = ((pixel >> 15) ) * 1.0f; p += 4; } - src += ps->region->pitch; + src += ps->pitch; } } -/*** PIPE_FORMAT_U_Z16 ***/ +/*** PIPE_FORMAT_Z16_UNORM ***/ /** * Return each Z value as four floats in [0,1]. @@ -171,13 +226,13 @@ z16_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const ushort *src - = ((const ushort *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const ushort *) (ps->map)) + + y * ps->pitch + x; const float scale = 1.0f / 65535.0f; unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_U_Z16); + assert(ps->format == PIPE_FORMAT_Z16_UNORM); CLIP_TILE; @@ -189,7 +244,7 @@ z16_get_tile(struct pipe_surface *ps, pRow[j * 4 + 2] = pRow[j * 4 + 3] = src[j] * scale; } - src += ps->region->pitch; + src += ps->pitch; p += 4 * w0; } } @@ -204,8 +259,8 @@ l8_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const ubyte *src - = ((const ubyte *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const ubyte *) (ps->map)) + + y * ps->pitch + x; unsigned i, j; unsigned w0 = w; @@ -222,7 +277,7 @@ l8_get_tile(struct pipe_surface *ps, pRow[3] = 1.0; pRow += 4; } - src += ps->region->pitch; + src += ps->pitch; p += w0 * 4; } } @@ -235,8 +290,8 @@ a8_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const ubyte *src - = ((const ubyte *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const ubyte *) (ps->map)) + + y * ps->pitch + x; unsigned i, j; unsigned w0 = w; @@ -253,25 +308,25 @@ a8_get_tile(struct pipe_surface *ps, pRow[3] = UBYTE_TO_FLOAT(src[j]); pRow += 4; } - src += ps->region->pitch; + src += ps->pitch; p += w0 * 4; } } -/*** PIPE_FORMAT_S_R16_G16_B16_A16 ***/ +/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/ static void r16g16b16a16_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const short *src - = ((const short *) (ps->region->map + ps->offset)) - + (y * ps->region->pitch + x) * 4; + = ((const short *) (ps->map)) + + (y * ps->pitch + x) * 4; unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_S_R16_G16_B16_A16); + assert(ps->format == PIPE_FORMAT_R16G16B16A16_SNORM); CLIP_TILE; @@ -286,7 +341,7 @@ r16g16b16a16_get_tile(struct pipe_surface *ps, pRow += 4; pixel += 4; } - src += ps->region->pitch * 4; + src += ps->pitch * 4; p += w0 * 4; } } @@ -298,12 +353,12 @@ r16g16b16a16_put_tile(struct pipe_surface *ps, const float *p) { short *dst - = ((short *) (ps->region->map + ps->offset)) - + (y * ps->region->pitch + x) * 4; + = ((short *) (ps->map)) + + (y * ps->pitch + x) * 4; unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_S_R16_G16_B16_A16); + assert(ps->format == PIPE_FORMAT_R16G16B16A16_SNORM); CLIP_TILE; @@ -321,7 +376,7 @@ r16g16b16a16_put_tile(struct pipe_surface *ps, dst[j*4+3] = a; pRow += 4; } - dst += ps->region->pitch * 4; + dst += ps->pitch * 4; p += w0 * 4; } } @@ -335,8 +390,8 @@ i8_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const ubyte *src - = ((const ubyte *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const ubyte *) (ps->map)) + + y * ps->pitch + x; unsigned i, j; unsigned w0 = w; @@ -353,7 +408,7 @@ i8_get_tile(struct pipe_surface *ps, pRow[3] = UBYTE_TO_FLOAT(src[j]); pRow += 4; } - src += ps->region->pitch; + src += ps->pitch; p += w0 * 4; } } @@ -366,8 +421,8 @@ a8_l8_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const ushort *src - = ((const ushort *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const ushort *) (ps->map)) + + y * ps->pitch + x; unsigned i, j; unsigned w0 = w; @@ -385,7 +440,7 @@ a8_l8_get_tile(struct pipe_surface *ps, pRow[3] = UBYTE_TO_FLOAT(p >> 8); pRow += 4; } - src += ps->region->pitch; + src += ps->pitch; p += w0 * 4; } } @@ -393,7 +448,7 @@ a8_l8_get_tile(struct pipe_surface *ps, -/*** PIPE_FORMAT_U_Z32 ***/ +/*** PIPE_FORMAT_Z32_UNORM ***/ /** * Return each Z value as four floats in [0,1]. @@ -403,13 +458,13 @@ z32_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const uint *src - = ((const uint *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const uint *) (ps->map)) + + y * ps->pitch + x; const double scale = 1.0 / (double) 0xffffffff; unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_U_Z16); + assert(ps->format == PIPE_FORMAT_Z16_UNORM); CLIP_TILE; @@ -421,13 +476,13 @@ z32_get_tile(struct pipe_surface *ps, pRow[j * 4 + 2] = pRow[j * 4 + 3] = (float) (scale * src[j]); } - src += ps->region->pitch; + src += ps->pitch; p += 4 * w0; } } -/*** PIPE_FORMAT_S8_Z24 ***/ +/*** PIPE_FORMAT_S8Z24_UNORM ***/ /** * Return Z component as four float in [0,1]. Stencil part ignored. @@ -437,13 +492,13 @@ s8z24_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const uint *src - = ((const uint *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const uint *) (ps->map)) + + y * ps->pitch + x; const double scale = 1.0 / ((1 << 24) - 1); unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_S8_Z24); + assert(ps->format == PIPE_FORMAT_S8Z24_UNORM); CLIP_TILE; @@ -455,13 +510,13 @@ s8z24_get_tile(struct pipe_surface *ps, pRow[j * 4 + 2] = pRow[j * 4 + 3] = (float) (scale * (src[j] & 0xffffff)); } - src += ps->region->pitch; + src += ps->pitch; p += 4 * w0; } } -/*** PIPE_FORMAT_Z24_S8 ***/ +/*** PIPE_FORMAT_Z24S8_UNORM ***/ /** * Return Z component as four float in [0,1]. Stencil part ignored. @@ -471,13 +526,13 @@ z24s8_get_tile(struct pipe_surface *ps, unsigned x, unsigned y, unsigned w, unsigned h, float *p) { const uint *src - = ((const uint *) (ps->region->map + ps->offset)) - + y * ps->region->pitch + x; + = ((const uint *) (ps->map)) + + y * ps->pitch + x; const double scale = 1.0 / ((1 << 24) - 1); unsigned i, j; unsigned w0 = w; - assert(ps->format == PIPE_FORMAT_Z24_S8); + assert(ps->format == PIPE_FORMAT_Z24S8_UNORM); CLIP_TILE; @@ -489,7 +544,7 @@ z24s8_get_tile(struct pipe_surface *ps, pRow[j * 4 + 2] = pRow[j * 4 + 3] = (float) (scale * (src[j] >> 8)); } - src += ps->region->pitch; + src += ps->pitch; p += 4 * w0; } } @@ -501,32 +556,35 @@ z24s8_get_tile(struct pipe_surface *ps, */ struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt, + struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) { + struct softpipe_texture *spt = softpipe_texture(pt); struct pipe_surface *ps; unsigned offset; /* in bytes */ - offset = mt->level[level].level_offset; + offset = spt->level_offset[level]; - if (mt->target == PIPE_TEXTURE_CUBE) { - offset += mt->level[level].image_offset[face] * mt->cpp; + if (pt->target == PIPE_TEXTURE_CUBE) { + offset += spt->image_offset[level][face] * pt->cpp; } - else if (mt->target == PIPE_TEXTURE_3D) { - offset += mt->level[level].image_offset[zslice] * mt->cpp; + else if (pt->target == PIPE_TEXTURE_3D) { + offset += spt->image_offset[level][zslice] * pt->cpp; } else { assert(face == 0); assert(zslice == 0); } - ps = pipe->winsys->surface_alloc(pipe->winsys, mt->format); + ps = pipe->winsys->surface_alloc(pipe->winsys, pt->format); if (ps) { assert(ps->format); assert(ps->refcount); - pipe_region_reference(&ps->region, mt->region); - ps->width = mt->level[level].width; - ps->height = mt->level[level].height; + pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = spt->pitch; ps->offset = offset; } return ps; @@ -541,12 +599,13 @@ softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, void *p, int dst_stride) { - const uint cpp = ps->region->cpp; + const uint cpp = ps->cpp; const ubyte *pSrc; + const uint src_stride = ps->pitch * cpp; ubyte *pDest; uint i; - assert(ps->region->map); + assert(ps->map); if (dst_stride == 0) { dst_stride = w * cpp; @@ -554,13 +613,13 @@ softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, CLIP_TILE; - pSrc = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp; + pSrc = ps->map + (y * ps->pitch + x) * cpp; pDest = (ubyte *) p; for (i = 0; i < h; i++) { memcpy(pDest, pSrc, w * cpp); pDest += dst_stride; - pSrc += ps->region->pitch * cpp; + pSrc += src_stride; } } @@ -573,12 +632,13 @@ softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps, uint x, uint y, uint w, uint h, const void *p, int src_stride) { - const uint cpp = ps->region->cpp; + const uint cpp = ps->cpp; const ubyte *pSrc; + const uint dst_stride = ps->pitch * cpp; ubyte *pDest; uint i; - assert(ps->region->map); + assert(ps->map); if (src_stride == 0) { src_stride = w * cpp; @@ -587,11 +647,11 @@ softpipe_put_tile(struct pipe_context *pipe, struct pipe_surface *ps, CLIP_TILE; pSrc = (const ubyte *) p; - pDest = ps->region->map + ps->offset + (y * ps->region->pitch + x) * cpp; + pDest = ps->map + (y * ps->pitch + x) * cpp; for (i = 0; i < h; i++) { memcpy(pDest, pSrc, w * cpp); - pDest += ps->region->pitch * cpp; + pDest += dst_stride; pSrc += src_stride; } } @@ -605,10 +665,13 @@ softpipe_get_tile_rgba(struct pipe_context *pipe, float *p) { switch (ps->format) { - case PIPE_FORMAT_U_A8_R8_G8_B8: + case PIPE_FORMAT_A8R8G8B8_UNORM: a8r8g8b8_get_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_U_A1_R5_G5_B5: + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_get_tile(ps, x, y, w, h, p); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: a1r5g5b5_get_tile(ps, x, y, w, h, p); break; case PIPE_FORMAT_U_L8: @@ -623,19 +686,19 @@ softpipe_get_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_U_A8_L8: a8_l8_get_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_S_R16_G16_B16_A16: + case PIPE_FORMAT_R16G16B16A16_SNORM: r16g16b16a16_get_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_U_Z16: + case PIPE_FORMAT_Z16_UNORM: z16_get_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_U_Z32: + case PIPE_FORMAT_Z32_UNORM: z32_get_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_S8_Z24: + case PIPE_FORMAT_S8Z24_UNORM: s8z24_get_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_Z24_S8: + case PIPE_FORMAT_Z24S8_UNORM: z24s8_get_tile(ps, x, y, w, h, p); break; default: @@ -652,10 +715,13 @@ softpipe_put_tile_rgba(struct pipe_context *pipe, const float *p) { switch (ps->format) { - case PIPE_FORMAT_U_A8_R8_G8_B8: + case PIPE_FORMAT_A8R8G8B8_UNORM: a8r8g8b8_put_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_U_A1_R5_G5_B5: + case PIPE_FORMAT_B8G8R8A8_UNORM: + b8g8r8a8_put_tile(ps, x, y, w, h, p); + break; + case PIPE_FORMAT_A1R5G5B5_UNORM: /*a1r5g5b5_put_tile(ps, x, y, w, h, p);*/ break; case PIPE_FORMAT_U_L8: @@ -670,19 +736,19 @@ softpipe_put_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_U_A8_L8: /*a8_l8_put_tile(ps, x, y, w, h, p);*/ break; - case PIPE_FORMAT_S_R16_G16_B16_A16: + case PIPE_FORMAT_R16G16B16A16_SNORM: r16g16b16a16_put_tile(ps, x, y, w, h, p); break; - case PIPE_FORMAT_U_Z16: + case PIPE_FORMAT_Z16_UNORM: /*z16_put_tile(ps, x, y, w, h, p);*/ break; - case PIPE_FORMAT_U_Z32: + case PIPE_FORMAT_Z32_UNORM: /*z32_put_tile(ps, x, y, w, h, p);*/ break; - case PIPE_FORMAT_S8_Z24: + case PIPE_FORMAT_S8Z24_UNORM: /*s8z24_put_tile(ps, x, y, w, h, p);*/ break; - case PIPE_FORMAT_Z24_S8: + case PIPE_FORMAT_Z24S8_UNORM: /*z24s8_put_tile(ps, x, y, w, h, p);*/ break; default: @@ -691,6 +757,177 @@ softpipe_put_tile_rgba(struct pipe_context *pipe, } +/** + * Copy 2D rect from one place to another. + * Position and sizes are in pixels. + */ +static void +copy_rect(ubyte * dst, + unsigned cpp, + unsigned dst_pitch, + unsigned dst_x, + unsigned dst_y, + unsigned width, + unsigned height, + const ubyte * src, + unsigned src_pitch, + unsigned src_x, + unsigned src_y) +{ + unsigned i; + + dst_pitch *= cpp; + src_pitch *= cpp; + dst += dst_x * cpp; + src += src_x * cpp; + dst += dst_y * dst_pitch; + src += src_y * src_pitch; + width *= cpp; + + if (width == dst_pitch && width == src_pitch) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_pitch; + src += src_pitch; + } + } +} + + +/* Upload data to a rectangular sub-region. Lots of choices how to do this: + * + * - memcpy by span to current destination + * - upload data as new buffer and blit + * + * Currently always memcpy. + */ +static void +sp_surface_data(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + const void *src, unsigned src_pitch, + unsigned srcx, unsigned srcy, unsigned width, unsigned height) +{ + copy_rect(pipe_surface_map(dst), + dst->cpp, + dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); + + pipe_surface_unmap(dst); +} + +/* Assumes all values are within bounds -- no checking at this level - + * do it higher up if required. + */ +static void +sp_surface_copy(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, unsigned width, unsigned height) +{ + assert( dst->cpp == src->cpp ); + + copy_rect(pipe_surface_map(dst), + dst->cpp, + dst->pitch, + dstx, dsty, + width, height, + pipe_surface_map(src), + src->pitch, + srcx, srcy); + + pipe_surface_unmap(src); + pipe_surface_unmap(dst); +} + + +static ubyte * +get_pointer(struct pipe_surface *dst, unsigned x, unsigned y) +{ + return dst->map + (y * dst->pitch + x) * dst->cpp; +} + + +#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8)) + + +/** + * Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +static void +sp_surface_fill(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, unsigned value) +{ + unsigned i, j; + + assert(dst->pitch > 0); + assert(width <= dst->pitch); + + (void)pipe_surface_map(dst); + + switch (dst->cpp) { + case 1: + { + ubyte *row = get_pointer(dst, dstx, dsty); + for (i = 0; i < height; i++) { + memset(row, value, width); + row += dst->pitch; + } + } + break; + case 2: + { + ushort *row = (ushort *) get_pointer(dst, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = (ushort) value; + row += dst->pitch; + } + } + break; + case 4: + { + unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + row[j] = value; + row += dst->pitch; + } + } + break; + case 8: + { + /* expand the 4-byte clear value to an 8-byte value */ + ushort *row = (ushort *) get_pointer(dst, dstx, dsty); + ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff); + ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff); + ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff); + ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff); + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + row[j*4+0] = val0; + row[j*4+1] = val1; + row[j*4+2] = val2; + row[j*4+3] = val3; + } + row += dst->pitch * 4; + } + } + break; + default: + assert(0); + break; + } + + pipe_surface_unmap( dst ); +} + void sp_init_surface_functions(struct softpipe_context *sp) @@ -700,4 +937,8 @@ sp_init_surface_functions(struct softpipe_context *sp) sp->pipe.get_tile_rgba = softpipe_get_tile_rgba; sp->pipe.put_tile_rgba = softpipe_put_tile_rgba; + + sp->pipe.surface_data = sp_surface_data; + sp->pipe.surface_copy = sp_surface_copy; + sp->pipe.surface_fill = sp_surface_fill; } diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h index cf87e1a92c..b652e7598e 100644 --- a/src/mesa/pipe/softpipe/sp_surface.h +++ b/src/mesa/pipe/softpipe/sp_surface.h @@ -41,7 +41,7 @@ struct softpipe_tile_cache; extern struct pipe_surface * softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt, + struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice); diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.h b/src/mesa/pipe/softpipe/sp_tex_layout.h deleted file mode 100644 index ea19c13b23..0000000000 --- a/src/mesa/pipe/softpipe/sp_tex_layout.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef SP_TEX_LAYOUT_H -#define SP_TEX_LAYOUT_H - - -struct pipe_context; -struct pipe_mipmap_tree; - - -extern boolean -softpipe_mipmap_tree_layout(struct pipe_context *pipe, - struct pipe_mipmap_tree *mt); - - -#endif /* SP_TEX_LAYOUT_H */ - - diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c index 92958400fc..9e48ed0cd2 100644 --- a/src/mesa/pipe/softpipe/sp_tex_sample.c +++ b/src/mesa/pipe/softpipe/sp_tex_sample.c @@ -422,7 +422,7 @@ compute_lambda(struct tgsi_sampler *sampler, dsdy = FABSF(dsdy); rho = MAX2(dsdx, dsdy); if (sampler->state->normalized_coords) - rho *= sampler->texture->width0; + rho *= sampler->texture->width[0]; } if (t) { float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]; @@ -432,7 +432,7 @@ compute_lambda(struct tgsi_sampler *sampler, dtdy = FABSF(dtdy); max = MAX2(dtdx, dtdy); if (sampler->state->normalized_coords) - max *= sampler->texture->height0; + max *= sampler->texture->height[0]; rho = MAX2(rho, max); } if (p) { @@ -443,7 +443,7 @@ compute_lambda(struct tgsi_sampler *sampler, dpdy = FABSF(dpdy); max = MAX2(dpdx, dpdy); if (sampler->state->normalized_coords) - max *= sampler->texture->depth0; + max *= sampler->texture->depth[0]; rho = MAX2(rho, max); } @@ -620,8 +620,8 @@ sp_get_samples_2d_common(struct tgsi_sampler *sampler, &level0, &level1, &levelBlend, &imgFilter); if (sampler->state->normalized_coords) { - width = sampler->texture->level[level0].width; - height = sampler->texture->level[level0].height; + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; } else { width = height = 1; @@ -757,9 +757,9 @@ sp_get_samples_3d(struct tgsi_sampler *sampler, &level0, &level1, &levelBlend, &imgFilter); if (sampler->state->normalized_coords) { - width = sampler->texture->level[level0].width; - height = sampler->texture->level[level0].height; - depth = sampler->texture->level[level0].depth; + width = sampler->texture->width[level0]; + height = sampler->texture->height[level0]; + depth = sampler->texture->depth[level0]; } else { width = height = depth = 1; @@ -883,7 +883,7 @@ sp_get_samples_cube(struct tgsi_sampler *sampler, /** * Called via tgsi_sampler::get_samples() * Use the sampler's state setting to get a filtered RGBA value - * from the sampler's texture (mipmap tree). + * from the sampler's texture. * * XXX we can implement many versions of this function, each * tightly coded for a specific combination of sampler state diff --git a/src/mesa/pipe/softpipe/sp_tex_layout.c b/src/mesa/pipe/softpipe/sp_texture.c index 8156b00301..2288c343bf 100644 --- a/src/mesa/pipe/softpipe/sp_tex_layout.c +++ b/src/mesa/pipe/softpipe/sp_texture.c @@ -32,8 +32,13 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "pipe/p_inlines.h" #include "pipe/p_util.h" -#include "sp_tex_layout.h" +#include "pipe/p_winsys.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_texture.h" /* At the moment, just make softpipe use the same layout for its @@ -54,100 +59,105 @@ static int align(int value, int alignment) static void -sp_miptree_set_level_info(struct pipe_mipmap_tree *mt, - unsigned level, - unsigned nr_images, - unsigned x, unsigned y, unsigned w, unsigned h, unsigned d) +sp_miptree_set_level_info(struct softpipe_texture *spt, + unsigned level, + unsigned nr_images, + unsigned x, unsigned y, unsigned w, unsigned h, + unsigned d) { + struct pipe_texture *pt = &spt->base; + assert(level < PIPE_MAX_TEXTURE_LEVELS); - mt->level[level].width = w; - mt->level[level].height = h; - mt->level[level].depth = d; - mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; - mt->level[level].nr_images = nr_images; + pt->width[level] = w; + pt->height[level] = h; + pt->depth[level] = d; + + spt->nr_images[level] = nr_images; + spt->level_offset[level] = (x + y * spt->pitch) * pt->cpp; /* DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - level, w, h, d, x, y, mt->level[level].level_offset); + level, w, h, d, x, y, spt->level_offset[level]); */ /* Not sure when this would happen, but anyway: */ - if (mt->level[level].image_offset) { - FREE( mt->level[level].image_offset ); - mt->level[level].image_offset = NULL; + if (spt->image_offset[level]) { + FREE( spt->image_offset[level] ); + spt->image_offset[level] = NULL; } assert(nr_images); - assert(!mt->level[level].image_offset); + assert(!spt->image_offset[level]); - mt->level[level].image_offset = (unsigned *) MALLOC( nr_images * sizeof(unsigned) ); - mt->level[level].image_offset[0] = 0; + spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) ); + spt->image_offset[level][0] = 0; } static void -sp_miptree_set_image_offset(struct pipe_mipmap_tree *mt, - unsigned level, unsigned img, unsigned x, unsigned y) +sp_miptree_set_image_offset(struct softpipe_texture *spt, + unsigned level, unsigned img, unsigned x, unsigned y) { if (img == 0 && level == 0) assert(x == 0 && y == 0); - assert(img < mt->level[level].nr_images); + assert(img < spt->nr_images[level]); - mt->level[level].image_offset[img] = (x + y * mt->pitch); + spt->image_offset[level][img] = (x + y * spt->pitch); /* DBG("%s level %d img %d pos %d,%d image_offset %x\n", - __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); + __FUNCTION__, level, img, x, y, spt->image_offset[level][img]); */ } static void -sp_miptree_layout_2d( struct pipe_mipmap_tree *mt ) +sp_miptree_layout_2d( struct softpipe_texture *spt ) { + struct pipe_texture *pt = &spt->base; int align_h = 2, align_w = 4; unsigned level; unsigned x = 0; unsigned y = 0; - unsigned width = mt->width0; - unsigned height = mt->height0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; - mt->pitch = mt->width0; + spt->pitch = pt->width[0]; /* XXX FIX THIS: * we use alignment=64 bytes in sp_region_alloc(). If we change * that, change this too. */ - if (mt->pitch < 16) - mt->pitch = 16; + if (spt->pitch < 16) + spt->pitch = 16; /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap. This occurs when the alignment * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ - if (mt->first_level != mt->last_level) { - unsigned mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); + if (pt->first_level != pt->last_level) { + unsigned mip1_width = align(minify(pt->width[0]), align_w) + + minify(minify(pt->width[0])); - if (mip1_width > mt->width0) - mt->pitch = mip1_width; + if (mip1_width > pt->width[0]) + spt->pitch = mip1_width; } /* Pitch must be a whole number of dwords, even though we * express it in texels. */ - mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; - mt->total_height = 0; + spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp; + spt->total_height = 0; - for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { + for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { unsigned img_height; - sp_miptree_set_level_info(mt, level, 1, x, y, width, height, 1); + sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1); - if (mt->compressed) + if (pt->compressed) img_height = MAX2(1, height/4); else img_height = align(height, align_h); @@ -156,11 +166,11 @@ sp_miptree_layout_2d( struct pipe_mipmap_tree *mt ) /* Because the images are packed better, the final offset * might not be the maximal one: */ - mt->total_height = MAX2(mt->total_height, y + img_height); + spt->total_height = MAX2(spt->total_height, y + img_height); /* Layout_below: step right after second mipmap. */ - if (level == mt->first_level + 1) { + if (level == pt->first_level + 1) { x += align(width, align_w); } else { @@ -193,16 +203,17 @@ static const int step_offsets[6][2] = { -boolean -softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * mt) +static boolean +softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt) { + struct pipe_texture *pt = &spt->base; unsigned level; - switch (mt->target) { + switch (pt->target) { case PIPE_TEXTURE_CUBE:{ - const unsigned dim = mt->width0; + const unsigned dim = pt->width[0]; unsigned face; - unsigned lvlWidth = mt->width0, lvlHeight = mt->height0; + unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; assert(lvlWidth == lvlHeight); /* cubemap images are square */ @@ -211,16 +222,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * * or the final row of 4x4, 2x2 and 1x1 faces below this. */ if (dim > 32) - mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; else - mt->pitch = 14 * 8; + spt->pitch = 14 * 8; - mt->total_height = dim * 4 + 4; + spt->total_height = dim * 4 + 4; /* Set all the levels to effectively occupy the whole rectangular region. */ - for (level = mt->first_level; level <= mt->last_level; level++) { - sp_miptree_set_level_info(mt, level, 6, + for (level = pt->first_level; level <= pt->last_level; level++) { + sp_miptree_set_level_info(spt, level, 6, 0, 0, lvlWidth, lvlHeight, 1); lvlWidth /= 2; @@ -234,16 +245,16 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * unsigned d = dim; if (dim == 4 && face >= 4) { - y = mt->total_height - 4; + y = spt->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4 && (face > 0 || mt->first_level > 0)) { - y = mt->total_height - 4; + else if (dim < 4 && (face > 0 || pt->first_level > 0)) { + y = spt->total_height - 4; x = face * 8; } - for (level = mt->first_level; level <= mt->last_level; level++) { - sp_miptree_set_image_offset(mt, level, face, x, y); + for (level = pt->first_level; level <= pt->last_level; level++) { + sp_miptree_set_image_offset(spt, level, face, x, y); d >>= 1; @@ -262,13 +273,13 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * break; case PIPE_TEX_FACE_POS_Z: case PIPE_TEX_FACE_NEG_Z: - y = mt->total_height - 4; + y = spt->total_height - 4; x = (face - 4) * 8; break; } case 2: - y = mt->total_height - 4; + y = spt->total_height - 4; x = 16 + face * 8; break; @@ -286,33 +297,33 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * break; } case PIPE_TEXTURE_3D:{ - unsigned width = mt->width0; - unsigned height = mt->height0; - unsigned depth = mt->depth0; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; unsigned pack_x_pitch, pack_x_nr; unsigned pack_y_pitch; unsigned level; - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; + spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; + spt->total_height = 0; - pack_y_pitch = MAX2(mt->height0, 2); - pack_x_pitch = mt->pitch; + pack_y_pitch = MAX2(pt->height[0], 2); + pack_x_pitch = spt->pitch; pack_x_nr = 1; - for (level = mt->first_level; level <= mt->last_level; level++) { - unsigned nr_images = mt->target == PIPE_TEXTURE_3D ? depth : 6; + for (level = pt->first_level; level <= pt->last_level; level++) { + unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6; int x = 0; int y = 0; unsigned q, j; - sp_miptree_set_level_info(mt, level, nr_images, - 0, mt->total_height, - width, height, depth); + sp_miptree_set_level_info(spt, level, nr_images, + 0, spt->total_height, + width, height, depth); for (q = 0; q < nr_images;) { for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - sp_miptree_set_image_offset(mt, level, q, x, y); + sp_miptree_set_image_offset(spt, level, q, x, y); x += pack_x_pitch; } @@ -321,12 +332,12 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * } - mt->total_height += y; + spt->total_height += y; if (pack_x_pitch > 4) { pack_x_pitch >>= 1; pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); + assert(pack_x_pitch * pack_x_nr <= spt->pitch); } if (pack_y_pitch > 2) { @@ -343,7 +354,7 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * case PIPE_TEXTURE_1D: case PIPE_TEXTURE_2D: // case PIPE_TEXTURE_RECTANGLE: - sp_miptree_layout_2d(mt); + sp_miptree_layout_2d(spt); break; default: assert(0); @@ -352,10 +363,69 @@ softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree * /* DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, - mt->pitch, - mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + spt->pitch, + spt->total_height, pt->cpp, spt->pitch * spt->total_height * pt->cpp); */ return TRUE; } +void +softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct softpipe_texture *spt = REALLOC(*pt, sizeof(struct pipe_texture), + sizeof(struct softpipe_texture)); + + if (spt) { + memset(&spt->base + 1, 0, + sizeof(struct softpipe_texture) - sizeof(struct pipe_texture)); + + if (softpipe_mipmap_tree_layout(pipe, spt)) { + spt->buffer = pipe->winsys->buffer_create(pipe->winsys, + PIPE_SURFACE_FLAG_TEXTURE); + + if (spt->buffer) { + pipe->winsys->buffer_data(pipe->winsys, spt->buffer, + spt->pitch * spt->base.cpp * + spt->total_height, NULL, + PIPE_BUFFER_USAGE_PIXEL); + } + } + + if (!spt->buffer) { + FREE(spt); + spt = NULL; + } + } + + *pt = &spt->base; +} + +void +softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) +{ + if (!*pt) + return; + + /* + DBG("%s %p refcount will be %d\n", + __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); + */ + if (--(*pt)->refcount <= 0) { + struct softpipe_texture *spt = softpipe_texture(*pt); + uint i; + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe->winsys->buffer_reference(pipe->winsys, &spt->buffer, NULL); + + for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) + if (spt->image_offset[i]) + free(spt->image_offset[i]); + + free(spt); + } + *pt = NULL; +} diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h new file mode 100644 index 0000000000..732064d986 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_texture.h @@ -0,0 +1,57 @@ +#ifndef SP_TEXTURE_H +#define SP_TEXTURE_H + + +struct pipe_context; +struct pipe_texture; + + +struct softpipe_texture +{ + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer_handle *buffer; +}; + + +/** cast wrapper */ +static INLINE struct softpipe_texture * +softpipe_texture(struct pipe_texture *pt) +{ + return (struct softpipe_texture *) pt; +} + + + +extern void +softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt); + +extern void +softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + + +#endif /* SP_TEXTURE */ + + diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index ea0c8b8f91..fadd169f5d 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -38,9 +38,7 @@ #include "sp_surface.h" #include "sp_tile_cache.h" -#define CLEAR_OPTIMIZATION 0 - -#define NUM_ENTRIES 20 +#define NUM_ENTRIES 30 /** XXX move these */ @@ -51,10 +49,15 @@ struct softpipe_tile_cache { struct pipe_surface *surface; /**< the surface we're caching */ - struct pipe_mipmap_tree *texture; /**< if caching a texture */ + struct pipe_texture *texture; /**< if caching a texture */ struct softpipe_cached_tile entries[NUM_ENTRIES]; uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32]; - float clear_value[4]; + float clear_color[4]; + uint clear_val; + boolean depth_stencil; /** Is the surface a depth/stencil format? */ + + struct pipe_surface *tex_surf; + int tex_face, tex_level, tex_z; }; @@ -69,7 +72,10 @@ struct softpipe_tile_cache -static uint +/** + * Is the tile at (x,y) in cleared state? + */ +static INLINE uint is_clear_flag_set(const uint *bitvec, int x, int y) { int pos, bit; @@ -82,7 +88,10 @@ is_clear_flag_set(const uint *bitvec, int x, int y) } -static void +/** + * Mark the tile at (x,y) as not cleared. + */ +static INLINE void clear_clear_flag(uint *bitvec, int x, int y) { int pos; @@ -122,14 +131,37 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc) } +/** + * Specify the surface to cache. + */ void sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, struct pipe_surface *ps) { + assert(!tc->texture); + + if (tc->surface && tc->surface->map) { + assert(tc->surface != ps); + pipe_surface_unmap(tc->surface); + } + pipe_surface_reference(&tc->surface, ps); + + if (!ps->map) + pipe_surface_map(ps); + + if (ps) { + tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || + ps->format == PIPE_FORMAT_Z16_UNORM || + ps->format == PIPE_FORMAT_Z32_UNORM || + ps->format == PIPE_FORMAT_U_S8); + } } +/** + * Return the surface being cached. + */ struct pipe_surface * sp_tile_cache_get_surface(struct softpipe_tile_cache *tc) { @@ -137,44 +169,165 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc) } +/** + * Specify the texture to cache. + */ void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, - struct pipe_mipmap_tree *texture) + struct pipe_texture *texture) { uint i; + assert(!tc->surface); + tc->texture = texture; + if (tc->tex_surf && tc->tex_surf->map) + pipe_surface_unmap(tc->tex_surf); + pipe_surface_reference(&tc->tex_surf, NULL); + /* 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++) { tc->entries[i].x = -1; } + + tc->tex_face = -1; /* any invalid value here */ +} + + +/** + * Set pixels in a tile to the given clear color/value, float. + */ +static void +clear_tile_rgba(struct softpipe_cached_tile *tile, + enum pipe_format format, + const float clear_value[4]) +{ + if (clear_value[0] == 0.0 && + clear_value[1] == 0.0 && + clear_value[2] == 0.0 && + clear_value[3] == 0.0) { + memset(tile->data.color, 0, sizeof(tile->data.color)); + } + else { + uint i, j; + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.color[i][j][0] = clear_value[0]; + tile->data.color[i][j][1] = clear_value[1]; + tile->data.color[i][j][2] = clear_value[2]; + tile->data.color[i][j][3] = clear_value[3]; + } + } + } +} + + +/** + * Set a tile to a solid value/color. + */ +static void +clear_tile(struct softpipe_cached_tile *tile, + enum pipe_format format, + uint clear_value) +{ + uint i, j; + + switch (format) { + case PIPE_FORMAT_U_S8: + /* 8 bpp */ + memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE); + break; + case PIPE_FORMAT_Z16_UNORM: + /* 16 bpp */ + if (clear_value == 0) { + memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE); + } + else { + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.depth16[i][j] = clear_value; + } + } + } + break; + default: + /* 32 bpp */ + if (clear_value == 0) { + memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE); + } + else { + for (i = 0; i < TILE_SIZE; i++) { + for (j = 0; j < TILE_SIZE; j++) { + tile->data.color32[i][j] = clear_value; + } + } + } + } +} + + +/** + * Actually clear the tiles which were flagged as being in a clear state. + */ +static void +sp_tile_cache_flush_clear(struct pipe_context *pipe, + struct softpipe_tile_cache *tc) +{ + struct pipe_surface *ps = tc->surface; + const uint w = tc->surface->width; + const uint h = tc->surface->height; + uint x, y; + struct softpipe_cached_tile tile; + uint numCleared = 0; + + /* clear one tile to the clear value */ + clear_tile(&tile, ps->format, tc->clear_val); + + /* push the tile to all positions marked as clear */ + for (y = 0; y < h; y += TILE_SIZE) { + for (x = 0; x < w; x += TILE_SIZE) { + if (is_clear_flag_set(tc->clear_flags, x, y)) { + pipe->put_tile(pipe, ps, + x, y, TILE_SIZE, TILE_SIZE, + tile.data.color32, 0/*STRIDE*/); + + /* do this? */ + clear_clear_flag(tc->clear_flags, x, y); + + numCleared++; + } + } + } +#if 0 + printf("num cleared: %u\n", numCleared); +#endif } +/** + * Flush the tile cache: write all dirty tiles back to the surface. + * any tiles "flagged" as cleared will be "really" cleared. + */ void sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_tile_cache *tc) { struct pipe_context *pipe = &softpipe->pipe; struct pipe_surface *ps = tc->surface; - boolean is_depth_stencil; int inuse = 0, pos; - if (!ps || !ps->region || !ps->region->map) + if (!ps || !ps->buffer) return; - is_depth_stencil = (ps->format == PIPE_FORMAT_S8_Z24 || - ps->format == PIPE_FORMAT_Z24_S8 || - ps->format == PIPE_FORMAT_U_Z16 || - ps->format == PIPE_FORMAT_U_Z32 || - ps->format == PIPE_FORMAT_U_S8); + if (!ps->map) + pipe_surface_map(ps); for (pos = 0; pos < NUM_ENTRIES; pos++) { struct softpipe_cached_tile *tile = tc->entries + pos; if (tile->x >= 0) { - if (is_depth_stencil) { + if (tc->depth_stencil) { pipe->put_tile(pipe, ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); @@ -184,30 +337,31 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } - tile->x = tile->y = -1; /* mark as empty */ inuse++; } } - /* +#if TILE_CLEAR_OPTIMIZATION + sp_tile_cache_flush_clear(&softpipe->pipe, tc); +#endif + +#if 0 printf("flushed tiles in use: %d\n", inuse); - */ +#endif } +/** + * Get a tile from the cache. + * \param x, y position of tile, in pixels + */ struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_context *softpipe, struct softpipe_tile_cache *tc, int x, int y) { struct pipe_context *pipe = &softpipe->pipe; struct pipe_surface *ps = tc->surface; - boolean is_depth_stencil - = (ps->format == PIPE_FORMAT_S8_Z24 || - ps->format == PIPE_FORMAT_Z24_S8 || - ps->format == PIPE_FORMAT_U_Z16 || - ps->format == PIPE_FORMAT_U_Z32 || - ps->format == PIPE_FORMAT_U_S8); /* tile pos in framebuffer: */ const int tile_x = x & ~(TILE_SIZE - 1); @@ -222,10 +376,10 @@ sp_get_cached_tile(struct softpipe_context *softpipe, if (tile->x != -1) { /* put dirty tile back in framebuffer */ - if (is_depth_stencil) { + if (tc->depth_stencil) { pipe->put_tile(pipe, ps, tile->x, tile->y, TILE_SIZE, TILE_SIZE, - tile->data.depth32, 0 /*STRIDE*/); + tile->data.depth32, 0/*STRIDE*/); } else { pipe->put_tile_rgba(pipe, ps, @@ -234,92 +388,32 @@ sp_get_cached_tile(struct softpipe_context *softpipe, } } + tile->x = tile_x; + tile->y = tile_y; + if (is_clear_flag_set(tc->clear_flags, x, y)) { /* don't get tile from framebuffer, just clear it */ - uint i, j; - /* XXX these loops could be optimized */ - switch (ps->format) { - case PIPE_FORMAT_U_Z16: - { - ushort clear_val = (ushort) (tc->clear_value[0] * 0xffff); - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile->data.depth16[i][j] = clear_val; - } - } - } - break; - case PIPE_FORMAT_U_Z32: - { - uint clear_val = (uint) (tc->clear_value[0] * 0xffffffff); - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile->data.depth32[i][j] = clear_val; - } - } - } - break; - case PIPE_FORMAT_S8_Z24: - { - uint clear_val = (uint) (tc->clear_value[0] * 0xffffff); - clear_val |= ((uint) tc->clear_value[1]) << 24; - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile->data.depth32[i][j] = clear_val; - } - } - } - break; - case PIPE_FORMAT_Z24_S8: - { - uint clear_val = ((uint) (tc->clear_value[0] * 0xffffff)) << 8; - clear_val |= ((uint) tc->clear_value[1]) & 0xff; - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile->data.depth32[i][j] = clear_val; - } - } - } - break; - case PIPE_FORMAT_U_S8: - { - ubyte clear_val = (uint) tc->clear_value[0]; - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile->data.stencil8[i][j] = clear_val; - } - } - } - break; - default: - /* color */ - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile->data.color[i][j][0] = tc->clear_value[0]; - tile->data.color[i][j][1] = tc->clear_value[1]; - tile->data.color[i][j][2] = tc->clear_value[2]; - tile->data.color[i][j][3] = tc->clear_value[3]; - } - } + if (tc->depth_stencil) { + clear_tile(tile, ps->format, tc->clear_val); + } + else { + clear_tile_rgba(tile, ps->format, tc->clear_color); } clear_clear_flag(tc->clear_flags, x, y); } else { - /* get new tile from framebuffer */ - if (is_depth_stencil) { + /* get new tile data from surface */ + if (tc->depth_stencil) { pipe->get_tile(pipe, ps, - tile_x, tile_y, TILE_SIZE, TILE_SIZE, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, tile->data.depth32, 0/*STRIDE*/); } else { pipe->get_tile_rgba(pipe, ps, - tile_x, tile_y, TILE_SIZE, TILE_SIZE, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, (float *) tile->data.color); } } - - tile->x = tile_x; - tile->y = tile_y; } return tile; @@ -363,16 +457,33 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, z != tile->z || face != tile->face || level != tile->level) { - /* XXX this call is a bit heavier than we'd like: */ - struct pipe_surface *ps - = pipe->get_tex_surface(pipe, tc->texture, face, level, z); + /* cache miss */ - pipe->get_tile_rgba(pipe, ps, - tile_x, tile_y, TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + /* check if we need to get a new surface */ + if (!tc->tex_surf || + tc->tex_face != face || + tc->tex_level != level || + tc->tex_z != z) { + /* get new surface (view into texture) */ + struct pipe_surface *ps; + + if (tc->tex_surf && tc->tex_surf->map) + pipe_surface_unmap(tc->tex_surf); + + ps = pipe->get_tex_surface(pipe, tc->texture, face, level, z); + pipe_surface_reference(&tc->tex_surf, ps); - pipe_surface_reference(&ps, NULL); + pipe_surface_map(ps); + tc->tex_face = face; + tc->tex_level = level; + tc->tex_z = z; + } + + /* get tile from the surface (view into texture) */ + pipe->get_tile_rgba(pipe, tc->tex_surf, + tile_x, tile_y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); tile->x = tile_x; tile->y = tile_y; tile->z = z; @@ -390,16 +501,45 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, * Save the color and set a 'clearflag' for each tile of the screen. */ void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4]) +sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue) { - tc->clear_value[0] = value[0]; - tc->clear_value[1] = value[1]; - tc->clear_value[2] = value[2]; - tc->clear_value[3] = value[3]; + uint r, g, b, a; + + tc->clear_val = clearValue; + + switch (tc->surface->format) { + case PIPE_FORMAT_R8G8B8A8_UNORM: + r = (clearValue >> 24) & 0xff; + g = (clearValue >> 16) & 0xff; + b = (clearValue >> 8) & 0xff; + a = (clearValue ) & 0xff; + break; + case PIPE_FORMAT_A8R8G8B8_UNORM: + r = (clearValue >> 16) & 0xff; + g = (clearValue >> 8) & 0xff; + b = (clearValue ) & 0xff; + a = (clearValue >> 24) & 0xff; + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + r = (clearValue >> 8) & 0xff; + g = (clearValue >> 16) & 0xff; + b = (clearValue >> 24) & 0xff; + a = (clearValue ) & 0xff; + break; + default: + r = g = b = a = 0; + } + + tc->clear_color[0] = r / 255.0; + tc->clear_color[1] = g / 255.0; + tc->clear_color[2] = b / 255.0; + tc->clear_color[3] = a / 255.0; -#if CLEAR_OPTIMIZATION +#if TILE_CLEAR_OPTIMIZATION + /* set flags to indicate all the tiles are cleared */ memset(tc->clear_flags, 255, sizeof(tc->clear_flags)); #else + /* disable the optimization */ memset(tc->clear_flags, 0, sizeof(tc->clear_flags)); #endif } diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h index e66fec2e20..91fb2795a2 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.h +++ b/src/mesa/pipe/softpipe/sp_tile_cache.h @@ -28,6 +28,8 @@ #ifndef SP_TILE_CACHE_H #define SP_TILE_CACHE_H +#define TILE_CLEAR_OPTIMIZATION 1 + #include "pipe/p_compiler.h" @@ -49,9 +51,11 @@ struct softpipe_cached_tile int z, face, level; /**< Extra texture indexes */ union { float color[TILE_SIZE][TILE_SIZE][4]; + uint color32[TILE_SIZE][TILE_SIZE]; uint depth32[TILE_SIZE][TILE_SIZE]; ushort depth16[TILE_SIZE][TILE_SIZE]; ubyte stencil8[TILE_SIZE][TILE_SIZE]; + ubyte any[1]; } data; }; @@ -71,14 +75,14 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc); extern void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, - struct pipe_mipmap_tree *texture); + struct pipe_texture *texture); extern void sp_flush_tile_cache(struct softpipe_context *softpipe, struct softpipe_tile_cache *tc); extern void -sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float value[4]); +sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue); extern struct softpipe_cached_tile * sp_get_cached_tile(struct softpipe_context *softpipe, |