diff options
Diffstat (limited to 'src/mesa/pipe')
37 files changed, 1254 insertions, 642 deletions
diff --git a/src/mesa/pipe/cell/common.h b/src/mesa/pipe/cell/common.h index f05070d25a..4c998722a2 100644 --- a/src/mesa/pipe/cell/common.h +++ b/src/mesa/pipe/cell/common.h @@ -60,6 +60,7 @@ #define CELL_CMD_RENDER 5 #define CELL_CMD_BATCH 6 #define CELL_CMD_STATE_DEPTH_STENCIL 7 +#define CELL_CMD_STATE_SAMPLER 8 #define CELL_NUM_BATCH_BUFFERS 3 diff --git a/src/mesa/pipe/cell/ppu/Makefile b/src/mesa/pipe/cell/ppu/Makefile index 6a1bd5982f..e7f2562da7 100644 --- a/src/mesa/pipe/cell/ppu/Makefile +++ b/src/mesa/pipe/cell/ppu/Makefile @@ -17,6 +17,7 @@ SPU_CODE_MODULE = ../spu/g3d_spu.a SOURCES = \ cell_batch.c \ + cell_clear.c \ cell_context.c \ cell_draw_arrays.c \ cell_flush.c \ @@ -31,6 +32,7 @@ SOURCES = \ cell_state_vertex.c \ cell_spu.c \ cell_surface.c \ + cell_texture.c \ cell_vbuf.c \ cell_winsys.c diff --git a/src/mesa/pipe/cell/ppu/cell_clear.c b/src/mesa/pipe/cell/ppu/cell_clear.c new file mode 100644 index 0000000000..48c1c8e2c8 --- /dev/null +++ b/src/mesa/pipe/cell/ppu/cell_clear.c @@ -0,0 +1,99 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * Authors + * Brian Paul + */ + +#include <stdio.h> +#include <assert.h> +#include <stdint.h> +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/cell/common.h" +#include "cell_clear.h" +#include "cell_context.h" +#include "cell_batch.h" +#include "cell_spu.h" + + +void +cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + struct cell_context *cell = cell_context(pipe); + uint i; + uint surfIndex; + + if (!cell->cbuf_map[0]) + cell->cbuf_map[0] = pipe_surface_map(ps); + + if (ps == cell->framebuffer.zbuf) { + surfIndex = 1; + } + else { + surfIndex = 0; + } + +#if 0 + for (i = 0; i < cell->num_spus; i++) { +#if 1 + uint clr = clearValue; + if (surfIndex == 0) { + /* XXX debug: clear color varied per-SPU to visualize tiles */ + if ((clr & 0xff) == 0) + clr |= 64 + i * 8; + if ((clr & 0xff00) == 0) + clr |= (64 + i * 8) << 8; + if ((clr & 0xff0000) == 0) + clr |= (64 + i * 8) << 16; + if ((clr & 0xff000000) == 0) + clr |= (64 + i * 8) << 24; + } + cell_global.command[i].clear.value = clr; +#else + cell_global.command[i].clear.value = clearValue; +#endif + cell_global.command[i].clear.surface = surfIndex; + send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE); + } +#else + { + struct cell_command_clear_surface *clr + = (struct cell_command_clear_surface *) + cell_batch_alloc(cell, sizeof(*clr)); + clr->opcode = CELL_CMD_CLEAR_SURFACE; + clr->surface = surfIndex; + clr->value = clearValue; + } +#endif + + /* XXX temporary */ + cell_flush(&cell->pipe, 0x0); + +} diff --git a/src/mesa/pipe/cell/ppu/cell_clear.h b/src/mesa/pipe/cell/ppu/cell_clear.h new file mode 100644 index 0000000000..4c69c4c89f --- /dev/null +++ b/src/mesa/pipe/cell/ppu/cell_clear.h @@ -0,0 +1,43 @@ +/************************************************************************** + * + * 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 CELL_SURFACE_H +#define CELL_SURFACE_H + + +struct pipe_context; +struct pipe_surface; + + +extern void +cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + + + +#endif /* CELL_SURFACE_H */ diff --git a/src/mesa/pipe/cell/ppu/cell_context.c b/src/mesa/pipe/cell/ppu/cell_context.c index 897c187d65..3db1dbdb46 100644 --- a/src/mesa/pipe/cell/ppu/cell_context.c +++ b/src/mesa/pipe/cell/ppu/cell_context.c @@ -39,6 +39,7 @@ #include "pipe/p_winsys.h" #include "pipe/cell/common.h" #include "pipe/draw/draw_context.h" +#include "cell_clear.h" #include "cell_context.h" #include "cell_draw_arrays.h" #include "cell_flush.h" @@ -46,6 +47,7 @@ #include "cell_state.h" #include "cell_surface.h" #include "cell_spu.h" +#include "cell_texture.h" #include "cell_vbuf.h" @@ -225,16 +227,20 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws) cell->pipe.clear = cell_clear_surface; cell->pipe.flush = cell_flush; + /* textures */ + cell->pipe.texture_create = cell_texture_create; + cell->pipe.texture_release = cell_texture_release; + cell->pipe.get_tex_surface = cell_get_tex_surface; + + cell->pipe.set_sampler_texture = cell_set_sampler_texture; + #if 0 cell->pipe.begin_query = cell_begin_query; cell->pipe.end_query = cell_end_query; cell->pipe.wait_query = cell_wait_query; - - /* textures */ - cell->pipe.mipmap_tree_layout = cell_mipmap_tree_layout; - cell->pipe.get_tex_surface = cell_get_tex_surface; #endif + cell_init_surface_functions(cell); cell->draw = draw_create(); diff --git a/src/mesa/pipe/cell/ppu/cell_context.h b/src/mesa/pipe/cell/ppu/cell_context.h index 08e448f14f..1937812e2d 100644 --- a/src/mesa/pipe/cell/ppu/cell_context.h +++ b/src/mesa/pipe/cell/ppu/cell_context.h @@ -76,7 +76,7 @@ struct cell_context struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; - struct softpipe_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_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/cell/ppu/cell_state.h b/src/mesa/pipe/cell/ppu/cell_state.h index d2091f8edf..fbca7c9574 100644 --- a/src/mesa/pipe/cell/ppu/cell_state.h +++ b/src/mesa/pipe/cell/ppu/cell_state.h @@ -86,6 +86,11 @@ void cell_set_constant_buffer(struct pipe_context *pipe, void cell_set_polygon_stipple( struct pipe_context *, const struct pipe_poly_stipple * ); +void +cell_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, + struct pipe_texture *texture); + void cell_set_scissor_state( struct pipe_context *, const struct pipe_scissor_state * ); diff --git a/src/mesa/pipe/cell/ppu/cell_state_derived.c b/src/mesa/pipe/cell/ppu/cell_state_derived.c index c654990325..1e31c11ecd 100644 --- a/src/mesa/pipe/cell/ppu/cell_state_derived.c +++ b/src/mesa/pipe/cell/ppu/cell_state_derived.c @@ -54,6 +54,7 @@ static void calculate_vertex_layout( struct cell_context *cell ) = cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct vertex_info *vinfo = &cell->vertex_info; uint front0; + uint src = 0; memset(vinfo, 0, sizeof(*vinfo)); @@ -68,10 +69,10 @@ static void calculate_vertex_layout( struct cell_context *cell ) #endif /* always emit vertex pos */ - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR); + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src++); #if 1 - front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); #endif #if 0 @@ -94,11 +95,11 @@ static void calculate_vertex_layout( struct cell_context *cell ) case TGSI_SEMANTIC_COLOR: if (vs->output_semantic_index[i] == 0) { - front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } else { assert(vs->output_semantic_index[i] == 1); - front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } break; @@ -113,7 +114,7 @@ static void calculate_vertex_layout( struct cell_context *cell ) break; case TGSI_SEMANTIC_FOG: - draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE); + draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE, src++); break; case TGSI_SEMANTIC_PSIZE: @@ -125,7 +126,7 @@ static void calculate_vertex_layout( struct cell_context *cell ) case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE); + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src++); break; default: @@ -140,14 +141,14 @@ static void calculate_vertex_layout( struct cell_context *cell ) * up 1:1 with the fragment shader inputs. */ if (emitBack0) { - back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } if (emitBack1) { - back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } if (emitPsize) { cell->psize_slot - = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT); + = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT, src++); } /* If the attributes have changed, tell the draw module about @@ -219,7 +220,7 @@ void cell_update_derived( struct cell_context *cell ) compute_cliprect(cell); #endif - //cell_emit_state(cell); + cell_emit_state(cell); cell->dirty = 0; } diff --git a/src/mesa/pipe/cell/ppu/cell_state_emit.c b/src/mesa/pipe/cell/ppu/cell_state_emit.c index e1a1458f39..e7d14d0d25 100644 --- a/src/mesa/pipe/cell/ppu/cell_state_emit.c +++ b/src/mesa/pipe/cell/ppu/cell_state_emit.c @@ -42,4 +42,11 @@ cell_emit_state(struct cell_context *cell) cell_batch_append(cell, cell->depth_stencil, sizeof(struct pipe_depth_stencil_alpha_state)); } + + if (cell->dirty & CELL_NEW_SAMPLER) { + uint cmd = CELL_CMD_STATE_SAMPLER; + cell_batch_append(cell, &cmd, 4); + cell_batch_append(cell, cell->sampler[0], + sizeof(struct pipe_sampler_state)); + } } diff --git a/src/mesa/pipe/cell/ppu/cell_state_sampler.c b/src/mesa/pipe/cell/ppu/cell_state_sampler.c index 1e7d4f08b8..ae1eeb4620 100644 --- a/src/mesa/pipe/cell/ppu/cell_state_sampler.c +++ b/src/mesa/pipe/cell/ppu/cell_state_sampler.c @@ -66,3 +66,17 @@ cell_delete_sampler_state(struct pipe_context *pipe, { FREE( sampler ); } + + + +void +cell_set_sampler_texture(struct pipe_context *pipe, + unsigned sampler, + struct pipe_texture *texture) +{ + struct cell_context *cell = cell_context(pipe); + + cell->texture[sampler] = texture; + + cell->dirty |= CELL_NEW_TEXTURE; +} diff --git a/src/mesa/pipe/cell/ppu/cell_surface.c b/src/mesa/pipe/cell/ppu/cell_surface.c index 53c5325ddd..c8796dab43 100644 --- a/src/mesa/pipe/cell/ppu/cell_surface.c +++ b/src/mesa/pipe/cell/ppu/cell_surface.c @@ -25,75 +25,158 @@ * **************************************************************************/ -/** - * Authors - * Brian Paul - */ - -#include <stdio.h> -#include <assert.h> -#include <stdint.h> -#include "pipe/p_inlines.h" +#include "pipe/p_defines.h" #include "pipe/p_util.h" -#include "pipe/cell/common.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" +#include "pipe/util/p_tile.h" #include "cell_context.h" -#include "cell_batch.h" #include "cell_surface.h" -#include "cell_spu.h" -void -cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue) +/* 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 +cell_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) { - struct cell_context *cell = cell_context(pipe); - uint i; - uint surfIndex; + pipe_copy_rect(pipe_surface_map(dst), + dst->cpp, + dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); - if (!cell->cbuf_map[0]) - cell->cbuf_map[0] = pipe_surface_map(ps); + pipe_surface_unmap(dst); +} - if (ps == cell->framebuffer.zbuf) { - surfIndex = 1; - } - else { - surfIndex = 0; - } -#if 0 - for (i = 0; i < cell->num_spus; i++) { -#if 1 - uint clr = clearValue; - if (surfIndex == 0) { - /* XXX debug: clear color varied per-SPU to visualize tiles */ - if ((clr & 0xff) == 0) - clr |= 64 + i * 8; - if ((clr & 0xff00) == 0) - clr |= (64 + i * 8) << 8; - if ((clr & 0xff0000) == 0) - clr |= (64 + i * 8) << 16; - if ((clr & 0xff000000) == 0) - clr |= (64 + i * 8) << 24; +static void +cell_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 ); + + pipe_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 void * +get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y) +{ + return (char *)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 +cell_surface_fill(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, unsigned value) +{ + unsigned i, j; + void *dst_map = pipe_surface_map(dst); + + assert(dst->pitch > 0); + assert(width <= dst->pitch); + + switch (dst->cpp) { + case 1: + { + ubyte *row = get_pointer(dst, dst_map, dstx, dsty); + for (i = 0; i < height; i++) { + memset(row, value, width); + row += dst->pitch; + } } - cell_global.command[i].clear.value = clr; -#else - cell_global.command[i].clear.value = clearValue; -#endif - cell_global.command[i].clear.surface = surfIndex; - send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_CLEAR_SURFACE); - } -#else - { - struct cell_command_clear_surface *clr - = (struct cell_command_clear_surface *) - cell_batch_alloc(cell, sizeof(*clr)); - clr->opcode = CELL_CMD_CLEAR_SURFACE; - clr->surface = surfIndex; - clr->value = clearValue; + break; + case 2: + { + 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; + row += dst->pitch; + } + } + break; + case 4: + { + unsigned *row = get_pointer(dst, dst_map, 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, 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); + ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff); + val0 = (val0 << 8) | val0; + val1 = (val1 << 8) | val1; + val2 = (val2 << 8) | val2; + val3 = (val3 << 8) | val3; + 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; } -#endif - /* XXX temporary */ - cell_flush(&cell->pipe, 0x0); + pipe_surface_unmap( dst ); +} + + +void +cell_init_surface_functions(struct cell_context *cell) +{ + cell->pipe.get_tile = pipe_get_tile_raw; + cell->pipe.put_tile = pipe_put_tile_raw; + cell->pipe.surface_data = cell_surface_data; + cell->pipe.surface_copy = cell_surface_copy; + cell->pipe.surface_fill = cell_surface_fill; } diff --git a/src/mesa/pipe/cell/ppu/cell_surface.h b/src/mesa/pipe/cell/ppu/cell_surface.h index 4c69c4c89f..9e58f32944 100644 --- a/src/mesa/pipe/cell/ppu/cell_surface.h +++ b/src/mesa/pipe/cell/ppu/cell_surface.h @@ -1,8 +1,8 @@ /************************************************************************** * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008 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 @@ -25,19 +25,18 @@ * **************************************************************************/ +/* Authors: Keith Whitwell <keith@tungstengraphics.com> + */ #ifndef CELL_SURFACE_H #define CELL_SURFACE_H -struct pipe_context; -struct pipe_surface; +struct cell_context; extern void -cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps, - unsigned clearValue); - +cell_init_surface_functions(struct cell_context *cell); -#endif /* CELL_SURFACE_H */ +#endif /* SP_SURFACE_H */ diff --git a/src/mesa/pipe/cell/ppu/cell_texture.c b/src/mesa/pipe/cell/ppu/cell_texture.c new file mode 100644 index 0000000000..8f342d8aad --- /dev/null +++ b/src/mesa/pipe/cell/ppu/cell_texture.c @@ -0,0 +1,168 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Michel Dänzer <michel@tungstengraphics.com> + */ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_inlines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" + +#include "cell_context.h" +#include "cell_state.h" +#include "cell_texture.h" + + +/* Simple, maximally packed layout. + */ + +static unsigned minify( unsigned d ) +{ + return MAX2(1, d>>1); +} + + +static void +cell_texture_layout(struct cell_texture * spt) +{ + struct pipe_texture *pt = &spt->base; + unsigned level; + unsigned width = pt->width[0]; + unsigned height = pt->height[0]; + unsigned depth = pt->depth[0]; + + spt->buffer_size = 0; + + for ( level = pt->first_level ; level <= pt->last_level ; level++ ) { + pt->width[level] = width; + pt->height[level] = height; + pt->depth[level] = depth; + + spt->level_offset[level] = spt->buffer_size; + + 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); + } +} + + +void +cell_texture_create(struct pipe_context *pipe, struct pipe_texture **pt) +{ + struct cell_texture *spt = REALLOC(*pt, sizeof(struct pipe_texture), + sizeof(struct cell_texture)); + + if (spt) { + memset(&spt->base + 1, 0, + sizeof(struct cell_texture) - sizeof(struct pipe_texture)); + + cell_texture_layout(spt); + + 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) { + FREE(spt); + spt = NULL; + } + } + + *pt = &spt->base; +} + +void +cell_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 cell_texture *spt = cell_texture(*pt); + + /* + DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); + */ + + pipe->winsys->buffer_reference(pipe->winsys, &spt->buffer, NULL); + + FREE(spt); + } + *pt = NULL; +} + + +/** + * Called via pipe->get_tex_surface() + */ +struct pipe_surface * +cell_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct cell_texture *spt = cell_texture(pt); + struct pipe_surface *ps; + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + 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; +} diff --git a/src/mesa/pipe/cell/ppu/cell_texture.h b/src/mesa/pipe/cell/ppu/cell_texture.h new file mode 100644 index 0000000000..97d8bd1230 --- /dev/null +++ b/src/mesa/pipe/cell/ppu/cell_texture.h @@ -0,0 +1,73 @@ +/************************************************************************** + * + * 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 CELL_TEXTURE_H +#define CELL_TEXTURE_H + + +struct pipe_context; +struct pipe_texture; + + +/** + * Subclass of pipe_texture + */ +struct cell_texture +{ + struct pipe_texture base; + + unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer_handle *buffer; + unsigned long buffer_size; +}; + + +/** cast wrapper */ +static INLINE struct cell_texture * +cell_texture(struct pipe_texture *pt) +{ + return (struct cell_texture *) pt; +} + + + +extern void +cell_texture_create(struct pipe_context *pipe, struct pipe_texture **pt); + +extern void +cell_texture_release(struct pipe_context *pipe, struct pipe_texture **pt); + +extern struct pipe_surface * +cell_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice); + + +#endif /* CELL_TEXTURE */ diff --git a/src/mesa/pipe/cell/spu/Makefile b/src/mesa/pipe/cell/spu/Makefile index b92a756cd5..417ae1b072 100644 --- a/src/mesa/pipe/cell/spu/Makefile +++ b/src/mesa/pipe/cell/spu/Makefile @@ -22,12 +22,17 @@ SOURCES = \ SPU_OBJECTS = $(SOURCES:.c=.o) \ +SPU_ASM_OUT = $(SOURCES:.c=.s) \ + INCLUDE_DIRS = -I$(TOP)/src/mesa .c.o: $(SPU_CC) $(SPU_CFLAGS) -c $< +.c.s: + $(SPU_CC) $(SPU_CFLAGS) -S $< + # The .a file will be linked into the main/PPU executable default: $(PROG_SPU_A) @@ -43,8 +48,11 @@ $(PROG_SPU): $(SPU_OBJECTS) +asmfiles: $(SPU_ASM_OUT) + + clean: - rm -f *~ *.o *.a *.d $(PROG_SPU) + rm -f *~ *.o *.a *.d *.s $(PROG_SPU) diff --git a/src/mesa/pipe/cell/spu/spu_main.c b/src/mesa/pipe/cell/spu/spu_main.c index bff098f06e..2e5cb76b4a 100644 --- a/src/mesa/pipe/cell/spu/spu_main.c +++ b/src/mesa/pipe/cell/spu/spu_main.c @@ -78,31 +78,27 @@ static void really_clear_tiles(uint surfaceIndex) { const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles; - uint i, j; + uint i; if (surfaceIndex == 0) { - for (i = 0; i < TILE_SIZE; i++) - for (j = 0; j < TILE_SIZE; j++) - ctile[i][j] = spu.fb.color_clear_value; /*0xff00ff;*/ + clear_c_tile(&ctile); for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) { uint tx = i % spu.fb.width_tiles; uint ty = i / spu.fb.width_tiles; if (tile_status[ty][tx] == TILE_STATUS_CLEAR) { - put_tile(tx, ty, (uint *) ctile, TAG_SURFACE_CLEAR, 0); + put_tile(tx, ty, &ctile, TAG_SURFACE_CLEAR, 0); } } } else { - for (i = 0; i < TILE_SIZE; i++) - for (j = 0; j < TILE_SIZE; j++) - ztile[i][j] = spu.fb.depth_clear_value; + clear_z_tile(&ztile); for (i = spu.init.id; i < num_tiles; i += spu.init.num_spus) { uint tx = i % spu.fb.width_tiles; uint ty = i / spu.fb.width_tiles; if (tile_status_z[ty][tx] == TILE_STATUS_CLEAR) - put_tile(tx, ty, (uint *) ctile, TAG_SURFACE_CLEAR, 1); + put_tile(tx, ty, &ctile, TAG_SURFACE_CLEAR, 1); } } @@ -116,7 +112,7 @@ static void cmd_clear_surface(const struct cell_command_clear_surface *clear) { const uint num_tiles = spu.fb.width_tiles * spu.fb.height_tiles; - uint i, j; + uint i; if (Debug) printf("SPU %u: CLEAR SURF %u to 0x%08x\n", spu.init.id, @@ -137,14 +133,12 @@ cmd_clear_surface(const struct cell_command_clear_surface *clear) #endif if (clear->surface == 0) { - for (i = 0; i < TILE_SIZE; i++) - for (j = 0; j < TILE_SIZE; j++) - ctile[i][j] = clear->value; + spu.fb.color_clear_value = clear->value; + clear_c_tile(&ctile); } else { - for (i = 0; i < TILE_SIZE; i++) - for (j = 0; j < TILE_SIZE; j++) - ztile[i][j] = clear->value; + spu.fb.depth_clear_value = clear->value; + clear_z_tile(&ztile); } /* @@ -156,9 +150,9 @@ cmd_clear_surface(const struct cell_command_clear_surface *clear) uint tx = i % spu.fb.width_tiles; uint ty = i / spu.fb.width_tiles; if (clear->surface == 0) - put_tile(tx, ty, (uint *) ctile, TAG_SURFACE_CLEAR, 0); + put_tile(tx, ty, &ctile, TAG_SURFACE_CLEAR, 0); else - put_tile(tx, ty, (uint *) ztile, TAG_SURFACE_CLEAR, 1); + put_tile(tx, ty, &ztile, TAG_SURFACE_CLEAR, 1); /* XXX we don't want this here, but it fixes bad tile results */ } @@ -239,8 +233,8 @@ cmd_render(const struct cell_command_render *render) /* how much vertex data */ vertex_bytes = render->num_verts * vertex_size; index_bytes = render->num_indexes * sizeof(ushort); - if (index_bytes < 8) - index_bytes = 8; + if (index_bytes < 16) + index_bytes = 16; else index_bytes = (index_bytes + 15) & ~0xf; /* multiple of 16 */ @@ -297,14 +291,14 @@ cmd_render(const struct cell_command_render *render) /* Start fetching color/z tiles. We'll wait for completion when * we need read/write to them later in triangle rasterization. */ - if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { + if (spu.depth_stencil.depth.enabled) { if (tile_status_z[ty][tx] != TILE_STATUS_CLEAR) { - get_tile(tx, ty, (uint *) ztile, TAG_READ_TILE_Z, 1); + get_tile(tx, ty, &ztile, TAG_READ_TILE_Z, 1); } } if (tile_status[ty][tx] != TILE_STATUS_CLEAR) { - get_tile(tx, ty, (uint *) ctile, TAG_READ_TILE_COLOR, 0); + get_tile(tx, ty, &ctile, TAG_READ_TILE_COLOR, 0); } ASSERT(render->prim_type == PIPE_PRIM_TRIANGLES); @@ -322,19 +316,19 @@ cmd_render(const struct cell_command_render *render) /* write color/z tiles back to main framebuffer, if dirtied */ if (tile_status[ty][tx] == TILE_STATUS_DIRTY) { - put_tile(tx, ty, (uint *) ctile, TAG_WRITE_TILE_COLOR, 0); + put_tile(tx, ty, &ctile, TAG_WRITE_TILE_COLOR, 0); tile_status[ty][tx] = TILE_STATUS_DEFINED; } - if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { + if (spu.depth_stencil.depth.enabled) { if (tile_status_z[ty][tx] == TILE_STATUS_DIRTY) { - put_tile(tx, ty, (uint *) ztile, TAG_WRITE_TILE_Z, 1); + put_tile(tx, ty, &ztile, TAG_WRITE_TILE_Z, 1); tile_status_z[ty][tx] = TILE_STATUS_DEFINED; } } /* XXX move these... */ wait_on_mask(1 << TAG_WRITE_TILE_COLOR); - if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { + if (spu.depth_stencil.depth.enabled) { wait_on_mask(1 << TAG_WRITE_TILE_Z); } } @@ -365,6 +359,13 @@ cmd_framebuffer(const struct cell_command_framebuffer *cmd) spu.fb.height = cmd->height; spu.fb.width_tiles = (spu.fb.width + TILE_SIZE - 1) / TILE_SIZE; spu.fb.height_tiles = (spu.fb.height + TILE_SIZE - 1) / TILE_SIZE; + + if (spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM) + spu.fb.zsize = 4; + else if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) + spu.fb.zsize = 2; + else + spu.fb.zsize = 0; } @@ -375,9 +376,19 @@ cmd_state_depth_stencil(const struct pipe_depth_stencil_alpha_state *state) printf("SPU %u: DEPTH_STENCIL: ztest %d\n", spu.init.id, state->depth.enabled); - /* + memcpy(&spu.depth_stencil, state, sizeof(*state)); - */ +} + + +static void +cmd_state_sampler(const struct pipe_sampler_state *state) +{ + if (Debug) + printf("SPU %u: SAMPLER\n", + spu.init.id); + + memcpy(&spu.sampler[0], state, sizeof(*state)); } @@ -500,6 +511,11 @@ cmd_batch(uint opcode) &buffer[pos+1]); pos += (1 + sizeof(struct pipe_depth_stencil_alpha_state) / 4); break; + case CELL_CMD_STATE_SAMPLER: + cmd_state_sampler((struct pipe_sampler_state *) + &buffer[pos+1]); + pos += (1 + sizeof(struct pipe_sampler_state) / 4); + break; default: printf("SPU %u: bad opcode: 0x%x\n", spu.init.id, buffer[pos]); ASSERT(0); diff --git a/src/mesa/pipe/cell/spu/spu_main.h b/src/mesa/pipe/cell/spu/spu_main.h index f39f375d24..3ef73c9473 100644 --- a/src/mesa/pipe/cell/spu/spu_main.h +++ b/src/mesa/pipe/cell/spu/spu_main.h @@ -43,6 +43,8 @@ struct spu_framebuffer { uint color_clear_value; uint depth_clear_value; + + uint zsize; /**< 0, 2 or 4 bytes per Z */ } ALIGN16_ATTRIB; @@ -56,6 +58,7 @@ struct spu_global struct spu_framebuffer fb; struct pipe_depth_stencil_alpha_state depth_stencil; struct pipe_blend_state blend; + struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; /* XXX more state to come */ } ALIGN16_ATTRIB; @@ -88,8 +91,26 @@ extern struct spu_global spu; } -void +extern void wait_on_mask(unsigned tag); +static INLINE void +memset16(ushort *d, ushort value, uint count) +{ + uint i; + for (i = 0; i < count; i++) + d[i] = value; +} + + +static INLINE void +memset32(uint *d, uint value, uint count) +{ + uint i; + for (i = 0; i < count; i++) + d[i] = value; +} + + #endif /* SPU_MAIN_H */ diff --git a/src/mesa/pipe/cell/spu/spu_tile.c b/src/mesa/pipe/cell/spu/spu_tile.c index 1505cb322b..ca1352f9f8 100644 --- a/src/mesa/pipe/cell/spu/spu_tile.c +++ b/src/mesa/pipe/cell/spu/spu_tile.c @@ -31,8 +31,8 @@ -uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB; -ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB; +tile_t ctile ALIGN16_ATTRIB; +tile_t ztile ALIGN16_ATTRIB; ubyte tile_status[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; ubyte tile_status_z[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; @@ -40,10 +40,10 @@ ubyte tile_status_z[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB; void -get_tile(uint tx, uint ty, uint *tile, int tag, int zBuf) +get_tile(uint tx, uint ty, tile_t *tile, int tag, int zBuf) { const uint offset = ty * spu.fb.width_tiles + tx; - const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? 2 : 4); + const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? spu.fb.zsize : 4); const ubyte *src = zBuf ? spu.fb.depth_start : spu.fb.color_start; src += offset * bytesPerTile; @@ -55,7 +55,7 @@ get_tile(uint tx, uint ty, uint *tile, int tag, int zBuf) printf("get_tile: dest: %p src: 0x%x size: %d\n", tile, (unsigned int) src, bytesPerTile); */ - mfc_get(tile, /* dest in local memory */ + mfc_get(tile->t32, /* dest in local memory */ (unsigned int) src, /* src in main memory */ bytesPerTile, tag, @@ -65,10 +65,10 @@ get_tile(uint tx, uint ty, uint *tile, int tag, int zBuf) void -put_tile(uint tx, uint ty, const uint *tile, int tag, int zBuf) +put_tile(uint tx, uint ty, const tile_t *tile, int tag, int zBuf) { const uint offset = ty * spu.fb.width_tiles + tx; - const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? 2 : 4); + const uint bytesPerTile = TILE_SIZE * TILE_SIZE * (zBuf ? spu.fb.zsize : 4); ubyte *dst = zBuf ? spu.fb.depth_start : spu.fb.color_start; dst += offset * bytesPerTile; @@ -81,8 +81,7 @@ put_tile(uint tx, uint ty, const uint *tile, int tag, int zBuf) spu.init.id, tile, (unsigned int) dst, bytesPerTile); */ - - mfc_put((void *) tile, /* src in local memory */ + mfc_put((void *) tile->t32, /* src in local memory */ (unsigned int) dst, /* dst in main memory */ bytesPerTile, tag, @@ -90,26 +89,3 @@ put_tile(uint tx, uint ty, const uint *tile, int tag, int zBuf) 0 /* rid */); } - -void -clear_tile(uint tile[TILE_SIZE][TILE_SIZE], uint value) -{ - uint i, j; - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile[i][j] = value; - } - } -} - -void -clear_tile_z(ushort tile[TILE_SIZE][TILE_SIZE], uint value) -{ - uint i, j; - for (i = 0; i < TILE_SIZE; i++) { - for (j = 0; j < TILE_SIZE; j++) { - tile[i][j] = value; - } - } -} - diff --git a/src/mesa/pipe/cell/spu/spu_tile.h b/src/mesa/pipe/cell/spu/spu_tile.h index 637923764b..f83dc009c2 100644 --- a/src/mesa/pipe/cell/spu/spu_tile.h +++ b/src/mesa/pipe/cell/spu/spu_tile.h @@ -39,8 +39,14 @@ #define MAX_HEIGHT 1024 -extern uint ctile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB; -extern ushort ztile[TILE_SIZE][TILE_SIZE] ALIGN16_ATTRIB; +typedef union { + ushort t16[TILE_SIZE][TILE_SIZE]; + uint t32[TILE_SIZE][TILE_SIZE]; +} tile_t; + + +extern tile_t ctile ALIGN16_ATTRIB; +extern tile_t ztile ALIGN16_ATTRIB; #define TILE_STATUS_CLEAR 1 @@ -52,16 +58,36 @@ extern ubyte tile_status_z[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_AT void -get_tile(uint tx, uint ty, uint *tile, int tag, int zBuf); - -void -put_tile(uint tx, uint ty, const uint *tile, int tag, int zBuf); - -void -clear_tile(uint tile[TILE_SIZE][TILE_SIZE], uint value); +get_tile(uint tx, uint ty, tile_t *tile, int tag, int zBuf); void -clear_tile_z(ushort tile[TILE_SIZE][TILE_SIZE], uint value); +put_tile(uint tx, uint ty, const tile_t *tile, int tag, int zBuf); + + + +static INLINE void +clear_c_tile(tile_t *ctile) +{ + memset32((uint*) ctile->t32, + spu.fb.color_clear_value, + TILE_SIZE * TILE_SIZE); +} + + +static INLINE void +clear_z_tile(tile_t *ztile) +{ + if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { + memset16((ushort*) ztile->t16, + spu.fb.depth_clear_value, + TILE_SIZE * TILE_SIZE); + } + else { + memset32((uint*) ztile->t32, + spu.fb.depth_clear_value, + TILE_SIZE * TILE_SIZE); + } +} #endif /* SPU_TILE_H */ diff --git a/src/mesa/pipe/cell/spu/spu_tri.c b/src/mesa/pipe/cell/spu/spu_tri.c index ddd5e662d2..1d73c5171c 100644 --- a/src/mesa/pipe/cell/spu/spu_tri.c +++ b/src/mesa/pipe/cell/spu/spu_tri.c @@ -217,8 +217,8 @@ static INLINE void eval_z( struct setup_stage *setup, float x, float y, float result[4]) { - uint slot = 0; - uint i = 2; + const uint slot = 0; + const uint i = 2; const float *dadx = setup->coef[slot].dadx; const float *dady = setup->coef[slot].dady; @@ -252,78 +252,128 @@ pack_color(const float color[4]) } -/** - * Emit a quad (pass to next stage). No clipping is done. - */ -static INLINE void -emit_quad( struct setup_stage *setup, int x, int y, unsigned mask ) +static uint +do_depth_test(struct setup_stage *setup, int x, int y, unsigned mask) { -#if 0 - struct softpipe_context *sp = setup->softpipe; - setup->quad.x0 = x; - setup->quad.y0 = y; - setup->quad.mask = mask; - sp->quad.first->run(sp->quad.first, &setup->quad); -#else - /* Cell: "write" quad fragments to the tile by setting prim color */ int ix = x - setup->cliprect_minx; int iy = y - setup->cliprect_miny; - float colors[4][4]; - uint z; + float zvals[4]; + + eval_z(setup, (float) x, (float) y, zvals); + + if (tile_status_z[setup->ty][setup->tx] == TILE_STATUS_CLEAR) { + /* now, _really_ clear the tile */ + clear_z_tile(&ztile); + } + else { + /* make sure we've got the tile from main mem */ + wait_on_mask(1 << TAG_READ_TILE_Z); + } + tile_status_z[setup->ty][setup->tx] = TILE_STATUS_DIRTY; - eval_coeff(setup, 1, (float) x, (float) y, colors); if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) { - float zvals[4]; - eval_z(setup, (float) x, (float) y, zvals); + const float zscale = 65535.0; + if (mask & MASK_TOP_LEFT) { + uint z = (uint) (zvals[0] * zscale); + if (z < ztile.t16[iy][ix]) + ztile.t16[iy][ix] = z; + else + mask &= ~MASK_TOP_LEFT; + } - if (tile_status_z[setup->ty][setup->tx] == TILE_STATUS_CLEAR) { - /* now, _really_ clear the tile */ - clear_tile_z(ztile, spu.fb.depth_clear_value); + if (mask & MASK_TOP_RIGHT) { + uint z = (uint) (zvals[1] * zscale); + if (z < ztile.t16[iy][ix+1]) + ztile.t16[iy][ix+1] = z; + else + mask &= ~MASK_TOP_RIGHT; } - else { - /* make sure we've got the tile from main mem */ - wait_on_mask(1 << TAG_READ_TILE_Z); + + if (mask & MASK_BOTTOM_LEFT) { + uint z = (uint) (zvals[2] * zscale); + if (z < ztile.t16[iy+1][ix]) + ztile.t16[iy+1][ix] = z; + else + mask &= ~MASK_BOTTOM_LEFT; } - tile_status_z[setup->ty][setup->tx] = TILE_STATUS_DIRTY; + if (mask & MASK_BOTTOM_RIGHT) { + uint z = (uint) (zvals[3] * zscale); + if (z < ztile.t16[iy+1][ix+1]) + ztile.t16[iy+1][ix+1] = z; + else + mask &= ~MASK_BOTTOM_RIGHT; + } + } + else { + const float zscale = (float) 0xffffffff; + ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM); if (mask & MASK_TOP_LEFT) { - z = (uint) (zvals[0] * 65535.0); - if (z < ztile[iy][ix]) - ztile[iy][ix] = z; + uint z = (uint) (zvals[0] * zscale); + if (z < ztile.t32[iy][ix]) + ztile.t32[iy][ix] = z; else mask &= ~MASK_TOP_LEFT; } if (mask & MASK_TOP_RIGHT) { - z = (uint) (zvals[1] * 65535.0); - if (z < ztile[iy][ix+1]) - ztile[iy][ix+1] = z; + uint z = (uint) (zvals[1] * zscale); + if (z < ztile.t32[iy][ix+1]) + ztile.t32[iy][ix+1] = z; else mask &= ~MASK_TOP_RIGHT; } if (mask & MASK_BOTTOM_LEFT) { - z = (uint) (zvals[2] * 65535.0); - if (z < ztile[iy+1][ix]) - ztile[iy+1][ix] = z; + uint z = (uint) (zvals[2] * zscale); + if (z < ztile.t32[iy+1][ix]) + ztile.t32[iy+1][ix] = z; else mask &= ~MASK_BOTTOM_LEFT; } if (mask & MASK_BOTTOM_RIGHT) { - z = (uint) (zvals[3] * 65535.0); - if (z < ztile[iy+1][ix+1]) - ztile[iy+1][ix+1] = z; + uint z = (uint) (zvals[3] * zscale); + if (z < ztile.t32[iy+1][ix+1]) + ztile.t32[iy+1][ix+1] = z; else mask &= ~MASK_BOTTOM_RIGHT; } } + return mask; +} + + +/** + * Emit a quad (pass to next stage). No clipping is done. + */ +static INLINE void +emit_quad( struct setup_stage *setup, int x, int y, unsigned mask ) +{ +#if 0 + struct softpipe_context *sp = setup->softpipe; + setup->quad.x0 = x; + setup->quad.y0 = y; + setup->quad.mask = mask; + sp->quad.first->run(sp->quad.first, &setup->quad); +#else + /* Cell: "write" quad fragments to the tile by setting prim color */ + const int ix = x - setup->cliprect_minx; + const int iy = y - setup->cliprect_miny; + float colors[4][4]; + + eval_coeff(setup, 1, (float) x, (float) y, colors); + + if (spu.depth_stencil.depth.enabled) { + mask &= do_depth_test(setup, x, y, mask); + } + if (mask) { if (tile_status[setup->ty][setup->tx] == TILE_STATUS_CLEAR) { /* now, _really_ clear the tile */ - clear_tile(ctile, spu.fb.color_clear_value); + clear_c_tile(&ctile); } else { /* make sure we've got the tile from main mem */ @@ -332,13 +382,13 @@ emit_quad( struct setup_stage *setup, int x, int y, unsigned mask ) tile_status[setup->ty][setup->tx] = TILE_STATUS_DIRTY; if (mask & MASK_TOP_LEFT) - ctile[iy][ix] = pack_color(colors[QUAD_TOP_LEFT]); + ctile.t32[iy][ix] = pack_color(colors[QUAD_TOP_LEFT]); if (mask & MASK_TOP_RIGHT) - ctile[iy][ix+1] = pack_color(colors[QUAD_TOP_RIGHT]); + ctile.t32[iy][ix+1] = pack_color(colors[QUAD_TOP_RIGHT]); if (mask & MASK_BOTTOM_LEFT) - ctile[iy+1][ix] = pack_color(colors[QUAD_BOTTOM_LEFT]); + ctile.t32[iy+1][ix] = pack_color(colors[QUAD_BOTTOM_LEFT]); if (mask & MASK_BOTTOM_RIGHT) - ctile[iy+1][ix+1] = pack_color(colors[QUAD_BOTTOM_RIGHT]); + ctile.t32[iy+1][ix+1] = pack_color(colors[QUAD_BOTTOM_RIGHT]); } #endif } diff --git a/src/mesa/pipe/draw/draw_context.c b/src/mesa/pipe/draw/draw_context.c index fd43d690f6..5b9ea55630 100644 --- a/src/mesa/pipe/draw/draw_context.c +++ b/src/mesa/pipe/draw/draw_context.c @@ -49,6 +49,7 @@ struct draw_context *draw_create( void ) /* create pipeline stages */ draw->pipeline.wide = draw_wide_stage( draw ); + draw->pipeline.stipple = draw_stipple_stage( draw ); draw->pipeline.unfilled = draw_unfilled_stage( draw ); draw->pipeline.twoside = draw_twoside_stage( draw ); draw->pipeline.offset = draw_offset_stage( draw ); @@ -70,7 +71,7 @@ struct draw_context *draw_create( void ) */ { uint i; - char *tmp = MALLOC( Elements(draw->vcache.vertex) * MAX_VERTEX_SIZE ); + char *tmp = (char*) MALLOC( Elements(draw->vcache.vertex) * MAX_VERTEX_SIZE ); for (i = 0; i < Elements(draw->vcache.vertex); i++) draw->vcache.vertex[i] = (struct vertex_header *)(tmp + i * MAX_VERTEX_SIZE); @@ -81,6 +82,9 @@ struct draw_context *draw_create( void ) draw->attrib_front1 = 0; draw->attrib_back1 = 0; + draw->convert_wide_points = TRUE; + draw->convert_wide_lines = TRUE; + draw->prim = ~0; /* != any of PIPE_PRIM_x */ draw_vertex_cache_invalidate( draw ); @@ -93,6 +97,7 @@ struct draw_context *draw_create( void ) void draw_destroy( struct draw_context *draw ) { draw->pipeline.wide->destroy( draw->pipeline.wide ); + draw->pipeline.stipple->destroy( draw->pipeline.stipple ); draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); draw->pipeline.twoside->destroy( draw->pipeline.twoside ); draw->pipeline.offset->destroy( draw->pipeline.offset ); @@ -215,6 +220,26 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, } +/** + * Tells the draw module whether to convert wide points (size != 1) + * into triangles. + */ +void +draw_convert_wide_points(struct draw_context *draw, boolean enable) +{ + draw->convert_wide_points = enable; +} + + +/** + * Tells the draw module whether to convert wide lines (width != 1) + * into triangles. + */ +void +draw_convert_wide_lines(struct draw_context *draw, boolean enable) +{ + draw->convert_wide_lines = enable; +} diff --git a/src/mesa/pipe/draw/draw_context.h b/src/mesa/pipe/draw/draw_context.h index 91e11e6930..cfde26ceb7 100644 --- a/src/mesa/pipe/draw/draw_context.h +++ b/src/mesa/pipe/draw/draw_context.h @@ -89,6 +89,10 @@ void draw_set_rasterizer_state( struct draw_context *draw, void draw_set_rasterize_stage( struct draw_context *draw, struct draw_stage *stage ); +void draw_convert_wide_points(struct draw_context *draw, boolean enable); + +void draw_convert_wide_lines(struct draw_context *draw, boolean enable); + struct draw_vertex_shader * draw_create_vertex_shader(struct draw_context *draw, diff --git a/src/mesa/pipe/draw/draw_linestipple.c b/src/mesa/pipe/draw/draw_linestipple.c deleted file mode 100644 index d7fe1071f0..0000000000 --- a/src/mesa/pipe/draw/draw_linestipple.c +++ /dev/null @@ -1,272 +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. - * - **************************************************************************/ - -/* Authors: Keith Whitwell <keith@tungstengraphics.com> - */ - -/* Implement line stipple by cutting lines up into smaller lines. - * There are hundreds of ways to implement line stipple, this is one - * choice that should work in all situations, requires no state - * manipulations, but with a penalty in terms of large amounts of - * generated geometry. - */ - -#include "imports.h" -#include "macros.h" - -#define CLIP_PRIVATE -#include "clip/clip_context.h" - -#define CLIP_PIPE_PRIVATE -#include "clip/clip_pipe.h" - - - -struct stipple_stage { - struct clip_pipe_stage stage; - - GLuint hw_data_offset; - - GLfloat counter; - GLuint pattern; - GLuint factor; -}; - - - - -static INLINE struct stipple_stage *stipple_stage( struct clip_pipe_stage *stage ) -{ - return (struct stipple_stage *)stage; -} - - - - -static void interp_attr( const struct vf_attr *a, - GLubyte *vdst, - GLfloat t, - const GLubyte *vin, - const GLubyte *vout ) -{ - GLuint offset = a->vertoffset; - GLfloat fin[4], fout[4], fdst[4]; - - a->extract( a, fin, vin + offset ); - a->extract( a, fout, vout + offset ); - - fdst[0] = LINTERP( t, fout[0], fin[0] ); - fdst[1] = LINTERP( t, fout[1], fin[1] ); - fdst[2] = LINTERP( t, fout[2], fin[2] ); - fdst[3] = LINTERP( t, fout[3], fin[3] ); - - a->insert[4-1]( a, vdst + offset, fdst ); -} - - - - -/* Weird screen-space interpolation?? Otherwise do something special - * with pos.w or fix vertices to always have clip coords available. - */ -static void screen_interp( struct vertex_fetch *vf, - struct vertex_header *dst, - GLfloat t, - const struct vertex_header *out, - const struct vertex_header *in ) -{ - GLubyte *vdst = (GLubyte *)dst; - const GLubyte *vin = (const GLubyte *)in; - const GLubyte *vout = (const GLubyte *)out; - - const struct vf_attr *a = vf->attr; - const GLuint attr_count = vf->attr_count; - GLuint j; - - /* Vertex header. - */ - { - assert(a[0].attrib == VF_ATTRIB_VERTEX_HEADER); - dst->clipmask = 0; - dst->edgeflag = 0; - dst->pad = 0; - dst->index = 0xffff; - } - - - /* Other attributes - */ - for (j = 1; j < attr_count; j++) { - interp_attr(&a[j], vdst, t, vin, vout); - } -} - - - -/* Clip a line against the viewport and user clip planes. - */ -static void draw_line_segment( struct clip_pipe_stage *stage, - struct prim_header *header, - GLfloat t0, - GLfloat t1 ) -{ - struct vertex_fetch *vf = stage->pipe->draw->vb.vf; - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - - struct prim_header newprim = *header; - header = &newprim; - - _mesa_printf("%s %f %f\n", __FUNCTION__, t0, t1); - - if (t0 > 0.0) { - screen_interp( vf, stage->tmp[0], t0, v0, v1 ); - header->v[0] = stage->tmp[0]; - } - - if (t1 < 1.0) { - screen_interp( vf, stage->tmp[1], t1, v0, v1 ); - header->v[1] = stage->tmp[1]; - } - - stage->next->line( stage->next, header ); -} - - - -/* XXX: don't really want to iterate like this. - */ -static INLINE unsigned -stipple_test(int counter, ushort pattern, int factor) -{ - int b = (counter / factor) & 0xf; - return (1 << b) & pattern; -} - - - -/* XXX: Need to have precalculated flatshading already. - */ -static void stipple_line( struct clip_pipe_stage *stage, - struct prim_header *header ) -{ - struct stipple_stage *stipple = stipple_stage(stage); - GLuint hw_data_offset = stipple->hw_data_offset; - const GLfloat *pos0 = (GLfloat *)&(header->v[0]->data[hw_data_offset]); - const GLfloat *pos1 = (GLfloat *)&(header->v[1]->data[hw_data_offset]); - GLfloat start = 0; - int state = 0; - - GLfloat x0 = (GLfloat)pos0[0]; - GLfloat x1 = (GLfloat)pos1[0]; - GLfloat y0 = (GLfloat)pos0[1]; - GLfloat y1 = (GLfloat)pos1[1]; - - GLfloat dx = x0 > x1 ? x0 - x1 : x1 - x0; - GLfloat dy = y0 > y1 ? y0 - y1 : y1 - y0; - - GLfloat length = MAX2(dx, dy); - GLint i; - - if (header->reset_line_stipple) - stipple->counter = 0; - - /* XXX: iterating like this is lame - */ - for (i = 0; i < length; i++) { - int result = !!stipple_test( stipple->counter+i, stipple->pattern, stipple->factor ); -// _mesa_printf("%d %f %d\n", i, length, result); - if (result != state) { - if (state) { - if (start != i) - draw_line_segment( stage, header, start / length, i / length ); - } - else { - start = i; - } - state = result; - } - } - - if (state && start < length) - draw_line_segment( stage, header, start / length, 1.0 ); - - stipple->counter += length; -} - - - -static void stipple_begin( struct clip_pipe_stage *stage ) -{ - struct stipple_stage *stipple = stipple_stage(stage); - struct clip_context *draw = stage->pipe->draw; - - if (stage->pipe->draw->vb_state.clipped_prims) - stipple->hw_data_offset = 16; - else - stipple->hw_data_offset = 0; - - stipple->stage.tri = clip_passthrough_tri; - stipple->stage.point = clip_passthrough_point; - - stipple->stage.line = stipple_line; - stipple->factor = draw->state.line_stipple_factor + 1; - stipple->pattern = draw->state.line_stipple_pattern; - - stage->next->begin( stage->next ); -} - - -static void stipple_end( struct clip_pipe_stage *stage ) -{ - stage->next->end( stage->next ); -} - - -static void stipple_destroy( struct clip_pipe_stage *stage ) -{ - FREE( stage ); -} - - -struct clip_pipe_stage *clip_pipe_stipple( struct clip_pipeline *pipe ) -{ - struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); - - clip_pipe_alloc_tmps( &stipple->stage, 4 ); - - stipple->stage.pipe = pipe; - stipple->stage.next = NULL; - stipple->stage.begin = stipple_begin; - stipple->stage.point = clip_passthrough_point; - stipple->stage.line = stipple_line; - stipple->stage.tri = clip_passthrough_tri; - stipple->stage.end = stipple_end; - stipple->stage.destroy = stipple_destroy; - - return &stipple->stage; -} diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index d8832449ea..a264fabfb4 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -158,6 +158,7 @@ struct draw_context struct draw_stage *twoside; struct draw_stage *offset; struct draw_stage *unfilled; + struct draw_stage *stipple; struct draw_stage *wide; struct draw_stage *rasterize; } pipeline; @@ -194,6 +195,9 @@ struct draw_context uint attrib_front0, attrib_back0; uint attrib_front1, attrib_back1; + boolean convert_wide_points; /**< convert wide points to tris? */ + boolean convert_wide_lines; /**< convert side lines to tris? */ + boolean drawing; /**< do we presently have something queued for drawing? */ unsigned prim; /**< current prim type: PIPE_PRIM_x */ unsigned reduced_prim; @@ -248,6 +252,7 @@ extern struct draw_stage *draw_offset_stage( struct draw_context *context ); extern struct draw_stage *draw_clip_stage( struct draw_context *context ); extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); extern struct draw_stage *draw_cull_stage( struct draw_context *context ); +extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); extern struct draw_stage *draw_wide_stage( struct draw_context *context ); extern struct draw_stage *draw_validate_stage( struct draw_context *context ); diff --git a/src/mesa/pipe/draw/draw_stipple.c b/src/mesa/pipe/draw/draw_stipple.c new file mode 100644 index 0000000000..3e0d5689e1 --- /dev/null +++ b/src/mesa/pipe/draw/draw_stipple.c @@ -0,0 +1,250 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* Authors: Keith Whitwell <keith@tungstengraphics.com> + */ + +/* Implement line stipple by cutting lines up into smaller lines. + * There are hundreds of ways to implement line stipple, this is one + * choice that should work in all situations, requires no state + * manipulations, but with a penalty in terms of large amounts of + * generated geometry. + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +/** Subclass of draw_stage */ +struct stipple_stage { + struct draw_stage stage; + float counter; + uint pattern; + uint factor; +}; + + +static INLINE struct stipple_stage * +stipple_stage(struct draw_stage *stage) +{ + return (struct stipple_stage *) stage; +} + + +/** + * Compute interpolated vertex attributes for 'dst' at position 't' + * between 'v0' and 'v1'. + */ +static void +screen_interp( struct draw_context *draw, + struct vertex_header *dst, + float t, + const struct vertex_header *v0, + const struct vertex_header *v1 ) +{ + uint attr; + for (attr = 0; attr < draw->vertex_info.num_attribs; attr++) { + switch (draw->vertex_info.interp_mode[attr]) { + case INTERP_NONE: + case INTERP_CONSTANT: + COPY_4FV(dst->data[attr], v0->data[attr]); + break; + case INTERP_PERSPECTIVE: + /* Fall-through */ + /* XXX special-case perspective? */ + case INTERP_LINEAR: + { + const float *val0 = v0->data[attr]; + const float *val1 = v1->data[attr]; + float *newv = dst->data[attr]; + uint i; + for (i = 0; i < 4; i++) { + newv[i] = val0[i] + t * (val1[i] - val0[i]); + } + } + break; + default: + abort(); + } + } +} + + +static void +emit_segment(struct draw_stage *stage, struct prim_header *header, + float t0, float t1) +{ + struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); + struct prim_header newprim = *header; + + if (t0 > 0.0) { + screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); + newprim.v[0] = v0new; + } + + if (t1 < 1.0) { + screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); + newprim.v[1] = v1new; + } + + stage->next->line( stage->next, &newprim ); +} + + +static INLINE unsigned +stipple_test(int counter, ushort pattern, int factor) +{ + int b = (counter / factor) & 0xf; + return (1 << b) & pattern; +} + + +static void +stipple_line(struct draw_stage *stage, struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->data[0]; + const float *pos1 = v1->data[0]; + float start = 0; + int state = 0; + + float x0 = pos0[0]; + float x1 = pos1[0]; + float y0 = pos0[1]; + float y1 = pos1[1]; + + float dx = x0 > x1 ? x0 - x1 : x1 - x0; + float dy = y0 > y1 ? y0 - y1 : y1 - y0; + + float length = MAX2(dx, dy); + int i; + + /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. + */ + for (i = 0; i < length; i++) { + int result = stipple_test( (int) stipple->counter+i, + (ushort) stipple->pattern, stipple->factor ); + if (result != state) { + /* changing from "off" to "on" or vice versa */ + if (state) { + if (start != i) { + /* finishing an "on" segment */ + emit_segment( stage, header, start / length, i / length ); + } + } + else { + /* starting an "on" segment */ + start = (float) i; + } + state = result; + } + } + + if (state && start < length) + emit_segment( stage, header, start / length, 1.0 ); + + stipple->counter += length; +} + + +static void +reset_stipple_counter(struct draw_stage *stage) +{ + struct stipple_stage *stipple = stipple_stage(stage); + stipple->counter = 0; + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +stipple_begin(struct draw_stage *stage) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct draw_context *draw = stage->draw; + + stipple->pattern = draw->rasterizer->line_stipple_pattern; + stipple->factor = draw->rasterizer->line_stipple_factor + 1; + + stage->next->begin( stage->next ); +} + + +static void +stipple_end(struct draw_stage *stage) +{ + stage->next->end( stage->next ); +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point( stage->next, header ); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +static void +stipple_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create line stippler stage + */ +struct draw_stage *draw_stipple_stage( struct draw_context *draw ) +{ + struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); + + draw_alloc_tmps( &stipple->stage, 2 ); + + stipple->stage.draw = draw; + stipple->stage.next = NULL; + stipple->stage.begin = stipple_begin; + stipple->stage.point = passthrough_point; + stipple->stage.line = stipple_line; + stipple->stage.tri = passthrough_tri; + stipple->stage.reset_stipple_counter = reset_stipple_counter; + stipple->stage.end = stipple_end; + stipple->stage.destroy = stipple_destroy; + + return &stipple->stage; +} diff --git a/src/mesa/pipe/draw/draw_validate.c b/src/mesa/pipe/draw/draw_validate.c index 58cf340281..3b1f5179a9 100644 --- a/src/mesa/pipe/draw/draw_validate.c +++ b/src/mesa/pipe/draw/draw_validate.c @@ -51,13 +51,18 @@ static void validate_begin( struct draw_stage *stage ) * shorter pipelines for lines & points. */ - if (draw->rasterizer->line_width != 1.0 || - draw->rasterizer->point_size != 1.0 || + if ((draw->rasterizer->line_width != 1.0 && draw->convert_wide_lines) || + (draw->rasterizer->point_size != 1.0 && draw->convert_wide_points) || draw->rasterizer->point_sprite) { draw->pipeline.wide->next = next; next = draw->pipeline.wide; } + if (draw->rasterizer->line_stipple_enable) { + draw->pipeline.stipple->next = next; + next = draw->pipeline.stipple; + } + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { draw->pipeline.unfilled->next = next; diff --git a/src/mesa/pipe/draw/draw_vbuf.c b/src/mesa/pipe/draw/draw_vbuf.c index 6cda122c3a..a4b6247e18 100644 --- a/src/mesa/pipe/draw/draw_vbuf.c +++ b/src/mesa/pipe/draw/draw_vbuf.c @@ -110,10 +110,11 @@ check_space( struct vbuf_stage *vbuf, unsigned nr ) /** - * Extract the needed fields from vertex_header and emit i915 dwords. + * Extract the needed fields from post-transformed vertex and emit + * a hardware(driver) vertex. * Recall that the vertices are constructed by the 'draw' module and * have a couple of slots at the beginning (1-dword header, 4-dword - * clip pos) that we ignore here. + * clip pos) that we ignore here. We only use the vertex->data[] fields. */ static INLINE void emit_vertex( struct vbuf_stage *vbuf, @@ -139,37 +140,42 @@ emit_vertex( struct vbuf_stage *vbuf, vertex->vertex_id = vbuf->nr_vertices++; for (i = 0; i < vinfo->num_attribs; i++) { + uint j = vinfo->src_index[i]; switch (vinfo->format[i]) { case FORMAT_OMIT: /* no-op */ break; case FORMAT_1F: - *vbuf->vertex_ptr++ = fui(vertex->data[i][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + count++; + break; + case FORMAT_1F_PSIZE: + *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size); count++; break; case FORMAT_2F: - *vbuf->vertex_ptr++ = fui(vertex->data[i][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[i][1]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); count += 2; break; case FORMAT_3F: - *vbuf->vertex_ptr++ = fui(vertex->data[i][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[i][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[i][2]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); count += 3; break; case FORMAT_4F: - *vbuf->vertex_ptr++ = fui(vertex->data[i][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[i][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[i][2]); - *vbuf->vertex_ptr++ = fui(vertex->data[i][3]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); + *vbuf->vertex_ptr++ = fui(vertex->data[j][3]); count += 4; break; case FORMAT_4UB: - *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[i][2] ), - float_to_ubyte( vertex->data[i][1] ), - float_to_ubyte( vertex->data[i][0] ), - float_to_ubyte( vertex->data[i][3] )); + *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ), + float_to_ubyte( vertex->data[j][1] ), + float_to_ubyte( vertex->data[j][0] ), + float_to_ubyte( vertex->data[j][3] )); count += 1; break; default: @@ -228,18 +234,43 @@ vbuf_point( struct draw_stage *stage, } +/** + * Set the prim type for subsequent vertices. + * This may result in a new vertex size. The existing vbuffer (if any) + * will be flushed if needed and a new one allocated. + */ +static void +vbuf_set_prim( struct draw_stage *stage, uint newprim ) +{ + struct vbuf_stage *vbuf = vbuf_stage(stage); + const struct vertex_info *vinfo; + unsigned vertex_size; + + assert(newprim == PIPE_PRIM_POINTS || + newprim == PIPE_PRIM_LINES || + newprim == PIPE_PRIM_TRIANGLES); + + vbuf->prim = newprim; + vbuf->render->set_primitive(vbuf->render, newprim); + + vinfo = vbuf->render->get_vertex_info(vbuf->render); + vertex_size = vinfo->size * sizeof(float); + + if (vertex_size != vbuf->vertex_size) + vbuf_flush_vertices(stage); + + if (!vbuf->vertices) + vbuf_alloc_vertices(stage, vertex_size); +} + + static void vbuf_first_tri( struct draw_stage *stage, struct prim_header *prim ) { - struct vbuf_stage *vbuf = vbuf_stage( stage ); - vbuf_flush_indices( stage ); - stage->tri = vbuf_tri; - vbuf->prim = PIPE_PRIM_TRIANGLES; - vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_TRIANGLES); - + vbuf_set_prim(stage, PIPE_PRIM_TRIANGLES); stage->tri( stage, prim ); } @@ -248,13 +279,9 @@ static void vbuf_first_line( struct draw_stage *stage, struct prim_header *prim ) { - struct vbuf_stage *vbuf = vbuf_stage( stage ); - vbuf_flush_indices( stage ); stage->line = vbuf_line; - vbuf->prim = PIPE_PRIM_LINES; - vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_LINES); - + vbuf_set_prim(stage, PIPE_PRIM_LINES); stage->line( stage, prim ); } @@ -263,14 +290,9 @@ static void vbuf_first_point( struct draw_stage *stage, struct prim_header *prim ) { - struct vbuf_stage *vbuf = vbuf_stage( stage ); - vbuf_flush_indices( stage ); - stage->point = vbuf_point; - vbuf->prim = PIPE_PRIM_POINTS; - vbuf->render->set_primitive(vbuf->render, PIPE_PRIM_POINTS); - + vbuf_set_prim(stage, PIPE_PRIM_POINTS); stage->point( stage, prim ); } @@ -352,7 +374,7 @@ vbuf_alloc_vertices( struct draw_stage *stage, /* Allocate a new vertex buffer */ vbuf->vertex_size = new_vertex_size; vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; - vbuf->vertices = vbuf->render->allocate_vertices(vbuf->render, + vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, (ushort) vbuf->vertex_size, (ushort) vbuf->max_vertices); vbuf->vertex_ptr = vbuf->vertices; @@ -362,12 +384,7 @@ vbuf_alloc_vertices( struct draw_stage *stage, static void vbuf_begin( struct draw_stage *stage ) { - struct vbuf_stage *vbuf = vbuf_stage(stage); - const struct vertex_info *vinfo = vbuf->render->get_vertex_info(vbuf->render); - unsigned vertex_size = vinfo->size * sizeof(float); - - /* XXX: Overkill */ - vbuf_alloc_vertices(&vbuf->stage, vertex_size); + /* no-op, vbuffer allocated by first point/line/tri */ } @@ -387,6 +404,7 @@ vbuf_end( struct draw_stage *stage ) static void vbuf_reset_stipple_counter( struct draw_stage *stage ) { + (void) stage; } @@ -420,11 +438,13 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, assert(render->max_indices < UNDEFINED_VERTEX_ID); vbuf->max_indices = render->max_indices; - vbuf->indices - = align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); + vbuf->indices = (ushort *) + align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; + + vbuf->prim = ~0; return &vbuf->stage; } diff --git a/src/mesa/pipe/draw/draw_vertex.c b/src/mesa/pipe/draw/draw_vertex.c index a1926d951a..6191fcedbf 100644 --- a/src/mesa/pipe/draw/draw_vertex.c +++ b/src/mesa/pipe/draw/draw_vertex.c @@ -65,6 +65,8 @@ draw_compute_vertex_size(struct vertex_info *vinfo) break; case FORMAT_4UB: /* fall-through */ + case FORMAT_1F_PSIZE: + /* fall-through */ case FORMAT_1F: vinfo->size += 1; break; diff --git a/src/mesa/pipe/draw/draw_vertex.h b/src/mesa/pipe/draw/draw_vertex.h index 8bb328affa..e4f85bc49f 100644 --- a/src/mesa/pipe/draw/draw_vertex.h +++ b/src/mesa/pipe/draw/draw_vertex.h @@ -41,12 +41,13 @@ struct draw_context; * Vertex attribute format */ enum attrib_format { - FORMAT_OMIT, + FORMAT_OMIT, /**< don't emit the attribute */ FORMAT_1F, + FORMAT_1F_PSIZE, /**< insert constant point size */ FORMAT_2F, FORMAT_3F, FORMAT_4F, - FORMAT_4UB + FORMAT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */ }; @@ -70,6 +71,7 @@ struct vertex_info uint hwfmt[4]; /**< hardware format info for this format */ enum interp_mode interp_mode[PIPE_MAX_SHADER_OUTPUTS]; enum attrib_format format[PIPE_MAX_SHADER_OUTPUTS]; /**< FORMAT_x */ + uint src_index[PIPE_MAX_SHADER_OUTPUTS]; uint size; /**< total vertex size in dwords */ }; @@ -77,16 +79,20 @@ struct vertex_info /** * Add another attribute to the given vertex_info object. + * \param src_index indicates which post-transformed vertex attrib slot + * corresponds to this attribute. * \return slot in which the attribute was added */ static INLINE uint draw_emit_vertex_attr(struct vertex_info *vinfo, - enum attrib_format format, enum interp_mode interp) + enum attrib_format format, enum interp_mode interp, + uint src_index) { const uint n = vinfo->num_attribs; assert(n < PIPE_MAX_SHADER_OUTPUTS); vinfo->format[n] = format; vinfo->interp_mode[n] = interp; + vinfo->src_index[n] = src_index; vinfo->num_attribs++; return n; } diff --git a/src/mesa/pipe/i915simple/i915_state_derived.c b/src/mesa/pipe/i915simple/i915_state_derived.c index be73769cf2..466c704d87 100644 --- a/src/mesa/pipe/i915simple/i915_state_derived.c +++ b/src/mesa/pipe/i915simple/i915_state_derived.c @@ -50,12 +50,13 @@ static void calculate_vertex_layout( struct i915_context *i915 ) boolean needW = 0; uint i; boolean texCoords[8]; + uint src = 0; memset(texCoords, 0, sizeof(texCoords)); memset(&vinfo, 0, sizeof(vinfo)); /* pos */ - draw_emit_vertex_attr(&vinfo, FORMAT_3F, INTERP_LINEAR); + draw_emit_vertex_attr(&vinfo, FORMAT_3F, INTERP_LINEAR, src++); /* Note: we'll set the S4_VFMT_XYZ[W] bits below */ for (i = 0; i < fs->num_inputs; i++) { @@ -64,12 +65,12 @@ static void calculate_vertex_layout( struct i915_context *i915 ) break; case TGSI_SEMANTIC_COLOR: if (fs->input_semantic_index[i] == 0) { - front0 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp); + front0 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp, src++); vinfo.hwfmt[0] |= S4_VFMT_COLOR; } else { assert(fs->input_semantic_index[i] == 1); - front1 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp); + front1 = draw_emit_vertex_attr(&vinfo, FORMAT_4UB, colorInterp, src++); vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; } break; @@ -79,7 +80,7 @@ static void calculate_vertex_layout( struct i915_context *i915 ) const uint unit = fs->input_semantic_index[i]; uint hwtc; texCoords[unit] = TRUE; - draw_emit_vertex_attr(&vinfo, FORMAT_4F, INTERP_PERSPECTIVE); + draw_emit_vertex_attr(&vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src++); hwtc = TEXCOORDFMT_4D; needW = TRUE; vinfo.hwfmt[1] |= hwtc << (unit * 4); @@ -87,7 +88,7 @@ static void calculate_vertex_layout( struct i915_context *i915 ) break; case TGSI_SEMANTIC_FOG: fprintf(stderr, "i915 fogcoord not implemented yet\n"); - draw_emit_vertex_attr(&vinfo, FORMAT_1F, INTERP_PERSPECTIVE); + draw_emit_vertex_attr(&vinfo, FORMAT_1F, INTERP_PERSPECTIVE, src++); break; default: assert(0); @@ -119,10 +120,10 @@ static void calculate_vertex_layout( struct i915_context *i915 ) */ if (i915->rasterizer->light_twoside) { if (front0) { - back0 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp); + back0 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp, src++); } if (back0) { - back1 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp); + back1 = draw_emit_vertex_attr(&vinfo, FORMAT_OMIT, colorInterp, src++); } } diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index 89f8df945c..cdc385e4db 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -769,7 +769,7 @@ line_persp_coeff(struct setup_stage *setup, { /* XXX double-check/verify this arithmetic */ const float a0 = setup->vmin->data[vertSlot][i] * setup->vmin->data[0][3]; - const float a1 = setup->vmax->data[vertSlot][i] * setup->vmin->data[0][3]; + const float a1 = setup->vmax->data[vertSlot][i] * setup->vmax->data[0][3]; const float da = a1 - a0; const float dadx = da * setup->emaj.dx * setup->oneoverarea; const float dady = da * setup->emaj.dy * setup->oneoverarea; @@ -873,20 +873,9 @@ plot(struct setup_stage *setup, int x, int y) /** - * Determine whether or not to emit a line fragment by checking - * line stipple pattern. - */ -static INLINE unsigned -stipple_test(int counter, ushort pattern, int factor) -{ - int b = (counter / factor) & 0xf; - return (1 << b) & pattern; -} - - -/** * Do setup for line rasterization, then render the line. - * XXX single-pixel width, no stipple, etc + * Single-pixel width, no stipple, etc. We rely on the 'draw' module + * to handle stippling and wide lines. */ static void setup_line(struct draw_stage *stage, struct prim_header *prim) @@ -894,8 +883,6 @@ setup_line(struct draw_stage *stage, struct prim_header *prim) const struct vertex_header *v0 = prim->v[0]; const struct vertex_header *v1 = prim->v[1]; struct setup_stage *setup = setup_stage( stage ); - struct softpipe_context *sp = setup->softpipe; - int x0 = (int) v0->data[0][0]; int x1 = (int) v1->data[0][0]; int y0 = (int) v0->data[0][1]; @@ -947,12 +934,7 @@ setup_line(struct draw_stage *stage, struct prim_header *prim) const int errorDec = error - dx; for (i = 0; i < dx; i++) { - if (!sp->rasterizer->line_stipple_enable || - stipple_test(sp->line_stipple_counter, - (ushort) sp->rasterizer->line_stipple_pattern, - sp->rasterizer->line_stipple_factor + 1)) { - plot(setup, x0, y0); - } + plot(setup, x0, y0); x0 += xstep; if (error < 0) { @@ -962,8 +944,6 @@ setup_line(struct draw_stage *stage, struct prim_header *prim) error += errorDec; y0 += ystep; } - - sp->line_stipple_counter++; } } else { @@ -974,15 +954,9 @@ setup_line(struct draw_stage *stage, struct prim_header *prim) const int errorDec = error - dy; for (i = 0; i < dy; i++) { - if (!sp->rasterizer->line_stipple_enable || - stipple_test(sp->line_stipple_counter, - (ushort) sp->rasterizer->line_stipple_pattern, - sp->rasterizer->line_stipple_factor + 1)) { - plot(setup, x0, y0); - } + plot(setup, x0, y0); y0 += ystep; - if (error < 0) { error += errorInc; } @@ -990,8 +964,6 @@ setup_line(struct draw_stage *stage, struct prim_header *prim) error += errorDec; x0 += xstep; } - - sp->line_stipple_counter++; } } @@ -1234,8 +1206,6 @@ static void setup_end( struct draw_stage *stage ) static void reset_stipple_counter( struct draw_stage *stage ) { - struct setup_stage *setup = setup_stage(stage); - setup->softpipe->line_stipple_counter = 0; } @@ -1341,8 +1311,8 @@ void sp_vbuf_render( struct pipe_context *pipe, break; case PIPE_PRIM_POINTS: - for (i = 0; i < nr_elements; i += 2) { - prim.v[i] = (struct vertex_header *)((char *)vertex_buffer + + for (i = 0; i < nr_elements; i++) { + prim.v[0] = (struct vertex_header *)((char *)vertex_buffer + elements[i] * vertex_size); setup->stage.point( &setup->stage, &prim ); } diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c index 630ae3163f..0f1410e5de 100644 --- a/src/mesa/pipe/softpipe/sp_state_derived.c +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -48,6 +48,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) boolean emitBack0 = FALSE, emitBack1 = FALSE, emitPsize = FALSE; uint front0 = 0, back0 = 0, front1 = 0, back1 = 0; uint i; + int src = 0; memset(vinfo, 0, sizeof(*vinfo)); @@ -61,7 +62,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) softpipe->psize_slot = -1; /* always emit vertex pos */ - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR); + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR, src++); /* * XXX I think we need to reconcile the vertex shader outputs with @@ -82,11 +83,11 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) case TGSI_SEMANTIC_COLOR: if (vs->output_semantic_index[i] == 0) { - front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } else { assert(vs->output_semantic_index[i] == 1); - front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } break; @@ -101,7 +102,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) break; case TGSI_SEMANTIC_FOG: - draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE); + draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE, src++); break; case TGSI_SEMANTIC_PSIZE: @@ -113,7 +114,7 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) case TGSI_SEMANTIC_GENERIC: /* this includes texcoords and varying vars */ - draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE); + draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE, src++); break; default: @@ -128,14 +129,14 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe ) * up 1:1 with the fragment shader inputs. */ if (emitBack0) { - back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } if (emitBack1) { - back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp); + back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp, src++); } if (emitPsize) { softpipe->psize_slot - = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT); + = draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT, src++); } /* If the attributes have changed, tell the draw module about diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index d5119654ed..e115705507 100644 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -32,44 +32,6 @@ #include "pipe/util/p_tile.h" #include "sp_context.h" #include "sp_surface.h" -#include "sp_texture.h" - - -/** - * Called via pipe->get_tex_surface() - * XXX is this in the right place? - */ -struct pipe_surface * -softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct softpipe_texture *spt = softpipe_texture(pt); - struct pipe_surface *ps; - - ps = pipe->winsys->surface_alloc(pipe->winsys); - if (ps) { - assert(ps->refcount); - assert(ps->winsys); - pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - 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; -} /* Upload data to a rectangular sub-region. Lots of choices how to do this: diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h index b652e7598e..22de3ba43f 100644 --- a/src/mesa/pipe/softpipe/sp_surface.h +++ b/src/mesa/pipe/softpipe/sp_surface.h @@ -31,40 +31,8 @@ #ifndef SP_SURFACE_H #define SP_SURFACE_H -#include "sp_headers.h" -#include "pipe/p_state.h" -struct pipe_context; struct softpipe_context; -struct softpipe_tile_cache; - - -extern struct pipe_surface * -softpipe_get_tex_surface(struct pipe_context *pipe, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice); - - -extern void -softpipe_get_tile(struct pipe_context *pipe, struct pipe_surface *ps, - uint x, uint y, uint w, uint h, void *p, int dst_stride); - -extern void -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); - -extern void -softpipe_get_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - float *p); - -extern void -softpipe_put_tile_rgba(struct pipe_context *pipe, - struct pipe_surface *ps, - uint x, uint y, uint w, uint h, - const float *p); extern void diff --git a/src/mesa/pipe/softpipe/sp_tex_sample.c b/src/mesa/pipe/softpipe/sp_tex_sample.c index 9e48ed0cd2..5e215c433a 100644 --- a/src/mesa/pipe/softpipe/sp_tex_sample.c +++ b/src/mesa/pipe/softpipe/sp_tex_sample.c @@ -33,6 +33,7 @@ */ #include "sp_context.h" +#include "sp_headers.h" #include "sp_surface.h" #include "sp_tex_sample.h" #include "sp_tile_cache.h" diff --git a/src/mesa/pipe/softpipe/sp_texture.c b/src/mesa/pipe/softpipe/sp_texture.c index 532bcfcc51..d43a6996e9 100644 --- a/src/mesa/pipe/softpipe/sp_texture.c +++ b/src/mesa/pipe/softpipe/sp_texture.c @@ -130,3 +130,39 @@ softpipe_texture_release(struct pipe_context *pipe, struct pipe_texture **pt) } *pt = NULL; } + + +/** + * Called via pipe->get_tex_surface() + */ +struct pipe_surface * +softpipe_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct softpipe_texture *spt = softpipe_texture(pt); + struct pipe_surface *ps; + + ps = pipe->winsys->surface_alloc(pipe->winsys); + if (ps) { + assert(ps->refcount); + assert(ps->winsys); + pipe->winsys->buffer_reference(pipe->winsys, &ps->buffer, spt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + 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; +} diff --git a/src/mesa/pipe/softpipe/sp_texture.h b/src/mesa/pipe/softpipe/sp_texture.h index e1a5db2791..0494bf365b 100644 --- a/src/mesa/pipe/softpipe/sp_texture.h +++ b/src/mesa/pipe/softpipe/sp_texture.h @@ -1,3 +1,30 @@ +/************************************************************************** + * + * 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_TEXTURE_H #define SP_TEXTURE_H @@ -34,7 +61,10 @@ 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 */ +extern struct pipe_surface * +softpipe_get_tex_surface(struct pipe_context *pipe, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice); +#endif /* SP_TEXTURE */ |