diff options
Diffstat (limited to 'src/mesa/pipe/cell')
-rw-r--r-- | src/mesa/pipe/cell/common.h | 1 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/Makefile | 2 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_clear.c | 99 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_clear.h | 43 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_context.c | 14 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_context.h | 2 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_state.h | 5 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_state_derived.c | 21 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_state_emit.c | 7 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_state_sampler.c | 14 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_surface.c | 199 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_surface.h | 15 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_texture.c | 168 | ||||
-rw-r--r-- | src/mesa/pipe/cell/ppu/cell_texture.h | 73 | ||||
-rw-r--r-- | src/mesa/pipe/cell/spu/Makefile | 10 | ||||
-rw-r--r-- | src/mesa/pipe/cell/spu/spu_main.c | 74 | ||||
-rw-r--r-- | src/mesa/pipe/cell/spu/spu_main.h | 23 | ||||
-rw-r--r-- | src/mesa/pipe/cell/spu/spu_tile.c | 40 | ||||
-rw-r--r-- | src/mesa/pipe/cell/spu/spu_tile.h | 42 | ||||
-rw-r--r-- | src/mesa/pipe/cell/spu/spu_tri.c | 138 |
20 files changed, 794 insertions, 196 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); +get_tile(uint tx, uint ty, tile_t *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); -void -clear_tile(uint tile[TILE_SIZE][TILE_SIZE], uint value); -void -clear_tile_z(ushort tile[TILE_SIZE][TILE_SIZE], uint value); + +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 } |