diff options
Diffstat (limited to 'src/mesa/pipe/cell/ppu')
-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 |
13 files changed, 581 insertions, 81 deletions
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 */ |