diff options
Diffstat (limited to 'src/gallium/drivers/cell')
17 files changed, 433 insertions, 151 deletions
diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile index c92f8e5cba..8769b826b5 100644 --- a/src/gallium/drivers/cell/ppu/Makefile +++ b/src/gallium/drivers/cell/ppu/Makefile @@ -21,6 +21,7 @@ SPU_CODE_MODULE = ../spu/g3d_spu.a SOURCES = \ cell_batch.c \ + cell_buffer.c \ cell_clear.c \ cell_context.c \ cell_draw_arrays.c \ diff --git a/src/gallium/drivers/cell/ppu/cell_buffer.c b/src/gallium/drivers/cell/ppu/cell_buffer.c new file mode 100644 index 0000000000..f56a28d62e --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_buffer.c @@ -0,0 +1,118 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * 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 VMWARE 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. + * + **************************************************************************/ + + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_math.h" + +#include "cell_screen.h" +#include "cell_buffer.h" + + +static void * +cell_buffer_map(struct pipe_screen *screen, + struct pipe_buffer *buf, + unsigned flags) +{ + struct cell_buffer *cell_buf = cell_buffer(buf); + return cell_buf->data; +} + + +static void +cell_buffer_unmap(struct pipe_screen *screen, + struct pipe_buffer *buf) +{ +} + + +static void +cell_buffer_destroy(struct pipe_buffer *buf) +{ + struct cell_buffer *sbuf = cell_buffer(buf); + + if (!sbuf->userBuffer) + align_free(sbuf->data); + + FREE(sbuf); +} + + +static struct pipe_buffer * +cell_buffer_create(struct pipe_screen *screen, + unsigned alignment, + unsigned usage, + unsigned size) +{ + struct cell_buffer *buffer = CALLOC_STRUCT(cell_buffer); + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = screen; + buffer->base.alignment = MAX2(alignment, 16); + buffer->base.usage = usage; + buffer->base.size = size; + + buffer->data = align_malloc(size, alignment); + + return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +cell_user_buffer_create(struct pipe_screen *screen, + void *ptr, + unsigned bytes) +{ + struct cell_buffer *buffer; + + buffer = CALLOC_STRUCT(cell_buffer); + if(!buffer) + return NULL; + + pipe_reference_init(&buffer->base.reference, 1); + buffer->base.screen = screen; + buffer->base.size = bytes; + buffer->userBuffer = TRUE; + buffer->data = ptr; + + return &buffer->base; +} + + +void +cell_init_screen_buffer_funcs(struct pipe_screen *screen) +{ + screen->buffer_create = cell_buffer_create; + screen->user_buffer_create = cell_user_buffer_create; + screen->buffer_map = cell_buffer_map; + screen->buffer_unmap = cell_buffer_unmap; + screen->buffer_destroy = cell_buffer_destroy; +} diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.h b/src/gallium/drivers/cell/ppu/cell_buffer.h index e227e065ff..ef0a8a70e5 100644 --- a/src/gallium/drivers/cell/ppu/cell_winsys.h +++ b/src/gallium/drivers/cell/ppu/cell_buffer.h @@ -1,8 +1,8 @@ /************************************************************************** - * - * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * + * Copyright 2009 VMware, Inc. * 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 @@ -10,38 +10,46 @@ * 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 + * IN NO EVENT SHALL VMWARE 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_WINSYS_H -#define CELL_WINSYS_H +#ifndef SP_BUFFER_H +#define SP_BUFFER_H #include "pipe/p_compiler.h" +#include "pipe/p_state.h" -/** - * Very simple winsys at this time. - * Will probably eventually add SPU control info. - */ -struct cell_winsys +struct cell_buffer { - uint dummy; + struct pipe_buffer base; + boolean userBuffer; /** Is this a user-space buffer? */ + void *data; }; +/** Cast wrapper */ +static INLINE struct cell_buffer * +cell_buffer( struct pipe_buffer *buf ) +{ + return (struct cell_buffer *)buf; +} + + +void +cell_init_screen_buffer_funcs(struct pipe_screen *screen); -#endif +#endif /* SP_BUFFER_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index 5bff9869fd..f6cb1fc9be 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -36,7 +36,6 @@ #include "pipe/p_defines.h" #include "pipe/p_format.h" #include "util/u_memory.h" -#include "util/u_simple_screen.h" #include "pipe/p_screen.h" #include "draw/draw_context.h" @@ -137,7 +136,7 @@ cell_create_context(struct pipe_screen *screen, memset(cell, 0, sizeof(*cell)); cell->winsys = NULL; /* XXX: fixme - get this from screen? */ - cell->pipe.winsys = screen->winsys; + cell->pipe.winsys = NULL; cell->pipe.screen = screen; cell->pipe.priv = priv; cell->pipe.destroy = cell_destroy_context; @@ -159,6 +158,7 @@ cell_create_context(struct pipe_screen *screen, cell_init_shader_functions(cell); cell_init_surface_functions(cell); cell_init_vertex_functions(cell); + cell_init_texture_transfer_funcs(cell); cell->draw = cell_draw_create(cell); diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index a77cc5b906..28f80b82cd 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -34,7 +34,7 @@ #include "pipe/p_defines.h" #include "draw/draw_vertex.h" #include "draw/draw_vbuf.h" -#include "cell_winsys.h" +/*#include "cell_winsys.h"*/ #include "cell/common.h" #include "rtasm/rtasm_ppc_spe.h" #include "tgsi/tgsi_scan.h" @@ -93,6 +93,11 @@ struct cell_buffer_list struct cell_buffer_node *head; }; +struct cell_velems_state +{ + unsigned count; + struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; +} /** * Per-context state, subclass of pipe_context. @@ -110,6 +115,7 @@ struct cell_context const struct pipe_rasterizer_state *rasterizer; const struct cell_vertex_shader_state *vs; const struct cell_fragment_shader_state *fs; + const struct cell_velems_state *velems; struct spe_function logic_op; @@ -125,8 +131,6 @@ struct cell_context struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; uint num_vertex_buffers; - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; - uint num_vertex_elements; ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; ubyte *zsbuf_map; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index bffd0fac6f..15d4e8338f 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -33,48 +33,18 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "util/u_simple_screen.h" #include "util/u_inlines.h" #include "cell_context.h" #include "cell_draw_arrays.h" #include "cell_state.h" #include "cell_flush.h" +#include "cell_buffer.h" #include "draw/draw_context.h" -static void -cell_map_constant_buffers(struct cell_context *sp) -{ - struct pipe_winsys *ws = sp->pipe.winsys; - uint i; - for (i = 0; i < 2; i++) { - if (sp->constants[i] && sp->constants[i]->size) { - sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i], - PIPE_BUFFER_USAGE_CPU_READ); - cell_flush_buffer_range(sp, sp->mapped_constants[i], - sp->constants[i]->size); - } - } - - draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, 0, - sp->mapped_constants[PIPE_SHADER_VERTEX], - sp->constants[PIPE_SHADER_VERTEX]->size); -} - -static void -cell_unmap_constant_buffers(struct cell_context *sp) -{ - struct pipe_winsys *ws = sp->pipe.winsys; - uint i; - for (i = 0; i < 2; i++) { - if (sp->constants[i] && sp->constants[i]->size) - ws->buffer_unmap(ws, sp->constants[i]); - sp->mapped_constants[i] = NULL; - } -} @@ -93,33 +63,27 @@ cell_draw_range_elements(struct pipe_context *pipe, unsigned max_index, unsigned mode, unsigned start, unsigned count) { - struct cell_context *sp = cell_context(pipe); - struct draw_context *draw = sp->draw; + struct cell_context *cell = cell_context(pipe); + struct draw_context *draw = cell->draw; unsigned i; - if (sp->dirty) - cell_update_derived( sp ); + if (cell->dirty) + cell_update_derived( cell ); #if 0 - cell_map_surfaces(sp); + cell_map_surfaces(cell); #endif - cell_map_constant_buffers(sp); /* * Map vertex buffers */ - for (i = 0; i < sp->num_vertex_buffers; i++) { - void *buf = pipe_buffer_map(pipe->screen, - sp->vertex_buffer[i].buffer, - PIPE_BUFFER_USAGE_CPU_READ); - cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size); + for (i = 0; i < cell->num_vertex_buffers; i++) { + void *buf = cell_buffer(cell->vertex_buffer[i].buffer)->data; draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ if (indexBuffer) { - void *mapped_indexes = pipe_buffer_map(pipe->screen, - indexBuffer, - PIPE_BUFFER_USAGE_CPU_READ); + void *mapped_indexes = cell_buffer(indexBuffer)->data; draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); } else { @@ -134,17 +98,19 @@ cell_draw_range_elements(struct pipe_context *pipe, /* * unmap vertex/index buffers - will cause draw module to flush */ - for (i = 0; i < sp->num_vertex_buffers; i++) { + for (i = 0; i < cell->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); - pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer); } if (indexBuffer) { draw_set_mapped_element_buffer(draw, 0, NULL); - pipe_buffer_unmap(pipe->screen, indexBuffer); } - /* Note: leave drawing surfaces mapped */ - cell_unmap_constant_buffers(sp); + /* + * TODO: Flush only when a user vertex/index buffer is present + * (or even better, modify draw module to do this + * internally when this condition is seen?) + */ + draw_flush(draw); } diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c index e10071529a..035ef41b89 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.c +++ b/src/gallium/drivers/cell/ppu/cell_fence.c @@ -92,7 +92,6 @@ cell_add_buffer_to_list(struct cell_context *cell, struct cell_buffer_list *list, struct pipe_buffer *buffer) { - struct pipe_screen *ps = cell->pipe.screen; struct cell_buffer_node *node = CALLOC_STRUCT(cell_buffer_node); /* create new list node which references the buffer, insert at head */ if (node) { @@ -157,8 +156,13 @@ cell_add_fenced_textures(struct cell_context *cell) printf("Adding texture %p buffer %p to list\n", ct, ct->tiled_buffer[level]); #endif - if (ct->buffer) +#if 00 + /* XXX this needs to be fixed/restored! + * Maybe keep pointers to textures, not buffers. + */ + if (ct->base.buffer) cell_add_buffer_to_list(cell, list, ct->buffer); +#endif } } } diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 3d8b4409c7..dce10ae7f8 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -292,17 +292,23 @@ cell_set_sampler_textures(struct pipe_context *pipe, static void cell_map_surfaces(struct cell_context *cell) { +#if 0 struct pipe_screen *screen = cell->pipe.screen; +#endif uint i; for (i = 0; i < 1; i++) { struct pipe_surface *ps = cell->framebuffer.cbufs[i]; if (ps) { struct cell_texture *ct = cell_texture(ps->texture); +#if 0 cell->cbuf_map[i] = screen->buffer_map(screen, ct->buffer, (PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE)); +#else + cell->cbuf_map[i] = ct->data; +#endif } } @@ -310,10 +316,14 @@ cell_map_surfaces(struct cell_context *cell) struct pipe_surface *ps = cell->framebuffer.zsbuf; if (ps) { struct cell_texture *ct = cell_texture(ps->texture); +#if 0 cell->zsbuf_map = screen->buffer_map(screen, ct->buffer, (PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE)); +#else + cell->zsbuf_map = ct->data; +#endif } } } @@ -325,17 +335,17 @@ cell_map_surfaces(struct cell_context *cell) static void cell_unmap_surfaces(struct cell_context *cell) { - struct pipe_screen *screen = cell->pipe.screen; + /*struct pipe_screen *screen = cell->pipe.screen;*/ uint i; for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { struct pipe_surface *ps = cell->framebuffer.cbufs[i]; if (ps && cell->cbuf_map[i]) { - struct cell_texture *ct = cell_texture(ps->texture); + /*struct cell_texture *ct = cell_texture(ps->texture);*/ assert(ps->texture); - assert(ct->buffer); + /*assert(ct->buffer);*/ - screen->buffer_unmap(screen, ct->buffer); + /*screen->buffer_unmap(screen, ct->buffer);*/ cell->cbuf_map[i] = NULL; } } @@ -343,8 +353,8 @@ cell_unmap_surfaces(struct cell_context *cell) { struct pipe_surface *ps = cell->framebuffer.zsbuf; if (ps && cell->zsbuf_map) { - struct cell_texture *ct = cell_texture(ps->texture); - screen->buffer_unmap(screen, ct->buffer); + /*struct cell_texture *ct = cell_texture(ps->texture);*/ + /*screen->buffer_unmap(screen, ct->buffer);*/ cell->zsbuf_map = NULL; } } diff --git a/src/gallium/drivers/cell/ppu/cell_public.h b/src/gallium/drivers/cell/ppu/cell_public.h new file mode 100644 index 0000000000..7e2e093565 --- /dev/null +++ b/src/gallium/drivers/cell/ppu/cell_public.h @@ -0,0 +1,10 @@ +#ifndef CELL_PUBLIC_H +#define CELL_PUBLIC_H + +struct pipe_screen; +struct sw_winsys; + +struct pipe_screen * +cell_create_screen(struct sw_winsys *winsys); + +#endif diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index a43f8638dc..31fd963d19 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -28,7 +28,6 @@ #include "util/u_memory.h" #include "util/u_simple_screen.h" -#include "util/u_simple_screen.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" @@ -36,7 +35,10 @@ #include "cell_context.h" #include "cell_screen.h" #include "cell_texture.h" -#include "cell_winsys.h" +#include "cell_buffer.h" +#include "cell_public.h" + +#include "state_tracker/sw_winsys.h" static const char * @@ -134,19 +136,28 @@ cell_is_format_supported( struct pipe_screen *screen, unsigned tex_usage, unsigned geom_flags ) { - /* cell supports most formats, XXX for now anyway */ + struct sw_winsys *winsys = cell_screen(screen)->winsys; + if (format == PIPE_FORMAT_DXT5_RGBA || format == PIPE_FORMAT_A8B8G8R8_SRGB) return FALSE; - else - return TRUE; + + if (tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!winsys->is_displaytarget_format_supported(winsys, format)) + return FALSE; + } + + /* This is often a lie. Pull in logic from llvmpipe to fix. + */ + return TRUE; } static void cell_destroy_screen( struct pipe_screen *screen ) { - struct pipe_winsys *winsys = screen->winsys; + struct cell_screen *sp_screen = cell_screen(screen); + struct sw_winsys *winsys = sp_screen->winsys; if(winsys->destroy) winsys->destroy(winsys); @@ -155,32 +166,34 @@ cell_destroy_screen( struct pipe_screen *screen ) } + /** * Create a new pipe_screen object * Note: we're not presently subclassing pipe_screen (no cell_screen) but * that would be the place to put SPU thread/context info... */ struct pipe_screen * -cell_create_screen(struct pipe_winsys *winsys) +cell_create_screen(struct sw_winsys *winsys) { - struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen); + struct cell_screen *screen = CALLOC_STRUCT(cell_screen); if (!screen) return NULL; screen->winsys = winsys; + screen->base.winsys = NULL; - screen->destroy = cell_destroy_screen; + screen->base.destroy = cell_destroy_screen; - screen->get_name = cell_get_name; - screen->get_vendor = cell_get_vendor; - screen->get_param = cell_get_param; - screen->get_paramf = cell_get_paramf; - screen->is_format_supported = cell_is_format_supported; - screen->context_create = cell_create_context; + screen->base.get_name = cell_get_name; + screen->base.get_vendor = cell_get_vendor; + screen->base.get_param = cell_get_param; + screen->base.get_paramf = cell_get_paramf; + screen->base.is_format_supported = cell_is_format_supported; + screen->base.context_create = cell_create_context; - cell_init_screen_texture_funcs(screen); - u_simple_screen_init(screen); + cell_init_screen_texture_funcs(&screen->base); + cell_init_screen_buffer_funcs(&screen->base); - return screen; + return &screen->base; } diff --git a/src/gallium/drivers/cell/ppu/cell_screen.h b/src/gallium/drivers/cell/ppu/cell_screen.h index c7e15889d6..baff9d3b7d 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.h +++ b/src/gallium/drivers/cell/ppu/cell_screen.h @@ -30,12 +30,26 @@ #define CELL_SCREEN_H -struct pipe_screen; -struct pipe_winsys; +#include "pipe/p_screen.h" +struct sw_winsys; -extern struct pipe_screen * -cell_create_screen(struct pipe_winsys *winsys); +struct cell_screen { + struct pipe_screen base; + + struct sw_winsys *winsys; + + /* Increments whenever textures are modified. Contexts can track + * this. + */ + unsigned timestamp; +}; + +static INLINE struct cell_screen * +cell_screen( struct pipe_screen *pipe ) +{ + return (struct cell_screen *)pipe; +} #endif /* CELL_SCREEN_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index a59c7828ac..424e2628a9 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -245,16 +245,13 @@ cell_emit_state(struct cell_context *cell) uint i, j; float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float))); uint32_t *ibuf = (uint32_t *) buf; - const float *constants = pipe_buffer_map(cell->pipe.screen, - cell->constants[shader], - PIPE_BUFFER_USAGE_CPU_READ); + const float *constants = cell->mapped_constants[shader]; ibuf[0] = CELL_CMD_STATE_FS_CONSTANTS; ibuf[4] = num_const; j = 8; for (i = 0; i < num_const; i++) { buf[j++] = constants[i]; } - pipe_buffer_unmap(cell->pipe.screen, cell->constants[shader]); } if (cell->dirty & (CELL_NEW_FRAMEBUFFER | diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c index 9b2f86fdfb..9e29ddc2d4 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c @@ -28,13 +28,13 @@ #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_inlines.h" -#include "util/u_simple_screen.h" #include "draw/draw_context.h" #include "tgsi/tgsi_parse.h" #include "cell_context.h" #include "cell_state.h" #include "cell_gen_fp.h" +#include "cell_buffer.h" /** cast wrapper */ @@ -183,17 +183,29 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs) static void cell_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf) + struct pipe_buffer *constants) { struct cell_context *cell = cell_context(pipe); + unsigned size = constants ? constants->size : 0; + const void *data = constants ? cell_buffer(constants)->data : NULL; assert(shader < PIPE_SHADER_TYPES); assert(index == 0); + if (cell->constants[shader] == constants) + return; + draw_flush(cell->draw); /* note: reference counting */ - pipe_buffer_reference(&cell->constants[shader], buf); + pipe_buffer_reference(&cell->constants[shader], constants); + + if(shader == PIPE_SHADER_VERTEX) { + draw_set_mapped_constant_buffer(cell->draw, PIPE_SHADER_VERTEX, 0, + data, size); + } + + cell->mapped_constants[shader] = data; if (shader == PIPE_SHADER_VERTEX) cell->dirty |= CELL_NEW_VS_CONSTANTS; diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c index fbe55c8472..9510ea9ac2 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -32,24 +32,44 @@ #include "cell_context.h" #include "cell_state.h" +#include "util/u_memory.h" #include "draw/draw_context.h" -static void -cell_set_vertex_elements(struct pipe_context *pipe, - unsigned count, - const struct pipe_vertex_element *elements) +void * +cell_create_vertex_elements_state(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *attribs) { - struct cell_context *cell = cell_context(pipe); - + struct cell_velems_state *velems; assert(count <= PIPE_MAX_ATTRIBS); + velems = (struct cell_velems_state *) MALLOC(sizeof(struct cell_velems_state)); + if (velems) { + velems->count = count; + memcpy(velems->velem, attribs, sizeof(*attribs) * count); + } + return velems; +} + +void +cell_bind_vertex_elements_state(struct pipe_context *pipe, + void *velems) +{ + struct cell_context *cell = cell_context(pipe); + struct cell_velems_state *cell_velems = (struct cell_velems_state *) velems; - memcpy(cell->vertex_element, elements, count * sizeof(elements[0])); - cell->num_vertex_elements = count; + cell->velems = cell_velems; cell->dirty |= CELL_NEW_VERTEX; - draw_set_vertex_elements(cell->draw, count, elements); + if (cell_velems) + draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem); +} + +void +cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) +{ + FREE( velems ); } @@ -75,5 +95,7 @@ void cell_init_vertex_functions(struct cell_context *cell) { cell->pipe.set_vertex_buffers = cell_set_vertex_buffers; - cell->pipe.set_vertex_elements = cell_set_vertex_elements; + cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state; + cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state; + cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state; } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c index fad290dfa0..c65c3b4f88 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.c +++ b/src/gallium/drivers/cell/ppu/cell_texture.c @@ -34,20 +34,23 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" -#include "util/u_simple_screen.h" #include "util/u_format.h" #include "util/u_math.h" #include "util/u_memory.h" #include "cell_context.h" +#include "cell_screen.h" #include "cell_state.h" #include "cell_texture.h" +#include "state_tracker/sw_winsys.h" -static void -cell_texture_layout(struct cell_texture *ct) + +static boolean +cell_texture_layout(struct pipe_screen *screen, + struct cell_texture *ct) { struct pipe_texture *pt = &ct->base; unsigned level; @@ -83,9 +86,34 @@ cell_texture_layout(struct cell_texture *ct) height = u_minify(height, 1); depth = u_minify(depth, 1); } + + ct->data = align_malloc(ct->buffer_size, 16); + + return ct->data != NULL; } +/** + * Texture layout for simple color buffers. + */ +static boolean +cell_displaytarget_layout(struct pipe_screen *screen, + struct cell_texture * ct) +{ + struct sw_winsys *winsys = cell_screen(screen)->winsys; + + /* Round up the surface size to a multiple of the tile size? + */ + ct->dt = winsys->displaytarget_create(winsys, + ct->base.format, + ct->base.width0, + ct->base.height0, + 16, + &ct->dt_stride ); + + return ct->dt != NULL; +} + static struct pipe_texture * cell_texture_create(struct pipe_screen *screen, const struct pipe_texture *templat) @@ -98,31 +126,46 @@ cell_texture_create(struct pipe_screen *screen, pipe_reference_init(&ct->base.reference, 1); ct->base.screen = screen; - cell_texture_layout(ct); + /* Create both a displaytarget (linear) and regular texture + * (twiddled). Convert twiddled->linear at flush_frontbuffer time. + */ + if (ct->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_SCANOUT | + PIPE_TEXTURE_USAGE_SHARED)) { + if (!cell_displaytarget_layout(screen, ct)) + goto fail; + } - ct->buffer = screen->buffer_create(screen, 32, PIPE_BUFFER_USAGE_PIXEL, - ct->buffer_size); + if (!cell_texture_layout(screen, ct)) + goto fail; - if (!ct->buffer) { - FREE(ct); - return NULL; + return &ct->base; + +fail: + if (ct->dt) { + struct sw_winsys *winsys = cell_screen(screen)->winsys; + winsys->displaytarget_destroy(winsys, ct->dt); } - return &ct->base; + FREE(ct); + + return NULL; } static void cell_texture_destroy(struct pipe_texture *pt) { + struct cell_screen *screen = cell_screen(pt->screen); + struct sw_winsys *winsys = screen->winsys; struct cell_texture *ct = cell_texture(pt); - if (ct->mapped) { - pipe_buffer_unmap(ct->buffer->screen, ct->buffer); - ct->mapped = NULL; + if (ct->dt) { + /* display target */ + winsys->displaytarget_destroy(winsys, ct->dt); } - pipe_buffer_reference(&ct->buffer, NULL); + align_free(ct->data); FREE(ct); } @@ -312,7 +355,7 @@ cell_tex_surface_destroy(struct pipe_surface *surf) * back out for glGetTexImage). */ static struct pipe_transfer * -cell_get_tex_transfer(struct pipe_screen *screen, +cell_get_tex_transfer(struct pipe_context *ctx, struct pipe_texture *texture, unsigned face, unsigned level, unsigned zslice, enum pipe_transfer_usage usage, @@ -359,7 +402,7 @@ cell_get_tex_transfer(struct pipe_screen *screen, static void -cell_tex_transfer_destroy(struct pipe_transfer *t) +cell_tex_transfer_destroy(struct pipe_context *ctx, struct pipe_transfer *t) { struct cell_transfer *transfer = cell_transfer(t); /* Effectively do the texture_update work here - if texture images @@ -376,7 +419,7 @@ cell_tex_transfer_destroy(struct pipe_transfer *t) * Return pointer to texture image data in linear layout. */ static void * -cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer) +cell_transfer_map(struct pipe_context *ctx, struct pipe_transfer *transfer) { struct cell_transfer *ctrans = cell_transfer(transfer); struct pipe_texture *pt = transfer->texture; @@ -389,10 +432,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer) assert(transfer->texture); - if (!ct->mapped) { - /* map now */ - ct->mapped = pipe_buffer_map(screen, ct->buffer, - pipe_transfer_buffer_flags(transfer)); + if (ct->mapped == NULL) { + ct->mapped = ct->data; } /* @@ -430,7 +471,7 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer) * to tiled data. */ static void -cell_transfer_unmap(struct pipe_screen *screen, +cell_transfer_unmap(struct pipe_context *ctx, struct pipe_transfer *transfer) { struct cell_transfer *ctrans = cell_transfer(transfer); @@ -442,9 +483,8 @@ cell_transfer_unmap(struct pipe_screen *screen, const uint stride = ct->stride[level]; if (!ct->mapped) { - /* map now */ - ct->mapped = pipe_buffer_map(screen, ct->buffer, - PIPE_BUFFER_USAGE_CPU_READ); + assert(0); + return; } if (transfer->usage & PIPE_TRANSFER_WRITE) { @@ -467,6 +507,50 @@ cell_transfer_unmap(struct pipe_screen *screen, } + +/* This used to be overriden by the co-state tracker, but really needs + * to be active with sw_winsys. + * + * Contrasting with llvmpipe and softpipe, this is the only place + * where we use the ct->dt display target in any real sense. + * + * Basically just untwiddle our local data into the linear + * displaytarget. + */ +static void +cell_flush_frontbuffer(struct pipe_screen *_screen, + struct pipe_surface *surface, + void *context_private) +{ + struct cell_screen *screen = cell_screen(_screen); + struct sw_winsys *winsys = screen->winsys; + struct cell_texture *ct = cell_texture(surface->texture); + + if (!ct->dt) + return; + + /* Need to untwiddle from our internal representation here: + */ + { + unsigned *map = winsys->displaytarget_map(winsys, ct->dt, + (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE)); + unsigned *src = (unsigned *)(ct->data + ct->level_offset[surface->level]); + + untwiddle_image_uint(surface->width, + surface->height, + TILE_SIZE, + map, + ct->dt_stride, + src); + + winsys->displaytarget_unmap(winsys, ct->dt); + } + + winsys->displaytarget_display(winsys, ct->dt, context_private); +} + + void cell_init_screen_texture_funcs(struct pipe_screen *screen) { @@ -476,9 +560,14 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen) screen->get_tex_surface = cell_get_tex_surface; screen->tex_surface_destroy = cell_tex_surface_destroy; - screen->get_tex_transfer = cell_get_tex_transfer; - screen->tex_transfer_destroy = cell_tex_transfer_destroy; + screen->flush_frontbuffer = cell_flush_frontbuffer; +} - screen->transfer_map = cell_transfer_map; - screen->transfer_unmap = cell_transfer_unmap; +void +cell_init_texture_transfer_funcs(struct cell_context *cell) +{ + cell->pipe.get_tex_transfer = cell_get_tex_transfer; + cell->pipe.tex_transfer_destroy = cell_tex_transfer_destroy; + cell->pipe.transfer_map = cell_transfer_map; + cell->pipe.transfer_unmap = cell_transfer_unmap; } diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h index 3ffc0bfdb5..ac0b916775 100644 --- a/src/gallium/drivers/cell/ppu/cell_texture.h +++ b/src/gallium/drivers/cell/ppu/cell_texture.h @@ -28,6 +28,7 @@ #ifndef CELL_TEXTURE_H #define CELL_TEXTURE_H +#include "cell/common.h" struct cell_context; struct pipe_texture; @@ -43,8 +44,20 @@ struct cell_texture unsigned long level_offset[CELL_MAX_TEXTURE_LEVELS]; unsigned long stride[CELL_MAX_TEXTURE_LEVELS]; - /** The tiled texture data is held in this buffer */ - struct pipe_buffer *buffer; + /** + * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET + * usage. + */ + struct sw_displaytarget *dt; + unsigned dt_stride; + + /** + * Malloc'ed data for regular textures, or a mapping to dt above. + */ + void *data; + + /* Size of the linear buffer?? + */ unsigned long buffer_size; /** The buffer above, mapped. This is the memory from which the @@ -82,5 +95,7 @@ cell_transfer(struct pipe_transfer *pt) extern void cell_init_screen_texture_funcs(struct pipe_screen *screen); +extern void +cell_init_texture_transfer_funcs(struct cell_context *cell); #endif /* CELL_TEXTURE_H */ diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c index cf8cd41159..3d389d6ea3 100644 --- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c +++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c @@ -31,7 +31,6 @@ #include "pipe/p_defines.h" #include "pipe/p_context.h" -#include "util/u_simple_screen.h" #include "util/u_math.h" #include "cell_context.h" |