diff options
| author | Ben Skeggs <skeggsb@gmail.com> | 2008-01-16 13:14:19 +1100 |
|---|---|---|
| committer | Ben Skeggs <skeggsb@gmail.com> | 2008-01-16 13:14:19 +1100 |
| commit | 3119e9a14b66fcfb08fcc3563602273dd2e1893c (patch) | |
| tree | 74ff685faec3430b66d70522b6ed717f57e54f00 /src/mesa/pipe/softpipe | |
| parent | 9de335f5807553bc9251931ba3e80c4b454b5818 (diff) | |
| parent | 587e2becc237bc1c900a1c0ba114a1a0192690ff (diff) | |
Merge branch 'upstream-gallium-0.1' into darktama-gallium-0.1
Conflicts:
src/mesa/pipe/Makefile
Diffstat (limited to 'src/mesa/pipe/softpipe')
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_context.c | 28 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_context.h | 2 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_prim_setup.c | 16 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_prim_setup.h | 99 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_prim_vbuf.c | 8 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_query.c | 6 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_state.h | 2 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_state_fs.c | 45 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_state_surface.c | 42 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_surface.c | 45 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_texture.c | 330 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_texture.h | 19 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_tile_cache.c | 70 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_tile_cache.h | 6 |
14 files changed, 208 insertions, 510 deletions
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c index c7af63cc2d..68c18e2d05 100644 --- a/src/mesa/pipe/softpipe/sp_context.c +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -75,22 +75,15 @@ softpipe_is_format_supported( struct pipe_context *pipe, void softpipe_map_surfaces(struct softpipe_context *sp) { - struct pipe_surface *ps; unsigned i; for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - ps = sp->framebuffer.cbufs[i]; - if (ps->buffer) - pipe_surface_map(ps); + sp_tile_cache_map_surfaces(sp->cbuf_cache[i]); } - ps = sp->framebuffer.zbuf; - if (ps && ps->buffer) - pipe_surface_map(ps); + sp_tile_cache_map_surfaces(sp->zbuf_cache); - ps = sp->framebuffer.sbuf; - if (ps && ps->buffer) - pipe_surface_map(ps); + sp_tile_cache_map_surfaces(sp->sbuf_cache); } @@ -100,7 +93,6 @@ softpipe_map_surfaces(struct softpipe_context *sp) void softpipe_unmap_surfaces(struct softpipe_context *sp) { - struct pipe_surface *ps; uint i; for (i = 0; i < sp->framebuffer.num_cbufs; i++) @@ -109,18 +101,12 @@ softpipe_unmap_surfaces(struct softpipe_context *sp) sp_flush_tile_cache(sp, sp->sbuf_cache); for (i = 0; i < sp->framebuffer.num_cbufs; i++) { - ps = sp->framebuffer.cbufs[i]; - if (ps->map) - pipe_surface_unmap(ps); + sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]); } - ps = sp->framebuffer.zbuf; - if (ps && ps->map) - pipe_surface_unmap(ps); + sp_tile_cache_unmap_surfaces(sp->zbuf_cache); - ps = sp->framebuffer.sbuf; - if (ps && ps->map) - pipe_surface_unmap(ps); + sp_tile_cache_unmap_surfaces(sp->sbuf_cache); } @@ -345,7 +331,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys, if (GETENV( "SP_VBUF" ) != NULL) { softpipe->vbuf = sp_draw_vbuf_stage(softpipe->draw, &softpipe->pipe, - sp_vbuf_setup_draw); + sp_vbuf_render); draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf); } diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index 394baf0109..3537f86a61 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -76,7 +76,7 @@ struct softpipe_context { /* Counter for occlusion queries. Note this supports overlapping * queries. */ - uint64_t occlusion_count; + uint64 occlusion_count; /* * Mapped vertex buffers diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index de45529bf9..722cadc5c0 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -1286,18 +1286,20 @@ static void calc_det( struct prim_header *header ) -/* Test harness - feed vertex buffer back into prim pipeline. +/** + * Render buffer of points/lines/triangles. + * Called by vbuf code when the vertex or index buffer is filled. * * The big issue at this point is that reset_stipple doesn't make it * through the interface. Probably need to split primitives at reset * stipple, perhaps using the ~0 index marker. */ -void sp_vbuf_setup_draw( struct pipe_context *pipe, - unsigned primitive, - const ushort *elements, - unsigned nr_elements, - const void *vertex_buffer, - unsigned nr_vertices ) +void sp_vbuf_render( struct pipe_context *pipe, + unsigned primitive, + const ushort *elements, + unsigned nr_elements, + const void *vertex_buffer, + unsigned nr_vertices ) { struct softpipe_context *softpipe = softpipe_context( pipe ); struct setup_stage *setup = setup_stage( softpipe->setup ); diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.h b/src/mesa/pipe/softpipe/sp_prim_setup.h index 598394f73e..c16dc634b0 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.h +++ b/src/mesa/pipe/softpipe/sp_prim_setup.h @@ -1,33 +1,49 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * +/************************************************************************** + * + * 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, sublicense, - * 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 shall be included - * in all copies or substantial portions of the Software. - * + * 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 NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL 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. - */ + * 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_PRIM_SETUP_H #define SP_PRIM_SETUP_H -/* Vertices are just an array of floats, with all the attributes +/** + * vbuf is a special stage to gather the stream of triangles, lines, points + * together and reconstruct vertex buffers for hardware upload. + * + * First attempt, work in progress. + * + * TODO: + * - separate out vertex buffer building and primitive emit, ie >1 draw per vb. + * - tell vbuf stage how to build hw vertices directly + * - pass vbuf stage a buffer pointer for direct emit to agp/vram. + * + * + * + * Vertices are just an array of floats, with all the attributes * packed. We currently assume a layout like: * * attr[0][0..3] - window position @@ -37,23 +53,11 @@ * all the enabled attributes run contiguously. */ + struct draw_stage; struct softpipe_context; -extern struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ); - - -/* A special stage to gather the stream of triangles, lines, points - * together and reconstruct vertex buffers for hardware upload. - * - * First attempt, work in progress. - * - * TODO: - * - separate out vertex buffer building and primitive emit, ie >1 draw per vb. - * - tell vbuf stage how to build hw vertices directly - * - pass vbuf stage a buffer pointer for direct emit to agp/vram. - */ typedef void (*vbuf_draw_func)( struct pipe_context *pipe, unsigned prim, const ushort *elements, @@ -62,20 +66,23 @@ typedef void (*vbuf_draw_func)( struct pipe_context *pipe, unsigned nr_vertices ); -extern struct draw_stage *sp_draw_vbuf_stage( struct draw_context *draw_context, - struct pipe_context *pipe, - vbuf_draw_func draw ); +extern struct draw_stage * +sp_draw_render_stage( struct softpipe_context *softpipe ); +extern struct draw_stage * +sp_draw_vbuf_stage( struct draw_context *draw_context, + struct pipe_context *pipe, + vbuf_draw_func draw ); -/* Test harness - */ -void sp_vbuf_setup_draw( struct pipe_context *pipe, - unsigned prim, - const ushort *elements, - unsigned nr_elements, - const void *vertex_buffer, - unsigned nr_vertices ); + +extern void +sp_vbuf_render( struct pipe_context *pipe, + unsigned prim, + const ushort *elements, + unsigned nr_elements, + const void *vertex_buffer, + unsigned nr_vertices ); diff --git a/src/mesa/pipe/softpipe/sp_prim_vbuf.c b/src/mesa/pipe/softpipe/sp_prim_vbuf.c index 2cfdeb5809..055cb19f9a 100644 --- a/src/mesa/pipe/softpipe/sp_prim_vbuf.c +++ b/src/mesa/pipe/softpipe/sp_prim_vbuf.c @@ -120,6 +120,12 @@ static void emit_vertex( struct vbuf_stage *vbuf, vertex->vertex_id = vbuf->nr_vertices++; //vbuf->emit_vertex( vbuf->vertex_ptr, vertex ); + + /* Note: for softpipe, the vertex includes the vertex header info + * such as clip flags and clip coords. In the future when vbuf is + * always used, we could just copy the vertex attributes/data here. + * The sp_prim_setup.c code doesn't use any of the vertex header info. + */ memcpy(vbuf->vertex_ptr, vertex, vbuf->vertex_size); vbuf->vertex_ptr += vbuf->vertex_size; @@ -221,7 +227,9 @@ static void vbuf_flush_elements( struct draw_stage *stage ) struct vbuf_stage *vbuf = vbuf_stage( stage ); if (vbuf->nr_elements) { + /* fprintf(stderr, "%s (%d elts)\n", __FUNCTION__, vbuf->nr_elements); + */ /* Draw now or add to list of primitives??? */ diff --git a/src/mesa/pipe/softpipe/sp_query.c b/src/mesa/pipe/softpipe/sp_query.c index bf753dad98..6a8a43aeda 100644 --- a/src/mesa/pipe/softpipe/sp_query.c +++ b/src/mesa/pipe/softpipe/sp_query.c @@ -37,8 +37,8 @@ #include "sp_query.h" struct softpipe_query { - uint64_t start; - uint64_t end; + uint64 start; + uint64 end; }; @@ -87,7 +87,7 @@ static boolean softpipe_get_query_result(struct pipe_context *pipe, struct pipe_query *q, boolean wait, - uint64_t *result ) + uint64 *result ) { struct softpipe_query *sq = softpipe_query(q); *result = sq->end - sq->start; diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h index c1f5555a86..bac7b0876f 100644 --- a/src/mesa/pipe/softpipe/sp_state.h +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -75,7 +75,7 @@ struct sp_fragment_shader_state { /** Subclass of pipe_shader_state */ struct sp_vertex_shader_state { struct pipe_shader_state shader; - void *draw_data; + struct draw_vertex_shader *draw_data; }; diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c index f72a91485f..945c93411f 100644 --- a/src/mesa/pipe/softpipe/sp_state_fs.c +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -38,8 +38,9 @@ #include "pipe/tgsi/exec/tgsi_sse2.h" -void * softpipe_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) +void * +softpipe_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) { struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader_state *state; @@ -58,13 +59,6 @@ void * softpipe_create_fs_state(struct pipe_context *pipe, tgsi_dump(state->shader.tokens, 0); } -#if defined(__i386__) || defined(__386__) - if (softpipe->use_sse) { - x86_init_func( &state->sse2_program ); - tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); - } -#endif - #ifdef MESA_LLVM state->llvm_prog = gallivm_from_tgsi(state->shader.tokens, GALLIVM_FS); if (!gallivm_global_cpu_engine()) { @@ -72,13 +66,19 @@ void * softpipe_create_fs_state(struct pipe_context *pipe, } else gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog); +#elif defined(__i386__) || defined(__386__) + if (softpipe->use_sse) { + x86_init_func( &state->sse2_program ); + tgsi_emit_sse2_fs( state->shader.tokens, &state->sse2_program ); + } #endif return state; } -void softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) +void +softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -88,10 +88,10 @@ void softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) } -void softpipe_delete_fs_state(struct pipe_context *pipe, - void *shader) +void +softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { - struct sp_fragment_shader_state *state = shader; + struct sp_fragment_shader_state *state = fs; #if defined(__i386__) || defined(__386__) x86_release_func( &state->sse2_program ); @@ -101,8 +101,9 @@ void softpipe_delete_fs_state(struct pipe_context *pipe, } -void * softpipe_create_vs_state(struct pipe_context *pipe, - const struct pipe_shader_state *templ) +void * +softpipe_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *templ) { struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_vertex_shader_state *state; @@ -125,7 +126,8 @@ void * softpipe_create_vs_state(struct pipe_context *pipe, } -void softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) +void +softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -137,7 +139,8 @@ void softpipe_bind_vs_state(struct pipe_context *pipe, void *vs) } -void softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) +void +softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -149,9 +152,11 @@ void softpipe_delete_vs_state(struct pipe_context *pipe, void *vs) } -void softpipe_set_constant_buffer(struct pipe_context *pipe, - uint shader, uint index, - const struct pipe_constant_buffer *buf) + +void +softpipe_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) { struct softpipe_context *softpipe = softpipe_context(pipe); struct pipe_winsys *ws = pipe->winsys; diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c index ee72aaf4c5..4a9a28cc4d 100644 --- a/src/mesa/pipe/softpipe/sp_state_surface.c +++ b/src/mesa/pipe/softpipe/sp_state_surface.c @@ -38,7 +38,7 @@ /** * XXX this might get moved someday * Set the framebuffer surface info: color buffers, zbuffer, stencil buffer. - * Here, we map the surfaces and update the tile cache to point to the new + * Here, we flush the old surfaces and update the tile cache to point to the new * surfaces. */ void @@ -46,7 +46,6 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct softpipe_context *sp = softpipe_context(pipe); - struct pipe_surface *ps; uint i; for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { @@ -54,19 +53,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) { /* flush old */ sp_flush_tile_cache(sp, sp->cbuf_cache[i]); - /* unmap old */ - ps = sp->framebuffer.cbufs[i]; - if (ps && ps->map) - pipe_surface_unmap(ps); - /* map new */ - ps = fb->cbufs[i]; - if (ps) - pipe_surface_map(ps); + /* assign new */ sp->framebuffer.cbufs[i] = fb->cbufs[i]; /* update cache */ - sp_tile_cache_set_surface(sp->cbuf_cache[i], ps); + sp_tile_cache_set_surface(sp->cbuf_cache[i], fb->cbufs[i]); } } @@ -76,23 +68,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, if (sp->framebuffer.zbuf != fb->zbuf) { /* flush old */ sp_flush_tile_cache(sp, sp->zbuf_cache); - /* unmap old */ - ps = sp->framebuffer.zbuf; - if (ps && ps->map) - pipe_surface_unmap(ps); - if (sp->framebuffer.sbuf == sp->framebuffer.zbuf) { - /* combined z/stencil */ - sp->framebuffer.sbuf = NULL; - } - /* map new */ - ps = fb->zbuf; - if (ps) - pipe_surface_map(ps); + /* assign new */ sp->framebuffer.zbuf = fb->zbuf; /* update cache */ - sp_tile_cache_set_surface(sp->zbuf_cache, ps); + sp_tile_cache_set_surface(sp->zbuf_cache, fb->zbuf); } /* XXX combined depth/stencil here */ @@ -101,14 +82,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, if (sp->framebuffer.sbuf != fb->sbuf) { /* flush old */ sp_flush_tile_cache(sp, sp->sbuf_cache_sep); - /* unmap old */ - ps = sp->framebuffer.sbuf; - if (ps && ps->map) - pipe_surface_unmap(ps); - /* map new */ - ps = fb->sbuf; - if (ps && fb->sbuf != fb->zbuf) - pipe_surface_map(ps); + /* assign new */ sp->framebuffer.sbuf = fb->sbuf; @@ -116,12 +90,12 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe, if (fb->sbuf != fb->zbuf) { /* separate stencil buf */ sp->sbuf_cache = sp->sbuf_cache_sep; - sp_tile_cache_set_surface(sp->sbuf_cache, ps); + sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf); } else { /* combined depth/stencil */ sp->sbuf_cache = sp->zbuf_cache; - sp_tile_cache_set_surface(sp->sbuf_cache, ps); + sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf); } } diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index 5259fbfd20..6c080d5b5c 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -46,20 +46,6 @@ softpipe_get_tex_surface(struct pipe_context *pipe, { struct softpipe_texture *spt = softpipe_texture(pt); struct pipe_surface *ps; - unsigned offset; /* in bytes */ - - offset = spt->level_offset[level]; - - if (pt->target == PIPE_TEXTURE_CUBE) { - offset += spt->image_offset[level][face] * pt->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); if (ps) { @@ -69,8 +55,17 @@ softpipe_get_tex_surface(struct pipe_context *pipe, ps->cpp = pt->cpp; ps->width = pt->width[level]; ps->height = pt->height[level]; - ps->pitch = spt->pitch; - ps->offset = offset; + ps->pitch = ps->width; + ps->offset = spt->level_offset[level]; + + if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { + ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * + (pt->compressed ? ps->height/4 : ps->height) * + ps->width * ps->cpp; + } else { + assert(face == 0); + assert(zslice == 0); + } } return ps; } @@ -163,10 +158,10 @@ sp_surface_copy(struct pipe_context *pipe, } -static ubyte * -get_pointer(struct pipe_surface *dst, unsigned x, unsigned y) +static void * +get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) { - return dst->map + (y * dst->pitch + x) * dst->cpp; + return (char *)dst_map + (y * dst->pitch + x) * dst->cpp; } @@ -184,16 +179,16 @@ sp_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { unsigned i, j; + void *dst_map = pipe_surface_map(dst); 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); + ubyte *row = get_pointer(dst, dst_map, dstx, dsty); for (i = 0; i < height; i++) { memset(row, value, width); row += dst->pitch; @@ -202,7 +197,7 @@ sp_surface_fill(struct pipe_context *pipe, break; case 2: { - ushort *row = (ushort *) get_pointer(dst, dstx, dsty); + ushort *row = get_pointer(dst, dst_map, dstx, dsty); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) row[j] = (ushort) value; @@ -212,7 +207,7 @@ sp_surface_fill(struct pipe_context *pipe, break; case 4: { - unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty); + unsigned *row = get_pointer(dst, dst_map, dstx, dsty); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) row[j] = value; @@ -223,7 +218,7 @@ sp_surface_fill(struct pipe_context *pipe, case 8: { /* expand the 4-byte clear value to an 8-byte value */ - ushort *row = (ushort *) get_pointer(dst, dstx, dsty); + ushort *row = (ushort *) get_pointer(dst, dst_map, 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); @@ -257,8 +252,6 @@ sp_init_surface_functions(struct softpipe_context *sp) { sp->pipe.get_tile = pipe_get_tile_raw; sp->pipe.put_tile = pipe_put_tile_raw; - sp->pipe.get_tile_rgba = pipe_get_tile_rgba; - sp->pipe.put_tile_rgba = pipe_put_tile_rgba; sp->pipe.surface_data = sp_surface_data; sp->pipe.surface_copy = sp_surface_copy; diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c index 44512e4281..e5e6bfe01b 100644 --- a/src/mesa/pipe/softpipe/sp_texture.c +++ b/src/mesa/pipe/softpipe/sp_texture.c @@ -41,10 +41,7 @@ #include "sp_texture.h" -/* At the moment, just make softpipe use the same layout for its - * textures as the i945. Softpipe needs some sort of texture layout, - * this one was handy. May be worthwhile to simplify this code a - * little. +/* Simple, maximally packed layout. */ static unsigned minify( unsigned d ) @@ -53,319 +50,35 @@ static unsigned minify( unsigned d ) } - -static void -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); - - 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, spt->level_offset[level]); - */ - - /* Not sure when this would happen, but anyway: - */ - if (spt->image_offset[level]) { - FREE( spt->image_offset[level] ); - spt->image_offset[level] = NULL; - } - - assert(nr_images); - assert(!spt->image_offset[level]); - - spt->image_offset[level] = (unsigned *) MALLOC( nr_images * sizeof(unsigned) ); - spt->image_offset[level][0] = 0; -} - - -static void -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 < spt->nr_images[level]); - - 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, spt->image_offset[level][img]); - */ -} - - static void -sp_miptree_layout_2d( struct softpipe_texture *spt ) +softpipe_texture_layout(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 = pt->width[0]; unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; - 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 (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 (pt->first_level != pt->last_level) { - unsigned mip1_width = align(minify(pt->width[0]), align_w) - + minify(minify(pt->width[0])); - - 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. - */ - spt->pitch = align(spt->pitch * pt->cpp, 4) / pt->cpp; - spt->total_height = 0; + spt->buffer_size = 0; for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { - unsigned img_height; - - sp_miptree_set_level_info(spt, level, 1, x, y, width, height, 1); - - if (pt->compressed) - img_height = MAX2(1, height/4); - else - img_height = align(height, align_h); + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + spt->level_offset[level] = spt->buffer_size; - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - spt->total_height = MAX2(spt->total_height, y + img_height); - - /* Layout_below: step right after second mipmap. - */ - if (level == pt->first_level + 1) { - x += align(width, align_w); - } - else { - y += img_height; - } + spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * + ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * + width * pt->cpp; width = minify(width); height = minify(height); + depth = minify(depth); } } -static const int initial_offsets[6][2] = { - {0, 0}, - {0, 2}, - {1, 0}, - {1, 2}, - {1, 1}, - {1, 3} -}; - -static const int step_offsets[6][2] = { - {0, 2}, - {0, 2}, - {-1, 2}, - {-1, 2}, - {-1, 1}, - {-1, 1} -}; - - - -static boolean -softpipe_mipmap_tree_layout(struct pipe_context *pipe, struct softpipe_texture * spt) -{ - struct pipe_texture *pt = &spt->base; - unsigned level; - - switch (pt->target) { - case PIPE_TEXTURE_CUBE:{ - const unsigned dim = pt->width[0]; - unsigned face; - unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0]; - - assert(lvlWidth == lvlHeight); /* cubemap images are square */ - - /* Depending on the size of the largest images, pitch can be - * determined either by the old-style packing of cubemap faces, - * or the final row of 4x4, 2x2 and 1x1 faces below this. - */ - if (dim > 32) - spt->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp; - else - spt->pitch = 14 * 8; - - spt->total_height = dim * 4 + 4; - - /* Set all the levels to effectively occupy the whole rectangular region. - */ - 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; - lvlHeight /= 2; - } - - - for (face = 0; face < 6; face++) { - unsigned x = initial_offsets[face][0] * dim; - unsigned y = initial_offsets[face][1] * dim; - unsigned d = dim; - - if (dim == 4 && face >= 4) { - y = spt->total_height - 4; - x = (face - 4) * 8; - } - else if (dim < 4 && (face > 0 || pt->first_level > 0)) { - y = spt->total_height - 4; - x = face * 8; - } - - for (level = pt->first_level; level <= pt->last_level; level++) { - sp_miptree_set_image_offset(spt, level, face, x, y); - - d >>= 1; - - switch (d) { - case 4: - switch (face) { - case PIPE_TEX_FACE_POS_X: - case PIPE_TEX_FACE_NEG_X: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - case PIPE_TEX_FACE_POS_Y: - case PIPE_TEX_FACE_NEG_Y: - y += 12; - x -= 8; - break; - case PIPE_TEX_FACE_POS_Z: - case PIPE_TEX_FACE_NEG_Z: - y = spt->total_height - 4; - x = (face - 4) * 8; - break; - } - - case 2: - y = spt->total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - break; - } - case PIPE_TEXTURE_3D:{ - 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; - - spt->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp; - spt->total_height = 0; - - pack_y_pitch = MAX2(pt->height[0], 2); - pack_x_pitch = spt->pitch; - pack_x_nr = 1; - - 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(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(spt, level, q, x, y); - x += pack_x_pitch; - } - - x = 0; - y += pack_y_pitch; - } - - - spt->total_height += y; - - if (pack_x_pitch > 4) { - pack_x_pitch >>= 1; - pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= spt->pitch); - } - - if (pack_y_pitch > 2) { - pack_y_pitch >>= 1; - } - - width = minify(width); - height = minify(height); - depth = minify(depth); - } - break; - } - - case PIPE_TEXTURE_1D: - case PIPE_TEXTURE_2D: -// case PIPE_TEXTURE_RECTANGLE: - sp_miptree_layout_2d(spt); - break; - default: - assert(0); - break; - } - - /* - DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, - 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) { @@ -376,15 +89,13 @@ softpipe_texture_create(struct pipe_context *pipe, struct pipe_texture **pt) 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, 32, 0, 0); + softpipe_texture_layout(spt); - if (spt->buffer) { - pipe->winsys->buffer_data(pipe->winsys, spt->buffer, - spt->pitch * spt->base.cpp * - spt->total_height, NULL, - PIPE_BUFFER_USAGE_PIXEL); - } + spt->buffer = pipe->winsys->buffer_create(pipe->winsys, 32, 0, 0); + + if (spt->buffer) { + pipe->winsys->buffer_data(pipe->winsys, spt->buffer, spt->buffer_size, + NULL, PIPE_BUFFER_USAGE_PIXEL); } if (!spt->buffer) { @@ -408,7 +119,6 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) */ if (--(*pt)->refcount <= 0) { struct softpipe_texture *spt = softpipe_texture(*pt); - uint i; /* DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); @@ -416,10 +126,6 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) 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 index 732064d986..e1a5db2791 100644 --- a/src/mesa/pipe/softpipe/sp_texture.h +++ b/src/mesa/pipe/softpipe/sp_texture.h @@ -10,29 +10,12 @@ 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; + unsigned long buffer_size; }; diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.c b/src/mesa/pipe/softpipe/sp_tile_cache.c index 1dbcc5aadd..6515ce668c 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.c +++ b/src/mesa/pipe/softpipe/sp_tile_cache.c @@ -34,6 +34,7 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "pipe/util/p_tile.h" #include "sp_context.h" #include "sp_surface.h" #include "sp_tile_cache.h" @@ -49,6 +50,7 @@ struct softpipe_tile_cache { struct pipe_surface *surface; /**< the surface we're caching */ + void *surface_map; 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]; @@ -57,6 +59,7 @@ struct softpipe_tile_cache boolean depth_stencil; /** Is the surface a depth/stencil format? */ struct pipe_surface *tex_surf; + void *tex_surf_map; int tex_face, tex_level, tex_z; struct softpipe_cached_tile tile; /**< scratch tile for clears */ @@ -150,7 +153,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, { assert(!tc->texture); - if (tc->surface && tc->surface->map) { + if (tc->surface_map) { /*assert(tc->surface != ps);*/ pipe_surface_unmap(tc->surface); } @@ -158,8 +161,8 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, pipe_surface_reference(&tc->surface, ps); if (ps) { - if (!ps->map) - pipe_surface_map(ps); + if (tc->surface_map) + tc->surface_map = pipe_surface_map(ps); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || @@ -179,6 +182,32 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc) } +void +sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc) +{ + if (tc->surface && !tc->surface_map) + tc->surface_map = pipe_surface_map(tc->surface); + + if (tc->tex_surf && !tc->tex_surf_map) + tc->tex_surf_map = pipe_surface_map(tc->tex_surf); +} + + +void +sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc) +{ + if (tc->surface_map) { + pipe_surface_unmap(tc->surface); + tc->surface_map = NULL; + } + + if (tc->tex_surf_map) { + pipe_surface_unmap(tc->tex_surf); + tc->tex_surf_map = NULL; + } +} + + /** * Specify the texture to cache. */ @@ -192,8 +221,10 @@ sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, tc->texture = texture; - if (tc->tex_surf && tc->tex_surf->map) + if (tc->tex_surf_map) { pipe_surface_unmap(tc->tex_surf); + tc->tex_surf_map = NULL; + } pipe_surface_reference(&tc->tex_surf, NULL); /* mark as entries as invalid/empty */ @@ -330,9 +361,6 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, if (!ps || !ps->buffer) return; - 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) { @@ -342,9 +370,9 @@ sp_flush_tile_cache(struct softpipe_context *softpipe, tile->data.depth32, 0/*STRIDE*/); } else { - pipe->put_tile_rgba(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + pipe_put_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); } tile->x = tile->y = -1; /* mark as empty */ inuse++; @@ -391,9 +419,9 @@ sp_get_cached_tile(struct softpipe_context *softpipe, tile->data.depth32, 0/*STRIDE*/); } else { - pipe->put_tile_rgba(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + pipe_put_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); } } @@ -418,9 +446,9 @@ sp_get_cached_tile(struct softpipe_context *softpipe, tile->data.depth32, 0/*STRIDE*/); } else { - pipe->get_tile_rgba(pipe, ps, - tile->x, tile->y, TILE_SIZE, TILE_SIZE, - (float *) tile->data.color); + pipe_get_tile_rgba(pipe, ps, + tile->x, tile->y, TILE_SIZE, TILE_SIZE, + (float *) tile->data.color); } } } @@ -475,11 +503,11 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, tc->tex_z != z) { /* get new surface (view into texture) */ - if (tc->tex_surf && tc->tex_surf->map) + if (tc->tex_surf_map) pipe_surface_unmap(tc->tex_surf); tc->tex_surf = pipe->get_tex_surface(pipe, tc->texture, face, level, z); - pipe_surface_map(tc->tex_surf); + tc->tex_surf_map = pipe_surface_map(tc->tex_surf); tc->tex_face = face; tc->tex_level = level; @@ -487,9 +515,9 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, } /* 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); + 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; diff --git a/src/mesa/pipe/softpipe/sp_tile_cache.h b/src/mesa/pipe/softpipe/sp_tile_cache.h index 91fb2795a2..7fd1081286 100644 --- a/src/mesa/pipe/softpipe/sp_tile_cache.h +++ b/src/mesa/pipe/softpipe/sp_tile_cache.h @@ -74,6 +74,12 @@ extern struct pipe_surface * sp_tile_cache_get_surface(struct softpipe_tile_cache *tc); extern void +sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc); + +extern void +sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc); + +extern void sp_tile_cache_set_texture(struct softpipe_tile_cache *tc, struct pipe_texture *texture); |
