diff options
Diffstat (limited to 'src/gallium')
60 files changed, 3084 insertions, 1956 deletions
diff --git a/src/gallium/README.portability b/src/gallium/README.portability index 18a97f449b4..d5d5987a7ff 100644 --- a/src/gallium/README.portability +++ b/src/gallium/README.portability @@ -6,7 +6,7 @@ The state tracker and winsys driver support a rather limited number of platforms. However, the pipe drivers are meant to run in a wide number of platforms. Hence the pipe drivers, the auxiliary modules, and all public -headers in general, should stricly follow these guidelines to ensure +headers in general, should strictly follow these guidelines to ensure = Compiler Support = diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index a1a3a9efaf3..af4af8ac1d4 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -292,7 +292,7 @@ enum pipe_error cso_set_blend(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state; cso->context = ctx->pipe; @@ -350,7 +350,7 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; cso->context = ctx->pipe; @@ -508,7 +508,7 @@ enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; cso->context = ctx->pipe; @@ -564,7 +564,7 @@ enum pipe_error cso_set_rasterizer(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(&cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; cso->context = ctx->pipe; @@ -726,7 +726,7 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, if (!cso) return PIPE_ERROR_OUT_OF_MEMORY; - cso->state = *templ; + memcpy(cso->state, templ, sizeof(*templ)); cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; cso->context = ctx->pipe; @@ -769,8 +769,7 @@ void cso_restore_vertex_shader(struct cso_context *ctx) enum pipe_error cso_set_framebuffer(struct cso_context *ctx, const struct pipe_framebuffer_state *fb) { - /* XXX this memcmp() fails to detect buffer size changes */ - if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) { + if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) { ctx->fb = *fb; ctx->pipe->set_framebuffer_state(ctx->pipe, fb); } diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 346a96e37fd..b1ed8aa24ea 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -415,8 +415,11 @@ aaline_create_texture(struct aaline_stage *aaline) assert(aaline->texture->width[level] == aaline->texture->height[level]); - surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); - data = pipe_surface_map(surface); + /* This texture is new, no need to flush. + */ + surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE); if (data == NULL) return FALSE; @@ -440,9 +443,8 @@ aaline_create_texture(struct aaline_stage *aaline) } /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); + screen->surface_unmap(screen, surface); + screen->tex_surface_release(screen, &surface); } return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 2dfd1800d55..4c92416eb19 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -376,8 +376,14 @@ pstip_update_texture(struct pstip_stage *pstip) uint i, j; ubyte *data; - surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); - data = pipe_surface_map(surface); + /* XXX: want to avoid flushing just because we use stipple: + */ + pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL ); + + surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0, + PIPE_BUFFER_USAGE_CPU_WRITE); + data = screen->surface_map(screen, surface, + PIPE_BUFFER_USAGE_CPU_WRITE); /* * Load alpha texture. @@ -399,9 +405,8 @@ pstip_update_texture(struct pstip_stage *pstip) } /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pstip->texture, 0, 0x1); + screen->surface_unmap(screen, surface); + screen->tex_surface_release(screen, &surface); } diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 86a7d1c7303..67b9a9503d2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -427,9 +427,6 @@ static void vbuf_destroy( struct draw_stage *stage ) if(vbuf->indices) align_free( vbuf->indices ); - if(vbuf->translate) - vbuf->translate->release( vbuf->translate ); - if (vbuf->render) vbuf->render->destroy( vbuf->render ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 100117a9aef..b96335b7895 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -184,7 +184,8 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { - translate_cache_destroy(fetch->cache); + if (fetch->cache) + translate_cache_destroy(fetch->cache); FREE(fetch); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index b7b970a297f..4ea7d4359ff 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -268,7 +268,8 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; - translate_cache_destroy(feme->cache); + if (feme->cache) + translate_cache_destroy(feme->cache); FREE(middle); } diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index d654dbcc919..ff09011b660 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -11,6 +11,7 @@ C_SOURCES = \ pb_bufmgr_mm.c \ pb_bufmgr_pool.c \ pb_bufmgr_slab.c \ + pb_validate.c \ pb_winsys.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript index 604a217982e..9db0c0eae3b 100644 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -10,6 +10,7 @@ pipebuffer = env.ConvenienceLibrary( 'pb_bufmgr_mm.c', 'pb_bufmgr_pool.c', 'pb_bufmgr_slab.c', + 'pb_validate.c', 'pb_winsys.c', ]) diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 49705cb8627..857ea53c786 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -146,6 +146,8 @@ pb_map(struct pb_buffer *buf, unsigned flags) { assert(buf); + if(!buf) + return NULL; return buf->vtbl->map(buf, flags); } @@ -154,6 +156,8 @@ static INLINE void pb_unmap(struct pb_buffer *buf) { assert(buf); + if(!buf) + return; buf->vtbl->unmap(buf); } @@ -163,6 +167,12 @@ pb_get_base_buffer( struct pb_buffer *buf, struct pb_buffer **base_buf, unsigned *offset ) { + assert(buf); + if(!buf) { + base_buf = NULL; + offset = 0; + return; + } buf->vtbl->get_base_buffer(buf, base_buf, offset); } @@ -171,7 +181,8 @@ static INLINE void pb_destroy(struct pb_buffer *buf) { assert(buf); - assert(buf->vtbl); + if(!buf) + return; buf->vtbl->destroy(buf); } diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 2fa08429715..7f236887a90 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -168,6 +168,28 @@ _fenced_buffer_remove(struct fenced_buffer *fenced_buf) } +static INLINE enum pipe_error +_fenced_buffer_finish(struct fenced_buffer *fenced_buf) +{ + struct fenced_buffer_list *fenced_list = fenced_buf->list; + struct pipe_winsys *winsys = fenced_list->winsys; + + debug_warning("waiting for GPU"); + + assert(fenced_buf->fence); + if(fenced_buf->fence) { + if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) { + return PIPE_ERROR; + } + /* Remove from the fenced list */ + _fenced_buffer_remove(fenced_buf); /* TODO: remove consequents */ + } + + fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; + return PIPE_OK; +} + + /** * Free as many fenced buffers from the list head as possible. */ @@ -207,40 +229,6 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, } -/** - * Serialize writes, but allow concurrent reads. - */ -static INLINE enum pipe_error -fenced_buffer_serialize(struct fenced_buffer *fenced_buf, unsigned flags) -{ - struct fenced_buffer_list *fenced_list = fenced_buf->list; - struct pipe_winsys *winsys = fenced_list->winsys; - - /* Allow concurrent reads */ - if(((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_WRITE) == 0) - return PIPE_OK; - - /* Wait for the CPU to finish */ - if(fenced_buf->mapcount) { - /* FIXME: Use thread conditions variables to signal when mapcount - * reaches zero */ - debug_warning("attemp to write concurrently to buffer"); - /* XXX: we must not fail here in order to support texture mipmap generation - return PIPE_ERROR_RETRY; - */ - } - - /* Wait for the GPU to finish */ - if(fenced_buf->fence) { - if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) - return PIPE_ERROR_RETRY; - _fenced_buffer_remove(fenced_buf); - } - - return PIPE_OK; -} - - static void fenced_buffer_destroy(struct pb_buffer *buf) { @@ -280,15 +268,28 @@ fenced_buffer_map(struct pb_buffer *buf, { struct fenced_buffer *fenced_buf = fenced_buffer(buf); void *map; - assert((flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE) == 0); + + assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE)); + flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE; - if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) - return NULL; + /* Check for GPU read/write access */ + if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) { + /* Wait for the GPU to finish writing */ + _fenced_buffer_finish(fenced_buf); + } + + /* Check for CPU write access (read is OK) */ + if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { + /* this is legal -- just for debugging */ + debug_warning("concurrent CPU writes"); + } map = pb_map(fenced_buf->buffer, flags); - if(map) + if(map) { ++fenced_buf->mapcount; - fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE; + fenced_buf->flags |= flags; + } + return map; } @@ -298,10 +299,12 @@ fenced_buffer_unmap(struct pb_buffer *buf) { struct fenced_buffer *fenced_buf = fenced_buffer(buf); assert(fenced_buf->mapcount); - pb_unmap(fenced_buf->buffer); - --fenced_buf->mapcount; - if(!fenced_buf->mapcount) - fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE; + if(fenced_buf->mapcount) { + pb_unmap(fenced_buf->buffer); + --fenced_buf->mapcount; + if(!fenced_buf->mapcount) + fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE; + } } @@ -334,8 +337,10 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list, return NULL; buf = CALLOC_STRUCT(fenced_buffer); - if(!buf) + if(!buf) { + pb_reference(&buffer, NULL); return NULL; + } buf->base.base.refcount = 1; buf->base.base.alignment = buffer->base.alignment; @@ -374,7 +379,7 @@ buffer_fence(struct pb_buffer *buf, fenced_list = fenced_buf->list; winsys = fenced_list->winsys; - if(fence == fenced_buf->fence) { + if(!fence || fence == fenced_buf->fence) { /* Handle the same fence case specially, not only because it is a fast * path, but mostly to avoid serializing two writes with the same fence, * as that would bring the hardware down to synchronous operation without @@ -384,11 +389,6 @@ buffer_fence(struct pb_buffer *buf, return; } - if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) { - /* FIXME: propagate error */ - (void)0; - } - _glthread_LOCK_MUTEX(fenced_list->mutex); if (fenced_buf->fence) _fenced_buffer_remove(fenced_buf); diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 8de286e3f94..f6cc7a525b7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -50,7 +50,8 @@ #define PB_BUFMGR_H_ -#include <stddef.h> +#include "pipe/p_compiler.h" +#include "pipe/p_error.h" #ifdef __cplusplus @@ -68,7 +69,6 @@ struct pipe_winsys; */ struct pb_manager { - /* XXX: we will likely need more allocation flags */ struct pb_buffer * (*create_buffer)( struct pb_manager *mgr, size_t size, diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index b931455056e..45ba158a4d9 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -47,9 +47,6 @@ #include "pb_bufmgr.h" -#define DRI_SLABPOOL_ALLOC_RETRIES 100 - - struct pb_slab; struct pb_slab_buffer @@ -313,7 +310,6 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, static struct pb_slab_buffer *buf; struct pb_slab *slab; struct list_head *list; - int count = DRI_SLABPOOL_ALLOC_RETRIES; /* check size */ assert(size == mgr->bufSize); @@ -331,23 +327,14 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, /* XXX: check for compatible buffer usage too? */ _glthread_LOCK_MUTEX(mgr->mutex); - while (mgr->slabs.next == &mgr->slabs && count > 0) { - if (mgr->slabs.next != &mgr->slabs) - break; - - _glthread_UNLOCK_MUTEX(mgr->mutex); - if (count != DRI_SLABPOOL_ALLOC_RETRIES) - util_time_sleep(1); - _glthread_LOCK_MUTEX(mgr->mutex); + if (mgr->slabs.next == &mgr->slabs) { (void) pb_slab_create(mgr); - count--; + if (mgr->slabs.next == &mgr->slabs) { + _glthread_UNLOCK_MUTEX(mgr->mutex); + return NULL; + } } - list = mgr->slabs.next; - if (list == &mgr->slabs) { - _glthread_UNLOCK_MUTEX(mgr->mutex); - return NULL; - } slab = LIST_ENTRY(struct pb_slab, list, head); if (--slab->numFree == 0) LIST_DELINIT(list); diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c new file mode 100644 index 00000000000..362fd896f31 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -0,0 +1,153 @@ +/************************************************************************** + * + * 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 + * 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. + * + **************************************************************************/ + +/** + * @file + * Buffer validation. + * + * @author Jose Fonseca <[email protected]> + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_error.h" +#include "pipe/p_util.h" +#include "pipe/p_debug.h" + +#include "pb_buffer.h" +#include "pb_buffer_fenced.h" +#include "pb_validate.h" + + +#define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */ + + +struct pb_validate +{ + struct pb_buffer **buffers; + unsigned used; + unsigned size; +}; + + +enum pipe_error +pb_validate_add_buffer(struct pb_validate *vl, + struct pb_buffer *buf) +{ + assert(buf); + if(!buf) + return PIPE_ERROR; + + /* We only need to store one reference for each buffer, so avoid storing + * consecutive references for the same buffer. It might not be the more + * common pasttern, but it is easy to implement. + */ + if(vl->used && vl->buffers[vl->used - 1] == buf) { + return PIPE_OK; + } + + /* Grow the table */ + if(vl->used == vl->size) { + unsigned new_size; + struct pb_buffer **new_buffers; + + new_size = vl->size * 2; + if(!new_size) + return PIPE_ERROR_OUT_OF_MEMORY; + + new_buffers = (struct pb_buffer **)REALLOC(vl->buffers, + vl->size*sizeof(struct pb_buffer *), + new_size*sizeof(struct pb_buffer *)); + if(!new_buffers) + return PIPE_ERROR_OUT_OF_MEMORY; + + memset(new_buffers + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_buffer *)); + + vl->size = new_size; + vl->buffers = new_buffers; + } + + assert(!vl->buffers[vl->used]); + pb_reference(&vl->buffers[vl->used], buf); + ++vl->used; + + return PIPE_OK; +} + + +enum pipe_error +pb_validate_validate(struct pb_validate *vl) +{ + /* FIXME: go through each buffer, ensure its not mapped, its address is + * available -- requires a new pb_buffer interface */ + return PIPE_OK; +} + + +void +pb_validate_fence(struct pb_validate *vl, + struct pipe_fence_handle *fence) +{ + unsigned i; + for(i = 0; i < vl->used; ++i) { + buffer_fence(vl->buffers[i], fence); + pb_reference(&vl->buffers[i], NULL); + } + vl->used = 0; +} + + +void +pb_validate_destroy(struct pb_validate *vl) +{ + unsigned i; + for(i = 0; i < vl->used; ++i) + pb_reference(&vl->buffers[i], NULL); + FREE(vl->buffers); + FREE(vl); +} + + +struct pb_validate * +pb_validate_create() +{ + struct pb_validate *vl; + + vl = CALLOC_STRUCT(pb_validate); + if(!vl) + return NULL; + + vl->size = PB_VALIDATE_INITIAL_SIZE; + vl->buffers = (struct pb_buffer **)CALLOC(vl->size, sizeof(struct pb_buffer *)); + if(!vl->buffers) { + FREE(vl); + return NULL; + } + + return vl; +} + diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h b/src/gallium/auxiliary/pipebuffer/pb_validate.h new file mode 100644 index 00000000000..3db1d5330b9 --- /dev/null +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.h @@ -0,0 +1,91 @@ +/************************************************************************** + * + * 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 + * 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. + * + **************************************************************************/ + +/** + * @file + * Buffer validation. + * + * @author Jose Fonseca <[email protected]> + */ + +#ifndef PB_VALIDATE_H_ +#define PB_VALIDATE_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +struct pb_buffer; +struct pipe_fence_handle; + + +/** + * Buffer validation list. + * + * It holds a list of buffers to be validated and fenced when flushing. + */ +struct pb_validate; + + +enum pipe_error +pb_validate_add_buffer(struct pb_validate *vl, + struct pb_buffer *buf); + +/** + * Validate all buffers for hardware access. + * + * Should be called right before issuing commands to the hardware. + */ +enum pipe_error +pb_validate_validate(struct pb_validate *vl); + +/** + * Fence all buffers and clear the list. + * + * Should be called right before issuing commands to the hardware. + */ +void +pb_validate_fence(struct pb_validate *vl, + struct pipe_fence_handle *fence); + +struct pb_validate * +pb_validate_create(void); + +void +pb_validate_destroy(struct pb_validate *vl); + + +#ifdef __cplusplus +} +#endif + +#endif /*PB_VALIDATE_H_*/ diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index d55d2c70818..0309de1ac22 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -5,6 +5,7 @@ util = env.ConvenienceLibrary( source = [ 'p_debug.c', 'p_debug_mem.c', + 'p_debug_prof.c', 'p_tile.c', 'p_util.c', 'u_blit.c', diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index 4ec17466624..ce7fb589562 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -67,7 +67,7 @@ void _debug_vprintf(const char *format, va_list ap) static char buf[512 + 1] = {'\0'}; size_t len = strlen(buf); int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); - if(ret > (int)(sizeof(buf) - len - 1) || strchr(buf + len, '\n')) { + if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { _EngDebugPrint("%s", buf); buf[0] = '\0'; } @@ -154,6 +154,7 @@ debug_get_option(const char *name, const char *dfault) { const char *result; #ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY +#ifdef DEBUG ULONG_PTR iFile = 0; const void *pMap = NULL; const char *sol, *eol, *sep; @@ -184,6 +185,9 @@ debug_get_option(const char *name, const char *dfault) EngUnmapFile(iFile); } #else + result = dfault; +#endif +#else result = getenv(name); if(!result) @@ -203,15 +207,15 @@ debug_get_bool_option(const char *name, boolean dfault) if(str == NULL) result = dfault; - else if(!strcmp(str, "n")) + else if(!util_strcmp(str, "n")) result = FALSE; - else if(!strcmp(str, "no")) + else if(!util_strcmp(str, "no")) result = FALSE; - else if(!strcmp(str, "0")) + else if(!util_strcmp(str, "0")) result = FALSE; - else if(!strcmp(str, "f")) + else if(!util_strcmp(str, "f")) result = FALSE; - else if(!strcmp(str, "false")) + else if(!util_strcmp(str, "false")) result = FALSE; else result = TRUE; @@ -244,7 +248,7 @@ debug_get_flags_option(const char *name, else { result = 0; while( flags->name ) { - if (!strcmp(str, "all") || strstr(str, flags->name )) + if (!util_strcmp(str, "all") || util_strstr(str, flags->name )) result |= flags->value; ++flags; } @@ -299,10 +303,10 @@ debug_dump_flags(const struct debug_named_value *names, while(names->name) { if((names->value & value) == names->value) { if (!first) - strncat(output, "|", sizeof(output)); + util_strncat(output, "|", sizeof(output)); else first = 0; - strncat(output, names->name, sizeof(output)); + util_strncat(output, names->name, sizeof(output)); value &= ~names->value; } ++names; @@ -310,12 +314,12 @@ debug_dump_flags(const struct debug_named_value *names, if (value) { if (!first) - strncat(output, "|", sizeof(output)); + util_strncat(output, "|", sizeof(output)); else first = 0; util_snprintf(rest, sizeof(rest), "0x%08lx", value); - strncat(output, rest, sizeof(output)); + util_strncat(output, rest, sizeof(output)); } if(first) @@ -325,101 +329,159 @@ debug_dump_flags(const struct debug_named_value *names, } +static const struct debug_named_value pipe_format_names[] = { +#ifdef DEBUG + DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR), + DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED), + DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_L8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA), + DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA), +#endif + DEBUG_NAMED_VALUE_END +}; - - +#ifdef DEBUG +void debug_print_format(const char *msg, unsigned fmt ) +{ + debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); +} +#endif char *pf_sprint_name( char *str, enum pipe_format format ) { - strcpy( str, "PIPE_FORMAT_" ); - switch (pf_layout( format )) { - case PIPE_FORMAT_LAYOUT_RGBAZS: - { - pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format; - uint i; - uint scale = 1 << (pf_exp8( rgbazs ) * 3); - - for (i = 0; i < 4; i++) { - uint size = pf_size_xyzw( rgbazs, i ); - - if (size == 0) { - break; - } - switch (pf_swizzle_xyzw( rgbazs, i )) { - case PIPE_FORMAT_COMP_R: - strcat( str, "R" ); - break; - case PIPE_FORMAT_COMP_G: - strcat( str, "G" ); - break; - case PIPE_FORMAT_COMP_B: - strcat( str, "B" ); - break; - case PIPE_FORMAT_COMP_A: - strcat( str, "A" ); - break; - case PIPE_FORMAT_COMP_0: - strcat( str, "0" ); - break; - case PIPE_FORMAT_COMP_1: - strcat( str, "1" ); - break; - case PIPE_FORMAT_COMP_Z: - strcat( str, "Z" ); - break; - case PIPE_FORMAT_COMP_S: - strcat( str, "S" ); - break; - } - util_snprintf( &str[strlen( str )], 32, "%u", size * scale ); - } - if (i != 0) { - strcat( str, "_" ); - } - switch (pf_type( rgbazs )) { - case PIPE_FORMAT_TYPE_UNKNOWN: - strcat( str, "NONE" ); - break; - case PIPE_FORMAT_TYPE_FLOAT: - strcat( str, "FLOAT" ); - break; - case PIPE_FORMAT_TYPE_UNORM: - strcat( str, "UNORM" ); - break; - case PIPE_FORMAT_TYPE_SNORM: - strcat( str, "SNORM" ); - break; - case PIPE_FORMAT_TYPE_USCALED: - strcat( str, "USCALED" ); - break; - case PIPE_FORMAT_TYPE_SSCALED: - strcat( str, "SSCALED" ); - break; - } - } - break; - case PIPE_FORMAT_LAYOUT_YCBCR: - { - pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format; - - strcat( str, "YCBCR" ); - if (pf_rev( ycbcr )) { - strcat( str, "_REV" ); - } - } - break; - } + strcpy( str, debug_dump_enum(pipe_format_names, format) ); return str; } #ifdef DEBUG -void debug_print_format(const char *msg, unsigned fmt ) +void debug_dump_image(const char *prefix, + unsigned format, unsigned cpp, + unsigned width, unsigned height, + unsigned pitch, + const void *data) { - char fmtstr[80]; - - pf_sprint_name(fmtstr, (enum pipe_format)fmt); +#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY + static unsigned no = 0; + char filename[256]; + WCHAR wfilename[sizeof(filename)]; + ULONG_PTR iFile = 0; + struct { + unsigned format; + unsigned cpp; + unsigned width; + unsigned height; + } header; + unsigned char *pMap = NULL; + unsigned i; - debug_printf("%s: %s\n", msg, fmtstr); + util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u%s.raw", ++no, prefix); + for(i = 0; i < sizeof(filename); ++i) + wfilename[i] = (WCHAR)filename[i]; + + pMap = (unsigned char *)EngMapFile(wfilename, sizeof(header) + cpp*width*height, &iFile); + if(!pMap) + return; + + header.format = format; + header.cpp = cpp; + header.width = width; + header.height = height; + memcpy(pMap, &header, sizeof(header)); + pMap += sizeof(header); + + for(i = 0; i < height; ++i) { + memcpy(pMap, (unsigned char *)data + cpp*pitch*i, cpp*width); + pMap += cpp*width; + } + + EngUnmapFile(iFile); +#endif } #endif diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c index 3b5e4fbaeea..78497c5f6af 100644 --- a/src/gallium/auxiliary/util/p_debug_mem.c +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -211,6 +211,7 @@ debug_memory_begin(void) void debug_memory_end(unsigned long start_no) { + size_t total_size = 0; struct list_head *entry; entry = list.prev; @@ -220,9 +221,15 @@ debug_memory_end(unsigned long start_no) hdr = LIST_ENTRY(struct debug_memory_header, entry, head); ptr = data_from_header(hdr); if(start_no <= hdr->no && hdr->no < last_no || - last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) + last_no < start_no && (hdr->no < last_no || start_no <= hdr->no)) { debug_printf("%s:%u:%s: %u bytes at %p not freed\n", hdr->file, hdr->line, hdr->function, hdr->size, ptr); + total_size += hdr->size; + } + } + if(total_size) { + debug_printf("Total of %u KB of system memory apparently leaked\n", + (total_size + 1023)/1024); } } diff --git a/src/gallium/auxiliary/util/p_debug_prof.c b/src/gallium/auxiliary/util/p_debug_prof.c new file mode 100644 index 00000000000..958f99c327c --- /dev/null +++ b/src/gallium/auxiliary/util/p_debug_prof.c @@ -0,0 +1,175 @@ +/************************************************************************** + * + * 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 + * 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. + * + **************************************************************************/ + +/** + * @file + * Poor-man profiling. + * + * @author José Fonseca <[email protected]> + * + * @sa http://blogs.msdn.com/joshpoley/archive/2008/03/12/poor-man-s-profiler.aspx + * @sa http://www.johnpanzer.com/aci_cuj/index.html + */ + +#include "pipe/p_config.h" + +#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +#include <windows.h> +#include <winddi.h> + +#include "pipe/p_debug.h" +#include "util/u_string.h" + + +#define PROFILE_FILE_SIZE 4*1024*1024 +#define FILE_NAME_SIZE 256 + +static WCHAR wFileName[FILE_NAME_SIZE]; +static ULONG_PTR iFile = 0; +static void *pMap = NULL; +static void *pMapEnd = NULL; + + +/** + * Called at the start of every method or function. + * + * @sa http://msdn.microsoft.com/en-us/library/c63a9b7h.aspx + */ +void __declspec(naked) __cdecl +_penter(void) { + _asm { + push ebx + mov ebx, [pMap] + test ebx, ebx + jz done + cmp ebx, [pMapEnd] + je done + push eax + push edx + mov eax, [esp+12] + and eax, 0xfffffffe + mov [ebx], eax + add ebx, 4 + rdtsc + mov [ebx], eax + add ebx, 4 + mov [pMap], ebx + pop edx + pop eax +done: + pop ebx + ret + } +} + + +/** + * Called at the end of Calls the end of every method or function. + * + * @sa http://msdn.microsoft.com/en-us/library/xc11y76y.aspx + */ +void __declspec(naked) __cdecl +_pexit(void) { + _asm { + push ebx + mov ebx, [pMap] + test ebx, ebx + jz done + cmp ebx, [pMapEnd] + je done + push eax + push edx + mov eax, [esp+12] + or eax, 0x00000001 + mov [ebx], eax + add ebx, 4 + rdtsc + mov [ebx], eax + add ebx, 4 + mov [pMap], ebx + pop edx + pop eax +done: + pop ebx + ret + } +} + + +void __declspec(naked) +__debug_profile_reference1(void) { + _asm { + call _penter + call _pexit + ret + } +} + + +void __declspec(naked) +__debug_profile_reference2(void) { + _asm { + call _penter + call __debug_profile_reference1 + call _pexit + ret + } +} + + +void +debug_profile_start(void) +{ + static unsigned no = 0; + char filename[FILE_NAME_SIZE]; + unsigned i; + + util_snprintf(filename, sizeof(filename), "\\??\\c:\\%03u.prof", ++no); + for(i = 0; i < FILE_NAME_SIZE; ++i) + wFileName[i] = (WCHAR)filename[i]; + + pMap = EngMapFile(wFileName, PROFILE_FILE_SIZE, &iFile); + if(pMap) { + pMapEnd = (unsigned char*)pMap + PROFILE_FILE_SIZE; + /* reference functions for calibration purposes */ + __debug_profile_reference2(); + } +} + +void +debug_profile_stop(void) +{ + if(iFile) { + EngUnmapFile(iFile); + /* TODO: truncate file */ + } + iFile = 0; + pMapEnd = pMap = NULL; +} + +#endif /* PROFILE */ diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 63e1cc6013a..5728757d2fb 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -50,6 +50,7 @@ pipe_get_tile_raw(struct pipe_context *pipe, uint x, uint y, uint w, uint h, void *p, int dst_stride) { + struct pipe_screen *screen = pipe->screen; const uint cpp = ps->cpp; const ubyte *pSrc; const uint src_stride = ps->pitch * cpp; @@ -63,7 +64,11 @@ pipe_get_tile_raw(struct pipe_context *pipe, if (pipe_clip_tile(x, y, &w, &h, ps)) return; - pSrc = (const ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + pSrc = (const ubyte *) screen->surface_map(screen, ps, + PIPE_BUFFER_USAGE_CPU_READ); + assert(pSrc); /* XXX: proper error handling! */ + + pSrc += (y * ps->pitch + x) * cpp; pDest = (ubyte *) p; for (i = 0; i < h; i++) { @@ -72,7 +77,7 @@ pipe_get_tile_raw(struct pipe_context *pipe, pSrc += src_stride; } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -86,6 +91,7 @@ pipe_put_tile_raw(struct pipe_context *pipe, uint x, uint y, uint w, uint h, const void *p, int src_stride) { + struct pipe_screen *screen = pipe->screen; const uint cpp = ps->cpp; const ubyte *pSrc; const uint dst_stride = ps->pitch * cpp; @@ -100,7 +106,11 @@ pipe_put_tile_raw(struct pipe_context *pipe, return; pSrc = (const ubyte *) p; - pDest = (ubyte *) pipe_surface_map(ps) + (y * ps->pitch + x) * cpp; + + pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + assert(pDest); /* XXX: proper error handling */ + + pDest += (y * ps->pitch + x) * cpp; for (i = 0; i < h; i++) { memcpy(pDest, pSrc, w * cpp); @@ -108,7 +118,7 @@ pipe_put_tile_raw(struct pipe_context *pipe, pSrc += src_stride; } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -834,18 +844,26 @@ pipe_get_tile_z(struct pipe_context *pipe, uint x, uint y, uint w, uint h, uint *z) { + struct pipe_screen *screen = pipe->screen; const uint dstStride = w; + void *map; uint *pDest = z; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; + map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + if (!map) { + assert(0); + return; + } + switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { const uint *pSrc - = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const uint *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += dstStride; @@ -857,7 +875,7 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_X8Z24_UNORM: { const uint *pSrc - = (const uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const uint *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 24-bit Z to 32-bit Z */ @@ -871,7 +889,7 @@ pipe_get_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_Z16_UNORM: { const ushort *pSrc - = (const ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + = (const ushort *)map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 16-bit Z to 32-bit Z */ @@ -886,7 +904,7 @@ pipe_get_tile_z(struct pipe_context *pipe, assert(0); } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } @@ -896,17 +914,25 @@ pipe_put_tile_z(struct pipe_context *pipe, uint x, uint y, uint w, uint h, const uint *zSrc) { + struct pipe_screen *screen = pipe->screen; const uint srcStride = w; const uint *pSrc = zSrc; + void *map; uint i, j; if (pipe_clip_tile(x, y, &w, &h, ps)) return; + map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE); + if (!map) { + assert(0); + return; + } + switch (ps->format) { case PIPE_FORMAT_Z32_UNORM: { - uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + uint *pDest = (uint *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { memcpy(pDest, pSrc, 4 * w); pDest += ps->pitch; @@ -917,7 +943,7 @@ pipe_put_tile_z(struct pipe_context *pipe, case PIPE_FORMAT_S8Z24_UNORM: case PIPE_FORMAT_X8Z24_UNORM: { - uint *pDest = (uint *) pipe_surface_map(ps) + (y * ps->pitch + x); + uint *pDest = (uint *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 24-bit Z (0 stencil) */ @@ -930,7 +956,7 @@ pipe_put_tile_z(struct pipe_context *pipe, break; case PIPE_FORMAT_Z16_UNORM: { - ushort *pDest = (ushort *) pipe_surface_map(ps) + (y * ps->pitch + x); + ushort *pDest = (ushort *) map + (y * ps->pitch + x); for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { /* convert 32-bit Z to 16-bit Z */ @@ -945,7 +971,7 @@ pipe_put_tile_z(struct pipe_context *pipe, assert(0); } - pipe_surface_unmap(ps); + screen->surface_unmap(screen, ps); } diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 568d62ced19..999a3e50995 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -287,7 +287,8 @@ util_blit_pixels(struct blit_state *ctx, if (!tex) return; - texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0); + texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); /* load temp texture */ pipe->surface_copy(pipe, FALSE, @@ -295,7 +296,9 @@ util_blit_pixels(struct blit_state *ctx, src, srcLeft, srcTop, /* src */ srcW, srcH); /* size */ - pipe->texture_update(pipe, tex, 0, 1 << 0); + /* free the surface, update the texture if necessary. + */ + screen->tex_surface_release(screen, &texSurf); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -356,8 +359,6 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_vertex_shader(ctx->cso); cso_restore_viewport(ctx->cso); - /* free the texture */ - pipe_surface_reference(&texSurf, NULL); screen->texture_release(screen, &tex); } diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index e659edb0881..bf143815d8b 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -82,52 +82,51 @@ util_draw_texquad(struct pipe_context *pipe, { struct pipe_buffer *vbuf; uint numAttribs = 2, vertexBytes, i, j; - float *v; vertexBytes = 4 * (4 * numAttribs * sizeof(float)); /* XXX create one-time */ vbuf = pipe->winsys->buffer_create(pipe->winsys, 32, PIPE_BUFFER_USAGE_VERTEX, vertexBytes); - assert(vbuf); - - v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf, - PIPE_BUFFER_USAGE_CPU_WRITE); - - /* - * Load vertex buffer - */ - for (i = j = 0; i < 4; i++) { - v[j + 2] = z; /* z */ - v[j + 3] = 1.0; /* w */ - v[j + 6] = 0.0; /* r */ - v[j + 7] = 1.0; /* q */ - j += 8; + if (vbuf) { + float *v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf, + PIPE_BUFFER_USAGE_CPU_WRITE); + if (v) { + /* + * Load vertex buffer + */ + for (i = j = 0; i < 4; i++) { + v[j + 2] = z; /* z */ + v[j + 3] = 1.0; /* w */ + v[j + 6] = 0.0; /* r */ + v[j + 7] = 1.0; /* q */ + j += 8; + } + + v[0] = x0; + v[1] = y0; + v[4] = 0.0; /*s*/ + v[5] = 0.0; /*t*/ + + v[8] = x1; + v[9] = y0; + v[12] = 1.0; + v[13] = 0.0; + + v[16] = x1; + v[17] = y1; + v[20] = 1.0; + v[21] = 1.0; + + v[24] = x0; + v[25] = y1; + v[28] = 0.0; + v[29] = 1.0; + + pipe->winsys->buffer_unmap(pipe->winsys, vbuf); + util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2); + } + + pipe_buffer_reference(pipe->winsys, &vbuf, NULL); } - - v[0] = x0; - v[1] = y0; - v[4] = 0.0; /*s*/ - v[5] = 0.0; /*t*/ - - v[8] = x1; - v[9] = y0; - v[12] = 1.0; - v[13] = 0.0; - - v[16] = x1; - v[17] = y1; - v[20] = 1.0; - v[21] = 1.0; - - v[24] = x0; - v[25] = y1; - v[28] = 0.0; - v[29] = 1.0; - - pipe->winsys->buffer_unmap(pipe->winsys, vbuf); - - util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2); - - pipe_buffer_reference(pipe->winsys, &vbuf, NULL); } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index c53c5122681..7d71aefda9d 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -589,8 +589,11 @@ make_1d_mipmap(struct gen_mipmap_state *ctx, struct pipe_surface *srcSurf, *dstSurf; void *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, PIPE_BUFFER_USAGE_CPU_READ) @@ -629,8 +632,10 @@ make_2d_mipmap(struct gen_mipmap_state *ctx, struct pipe_surface *srcSurf, *dstSurf; ubyte *srcMap, *dstMap; - srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice); - dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice, + PIPE_BUFFER_USAGE_CPU_READ); + dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_CPU_WRITE); srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer, PIPE_BUFFER_USAGE_CPU_READ) @@ -891,10 +896,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; + struct pipe_surface *surf = + screen->get_tex_surface(screen, pt, face, dstLevel, zslice, + PIPE_BUFFER_USAGE_GPU_WRITE); + /* * Setup framebuffer / dest surface */ - fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice); + fb.cbufs[0] = surf; fb.width = pt->width[dstLevel]; fb.height = pt->height[dstLevel]; cso_set_framebuffer(ctx->cso, &fb); @@ -925,7 +934,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); /* need to signal that the texture has changed _after_ rendering to it */ - pipe->texture_update(pipe, pt, face, (1 << dstLevel)); + pipe_surface_reference( &surf, NULL ); } /* restore state we changed */ diff --git a/src/gallium/auxiliary/util/u_hash_table.c b/src/gallium/auxiliary/util/u_hash_table.c index f3f16a8d94f..dd5eca7fca3 100644 --- a/src/gallium/auxiliary/util/u_hash_table.c +++ b/src/gallium/auxiliary/util/u_hash_table.c @@ -67,6 +67,13 @@ struct hash_table_item }; +static INLINE struct hash_table_item * +hash_table_item(struct cso_hash_iter iter) +{ + return (struct hash_table_item *)cso_hash_iter_data(iter); +} + + struct hash_table * hash_table_create(unsigned (*hash)(void *key), int (*compare)(void *key1, void *key2)) @@ -90,7 +97,27 @@ hash_table_create(unsigned (*hash)(void *key), } -static struct hash_table_item * +static INLINE struct cso_hash_iter +hash_table_find_iter(struct hash_table *ht, + void *key, + unsigned key_hash) +{ + struct cso_hash_iter iter; + struct hash_table_item *item; + + iter = cso_hash_find(ht->cso, key_hash); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_iter_data(iter); + if (!ht->compare(item->key, key)) + break; + iter = cso_hash_iter_next(iter); + } + + return iter; +} + + +static INLINE struct hash_table_item * hash_table_find_item(struct hash_table *ht, void *key, unsigned key_hash) @@ -117,6 +144,7 @@ hash_table_set(struct hash_table *ht, { unsigned key_hash; struct hash_table_item *item; + struct cso_hash_iter iter; assert(ht); @@ -136,9 +164,8 @@ hash_table_set(struct hash_table *ht, item->key = key; item->value = value; - cso_hash_insert(ht->cso, key_hash, item); - /* FIXME: there is no OOM propagation in cso_hash */ - if(0) { + iter = cso_hash_insert(ht->cso, key_hash, item); + if(cso_hash_iter_is_null(iter)) { FREE(item); return PIPE_ERROR_OUT_OF_MEMORY; } @@ -171,19 +198,39 @@ hash_table_remove(struct hash_table *ht, void *key) { unsigned key_hash; + struct cso_hash_iter iter; struct hash_table_item *item; assert(ht); key_hash = ht->hash(key); - item = hash_table_find_item(ht, key, key_hash); - if(!item) + iter = hash_table_find_iter(ht, key, key_hash); + if(cso_hash_iter_is_null(iter)) return; - /* FIXME: cso_hash_take takes the first element of the collision list - * indiscriminately, so we can not take the item down. */ - item->value = NULL; + item = hash_table_item(iter); + assert(item); + FREE(item); + + cso_hash_erase(ht->cso, iter); +} + + +void +hash_table_clear(struct hash_table *ht) +{ + struct cso_hash_iter iter; + struct hash_table_item *item; + + assert(ht); + + iter = cso_hash_first_node(ht->cso); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter)); + FREE(item); + iter = cso_hash_first_node(ht->cso); + } } @@ -196,6 +243,8 @@ hash_table_foreach(struct hash_table *ht, struct hash_table_item *item; enum pipe_error result; + assert(ht); + iter = cso_hash_first_node(ht->cso); while (!cso_hash_iter_is_null(iter)) { item = (struct hash_table_item *)cso_hash_iter_data(iter); @@ -212,7 +261,17 @@ hash_table_foreach(struct hash_table *ht, void hash_table_destroy(struct hash_table *ht) { + struct cso_hash_iter iter; + struct hash_table_item *item; + assert(ht); + + iter = cso_hash_first_node(ht->cso); + while (!cso_hash_iter_is_null(iter)) { + item = (struct hash_table_item *)cso_hash_iter_data(iter); + FREE(item); + iter = cso_hash_iter_next(iter); + } cso_hash_delete(ht->cso); diff --git a/src/gallium/auxiliary/util/u_hash_table.h b/src/gallium/auxiliary/util/u_hash_table.h index 1583bd7548c..feee881582e 100644 --- a/src/gallium/auxiliary/util/u_hash_table.h +++ b/src/gallium/auxiliary/util/u_hash_table.h @@ -75,6 +75,10 @@ hash_table_remove(struct hash_table *ht, void *key); +void +hash_table_clear(struct hash_table *ht); + + enum pipe_error hash_table_foreach(struct hash_table *ht, enum pipe_error (*callback)(void *key, void *value, void *data), diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 0b917c005f1..655e2c82592 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -101,6 +101,19 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; + case PIPE_FORMAT_A8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = a; + } + return; + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_I8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = r; + } + return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { float *d = (float *) dest; @@ -198,6 +211,19 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest) *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); } return; + case PIPE_FORMAT_A8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = a; + } + return; + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_I8_UNORM: + { + ubyte *d = (ubyte *) dest; + *d = r; + } + return; case PIPE_FORMAT_R32G32B32A32_FLOAT: { float *d = (float *) dest; diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index b99d4e8021c..73c88d87b4c 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -41,6 +41,8 @@ #include <stddef.h> #include <stdarg.h> +#include "pipe/p_compiler.h" + #ifdef __cplusplus extern "C" { @@ -48,11 +50,129 @@ extern "C" { #ifdef WIN32 + int util_vsnprintf(char *, size_t, const char *, va_list); int util_snprintf(char *str, size_t size, const char *format, ...); + +static INLINE void +util_vsprintf(char *str, const char *format, va_list ap) +{ + util_vsnprintf(str, (size_t)-1, format, ap); +} + +static INLINE void +util_sprintf(char *str, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + util_vsnprintf(str, (size_t)-1, format, ap); + va_end(ap); +} + +static INLINE char * +util_strchr(const char *s, char c) +{ + while(*s) { + if(*s == c) + return (char *)s; + ++s; + } + return NULL; +} + +static INLINE char* +util_strncat(char *dst, const char *src, size_t n) +{ + char *p = dst + strlen(dst); + const char *q = src; + size_t i; + + for (i = 0; i < n && *q != '\0'; ++i) + *p++ = *q++; + *p = '\0'; + + return dst; +} + +static INLINE int +util_strcmp(const char *s1, const char *s2) +{ + unsigned char u1, u2; + + while (1) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE int +util_strncmp(const char *s1, const char *s2, size_t n) +{ + unsigned char u1, u2; + + while (n-- > 0) { + u1 = (unsigned char) *s1++; + u2 = (unsigned char) *s2++; + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + } + return 0; +} + +static INLINE char * +util_strstr(const char *haystack, const char *needle) +{ + const char *p = haystack; + int len = strlen(needle); + + for (; (p = util_strchr(p, *needle)) != 0; p++) { + if (util_strncmp(p, needle, len) == 0) { + return (char *)p; + } + } + return NULL; +} + +static INLINE void * +util_memmove(void *dest, const void *src, size_t n) +{ + char *p = (char *)dest; + const char *q = (const char *)src; + if (dest < src) { + while (n--) + *p++ = *q++; + } + else + { + p += n; + q += n; + while (n--) + *--p = *--q; + } + return dest; +} + + #else + #define util_vsnprintf vsnprintf #define util_snprintf snprintf +#define util_vsprintf vsprintf +#define util_sprintf sprintf +#define util_strchr strchr +#define util_strcmp strcmp +#define util_strncmp strncmp +#define util_strncat strncat +#define util_strstr strstr +#define util_memmove memmove + #endif diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index cb95ba516f9..014a3e31d50 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -147,8 +147,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.texture_create = hw->texture_create; failover->pipe.texture_release = hw->texture_release; failover->pipe.get_tex_surface = hw->get_tex_surface; -#endif failover->pipe.texture_update = hw->texture_update; +#endif failover->pipe.flush = hw->flush; diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h index 38e6a348845..53fc5ed0795 100644 --- a/src/gallium/drivers/i915simple/i915_context.h +++ b/src/gallium/drivers/i915simple/i915_context.h @@ -1,341 +1,341 @@ - /**************************************************************************
- *
- * Copyright 2003 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 I915_CONTEXT_H
-#define I915_CONTEXT_H
-
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-
-#include "draw/draw_vertex.h"
-
-#include "tgsi/util/tgsi_scan.h"
-
-
-#define I915_TEX_UNITS 8
-
-#define I915_DYNAMIC_MODES4 0
-#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */
-#define I915_DYNAMIC_DEPTHSCALE_1 2
-#define I915_DYNAMIC_IAB 3
-#define I915_DYNAMIC_BC_0 4 /* just the header */
-#define I915_DYNAMIC_BC_1 5
-#define I915_DYNAMIC_BFO_0 6
-#define I915_DYNAMIC_BFO_1 7
-#define I915_DYNAMIC_STP_0 8
-#define I915_DYNAMIC_STP_1 9
-#define I915_DYNAMIC_SC_ENA_0 10
-#define I915_DYNAMIC_SC_RECT_0 11
-#define I915_DYNAMIC_SC_RECT_1 12
-#define I915_DYNAMIC_SC_RECT_2 13
-#define I915_MAX_DYNAMIC 14
-
-
-#define I915_IMMEDIATE_S0 0
-#define I915_IMMEDIATE_S1 1
-#define I915_IMMEDIATE_S2 2
-#define I915_IMMEDIATE_S3 3
-#define I915_IMMEDIATE_S4 4
-#define I915_IMMEDIATE_S5 5
-#define I915_IMMEDIATE_S6 6
-#define I915_IMMEDIATE_S7 7
-#define I915_MAX_IMMEDIATE 8
-
-/* These must mach the order of LI0_STATE_* bits, as they will be used
- * to generate hardware packets:
- */
-#define I915_CACHE_STATIC 0
-#define I915_CACHE_DYNAMIC 1 /* handled specially */
-#define I915_CACHE_SAMPLER 2
-#define I915_CACHE_MAP 3
-#define I915_CACHE_PROGRAM 4
-#define I915_CACHE_CONSTANTS 5
-#define I915_MAX_CACHE 6
-
-#define I915_MAX_CONSTANT 32
-
-
-/** See constant_flags[] below */
-#define I915_CONSTFLAG_USER 0x1f
-
-
-/**
- * Subclass of pipe_shader_state
- */
-struct i915_fragment_shader
-{
- struct pipe_shader_state state;
-
- struct tgsi_shader_info info;
-
- uint *program;
- uint program_len;
-
- /**
- * constants introduced during translation.
- * These are placed at the end of the constant buffer and grow toward
- * the beginning (eg: slot 31, 30 29, ...)
- * User-provided constants start at 0.
- * This allows both types of constants to co-exist (until there's too many)
- * and doesn't require regenerating/changing the fragment program to
- * shuffle constants around.
- */
- uint num_constants;
- float constants[I915_MAX_CONSTANT][4];
-
- /**
- * Status of each constant
- * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding
- * slot of the user's constant buffer. (set by pipe->set_constant_buffer())
- * Else, the bitmask indicates which components are occupied by immediates.
- */
- ubyte constant_flags[I915_MAX_CONSTANT];
-};
-
-
-struct i915_cache_context;
-
-/* Use to calculate differences between state emitted to hardware and
- * current driver-calculated state.
- */
-struct i915_state
-{
- unsigned immediate[I915_MAX_IMMEDIATE];
- unsigned dynamic[I915_MAX_DYNAMIC];
-
- float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];
- /** number of constants passed in through a constant buffer */
- uint num_user_constants[PIPE_SHADER_TYPES];
-
- /* texture sampler state */
- unsigned sampler[I915_TEX_UNITS][3];
- unsigned sampler_enable_flags;
- unsigned sampler_enable_nr;
-
- /* texture image buffers */
- unsigned texbuffer[I915_TEX_UNITS][2];
-
- /** Describes the current hardware vertex layout */
- struct vertex_info vertex_info;
-
- unsigned id; /* track lost context events */
-};
-
-struct i915_blend_state {
- unsigned iab;
- unsigned modes4;
- unsigned LIS5;
- unsigned LIS6;
-};
-
-struct i915_depth_stencil_state {
- unsigned stencil_modes4;
- unsigned bfo[2];
- unsigned stencil_LIS5;
- unsigned depth_LIS6;
-};
-
-struct i915_rasterizer_state {
- int light_twoside : 1;
- unsigned st;
- enum interp_mode color_interp;
-
- unsigned LIS4;
- unsigned LIS7;
- unsigned sc[1];
-
- const struct pipe_rasterizer_state *templ;
-
- union { float f; unsigned u; } ds[2];
-};
-
-struct i915_sampler_state {
- unsigned state[3];
- const struct pipe_sampler_state *templ;
-};
-
-
-struct i915_texture {
- struct pipe_texture base;
-
- /* Derived from the above:
- */
- unsigned pitch;
- unsigned depth_pitch; /* per-image on i945? */
- unsigned total_height;
-
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
-
- /* Explicitly store the offset of each image for each cube face or
- * depth value. Pretty much have to accept that hardware formats
- * are going to be so diverse that there is no unified way to
- * compute the offsets of depth/cube images within a mipmap level,
- * so have to store them as a lookup table:
- */
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
-
- /* Includes image offset tables:
- */
- unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
-
- /* The data is held here:
- */
- struct pipe_buffer *buffer;
-};
-
-struct i915_context
-{
- struct pipe_context pipe;
- struct i915_winsys *winsys;
- struct draw_context *draw;
-
- /* The most recent drawing state as set by the driver:
- */
- const struct i915_blend_state *blend;
- const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS];
- const struct i915_depth_stencil_state *depth_stencil;
- const struct i915_rasterizer_state *rasterizer;
-
- struct i915_fragment_shader *fs;
-
- struct pipe_blend_color blend_color;
- struct pipe_clip_state clip;
- struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
- struct pipe_framebuffer_state framebuffer;
- struct pipe_poly_stipple poly_stipple;
- struct pipe_scissor_state scissor;
- struct i915_texture *texture[PIPE_MAX_SAMPLERS];
- struct pipe_viewport_state viewport;
- struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
-
- unsigned dirty;
-
- unsigned num_samplers;
- unsigned num_textures;
- unsigned num_vertex_elements;
- unsigned num_vertex_buffers;
-
- unsigned *batch_start;
-
- /** Vertex buffer */
- struct pipe_buffer *vbo;
-
- struct i915_state current;
- unsigned hardware_dirty;
-
- unsigned debug;
-};
-
-/* A flag for each state_tracker state object:
- */
-#define I915_NEW_VIEWPORT 0x1
-#define I915_NEW_RASTERIZER 0x2
-#define I915_NEW_FS 0x4
-#define I915_NEW_BLEND 0x8
-#define I915_NEW_CLIP 0x10
-#define I915_NEW_SCISSOR 0x20
-#define I915_NEW_STIPPLE 0x40
-#define I915_NEW_FRAMEBUFFER 0x80
-#define I915_NEW_ALPHA_TEST 0x100
-#define I915_NEW_DEPTH_STENCIL 0x200
-#define I915_NEW_SAMPLER 0x400
-#define I915_NEW_TEXTURE 0x800
-#define I915_NEW_CONSTANTS 0x1000
-#define I915_NEW_VBO 0x2000
-#define I915_NEW_VS 0x4000
-
-
-/* Driver's internally generated state flags:
- */
-#define I915_NEW_VERTEX_FORMAT 0x10000
-
-
-/* Dirty flags for hardware emit
- */
-#define I915_HW_STATIC (1<<I915_CACHE_STATIC)
-#define I915_HW_DYNAMIC (1<<I915_CACHE_DYNAMIC)
-#define I915_HW_SAMPLER (1<<I915_CACHE_SAMPLER)
-#define I915_HW_MAP (1<<I915_CACHE_MAP)
-#define I915_HW_PROGRAM (1<<I915_CACHE_PROGRAM)
-#define I915_HW_CONSTANTS (1<<I915_CACHE_CONSTANTS)
-#define I915_HW_IMMEDIATE (1<<(I915_MAX_CACHE+0))
-#define I915_HW_INVARIENT (1<<(I915_MAX_CACHE+1))
-
-
-/***********************************************************************
- * i915_prim_emit.c:
- */
-struct draw_stage *i915_draw_render_stage( struct i915_context *i915 );
-
-
-/***********************************************************************
- * i915_prim_vbuf.c:
- */
-struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 );
-
-
-/***********************************************************************
- * i915_state_emit.c:
- */
-void i915_emit_hardware_state(struct i915_context *i915 );
-
-
-
-/***********************************************************************
- * i915_clear.c:
- */
-void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,
- unsigned clearValue);
-
-
-/***********************************************************************
- * i915_surface.c:
- */
-void i915_init_surface_functions( struct i915_context *i915 );
-
-void i915_init_state_functions( struct i915_context *i915 );
-void i915_init_flush_functions( struct i915_context *i915 );
-void i915_init_string_functions( struct i915_context *i915 );
-
-
-
-
-/***********************************************************************
- * Inline conversion functions. These are better-typed than the
- * macros used previously:
- */
-static INLINE struct i915_context *
-i915_context( struct pipe_context *pipe )
-{
- return (struct i915_context *)pipe;
-}
-
-
-
-#endif
+ /************************************************************************** + * + * Copyright 2003 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 I915_CONTEXT_H +#define I915_CONTEXT_H + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "tgsi/util/tgsi_scan.h" + + +#define I915_TEX_UNITS 8 + +#define I915_DYNAMIC_MODES4 0 +#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */ +#define I915_DYNAMIC_DEPTHSCALE_1 2 +#define I915_DYNAMIC_IAB 3 +#define I915_DYNAMIC_BC_0 4 /* just the header */ +#define I915_DYNAMIC_BC_1 5 +#define I915_DYNAMIC_BFO_0 6 +#define I915_DYNAMIC_BFO_1 7 +#define I915_DYNAMIC_STP_0 8 +#define I915_DYNAMIC_STP_1 9 +#define I915_DYNAMIC_SC_ENA_0 10 +#define I915_DYNAMIC_SC_RECT_0 11 +#define I915_DYNAMIC_SC_RECT_1 12 +#define I915_DYNAMIC_SC_RECT_2 13 +#define I915_MAX_DYNAMIC 14 + + +#define I915_IMMEDIATE_S0 0 +#define I915_IMMEDIATE_S1 1 +#define I915_IMMEDIATE_S2 2 +#define I915_IMMEDIATE_S3 3 +#define I915_IMMEDIATE_S4 4 +#define I915_IMMEDIATE_S5 5 +#define I915_IMMEDIATE_S6 6 +#define I915_IMMEDIATE_S7 7 +#define I915_MAX_IMMEDIATE 8 + +/* These must mach the order of LI0_STATE_* bits, as they will be used + * to generate hardware packets: + */ +#define I915_CACHE_STATIC 0 +#define I915_CACHE_DYNAMIC 1 /* handled specially */ +#define I915_CACHE_SAMPLER 2 +#define I915_CACHE_MAP 3 +#define I915_CACHE_PROGRAM 4 +#define I915_CACHE_CONSTANTS 5 +#define I915_MAX_CACHE 6 + +#define I915_MAX_CONSTANT 32 + + +/** See constant_flags[] below */ +#define I915_CONSTFLAG_USER 0x1f + + +/** + * Subclass of pipe_shader_state + */ +struct i915_fragment_shader +{ + struct pipe_shader_state state; + + struct tgsi_shader_info info; + + uint *program; + uint program_len; + + /** + * constants introduced during translation. + * These are placed at the end of the constant buffer and grow toward + * the beginning (eg: slot 31, 30 29, ...) + * User-provided constants start at 0. + * This allows both types of constants to co-exist (until there's too many) + * and doesn't require regenerating/changing the fragment program to + * shuffle constants around. + */ + uint num_constants; + float constants[I915_MAX_CONSTANT][4]; + + /** + * Status of each constant + * if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding + * slot of the user's constant buffer. (set by pipe->set_constant_buffer()) + * Else, the bitmask indicates which components are occupied by immediates. + */ + ubyte constant_flags[I915_MAX_CONSTANT]; +}; + + +struct i915_cache_context; + +/* Use to calculate differences between state emitted to hardware and + * current driver-calculated state. + */ +struct i915_state +{ + unsigned immediate[I915_MAX_IMMEDIATE]; + unsigned dynamic[I915_MAX_DYNAMIC]; + + float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4]; + /** number of constants passed in through a constant buffer */ + uint num_user_constants[PIPE_SHADER_TYPES]; + + /* texture sampler state */ + unsigned sampler[I915_TEX_UNITS][3]; + unsigned sampler_enable_flags; + unsigned sampler_enable_nr; + + /* texture image buffers */ + unsigned texbuffer[I915_TEX_UNITS][2]; + + /** Describes the current hardware vertex layout */ + struct vertex_info vertex_info; + + unsigned id; /* track lost context events */ +}; + +struct i915_blend_state { + unsigned iab; + unsigned modes4; + unsigned LIS5; + unsigned LIS6; +}; + +struct i915_depth_stencil_state { + unsigned stencil_modes4; + unsigned bfo[2]; + unsigned stencil_LIS5; + unsigned depth_LIS6; +}; + +struct i915_rasterizer_state { + int light_twoside : 1; + unsigned st; + enum interp_mode color_interp; + + unsigned LIS4; + unsigned LIS7; + unsigned sc[1]; + + const struct pipe_rasterizer_state *templ; + + union { float f; unsigned u; } ds[2]; +}; + +struct i915_sampler_state { + unsigned state[3]; + const struct pipe_sampler_state *templ; +}; + + +struct i915_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +struct i915_context +{ + struct pipe_context pipe; + struct i915_winsys *winsys; + struct draw_context *draw; + + /* The most recent drawing state as set by the driver: + */ + const struct i915_blend_state *blend; + const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + const struct i915_depth_stencil_state *depth_stencil; + const struct i915_rasterizer_state *rasterizer; + + struct i915_fragment_shader *fs; + + struct pipe_blend_color blend_color; + struct pipe_clip_state clip; + struct pipe_constant_buffer constants[PIPE_SHADER_TYPES]; + struct pipe_framebuffer_state framebuffer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct i915_texture *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + + unsigned dirty; + + unsigned num_samplers; + unsigned num_textures; + unsigned num_vertex_elements; + unsigned num_vertex_buffers; + + unsigned *batch_start; + + /** Vertex buffer */ + struct pipe_buffer *vbo; + + struct i915_state current; + unsigned hardware_dirty; + + unsigned debug; +}; + +/* A flag for each state_tracker state object: + */ +#define I915_NEW_VIEWPORT 0x1 +#define I915_NEW_RASTERIZER 0x2 +#define I915_NEW_FS 0x4 +#define I915_NEW_BLEND 0x8 +#define I915_NEW_CLIP 0x10 +#define I915_NEW_SCISSOR 0x20 +#define I915_NEW_STIPPLE 0x40 +#define I915_NEW_FRAMEBUFFER 0x80 +#define I915_NEW_ALPHA_TEST 0x100 +#define I915_NEW_DEPTH_STENCIL 0x200 +#define I915_NEW_SAMPLER 0x400 +#define I915_NEW_TEXTURE 0x800 +#define I915_NEW_CONSTANTS 0x1000 +#define I915_NEW_VBO 0x2000 +#define I915_NEW_VS 0x4000 + + +/* Driver's internally generated state flags: + */ +#define I915_NEW_VERTEX_FORMAT 0x10000 + + +/* Dirty flags for hardware emit + */ +#define I915_HW_STATIC (1<<I915_CACHE_STATIC) +#define I915_HW_DYNAMIC (1<<I915_CACHE_DYNAMIC) +#define I915_HW_SAMPLER (1<<I915_CACHE_SAMPLER) +#define I915_HW_MAP (1<<I915_CACHE_MAP) +#define I915_HW_PROGRAM (1<<I915_CACHE_PROGRAM) +#define I915_HW_CONSTANTS (1<<I915_CACHE_CONSTANTS) +#define I915_HW_IMMEDIATE (1<<(I915_MAX_CACHE+0)) +#define I915_HW_INVARIENT (1<<(I915_MAX_CACHE+1)) + + +/*********************************************************************** + * i915_prim_emit.c: + */ +struct draw_stage *i915_draw_render_stage( struct i915_context *i915 ); + + +/*********************************************************************** + * i915_prim_vbuf.c: + */ +struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 ); + + +/*********************************************************************** + * i915_state_emit.c: + */ +void i915_emit_hardware_state(struct i915_context *i915 ); + + + +/*********************************************************************** + * i915_clear.c: + */ +void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + + +/*********************************************************************** + * i915_surface.c: + */ +void i915_init_surface_functions( struct i915_context *i915 ); + +void i915_init_state_functions( struct i915_context *i915 ); +void i915_init_flush_functions( struct i915_context *i915 ); +void i915_init_string_functions( struct i915_context *i915 ); + + + + +/*********************************************************************** + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static INLINE struct i915_context * +i915_context( struct pipe_context *pipe ) +{ + return (struct i915_context *)pipe; +} + + + +#endif diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 646cfd921d1..ba8f183bdf0 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -201,6 +201,35 @@ i915_destroy_screen( struct pipe_screen *screen ) } +static void * +i915_surface_map( struct pipe_screen *screen, + struct pipe_surface *surface, + unsigned flags ) +{ + char *map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags ); + if (map == NULL) + return NULL; + + if (surface->texture && + (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) + { + /* Do something to notify contexts of a texture change. + */ + /* i915_screen(screen)->timestamp++; */ + } + + return map + surface->offset; +} + +static void +i915_surface_unmap(struct pipe_screen *screen, + struct pipe_surface *surface) +{ + screen->winsys->buffer_unmap( screen->winsys, surface->buffer ); +} + + + /** * Create a new i915_screen object */ @@ -244,6 +273,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) i915screen->screen.get_param = i915_get_param; i915screen->screen.get_paramf = i915_get_paramf; i915screen->screen.is_format_supported = i915_is_format_supported; + i915screen->screen.surface_map = i915_surface_map; + i915screen->screen.surface_unmap = i915_surface_unmap; i915_init_screen_texture_functions(&i915screen->screen); diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c index 964bd7c871c..e6c4671700e 100644 --- a/src/gallium/drivers/i915simple/i915_state.c +++ b/src/gallium/drivers/i915simple/i915_state.c @@ -466,7 +466,7 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader) FREE(ifs->program); ifs->program_len = 0; - FREE(ifs->state.tokens); + FREE((struct tgsi_token *)ifs->state.tokens); FREE(ifs); } diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c index f4fbedbe9bc..98367ac0739 100644 --- a/src/gallium/drivers/i915simple/i915_surface.c +++ b/src/gallium/drivers/i915simple/i915_surface.c @@ -51,17 +51,25 @@ i915_surface_copy(struct pipe_context *pipe, assert( dst->cpp == src->cpp ); if (0) { - pipe_copy_rect(pipe_surface_map(dst), + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, dstx, dsty, width, height, - pipe_surface_map(src), + src_map, do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } else { i915_copy_blit( i915_context(pipe), @@ -92,7 +100,10 @@ i915_surface_fill(struct pipe_context *pipe, { if (0) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + switch (dst->cpp) { case 1: { @@ -126,7 +137,7 @@ i915_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } else { i915_fill_blit( i915_context(pipe), diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c index c39e747705b..df11ba0544c 100644 --- a/src/gallium/drivers/i915simple/i915_texture.c +++ b/src/gallium/drivers/i915simple/i915_texture.c @@ -105,6 +105,51 @@ i915_miptree_set_image_offset(struct i915_texture *tex, } +/* Hack it up to use the old winsys->surface_alloc_storage() + * method for now: + */ +static boolean +i915_displaytarget_layout(struct pipe_screen *screen, + struct i915_texture *tex) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface surf; + unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + + memset(&surf, 0, sizeof(surf)); + + ws->surface_alloc_storage( ws, + &surf, + tex->base.width[0], + tex->base.height[0], + tex->base.format, + flags, + tex->base.tex_usage); + + /* Now extract the goodies: + */ + i915_miptree_set_level_info( tex, 0, 1, 0, 0, + tex->base.width[0], + tex->base.height[0], + 1 ); + i915_miptree_set_image_offset( tex, 0, 0, 0, 0 ); + + tex->buffer = surf.buffer; + tex->pitch = surf.pitch; + tex->total_height = 0; + + + return tex->buffer != NULL; +} + + + + + static void i945_miptree_layout_2d( struct i915_texture *tex ) { @@ -480,39 +525,54 @@ i945_miptree_layout(struct i915_texture * tex) static struct pipe_texture * -i915_texture_create_screen(struct pipe_screen *screen, - const struct pipe_texture *templat) +i915_texture_create(struct pipe_screen *screen, + const struct pipe_texture *templat) { + struct i915_screen *i915screen = i915_screen(screen); + struct pipe_winsys *ws = screen->winsys; struct i915_texture *tex = CALLOC_STRUCT(i915_texture); - if (tex) { - struct i915_screen *i915screen = i915_screen(screen); - struct pipe_winsys *ws = screen->winsys; - - tex->base = *templat; - tex->base.refcount = 1; - tex->base.screen = screen; + if (!tex) + return NULL; - if (i915screen->is_i945 ? i945_miptree_layout(tex) : - i915_miptree_layout(tex)) - tex->buffer = ws->buffer_create(ws, 64, - PIPE_BUFFER_USAGE_PIXEL, - tex->pitch * tex->base.cpp * - tex->total_height); + tex->base = *templat; + tex->base.refcount = 1; + tex->base.screen = screen; - if (!tex->buffer) { - FREE(tex); - return NULL; + if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!i915_displaytarget_layout(screen, tex)) + goto fail; + } + else { + if (i915screen->is_i945) { + if (!i945_miptree_layout(tex)) + goto fail; } + else { + if (!i915_miptree_layout(tex)) + goto fail; + } + + tex->buffer = ws->buffer_create(ws, 64, + PIPE_BUFFER_USAGE_PIXEL, + tex->pitch * tex->base.cpp * + tex->total_height); + + if (!tex->buffer) + goto fail; } return &tex->base; + + fail: + FREE(tex); + return NULL; } static void -i915_texture_release_screen(struct pipe_screen *screen, - struct pipe_texture **pt) +i915_texture_release(struct pipe_screen *screen, + struct pipe_texture **pt) { if (!*pt) return; @@ -541,21 +601,15 @@ i915_texture_release_screen(struct pipe_screen *screen, } -static void -i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, - uint face, uint levelsMask) -{ - /* no-op? */ -} - /* * XXX note: same as code in sp_surface.c */ static struct pipe_surface * -i915_get_tex_surface_screen(struct pipe_screen *screen, - struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) +i915_get_tex_surface(struct pipe_screen *screen, + struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) { struct i915_texture *tex = (struct i915_texture *)pt; struct pipe_winsys *ws = screen->winsys; @@ -579,6 +633,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, if (ps) { assert(ps->refcount); assert(ps->winsys); + pipe_texture_reference(&ps->texture, pt); pipe_buffer_reference(ws, &ps->buffer, tex->buffer); ps->format = pt->format; ps->cpp = pt->cpp; @@ -586,6 +641,7 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, ps->height = pt->height[level]; ps->pitch = tex->pitch; ps->offset = offset; + ps->usage = flags; } return ps; } @@ -594,14 +650,38 @@ i915_get_tex_surface_screen(struct pipe_screen *screen, void i915_init_texture_functions(struct i915_context *i915) { - i915->pipe.texture_update = i915_texture_update; +// i915->pipe.texture_update = i915_texture_update; } +static void +i915_tex_surface_release(struct pipe_screen *screen, + struct pipe_surface **surface) +{ + struct pipe_surface *surf = *surface; + + if (--surf->refcount == 0) { + + /* This really should not be possible, but it's actually + * happening quite a bit... Will fix. + */ + if (surf->status == PIPE_SURFACE_STATUS_CLEAR) { + debug_printf("XXX destroying a surface with pending clears...\n"); + assert(0); + } + + pipe_texture_reference(&surf->texture, NULL); + pipe_buffer_reference(screen->winsys, &surf->buffer, NULL); + FREE(surf); + } + + *surface = NULL; +} void i915_init_screen_texture_functions(struct pipe_screen *screen) { - screen->texture_create = i915_texture_create_screen; - screen->texture_release = i915_texture_release_screen; - screen->get_tex_surface = i915_get_tex_surface_screen; + screen->texture_create = i915_texture_create; + screen->texture_release = i915_texture_release; + screen->get_tex_surface = i915_get_tex_surface; + screen->tex_surface_release = i915_tex_surface_release; } diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index eeccf367856..8ac6b4e6897 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -1,684 +1,684 @@ -/*
- Copyright (C) Intel Corp. 2006. All Rights Reserved.
- Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
- develop this 3D driver.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice (including the
- next paragraph) shall be included in all copies or substantial
- portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 <[email protected]>
- */
-
-
-#ifndef BRWCONTEXT_INC
-#define BRWCONTEXT_INC
-
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-
-#include "tgsi/util/tgsi_scan.h"
-
-#include "brw_structs.h"
-#include "brw_winsys.h"
-
-
-/* Glossary:
- *
- * URB - uniform resource buffer. A mid-sized buffer which is
- * partitioned between the fixed function units and used for passing
- * values (vertices, primitives, constants) between them.
- *
- * CURBE - constant URB entry. An urb region (entry) used to hold
- * constant values which the fixed function units can be instructed to
- * preload into the GRF when spawining a thread.
- *
- * VUE - vertex URB entry. An urb entry holding a vertex and usually
- * a vertex header. The header contains control information and
- * things like primitive type, Begin/end flags and clip codes.
- *
- * PUE - primitive URB entry. An urb entry produced by the setup (SF)
- * unit holding rasterization and interpolation parameters.
- *
- * GRF - general register file. One of several register files
- * addressable by programmed threads. The inputs (r0, payload, curbe,
- * urb) of the thread are preloaded to this area before the thread is
- * spawned. The registers are individually 8 dwords wide and suitable
- * for general usage. Registers holding thread input values are not
- * special and may be overwritten.
- *
- * MRF - message register file. Threads communicate (and terminate)
- * by sending messages. Message parameters are placed in contigous
- * MRF registers. All program output is via these messages. URB
- * entries are populated by sending a message to the shared URB
- * function containing the new data, together with a control word,
- * often an unmodified copy of R0.
- *
- * R0 - GRF register 0. Typically holds control information used when
- * sending messages to other threads.
- *
- * EU or GEN4 EU: The name of the programmable subsystem of the
- * i965 hardware. Threads are executed by the EU, the registers
- * described above are part of the EU architecture.
- *
- * Fixed function units:
- *
- * CS - Command streamer. Notional first unit, little software
- * interaction. Holds the URB entries used for constant data, ie the
- * CURBEs.
- *
- * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of
- * this unit is responsible for pulling vertices out of vertex buffers
- * in vram and injecting them into the processing pipe as VUEs. If
- * enabled, it first passes them to a VS thread which is a good place
- * for the driver to implement any active vertex shader.
- *
- * GS - Geometry Shader. This corresponds to a new DX10 concept. If
- * enabled, incoming strips etc are passed to GS threads in individual
- * line/triangle/point units. The GS thread may perform arbitary
- * computation and emit whatever primtives with whatever vertices it
- * chooses. This makes GS an excellent place to implement GL's
- * unfilled polygon modes, though of course it is capable of much
- * more. Additionally, GS is used to translate away primitives not
- * handled by latter units, including Quads and Lineloops.
- *
- * CS - Clipper. Mesa's clipping algorithms are imported to run on
- * this unit. The fixed function part performs cliptesting against
- * the 6 fixed clipplanes and makes descisions on whether or not the
- * incoming primitive needs to be passed to a thread for clipping.
- * User clip planes are handled via cooperation with the VS thread.
- *
- * SF - Strips Fans or Setup: Triangles are prepared for
- * rasterization. Interpolation coefficients are calculated.
- * Flatshading and two-side lighting usually performed here.
- *
- * WM - Windower. Interpolation of vertex attributes performed here.
- * Fragment shader implemented here. SIMD aspects of EU taken full
- * advantage of, as pixels are processed in blocks of 16.
- *
- * CC - Color Calculator. No EU threads associated with this unit.
- * Handles blending and (presumably) depth and stencil testing.
- */
-
-#define BRW_MAX_CURBE (32*16)
-
-struct brw_context;
-struct brw_winsys;
-
-
-/* Raised when we receive new state across the pipe interface:
- */
-#define BRW_NEW_VIEWPORT 0x1
-#define BRW_NEW_RASTERIZER 0x2
-#define BRW_NEW_FS 0x4
-#define BRW_NEW_BLEND 0x8
-#define BRW_NEW_CLIP 0x10
-#define BRW_NEW_SCISSOR 0x20
-#define BRW_NEW_STIPPLE 0x40
-#define BRW_NEW_FRAMEBUFFER 0x80
-#define BRW_NEW_ALPHA_TEST 0x100
-#define BRW_NEW_DEPTH_STENCIL 0x200
-#define BRW_NEW_SAMPLER 0x400
-#define BRW_NEW_TEXTURE 0x800
-#define BRW_NEW_CONSTANTS 0x1000
-#define BRW_NEW_VBO 0x2000
-#define BRW_NEW_VS 0x4000
-
-/* Raised for other internal events:
- */
-#define BRW_NEW_URB_FENCE 0x10000
-#define BRW_NEW_PSP 0x20000
-#define BRW_NEW_CURBE_OFFSETS 0x40000
-#define BRW_NEW_REDUCED_PRIMITIVE 0x80000
-#define BRW_NEW_PRIMITIVE 0x100000
-#define BRW_NEW_SCENE 0x200000
-#define BRW_NEW_SF_LINKAGE 0x400000
-
-extern int BRW_DEBUG;
-
-#define DEBUG_TEXTURE 0x1
-#define DEBUG_STATE 0x2
-#define DEBUG_IOCTL 0x4
-#define DEBUG_PRIMS 0x8
-#define DEBUG_VERTS 0x10
-#define DEBUG_FALLBACKS 0x20
-#define DEBUG_VERBOSE 0x40
-#define DEBUG_DRI 0x80
-#define DEBUG_DMA 0x100
-#define DEBUG_SANITY 0x200
-#define DEBUG_SYNC 0x400
-#define DEBUG_SLEEP 0x800
-#define DEBUG_PIXEL 0x1000
-#define DEBUG_STATS 0x2000
-#define DEBUG_TILE 0x4000
-#define DEBUG_SINGLE_THREAD 0x8000
-#define DEBUG_WM 0x10000
-#define DEBUG_URB 0x20000
-#define DEBUG_VS 0x40000
-#define DEBUG_BATCH 0x80000
-#define DEBUG_BUFMGR 0x100000
-#define DEBUG_BLIT 0x200000
-#define DEBUG_REGION 0x400000
-#define DEBUG_MIPTREE 0x800000
-
-#define DBG(...) do { \
- if (BRW_DEBUG & FILE_DEBUG_FLAG) \
- debug_printf(__VA_ARGS__); \
-} while(0)
-
-#define PRINT(...) do { \
- debug_printf(brw->pipe.winsys, __VA_ARGS__); \
-} while(0)
-
-struct brw_state_flags {
- unsigned cache;
- unsigned brw;
-};
-
-
-struct brw_vertex_program {
- struct pipe_shader_state program;
- struct tgsi_shader_info info;
- int id;
-};
-
-
-struct brw_fragment_program {
- struct pipe_shader_state program;
- struct tgsi_shader_info info;
-
- boolean UsesDepth; /* XXX add this to tgsi_shader_info? */
- int id;
-};
-
-
-struct pipe_setup_linkage {
- struct {
- unsigned vp_output:5;
- unsigned interp_mode:4;
- unsigned bf_vp_output:5;
- } fp_input[PIPE_MAX_SHADER_INPUTS];
-
- unsigned fp_input_count:5;
- unsigned max_vp_output:5;
-};
-
-
-
-struct brw_texture {
- struct pipe_texture base;
-
- /* Derived from the above:
- */
- unsigned pitch;
- unsigned depth_pitch; /* per-image on i945? */
- unsigned total_height;
-
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
-
- /* Explicitly store the offset of each image for each cube face or
- * depth value. Pretty much have to accept that hardware formats
- * are going to be so diverse that there is no unified way to
- * compute the offsets of depth/cube images within a mipmap level,
- * so have to store them as a lookup table:
- */
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
-
- /* Includes image offset tables:
- */
- unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
-
- /* The data is held here:
- */
- struct pipe_buffer *buffer;
-};
-
-/* Data about a particular attempt to compile a program. Note that
- * there can be many of these, each in a different GL state
- * corresponding to a different brw_wm_prog_key struct, with different
- * compiled programs:
- */
-/* Data about a particular attempt to compile a program. Note that
- * there can be many of these, each in a different GL state
- * corresponding to a different brw_wm_prog_key struct, with different
- * compiled programs:
- */
-
-struct brw_wm_prog_data {
- unsigned curb_read_length;
- unsigned urb_read_length;
-
- unsigned first_curbe_grf;
- unsigned total_grf;
- unsigned total_scratch;
-
- /* Internally generated constants for the CURBE. These are loaded
- * ahead of the data from the constant buffer.
- */
- const float internal_const[8];
- unsigned nr_internal_consts;
- unsigned max_const;
-
- boolean error;
-};
-
-struct brw_sf_prog_data {
- unsigned urb_read_length;
- unsigned total_grf;
-
- /* Each vertex may have upto 12 attributes, 4 components each,
- * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11
- * rows.
- *
- * Actually we use 4 for each, so call it 12 rows.
- */
- unsigned urb_entry_size;
-};
-
-struct brw_clip_prog_data {
- unsigned curb_read_length; /* user planes? */
- unsigned clip_mode;
- unsigned urb_read_length;
- unsigned total_grf;
-};
-
-struct brw_gs_prog_data {
- unsigned urb_read_length;
- unsigned total_grf;
-};
-
-struct brw_vs_prog_data {
- unsigned curb_read_length;
- unsigned urb_read_length;
- unsigned total_grf;
- unsigned outputs_written;
-
- unsigned inputs_read;
-
- unsigned max_const;
-
- float imm_buf[PIPE_MAX_CONSTANT][4];
- unsigned num_imm;
- unsigned num_consts;
-
- /* Used for calculating urb partitions:
- */
- unsigned urb_entry_size;
-};
-
-
-#define BRW_MAX_TEX_UNIT 8
-#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1
-
-/* Create a fixed sized struct for caching binding tables:
- */
-struct brw_surface_binding_table {
- unsigned surf_ss_offset[BRW_WM_MAX_SURF];
-};
-
-
-struct brw_cache;
-
-struct brw_mem_pool {
- struct pipe_buffer *buffer;
-
- unsigned size;
- unsigned offset; /* offset of first free byte */
-
- struct brw_context *brw;
-};
-
-struct brw_cache_item {
- unsigned hash;
- unsigned key_size; /* for variable-sized keys */
- const void *key;
-
- unsigned offset; /* offset within pool's buffer */
- unsigned data_size;
-
- struct brw_cache_item *next;
-};
-
-
-
-struct brw_cache {
- unsigned id;
-
- const char *name;
-
- struct brw_context *brw;
- struct brw_mem_pool *pool;
-
- struct brw_cache_item **items;
- unsigned size, n_items;
-
- unsigned key_size; /* for fixed-size keys */
- unsigned aux_size;
-
- unsigned last_addr; /* offset of active item */
-};
-
-
-
-
-/* Considered adding a member to this struct to document which flags
- * an update might raise so that ordering of the state atoms can be
- * checked or derived at runtime. Dropped the idea in favor of having
- * a debug mode where the state is monitored for flags which are
- * raised that have already been tested against.
- */
-struct brw_tracked_state {
- struct brw_state_flags dirty;
- void (*update)( struct brw_context *brw );
-};
-
-
-/* Flags for brw->state.cache.
- */
-#define CACHE_NEW_CC_VP (1<<BRW_CC_VP)
-#define CACHE_NEW_CC_UNIT (1<<BRW_CC_UNIT)
-#define CACHE_NEW_WM_PROG (1<<BRW_WM_PROG)
-#define CACHE_NEW_SAMPLER_DEFAULT_COLOR (1<<BRW_SAMPLER_DEFAULT_COLOR)
-#define CACHE_NEW_SAMPLER (1<<BRW_SAMPLER)
-#define CACHE_NEW_WM_UNIT (1<<BRW_WM_UNIT)
-#define CACHE_NEW_SF_PROG (1<<BRW_SF_PROG)
-#define CACHE_NEW_SF_VP (1<<BRW_SF_VP)
-#define CACHE_NEW_SF_UNIT (1<<BRW_SF_UNIT)
-#define CACHE_NEW_VS_UNIT (1<<BRW_VS_UNIT)
-#define CACHE_NEW_VS_PROG (1<<BRW_VS_PROG)
-#define CACHE_NEW_GS_UNIT (1<<BRW_GS_UNIT)
-#define CACHE_NEW_GS_PROG (1<<BRW_GS_PROG)
-#define CACHE_NEW_CLIP_VP (1<<BRW_CLIP_VP)
-#define CACHE_NEW_CLIP_UNIT (1<<BRW_CLIP_UNIT)
-#define CACHE_NEW_CLIP_PROG (1<<BRW_CLIP_PROG)
-#define CACHE_NEW_SURFACE (1<<BRW_SS_SURFACE)
-#define CACHE_NEW_SURF_BIND (1<<BRW_SS_SURF_BIND)
-
-
-
-
-enum brw_mempool_id {
- BRW_GS_POOL,
- BRW_SS_POOL,
- BRW_MAX_POOL
-};
-
-
-struct brw_cached_batch_item {
- struct header *header;
- unsigned sz;
- struct brw_cached_batch_item *next;
-};
-
-
-
-/* Protect against a future where PIPE_MAX_ATTRIBS > 32. Wouldn't life
- * be easier if C allowed arrays of packed elements?
- */
-#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32)
-
-
-
-
-struct brw_vertex_info {
- unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */
- unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */
-};
-
-
-
-
-
-struct brw_context
-{
- struct pipe_context pipe;
- struct brw_winsys *winsys;
-
- unsigned primitive;
- unsigned reduced_primitive;
-
- boolean emit_state_always;
-
- struct {
- struct brw_state_flags dirty;
- } state;
-
-
- struct {
- const struct pipe_blend_state *Blend;
- const struct pipe_depth_stencil_alpha_state *DepthStencil;
- const struct pipe_poly_stipple *PolygonStipple;
- const struct pipe_rasterizer_state *Raster;
- const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS];
- const struct brw_vertex_program *VertexProgram;
- const struct brw_fragment_program *FragmentProgram;
-
- struct pipe_clip_state Clip;
- struct pipe_blend_color BlendColor;
- struct pipe_scissor_state Scissor;
- struct pipe_viewport_state Viewport;
- struct pipe_framebuffer_state FrameBuffer;
-
- const struct pipe_constant_buffer *Constants[2];
- const struct brw_texture *Texture[PIPE_MAX_SAMPLERS];
- } attribs;
-
- unsigned num_samplers;
- unsigned num_textures;
-
- struct brw_mem_pool pool[BRW_MAX_POOL];
- struct brw_cache cache[BRW_MAX_CACHE];
- struct brw_cached_batch_item *cached_batch_items;
-
- struct {
-
- /* Arrays with buffer objects to copy non-bufferobj arrays into
- * for upload:
- */
- const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS];
-
- struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS];
-
-#define BRW_NR_UPLOAD_BUFS 17
-#define BRW_UPLOAD_INIT_SIZE (128*1024)
-
- /* Summary of size and varying of active arrays, so we can check
- * for changes to this state:
- */
- struct brw_vertex_info info;
- } vb;
-
-
- unsigned hardware_dirty;
- unsigned dirty;
- unsigned pci_id;
- /* BRW_NEW_URB_ALLOCATIONS:
- */
- struct {
- unsigned vsize; /* vertex size plus header in urb registers */
- unsigned csize; /* constant buffer size in urb registers */
- unsigned sfsize; /* setup data size in urb registers */
-
- boolean constrained;
-
- unsigned nr_vs_entries;
- unsigned nr_gs_entries;
- unsigned nr_clip_entries;
- unsigned nr_sf_entries;
- unsigned nr_cs_entries;
-
-/* unsigned vs_size; */
-/* unsigned gs_size; */
-/* unsigned clip_size; */
-/* unsigned sf_size; */
-/* unsigned cs_size; */
-
- unsigned vs_start;
- unsigned gs_start;
- unsigned clip_start;
- unsigned sf_start;
- unsigned cs_start;
- } urb;
-
-
- /* BRW_NEW_CURBE_OFFSETS:
- */
- struct {
- unsigned wm_start;
- unsigned wm_size;
- unsigned clip_start;
- unsigned clip_size;
- unsigned vs_start;
- unsigned vs_size;
- unsigned total_size;
-
- unsigned gs_offset;
-
- float *last_buf;
- unsigned last_bufsz;
- } curbe;
-
- struct {
- struct brw_vs_prog_data *prog_data;
-
- unsigned prog_gs_offset;
- unsigned state_gs_offset;
- } vs;
-
- struct {
- struct brw_gs_prog_data *prog_data;
-
- boolean prog_active;
- unsigned prog_gs_offset;
- unsigned state_gs_offset;
- } gs;
-
- struct {
- struct brw_clip_prog_data *prog_data;
-
- unsigned prog_gs_offset;
- unsigned vp_gs_offset;
- unsigned state_gs_offset;
- } clip;
-
-
- struct {
- struct brw_sf_prog_data *prog_data;
-
- struct pipe_setup_linkage linkage;
-
- unsigned prog_gs_offset;
- unsigned vp_gs_offset;
- unsigned state_gs_offset;
- } sf;
-
- struct {
- struct brw_wm_prog_data *prog_data;
-
-// struct brw_wm_compiler *compile_data;
-
-
- /**
- * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER
- * cache
- */
- struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT];
-
- unsigned render_surf;
- unsigned nr_surfaces;
-
- unsigned max_threads;
- struct pipe_buffer *scratch_buffer;
- unsigned scratch_buffer_size;
-
- unsigned sampler_count;
- unsigned sampler_gs_offset;
-
- struct brw_surface_binding_table bind;
- unsigned bind_ss_offset;
-
- unsigned prog_gs_offset;
- unsigned state_gs_offset;
- } wm;
-
-
- struct {
- unsigned vp_gs_offset;
- unsigned state_gs_offset;
- } cc;
-
-
- /* Used to give every program string a unique id
- */
- unsigned program_id;
-};
-
-
-#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a)
-
-
-/*======================================================================
- * brw_vtbl.c
- */
-void brw_do_flush( struct brw_context *brw,
- unsigned flags );
-
-
-/*======================================================================
- * brw_state.c
- */
-void brw_validate_state(struct brw_context *brw);
-void brw_init_state(struct brw_context *brw);
-void brw_destroy_state(struct brw_context *brw);
-
-
-/*======================================================================
- * brw_tex.c
- */
-void brwUpdateTextureState( struct brw_context *brw );
-
-
-/* brw_urb.c
- */
-void brw_upload_urb_fence(struct brw_context *brw);
-
-void brw_upload_constant_buffer_state(struct brw_context *brw);
-
-void brw_init_surface_functions(struct brw_context *brw);
-void brw_init_state_functions(struct brw_context *brw);
-void brw_init_flush_functions(struct brw_context *brw);
-void brw_init_string_functions(struct brw_context *brw);
-
-/*======================================================================
- * Inline conversion functions. These are better-typed than the
- * macros used previously:
- */
-static inline struct brw_context *
-brw_context( struct pipe_context *ctx )
-{
- return (struct brw_context *)ctx;
-}
-
-#endif
-
+/* + Copyright (C) Intel Corp. 2006. All Rights Reserved. + Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to + develop this 3D driver. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 <[email protected]> + */ + + +#ifndef BRWCONTEXT_INC +#define BRWCONTEXT_INC + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "tgsi/util/tgsi_scan.h" + +#include "brw_structs.h" +#include "brw_winsys.h" + + +/* Glossary: + * + * URB - uniform resource buffer. A mid-sized buffer which is + * partitioned between the fixed function units and used for passing + * values (vertices, primitives, constants) between them. + * + * CURBE - constant URB entry. An urb region (entry) used to hold + * constant values which the fixed function units can be instructed to + * preload into the GRF when spawining a thread. + * + * VUE - vertex URB entry. An urb entry holding a vertex and usually + * a vertex header. The header contains control information and + * things like primitive type, Begin/end flags and clip codes. + * + * PUE - primitive URB entry. An urb entry produced by the setup (SF) + * unit holding rasterization and interpolation parameters. + * + * GRF - general register file. One of several register files + * addressable by programmed threads. The inputs (r0, payload, curbe, + * urb) of the thread are preloaded to this area before the thread is + * spawned. The registers are individually 8 dwords wide and suitable + * for general usage. Registers holding thread input values are not + * special and may be overwritten. + * + * MRF - message register file. Threads communicate (and terminate) + * by sending messages. Message parameters are placed in contigous + * MRF registers. All program output is via these messages. URB + * entries are populated by sending a message to the shared URB + * function containing the new data, together with a control word, + * often an unmodified copy of R0. + * + * R0 - GRF register 0. Typically holds control information used when + * sending messages to other threads. + * + * EU or GEN4 EU: The name of the programmable subsystem of the + * i965 hardware. Threads are executed by the EU, the registers + * described above are part of the EU architecture. + * + * Fixed function units: + * + * CS - Command streamer. Notional first unit, little software + * interaction. Holds the URB entries used for constant data, ie the + * CURBEs. + * + * VF/VS - Vertex Fetch / Vertex Shader. The fixed function part of + * this unit is responsible for pulling vertices out of vertex buffers + * in vram and injecting them into the processing pipe as VUEs. If + * enabled, it first passes them to a VS thread which is a good place + * for the driver to implement any active vertex shader. + * + * GS - Geometry Shader. This corresponds to a new DX10 concept. If + * enabled, incoming strips etc are passed to GS threads in individual + * line/triangle/point units. The GS thread may perform arbitary + * computation and emit whatever primtives with whatever vertices it + * chooses. This makes GS an excellent place to implement GL's + * unfilled polygon modes, though of course it is capable of much + * more. Additionally, GS is used to translate away primitives not + * handled by latter units, including Quads and Lineloops. + * + * CS - Clipper. Mesa's clipping algorithms are imported to run on + * this unit. The fixed function part performs cliptesting against + * the 6 fixed clipplanes and makes descisions on whether or not the + * incoming primitive needs to be passed to a thread for clipping. + * User clip planes are handled via cooperation with the VS thread. + * + * SF - Strips Fans or Setup: Triangles are prepared for + * rasterization. Interpolation coefficients are calculated. + * Flatshading and two-side lighting usually performed here. + * + * WM - Windower. Interpolation of vertex attributes performed here. + * Fragment shader implemented here. SIMD aspects of EU taken full + * advantage of, as pixels are processed in blocks of 16. + * + * CC - Color Calculator. No EU threads associated with this unit. + * Handles blending and (presumably) depth and stencil testing. + */ + +#define BRW_MAX_CURBE (32*16) + +struct brw_context; +struct brw_winsys; + + +/* Raised when we receive new state across the pipe interface: + */ +#define BRW_NEW_VIEWPORT 0x1 +#define BRW_NEW_RASTERIZER 0x2 +#define BRW_NEW_FS 0x4 +#define BRW_NEW_BLEND 0x8 +#define BRW_NEW_CLIP 0x10 +#define BRW_NEW_SCISSOR 0x20 +#define BRW_NEW_STIPPLE 0x40 +#define BRW_NEW_FRAMEBUFFER 0x80 +#define BRW_NEW_ALPHA_TEST 0x100 +#define BRW_NEW_DEPTH_STENCIL 0x200 +#define BRW_NEW_SAMPLER 0x400 +#define BRW_NEW_TEXTURE 0x800 +#define BRW_NEW_CONSTANTS 0x1000 +#define BRW_NEW_VBO 0x2000 +#define BRW_NEW_VS 0x4000 + +/* Raised for other internal events: + */ +#define BRW_NEW_URB_FENCE 0x10000 +#define BRW_NEW_PSP 0x20000 +#define BRW_NEW_CURBE_OFFSETS 0x40000 +#define BRW_NEW_REDUCED_PRIMITIVE 0x80000 +#define BRW_NEW_PRIMITIVE 0x100000 +#define BRW_NEW_SCENE 0x200000 +#define BRW_NEW_SF_LINKAGE 0x400000 + +extern int BRW_DEBUG; + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 +#define DEBUG_PIXEL 0x1000 +#define DEBUG_STATS 0x2000 +#define DEBUG_TILE 0x4000 +#define DEBUG_SINGLE_THREAD 0x8000 +#define DEBUG_WM 0x10000 +#define DEBUG_URB 0x20000 +#define DEBUG_VS 0x40000 +#define DEBUG_BATCH 0x80000 +#define DEBUG_BUFMGR 0x100000 +#define DEBUG_BLIT 0x200000 +#define DEBUG_REGION 0x400000 +#define DEBUG_MIPTREE 0x800000 + +#define DBG(...) do { \ + if (BRW_DEBUG & FILE_DEBUG_FLAG) \ + debug_printf(__VA_ARGS__); \ +} while(0) + +#define PRINT(...) do { \ + debug_printf(brw->pipe.winsys, __VA_ARGS__); \ +} while(0) + +struct brw_state_flags { + unsigned cache; + unsigned brw; +}; + + +struct brw_vertex_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + int id; +}; + + +struct brw_fragment_program { + struct pipe_shader_state program; + struct tgsi_shader_info info; + + boolean UsesDepth; /* XXX add this to tgsi_shader_info? */ + int id; +}; + + +struct pipe_setup_linkage { + struct { + unsigned vp_output:5; + unsigned interp_mode:4; + unsigned bf_vp_output:5; + } fp_input[PIPE_MAX_SHADER_INPUTS]; + + unsigned fp_input_count:5; + unsigned max_vp_output:5; +}; + + + +struct brw_texture { + struct pipe_texture base; + + /* Derived from the above: + */ + unsigned pitch; + unsigned depth_pitch; /* per-image on i945? */ + unsigned total_height; + + unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS]; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */ + + /* Includes image offset tables: + */ + unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct pipe_buffer *buffer; +}; + +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ +/* Data about a particular attempt to compile a program. Note that + * there can be many of these, each in a different GL state + * corresponding to a different brw_wm_prog_key struct, with different + * compiled programs: + */ + +struct brw_wm_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + + unsigned first_curbe_grf; + unsigned total_grf; + unsigned total_scratch; + + /* Internally generated constants for the CURBE. These are loaded + * ahead of the data from the constant buffer. + */ + const float internal_const[8]; + unsigned nr_internal_consts; + unsigned max_const; + + boolean error; +}; + +struct brw_sf_prog_data { + unsigned urb_read_length; + unsigned total_grf; + + /* Each vertex may have upto 12 attributes, 4 components each, + * except WPOS which requires only 2. (11*4 + 2) == 44 ==> 11 + * rows. + * + * Actually we use 4 for each, so call it 12 rows. + */ + unsigned urb_entry_size; +}; + +struct brw_clip_prog_data { + unsigned curb_read_length; /* user planes? */ + unsigned clip_mode; + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_gs_prog_data { + unsigned urb_read_length; + unsigned total_grf; +}; + +struct brw_vs_prog_data { + unsigned curb_read_length; + unsigned urb_read_length; + unsigned total_grf; + unsigned outputs_written; + + unsigned inputs_read; + + unsigned max_const; + + float imm_buf[PIPE_MAX_CONSTANT][4]; + unsigned num_imm; + unsigned num_consts; + + /* Used for calculating urb partitions: + */ + unsigned urb_entry_size; +}; + + +#define BRW_MAX_TEX_UNIT 8 +#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + 1 + +/* Create a fixed sized struct for caching binding tables: + */ +struct brw_surface_binding_table { + unsigned surf_ss_offset[BRW_WM_MAX_SURF]; +}; + + +struct brw_cache; + +struct brw_mem_pool { + struct pipe_buffer *buffer; + + unsigned size; + unsigned offset; /* offset of first free byte */ + + struct brw_context *brw; +}; + +struct brw_cache_item { + unsigned hash; + unsigned key_size; /* for variable-sized keys */ + const void *key; + + unsigned offset; /* offset within pool's buffer */ + unsigned data_size; + + struct brw_cache_item *next; +}; + + + +struct brw_cache { + unsigned id; + + const char *name; + + struct brw_context *brw; + struct brw_mem_pool *pool; + + struct brw_cache_item **items; + unsigned size, n_items; + + unsigned key_size; /* for fixed-size keys */ + unsigned aux_size; + + unsigned last_addr; /* offset of active item */ +}; + + + + +/* Considered adding a member to this struct to document which flags + * an update might raise so that ordering of the state atoms can be + * checked or derived at runtime. Dropped the idea in favor of having + * a debug mode where the state is monitored for flags which are + * raised that have already been tested against. + */ +struct brw_tracked_state { + struct brw_state_flags dirty; + void (*update)( struct brw_context *brw ); +}; + + +/* Flags for brw->state.cache. + */ +#define CACHE_NEW_CC_VP (1<<BRW_CC_VP) +#define CACHE_NEW_CC_UNIT (1<<BRW_CC_UNIT) +#define CACHE_NEW_WM_PROG (1<<BRW_WM_PROG) +#define CACHE_NEW_SAMPLER_DEFAULT_COLOR (1<<BRW_SAMPLER_DEFAULT_COLOR) +#define CACHE_NEW_SAMPLER (1<<BRW_SAMPLER) +#define CACHE_NEW_WM_UNIT (1<<BRW_WM_UNIT) +#define CACHE_NEW_SF_PROG (1<<BRW_SF_PROG) +#define CACHE_NEW_SF_VP (1<<BRW_SF_VP) +#define CACHE_NEW_SF_UNIT (1<<BRW_SF_UNIT) +#define CACHE_NEW_VS_UNIT (1<<BRW_VS_UNIT) +#define CACHE_NEW_VS_PROG (1<<BRW_VS_PROG) +#define CACHE_NEW_GS_UNIT (1<<BRW_GS_UNIT) +#define CACHE_NEW_GS_PROG (1<<BRW_GS_PROG) +#define CACHE_NEW_CLIP_VP (1<<BRW_CLIP_VP) +#define CACHE_NEW_CLIP_UNIT (1<<BRW_CLIP_UNIT) +#define CACHE_NEW_CLIP_PROG (1<<BRW_CLIP_PROG) +#define CACHE_NEW_SURFACE (1<<BRW_SS_SURFACE) +#define CACHE_NEW_SURF_BIND (1<<BRW_SS_SURF_BIND) + + + + +enum brw_mempool_id { + BRW_GS_POOL, + BRW_SS_POOL, + BRW_MAX_POOL +}; + + +struct brw_cached_batch_item { + struct header *header; + unsigned sz; + struct brw_cached_batch_item *next; +}; + + + +/* Protect against a future where PIPE_MAX_ATTRIBS > 32. Wouldn't life + * be easier if C allowed arrays of packed elements? + */ +#define ATTRIB_BIT_DWORDS ((PIPE_MAX_ATTRIBS+31)/32) + + + + +struct brw_vertex_info { + unsigned varying; /* varying:1[PIPE_MAX_ATTRIBS] */ + unsigned sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[PIPE_MAX_ATTRIBS] */ +}; + + + + + +struct brw_context +{ + struct pipe_context pipe; + struct brw_winsys *winsys; + + unsigned primitive; + unsigned reduced_primitive; + + boolean emit_state_always; + + struct { + struct brw_state_flags dirty; + } state; + + + struct { + const struct pipe_blend_state *Blend; + const struct pipe_depth_stencil_alpha_state *DepthStencil; + const struct pipe_poly_stipple *PolygonStipple; + const struct pipe_rasterizer_state *Raster; + const struct pipe_sampler_state *Samplers[PIPE_MAX_SAMPLERS]; + const struct brw_vertex_program *VertexProgram; + const struct brw_fragment_program *FragmentProgram; + + struct pipe_clip_state Clip; + struct pipe_blend_color BlendColor; + struct pipe_scissor_state Scissor; + struct pipe_viewport_state Viewport; + struct pipe_framebuffer_state FrameBuffer; + + const struct pipe_constant_buffer *Constants[2]; + const struct brw_texture *Texture[PIPE_MAX_SAMPLERS]; + } attribs; + + unsigned num_samplers; + unsigned num_textures; + + struct brw_mem_pool pool[BRW_MAX_POOL]; + struct brw_cache cache[BRW_MAX_CACHE]; + struct brw_cached_batch_item *cached_batch_items; + + struct { + + /* Arrays with buffer objects to copy non-bufferobj arrays into + * for upload: + */ + const struct pipe_vertex_buffer *vbo_array[PIPE_MAX_ATTRIBS]; + + struct brw_vertex_element_state inputs[PIPE_MAX_ATTRIBS]; + +#define BRW_NR_UPLOAD_BUFS 17 +#define BRW_UPLOAD_INIT_SIZE (128*1024) + + /* Summary of size and varying of active arrays, so we can check + * for changes to this state: + */ + struct brw_vertex_info info; + } vb; + + + unsigned hardware_dirty; + unsigned dirty; + unsigned pci_id; + /* BRW_NEW_URB_ALLOCATIONS: + */ + struct { + unsigned vsize; /* vertex size plus header in urb registers */ + unsigned csize; /* constant buffer size in urb registers */ + unsigned sfsize; /* setup data size in urb registers */ + + boolean constrained; + + unsigned nr_vs_entries; + unsigned nr_gs_entries; + unsigned nr_clip_entries; + unsigned nr_sf_entries; + unsigned nr_cs_entries; + +/* unsigned vs_size; */ +/* unsigned gs_size; */ +/* unsigned clip_size; */ +/* unsigned sf_size; */ +/* unsigned cs_size; */ + + unsigned vs_start; + unsigned gs_start; + unsigned clip_start; + unsigned sf_start; + unsigned cs_start; + } urb; + + + /* BRW_NEW_CURBE_OFFSETS: + */ + struct { + unsigned wm_start; + unsigned wm_size; + unsigned clip_start; + unsigned clip_size; + unsigned vs_start; + unsigned vs_size; + unsigned total_size; + + unsigned gs_offset; + + float *last_buf; + unsigned last_bufsz; + } curbe; + + struct { + struct brw_vs_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } vs; + + struct { + struct brw_gs_prog_data *prog_data; + + boolean prog_active; + unsigned prog_gs_offset; + unsigned state_gs_offset; + } gs; + + struct { + struct brw_clip_prog_data *prog_data; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } clip; + + + struct { + struct brw_sf_prog_data *prog_data; + + struct pipe_setup_linkage linkage; + + unsigned prog_gs_offset; + unsigned vp_gs_offset; + unsigned state_gs_offset; + } sf; + + struct { + struct brw_wm_prog_data *prog_data; + +// struct brw_wm_compiler *compile_data; + + + /** + * Array of sampler state uploaded at sampler_gs_offset of BRW_SAMPLER + * cache + */ + struct brw_sampler_state sampler[BRW_MAX_TEX_UNIT]; + + unsigned render_surf; + unsigned nr_surfaces; + + unsigned max_threads; + struct pipe_buffer *scratch_buffer; + unsigned scratch_buffer_size; + + unsigned sampler_count; + unsigned sampler_gs_offset; + + struct brw_surface_binding_table bind; + unsigned bind_ss_offset; + + unsigned prog_gs_offset; + unsigned state_gs_offset; + } wm; + + + struct { + unsigned vp_gs_offset; + unsigned state_gs_offset; + } cc; + + + /* Used to give every program string a unique id + */ + unsigned program_id; +}; + + +#define BRW_PACKCOLOR8888(r,g,b,a) ((r<<24) | (g<<16) | (b<<8) | a) + + +/*====================================================================== + * brw_vtbl.c + */ +void brw_do_flush( struct brw_context *brw, + unsigned flags ); + + +/*====================================================================== + * brw_state.c + */ +void brw_validate_state(struct brw_context *brw); +void brw_init_state(struct brw_context *brw); +void brw_destroy_state(struct brw_context *brw); + + +/*====================================================================== + * brw_tex.c + */ +void brwUpdateTextureState( struct brw_context *brw ); + + +/* brw_urb.c + */ +void brw_upload_urb_fence(struct brw_context *brw); + +void brw_upload_constant_buffer_state(struct brw_context *brw); + +void brw_init_surface_functions(struct brw_context *brw); +void brw_init_state_functions(struct brw_context *brw); +void brw_init_flush_functions(struct brw_context *brw); +void brw_init_string_functions(struct brw_context *brw); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static inline struct brw_context * +brw_context( struct pipe_context *ctx ) +{ + return (struct brw_context *)ctx; +} + +#endif + diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c index ac243b7e4f9..caeeba46300 100644 --- a/src/gallium/drivers/i965simple/brw_state.c +++ b/src/gallium/drivers/i965simple/brw_state.c @@ -1,469 +1,469 @@ -/**************************************************************************
- *
- * 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: Zack Rusin <[email protected]>
- * Keith Whitwell <[email protected]>
- */
-
-
-#include "pipe/p_winsys.h"
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/util/tgsi_dump.h"
-#include "tgsi/util/tgsi_parse.h"
-
-#include "brw_context.h"
-#include "brw_defines.h"
-#include "brw_state.h"
-#include "brw_draw.h"
-
-
-#define DUP( TYPE, VAL ) \
-do { \
- struct TYPE *x = malloc(sizeof(*x)); \
- memcpy(x, VAL, sizeof(*x) ); \
- return x; \
-} while (0)
-
-/************************************************************************
- * Blend
- */
-static void *
-brw_create_blend_state(struct pipe_context *pipe,
- const struct pipe_blend_state *blend)
-{
- DUP( pipe_blend_state, blend );
-}
-
-static void brw_bind_blend_state(struct pipe_context *pipe,
- void *blend)
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.Blend = (struct pipe_blend_state*)blend;
- brw->state.dirty.brw |= BRW_NEW_BLEND;
-}
-
-
-static void brw_delete_blend_state(struct pipe_context *pipe, void *blend)
-{
- free(blend);
-}
-
-static void brw_set_blend_color( struct pipe_context *pipe,
- const struct pipe_blend_color *blend_color )
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.BlendColor = *blend_color;
-
- brw->state.dirty.brw |= BRW_NEW_BLEND;
-}
-
-/************************************************************************
- * Sampler
- */
-
-static void *
-brw_create_sampler_state(struct pipe_context *pipe,
- const struct pipe_sampler_state *sampler)
-{
- DUP( pipe_sampler_state, sampler );
-}
-
-static void brw_bind_sampler_states(struct pipe_context *pipe,
- unsigned num, void **sampler)
-{
- struct brw_context *brw = brw_context(pipe);
-
- assert(num <= PIPE_MAX_SAMPLERS);
-
- /* Check for no-op */
- if (num == brw->num_samplers &&
- !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *)))
- return;
-
- memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *));
- memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) *
- sizeof(void *));
-
- brw->num_samplers = num;
-
- brw->state.dirty.brw |= BRW_NEW_SAMPLER;
-}
-
-static void brw_delete_sampler_state(struct pipe_context *pipe,
- void *sampler)
-{
- free(sampler);
-}
-
-
-/************************************************************************
- * Depth stencil
- */
-
-static void *
-brw_create_depth_stencil_state(struct pipe_context *pipe,
- const struct pipe_depth_stencil_alpha_state *depth_stencil)
-{
- DUP( pipe_depth_stencil_alpha_state, depth_stencil );
-}
-
-static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
- void *depth_stencil)
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
-
- brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;
-}
-
-static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
- void *depth_stencil)
-{
- free(depth_stencil);
-}
-
-/************************************************************************
- * Scissor
- */
-static void brw_set_scissor_state( struct pipe_context *pipe,
- const struct pipe_scissor_state *scissor )
-{
- struct brw_context *brw = brw_context(pipe);
-
- memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );
- brw->state.dirty.brw |= BRW_NEW_SCISSOR;
-}
-
-
-/************************************************************************
- * Stipple
- */
-
-static void brw_set_polygon_stipple( struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple )
-{
-}
-
-
-/************************************************************************
- * Fragment shader
- */
-
-static void * brw_create_fs_state(struct pipe_context *pipe,
- const struct pipe_shader_state *shader)
-{
- struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
-
- brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens);
- brw_fp->id = brw_context(pipe)->program_id++;
-
- tgsi_scan_shader(shader->tokens, &brw_fp->info);
-
-#if 0
- brw_shader_info(shader->tokens,
- &brw_fp->info2);
-#endif
-
- tgsi_dump(shader->tokens, 0);
-
-
- return (void *)brw_fp;
-}
-
-static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;
- brw->state.dirty.brw |= BRW_NEW_FS;
-}
-
-static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
-{
- struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader;
-
- FREE((void *) brw_fp->program.tokens);
- FREE(brw_fp);
-}
-
-
-/************************************************************************
- * Vertex shader and other TNL state
- */
-
-static void *brw_create_vs_state(struct pipe_context *pipe,
- const struct pipe_shader_state *shader)
-{
- struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
-
- brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens);
- brw_vp->id = brw_context(pipe)->program_id++;
-
- tgsi_scan_shader(shader->tokens, &brw_vp->info);
-
-#if 0
- brw_shader_info(shader->tokens,
- &brw_vp->info2);
-#endif
- tgsi_dump(shader->tokens, 0);
-
- return (void *)brw_vp;
-}
-
-static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;
- brw->state.dirty.brw |= BRW_NEW_VS;
-
- debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");
-}
-
-static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
-{
- struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader;
-
- FREE((void *) brw_vp->program.tokens);
- FREE(brw_vp);
-}
-
-
-static void brw_set_clip_state( struct pipe_context *pipe,
- const struct pipe_clip_state *clip )
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.Clip = *clip;
-}
-
-
-static void brw_set_viewport_state( struct pipe_context *pipe,
- const struct pipe_viewport_state *viewport )
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.Viewport = *viewport; /* struct copy */
- brw->state.dirty.brw |= BRW_NEW_VIEWPORT;
-
- /* pass the viewport info to the draw module */
- //draw_set_viewport_state(brw->draw, viewport);
-}
-
-
-static void brw_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_buffer *buffers)
-{
- struct brw_context *brw = brw_context(pipe);
- memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0]));
-}
-
-static void brw_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
-{
- /* flush ? */
- struct brw_context *brw = brw_context(pipe);
- uint i;
-
- assert(count <= PIPE_MAX_ATTRIBS);
-
- for (i = 0; i < count; i++) {
- struct brw_vertex_element_state el;
- memset(&el, 0, sizeof(el));
-
- el.ve0.src_offset = elements[i].src_offset;
- el.ve0.src_format = brw_translate_surface_format(elements[i].src_format);
- el.ve0.valid = 1;
- el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index;
-
- el.ve1.dst_offset = i * 4;
-
- el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
- el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
- el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
- el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
-
- switch (elements[i].nr_components) {
- case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
- case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
- case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
- break;
- }
-
- brw->vb.inputs[i] = el;
- }
-}
-
-
-
-/************************************************************************
- * Constant buffers
- */
-
-static void brw_set_constant_buffer(struct pipe_context *pipe,
- uint shader, uint index,
- const struct pipe_constant_buffer *buf)
-{
- struct brw_context *brw = brw_context(pipe);
-
- assert(buf == 0 || index == 0);
-
- brw->attribs.Constants[shader] = buf;
- brw->state.dirty.brw |= BRW_NEW_CONSTANTS;
-}
-
-
-/************************************************************************
- * Texture surfaces
- */
-
-
-static void brw_set_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
-{
- struct brw_context *brw = brw_context(pipe);
- uint i;
-
- assert(num <= PIPE_MAX_SAMPLERS);
-
- /* Check for no-op */
- if (num == brw->num_textures &&
- !memcmp(brw->attribs.Texture, texture, num *
- sizeof(struct pipe_texture *)))
- return;
-
- for (i = 0; i < num; i++)
- pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
- texture[i]);
-
- for (i = num; i < brw->num_textures; i++)
- pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
- NULL);
-
- brw->num_textures = num;
-
- brw->state.dirty.brw |= BRW_NEW_TEXTURE;
-}
-
-
-/************************************************************************
- * Render targets, etc
- */
-
-static void brw_set_framebuffer_state(struct pipe_context *pipe,
- const struct pipe_framebuffer_state *fb)
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.FrameBuffer = *fb; /* struct copy */
-
- brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;
-}
-
-
-
-/************************************************************************
- * Rasterizer state
- */
-
-static void *
-brw_create_rasterizer_state(struct pipe_context *pipe,
- const struct pipe_rasterizer_state *rasterizer)
-{
- DUP(pipe_rasterizer_state, rasterizer);
-}
-
-static void brw_bind_rasterizer_state( struct pipe_context *pipe,
- void *setup )
-{
- struct brw_context *brw = brw_context(pipe);
-
- brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;
-
- /* Also pass-through to draw module:
- */
- //draw_set_rasterizer_state(brw->draw, setup);
-
- brw->state.dirty.brw |= BRW_NEW_RASTERIZER;
-}
-
-static void brw_delete_rasterizer_state(struct pipe_context *pipe,
- void *setup)
-{
- free(setup);
-}
-
-
-
-void
-brw_init_state_functions( struct brw_context *brw )
-{
- brw->pipe.create_blend_state = brw_create_blend_state;
- brw->pipe.bind_blend_state = brw_bind_blend_state;
- brw->pipe.delete_blend_state = brw_delete_blend_state;
-
- brw->pipe.create_sampler_state = brw_create_sampler_state;
- brw->pipe.bind_sampler_states = brw_bind_sampler_states;
- brw->pipe.delete_sampler_state = brw_delete_sampler_state;
-
- brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
- brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;
- brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;
-
- brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;
- brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;
- brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;
- brw->pipe.create_fs_state = brw_create_fs_state;
- brw->pipe.bind_fs_state = brw_bind_fs_state;
- brw->pipe.delete_fs_state = brw_delete_fs_state;
- brw->pipe.create_vs_state = brw_create_vs_state;
- brw->pipe.bind_vs_state = brw_bind_vs_state;
- brw->pipe.delete_vs_state = brw_delete_vs_state;
-
- brw->pipe.set_blend_color = brw_set_blend_color;
- brw->pipe.set_clip_state = brw_set_clip_state;
- brw->pipe.set_constant_buffer = brw_set_constant_buffer;
- brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;
-
-// brw->pipe.set_feedback_state = brw_set_feedback_state;
-// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;
-
- brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;
- brw->pipe.set_scissor_state = brw_set_scissor_state;
- brw->pipe.set_sampler_textures = brw_set_sampler_textures;
- brw->pipe.set_viewport_state = brw_set_viewport_state;
- brw->pipe.set_vertex_buffers = brw_set_vertex_buffers;
- brw->pipe.set_vertex_elements = brw_set_vertex_elements;
-}
+/************************************************************************** + * + * 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: Zack Rusin <[email protected]> + * Keith Whitwell <[email protected]> + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_dump.h" +#include "tgsi/util/tgsi_parse.h" + +#include "brw_context.h" +#include "brw_defines.h" +#include "brw_state.h" +#include "brw_draw.h" + + +#define DUP( TYPE, VAL ) \ +do { \ + struct TYPE *x = malloc(sizeof(*x)); \ + memcpy(x, VAL, sizeof(*x) ); \ + return x; \ +} while (0) + +/************************************************************************ + * Blend + */ +static void * +brw_create_blend_state(struct pipe_context *pipe, + const struct pipe_blend_state *blend) +{ + DUP( pipe_blend_state, blend ); +} + +static void brw_bind_blend_state(struct pipe_context *pipe, + void *blend) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Blend = (struct pipe_blend_state*)blend; + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + + +static void brw_delete_blend_state(struct pipe_context *pipe, void *blend) +{ + free(blend); +} + +static void brw_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.BlendColor = *blend_color; + + brw->state.dirty.brw |= BRW_NEW_BLEND; +} + +/************************************************************************ + * Sampler + */ + +static void * +brw_create_sampler_state(struct pipe_context *pipe, + const struct pipe_sampler_state *sampler) +{ + DUP( pipe_sampler_state, sampler ); +} + +static void brw_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct brw_context *brw = brw_context(pipe); + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_samplers && + !memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *))) + return; + + memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *)); + memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) * + sizeof(void *)); + + brw->num_samplers = num; + + brw->state.dirty.brw |= BRW_NEW_SAMPLER; +} + +static void brw_delete_sampler_state(struct pipe_context *pipe, + void *sampler) +{ + free(sampler); +} + + +/************************************************************************ + * Depth stencil + */ + +static void * +brw_create_depth_stencil_state(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *depth_stencil) +{ + DUP( pipe_depth_stencil_alpha_state, depth_stencil ); +} + +static void brw_bind_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil; + + brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL; +} + +static void brw_delete_depth_stencil_state(struct pipe_context *pipe, + void *depth_stencil) +{ + free(depth_stencil); +} + +/************************************************************************ + * Scissor + */ +static void brw_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct brw_context *brw = brw_context(pipe); + + memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) ); + brw->state.dirty.brw |= BRW_NEW_SCISSOR; +} + + +/************************************************************************ + * Stipple + */ + +static void brw_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ +} + + +/************************************************************************ + * Fragment shader + */ + +static void * brw_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program); + + brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens); + brw_fp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_fp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_fp->info2); +#endif + + tgsi_dump(shader->tokens, 0); + + + return (void *)brw_fp; +} + +static void brw_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader; + brw->state.dirty.brw |= BRW_NEW_FS; +} + +static void brw_delete_fs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader; + + FREE((void *) brw_fp->program.tokens); + FREE(brw_fp); +} + + +/************************************************************************ + * Vertex shader and other TNL state + */ + +static void *brw_create_vs_state(struct pipe_context *pipe, + const struct pipe_shader_state *shader) +{ + struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program); + + brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens); + brw_vp->id = brw_context(pipe)->program_id++; + + tgsi_scan_shader(shader->tokens, &brw_vp->info); + +#if 0 + brw_shader_info(shader->tokens, + &brw_vp->info2); +#endif + tgsi_dump(shader->tokens, 0); + + return (void *)brw_vp; +} + +static void brw_bind_vs_state(struct pipe_context *pipe, void *vs) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.VertexProgram = (struct brw_vertex_program *)vs; + brw->state.dirty.brw |= BRW_NEW_VS; + + debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n"); +} + +static void brw_delete_vs_state(struct pipe_context *pipe, void *shader) +{ + struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader; + + FREE((void *) brw_vp->program.tokens); + FREE(brw_vp); +} + + +static void brw_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Clip = *clip; +} + + +static void brw_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Viewport = *viewport; /* struct copy */ + brw->state.dirty.brw |= BRW_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + //draw_set_viewport_state(brw->draw, viewport); +} + + +static void brw_set_vertex_buffers(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct brw_context *brw = brw_context(pipe); + memcpy(brw->vb.vbo_array, buffers, count * sizeof(buffers[0])); +} + +static void brw_set_vertex_elements(struct pipe_context *pipe, + unsigned count, + const struct pipe_vertex_element *elements) +{ + /* flush ? */ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(count <= PIPE_MAX_ATTRIBS); + + for (i = 0; i < count; i++) { + struct brw_vertex_element_state el; + memset(&el, 0, sizeof(el)); + + el.ve0.src_offset = elements[i].src_offset; + el.ve0.src_format = brw_translate_surface_format(elements[i].src_format); + el.ve0.valid = 1; + el.ve0.vertex_buffer_index = elements[i].vertex_buffer_index; + + el.ve1.dst_offset = i * 4; + + el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC; + el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC; + + switch (elements[i].nr_components) { + case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0; + case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0; + case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT; + break; + } + + brw->vb.inputs[i] = el; + } +} + + + +/************************************************************************ + * Constant buffers + */ + +static void brw_set_constant_buffer(struct pipe_context *pipe, + uint shader, uint index, + const struct pipe_constant_buffer *buf) +{ + struct brw_context *brw = brw_context(pipe); + + assert(buf == 0 || index == 0); + + brw->attribs.Constants[shader] = buf; + brw->state.dirty.brw |= BRW_NEW_CONSTANTS; +} + + +/************************************************************************ + * Texture surfaces + */ + + +static void brw_set_sampler_textures(struct pipe_context *pipe, + unsigned num, + struct pipe_texture **texture) +{ + struct brw_context *brw = brw_context(pipe); + uint i; + + assert(num <= PIPE_MAX_SAMPLERS); + + /* Check for no-op */ + if (num == brw->num_textures && + !memcmp(brw->attribs.Texture, texture, num * + sizeof(struct pipe_texture *))) + return; + + for (i = 0; i < num; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + texture[i]); + + for (i = num; i < brw->num_textures; i++) + pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i], + NULL); + + brw->num_textures = num; + + brw->state.dirty.brw |= BRW_NEW_TEXTURE; +} + + +/************************************************************************ + * Render targets, etc + */ + +static void brw_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.FrameBuffer = *fb; /* struct copy */ + + brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER; +} + + + +/************************************************************************ + * Rasterizer state + */ + +static void * +brw_create_rasterizer_state(struct pipe_context *pipe, + const struct pipe_rasterizer_state *rasterizer) +{ + DUP(pipe_rasterizer_state, rasterizer); +} + +static void brw_bind_rasterizer_state( struct pipe_context *pipe, + void *setup ) +{ + struct brw_context *brw = brw_context(pipe); + + brw->attribs.Raster = (struct pipe_rasterizer_state *)setup; + + /* Also pass-through to draw module: + */ + //draw_set_rasterizer_state(brw->draw, setup); + + brw->state.dirty.brw |= BRW_NEW_RASTERIZER; +} + +static void brw_delete_rasterizer_state(struct pipe_context *pipe, + void *setup) +{ + free(setup); +} + + + +void +brw_init_state_functions( struct brw_context *brw ) +{ + brw->pipe.create_blend_state = brw_create_blend_state; + brw->pipe.bind_blend_state = brw_bind_blend_state; + brw->pipe.delete_blend_state = brw_delete_blend_state; + + brw->pipe.create_sampler_state = brw_create_sampler_state; + brw->pipe.bind_sampler_states = brw_bind_sampler_states; + brw->pipe.delete_sampler_state = brw_delete_sampler_state; + + brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; + brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; + brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; + + brw->pipe.create_rasterizer_state = brw_create_rasterizer_state; + brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state; + brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state; + brw->pipe.create_fs_state = brw_create_fs_state; + brw->pipe.bind_fs_state = brw_bind_fs_state; + brw->pipe.delete_fs_state = brw_delete_fs_state; + brw->pipe.create_vs_state = brw_create_vs_state; + brw->pipe.bind_vs_state = brw_bind_vs_state; + brw->pipe.delete_vs_state = brw_delete_vs_state; + + brw->pipe.set_blend_color = brw_set_blend_color; + brw->pipe.set_clip_state = brw_set_clip_state; + brw->pipe.set_constant_buffer = brw_set_constant_buffer; + brw->pipe.set_framebuffer_state = brw_set_framebuffer_state; + +// brw->pipe.set_feedback_state = brw_set_feedback_state; +// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer; + + brw->pipe.set_polygon_stipple = brw_set_polygon_stipple; + brw->pipe.set_scissor_state = brw_set_scissor_state; + brw->pipe.set_sampler_textures = brw_set_sampler_textures; + brw->pipe.set_viewport_state = brw_set_viewport_state; + brw->pipe.set_vertex_buffers = brw_set_vertex_buffers; + brw->pipe.set_vertex_elements = brw_set_vertex_elements; +} diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c index c99a91dcf76..3e3736b2806 100644 --- a/src/gallium/drivers/i965simple/brw_surface.c +++ b/src/gallium/drivers/i965simple/brw_surface.c @@ -35,27 +35,6 @@ #include "util/p_tile.h" -/* 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 -brw_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) -{ - pipe_copy_rect(pipe_surface_map(dst) + dst->offset, - dst->cpp, dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - pipe_surface_unmap(dst); -} - /* Assumes all values are within bounds -- no checking at this level - * do it higher up if required. @@ -72,17 +51,25 @@ brw_surface_copy(struct pipe_context *pipe, assert(dst->cpp == src->cpp); if (0) { - pipe_copy_rect(pipe_surface_map(dst) + dst->offset, + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, - dstx, dsty, - width, height, - pipe_surface_map(src) + src->offset, - do_flip ? -src->pitch : src->pitch, + dstx, dsty, + width, height, + src_map, + do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } else { brw_copy_blit(brw_context(pipe), @@ -113,7 +100,10 @@ brw_surface_fill(struct pipe_context *pipe, { if (0) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + switch (dst->cpp) { case 1: { @@ -147,7 +137,7 @@ brw_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } else { brw_fill_blit(brw_context(pipe), @@ -164,7 +154,6 @@ brw_surface_fill(struct pipe_context *pipe, void brw_init_surface_functions(struct brw_context *brw) { - (void) brw_surface_data; /* silence warning */ brw->pipe.surface_copy = brw_surface_copy; brw->pipe.surface_fill = brw_surface_fill; } diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c index b580f98204c..78ae0b1223e 100644 --- a/src/gallium/drivers/i965simple/brw_tex_layout.c +++ b/src/gallium/drivers/i965simple/brw_tex_layout.c @@ -357,14 +357,6 @@ brw_texture_release_screen(struct pipe_screen *screen, } -static void -brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture, - uint face, uint levelsMask) -{ - /* no-op? */ -} - - static struct pipe_surface * brw_get_tex_surface_screen(struct pipe_screen *screen, struct pipe_texture *pt, @@ -407,7 +399,7 @@ brw_get_tex_surface_screen(struct pipe_screen *screen, void brw_init_texture_functions(struct brw_context *brw) { - brw->pipe.texture_update = brw_texture_update; +// brw->pipe.texture_update = brw_texture_update; } diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index fe9cd8375e3..2af0db37143 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -192,11 +192,11 @@ softpipe_create( struct pipe_screen *screen, * Must be before quad stage setup! */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) - softpipe->cbuf_cache[i] = sp_create_tile_cache(); - softpipe->zsbuf_cache = sp_create_tile_cache(); + softpipe->cbuf_cache[i] = sp_create_tile_cache( screen ); + softpipe->zsbuf_cache = sp_create_tile_cache( screen ); for (i = 0; i < PIPE_MAX_SAMPLERS; i++) - softpipe->tex_cache[i] = sp_create_tile_cache(); + softpipe->tex_cache[i] = sp_create_tile_cache( screen ); /* setup quad rendering stages */ diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 0625b69099b..e03994b63b7 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -50,25 +50,28 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); - /* - flush the quad pipeline - * - flush the texture cache - * - flush the render cache - */ + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + for (i = 0; i < softpipe->num_textures; i++) { + sp_flush_tile_cache(softpipe, softpipe->tex_cache[i]); + } + } - for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) - if (softpipe->cbuf_cache[i]) - sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); + if (flags & PIPE_FLUSH_RENDER_CACHE) { + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) + if (softpipe->cbuf_cache[i]) + sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]); - if (softpipe->zsbuf_cache) - sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); + if (softpipe->zsbuf_cache) + sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache); - /* Need this call for hardware buffers before swapbuffers. - * - * there should probably be another/different flush-type function - * that's called before swapbuffers because we don't always want - * to unmap surfaces when flushing. - */ - softpipe_unmap_surfaces(softpipe); + /* Need this call for hardware buffers before swapbuffers. + * + * there should probably be another/different flush-type function + * that's called before swapbuffers because we don't always want + * to unmap surfaces when flushing. + */ + softpipe_unmap_surfaces(softpipe); + } if (fence) *fence = NULL; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 7dacb1c4613..e9926bf41f9 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -33,6 +33,7 @@ #include "sp_texture.h" #include "sp_winsys.h" +#include "sp_screen.h" static const char * @@ -137,6 +138,7 @@ softpipe_destroy_screen( struct pipe_screen *screen ) } + /** * Create a new pipe_screen object * Note: we're not presently subclassing pipe_screen (no softpipe_screen). @@ -144,22 +146,22 @@ softpipe_destroy_screen( struct pipe_screen *screen ) struct pipe_screen * softpipe_create_screen(struct pipe_winsys *winsys) { - struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen); + struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen); if (!screen) return NULL; - screen->winsys = winsys; + screen->base.winsys = winsys; - screen->destroy = softpipe_destroy_screen; + screen->base.destroy = softpipe_destroy_screen; - screen->get_name = softpipe_get_name; - screen->get_vendor = softpipe_get_vendor; - screen->get_param = softpipe_get_param; - screen->get_paramf = softpipe_get_paramf; - screen->is_format_supported = softpipe_is_format_supported; + screen->base.get_name = softpipe_get_name; + screen->base.get_vendor = softpipe_get_vendor; + screen->base.get_param = softpipe_get_param; + screen->base.get_paramf = softpipe_get_paramf; + screen->base.is_format_supported = softpipe_is_format_supported; - softpipe_init_screen_texture_funcs(screen); + softpipe_init_screen_texture_funcs(&screen->base); - return screen; + return &screen->base; } diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h new file mode 100644 index 00000000000..3d4bfd3e840 --- /dev/null +++ b/src/gallium/drivers/softpipe/sp_screen.h @@ -0,0 +1,58 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Authors: Keith Whitwell <[email protected]> + */ + +#ifndef SP_SCREEN_H +#define SP_SCREEN_H + +#include "pipe/p_screen.h" +#include "pipe/p_defines.h" + + + +struct softpipe_screen { + struct pipe_screen base; + + /* Increments whenever textures are modified. Contexts can track + * this. + */ + unsigned timestamp; +}; + + + + +static INLINE struct softpipe_screen * +softpipe_screen( struct pipe_screen *pipe ) +{ + return (struct softpipe_screen *)pipe; +} + + +#endif /* SP_SCREEN_H */ diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 653449c4f18..29a1e92416e 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -46,19 +46,28 @@ sp_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); + + const void *src_map = pipe->screen->surface_map( pipe->screen, + src, + PIPE_BUFFER_USAGE_CPU_READ ); + assert( dst->cpp == src->cpp ); + assert(src_map && dst_map); - pipe_copy_rect(pipe_surface_map(dst), + pipe_copy_rect(dst_map, dst->cpp, dst->pitch, dstx, dsty, width, height, - pipe_surface_map(src), + src_map, do_flip ? -(int) src->pitch : src->pitch, srcx, do_flip ? 1 - srcy - height : srcy); - pipe_surface_unmap(src); - pipe_surface_unmap(dst); + pipe->screen->surface_unmap(pipe->screen, src); + pipe->screen->surface_unmap(pipe->screen, dst); } @@ -83,7 +92,9 @@ sp_surface_fill(struct pipe_context *pipe, unsigned width, unsigned height, unsigned value) { unsigned i, j; - void *dst_map = pipe_surface_map(dst); + void *dst_map = pipe->screen->surface_map( pipe->screen, + dst, + PIPE_BUFFER_USAGE_CPU_WRITE ); assert(dst->pitch > 0); assert(width <= dst->pitch); @@ -147,7 +158,7 @@ sp_surface_fill(struct pipe_context *pipe, break; } - pipe_surface_unmap( dst ); + pipe->screen->surface_unmap(pipe->screen, dst); } diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 256586ec886..1d7a1fffe4d 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -40,6 +40,7 @@ #include "sp_state.h" #include "sp_texture.h" #include "sp_tile_cache.h" +#include "sp_screen.h" /* Simple, maximally packed layout. @@ -51,40 +52,88 @@ static unsigned minify( unsigned d ) } -static void -softpipe_texture_layout(struct softpipe_texture * spt) +/* Conventional allocation path for non-display textures: + */ +static boolean +softpipe_texture_layout(struct pipe_screen *screen, + struct softpipe_texture * spt) { + struct pipe_winsys *ws = screen->winsys; 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; + unsigned buffer_size = 0; for (level = 0; level <= pt->last_level; level++) { pt->width[level] = width; pt->height[level] = height; pt->depth[level] = depth; + spt->pitch[level] = width; - spt->level_offset[level] = spt->buffer_size; + spt->level_offset[level] = buffer_size; - spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) * - ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) * - width * pt->cpp; + 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); } + + spt->buffer = ws->buffer_create(ws, 32, + PIPE_BUFFER_USAGE_PIXEL, + buffer_size); + + return spt->buffer != NULL; +} + + + +/* Hack it up to use the old winsys->surface_alloc_storage() + * method for now: + */ +static boolean +softpipe_displaytarget_layout(struct pipe_screen *screen, + struct softpipe_texture * spt) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_surface surf; + unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + + memset(&surf, 0, sizeof(surf)); + + ws->surface_alloc_storage( ws, + &surf, + spt->base.width[0], + spt->base.height[0], + spt->base.format, + flags, + spt->base.tex_usage); + + /* Now extract the goodies: + */ + spt->buffer = surf.buffer; + spt->pitch[0] = surf.pitch; + + return spt->buffer != NULL; } + + + static struct pipe_texture * softpipe_texture_create(struct pipe_screen *screen, const struct pipe_texture *templat) { - struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture); if (!spt) return NULL; @@ -93,19 +142,21 @@ softpipe_texture_create(struct pipe_screen *screen, spt->base.refcount = 1; spt->base.screen = screen; - softpipe_texture_layout(spt); - - spt->buffer = ws->buffer_create(ws, 32, - PIPE_BUFFER_USAGE_PIXEL, - spt->buffer_size); - if (!spt->buffer) { - FREE(spt); - return NULL; + if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) { + if (!softpipe_displaytarget_layout(screen, spt)) + goto fail; } - + else { + if (!softpipe_texture_layout(screen, spt)) + goto fail; + } + assert(spt->base.refcount == 1); - return &spt->base; + + fail: + FREE(spt); + return NULL; } @@ -116,19 +167,10 @@ softpipe_texture_release(struct pipe_screen *screen, if (!*pt) return; - /* - DBG("%s %p refcount will be %d\n", - __FUNCTION__, (void *) *pt, (*pt)->refcount - 1); - */ if (--(*pt)->refcount <= 0) { struct softpipe_texture *spt = softpipe_texture(*pt); - /* - DBG("%s deleting %p\n", __FUNCTION__, (void *) spt); - */ - pipe_buffer_reference(screen->winsys, &spt->buffer, NULL); - FREE(spt); } *pt = NULL; @@ -138,7 +180,8 @@ softpipe_texture_release(struct pipe_screen *screen, static struct pipe_surface * softpipe_get_tex_surface(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) + unsigned face, unsigned level, unsigned zslice, + unsigned usage) { struct pipe_winsys *ws = screen->winsys; struct softpipe_texture *spt = softpipe_texture(pt); @@ -157,6 +200,24 @@ softpipe_get_tex_surface(struct pipe_screen *screen, ps->height = pt->height[level]; ps->pitch = ps->width; ps->offset = spt->level_offset[level]; + ps->usage = usage; + + /* Because we are softpipe, anything that the state tracker + * thought was going to be done with the GPU will actually get + * done with the CPU. Let's adjust the flags to take that into + * account. + */ + if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) + ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE; + + if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ) + ps->usage |= PIPE_BUFFER_USAGE_CPU_READ; + + + pipe_texture_reference(&ps->texture, pt); + ps->face = face; + ps->level = level; + ps->zslice = zslice; if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * @@ -172,25 +233,64 @@ softpipe_get_tex_surface(struct pipe_screen *screen, } -static void -softpipe_texture_update(struct pipe_context *pipe, - struct pipe_texture *texture, - uint face, uint levelsMask) +static void +softpipe_tex_surface_release(struct pipe_screen *screen, + struct pipe_surface **s) { - struct softpipe_context *softpipe = softpipe_context(pipe); - uint unit; - for (unit = 0; unit < softpipe->num_textures; unit++) { - if (softpipe->texture[unit] == texture) { - sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]); - } + /* Effectively do the texture_update work here - if texture images + * needed post-processing to put them into hardware layout, this is + * where it would happen. For softpipe, nothing to do. + */ + assert ((*s)->texture); + pipe_texture_reference(&(*s)->texture, NULL); + + screen->winsys->surface_release(screen->winsys, s); +} + + +static void * +softpipe_surface_map( struct pipe_screen *screen, + struct pipe_surface *surface, + unsigned flags ) +{ + ubyte *map; + + if (flags & ~surface->usage) { + assert(0); + return NULL; + } + + map = screen->winsys->buffer_map( screen->winsys, surface->buffer, flags ); + if (map == NULL) + return NULL; + + /* May want to different things here depending on read/write nature + * of the map: + */ + if (surface->texture && + (flags & PIPE_BUFFER_USAGE_CPU_WRITE)) + { + /* Do something to notify sharing contexts of a texture change. + * In softpipe, that would mean flushing the texture cache. + */ + softpipe_screen(screen)->timestamp++; } + + return map + surface->offset; +} + + +static void +softpipe_surface_unmap(struct pipe_screen *screen, + struct pipe_surface *surface) +{ + screen->winsys->buffer_unmap( screen->winsys, surface->buffer ); } void -softpipe_init_texture_funcs( struct softpipe_context *softpipe ) +softpipe_init_texture_funcs(struct softpipe_context *sp) { - softpipe->pipe.texture_update = softpipe_texture_update; } @@ -199,5 +299,10 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen) { screen->texture_create = softpipe_texture_create; screen->texture_release = softpipe_texture_release; + screen->get_tex_surface = softpipe_get_tex_surface; + screen->tex_surface_release = softpipe_tex_surface_release; + + screen->surface_map = softpipe_surface_map; + screen->surface_unmap = softpipe_surface_unmap; } diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h index a7322144e6f..779a9d8fc97 100644 --- a/src/gallium/drivers/softpipe/sp_texture.h +++ b/src/gallium/drivers/softpipe/sp_texture.h @@ -42,11 +42,11 @@ struct softpipe_texture struct pipe_texture base; unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; /* The data is held here: */ struct pipe_buffer *buffer; - unsigned long buffer_size; }; @@ -61,7 +61,6 @@ softpipe_texture(struct pipe_texture *pt) extern void softpipe_init_texture_funcs( struct softpipe_context *softpipe ); - extern void softpipe_init_screen_texture_funcs(struct pipe_screen *screen); diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 1117c0ad4c7..28c29da87c9 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -49,6 +49,7 @@ struct softpipe_tile_cache { + struct pipe_screen *screen; struct pipe_surface *surface; /**< the surface we're caching */ void *surface_map; struct pipe_texture *texture; /**< if caching a texture */ @@ -109,13 +110,14 @@ clear_clear_flag(uint *bitvec, int x, int y) struct softpipe_tile_cache * -sp_create_tile_cache(void) +sp_create_tile_cache( struct pipe_screen *screen ) { struct softpipe_tile_cache *tc; uint pos; tc = CALLOC_STRUCT( softpipe_tile_cache ); if (tc) { + tc->screen = screen; for (pos = 0; pos < NUM_ENTRIES; pos++) { tc->entries[pos].x = tc->entries[pos].y = -1; @@ -154,16 +156,17 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, assert(!tc->texture); if (tc->surface_map) { - /*assert(tc->surface != ps);*/ - pipe_surface_unmap(tc->surface); + tc->screen->surface_unmap(tc->screen, tc->surface); tc->surface_map = NULL; } pipe_surface_reference(&tc->surface, ps); - if (ps) { - if (tc->surface_map) - tc->surface_map = pipe_surface_map(ps); + if (tc->surface) { + if (tc->surface_map) /* XXX: this is always NULL!? */ + tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM || ps->format == PIPE_FORMAT_Z16_UNORM || @@ -187,10 +190,13 @@ void sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc) { if (tc->surface && !tc->surface_map) - tc->surface_map = pipe_surface_map(tc->surface); + tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface, + PIPE_BUFFER_USAGE_CPU_WRITE | + PIPE_BUFFER_USAGE_CPU_READ); if (tc->tex_surf && !tc->tex_surf_map) - tc->tex_surf_map = pipe_surface_map(tc->tex_surf); + tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf, + PIPE_BUFFER_USAGE_CPU_READ); } @@ -198,12 +204,12 @@ void sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc) { if (tc->surface_map) { - pipe_surface_unmap(tc->surface); + tc->screen->surface_unmap(tc->screen, tc->surface); tc->surface_map = NULL; } if (tc->tex_surf_map) { - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); tc->tex_surf_map = NULL; } } @@ -224,7 +230,7 @@ sp_tile_cache_set_texture(struct pipe_context *pipe, pipe_texture_reference(&tc->texture, texture); if (tc->tex_surf_map) { - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); tc->tex_surf_map = NULL; } pipe_surface_reference(&tc->tex_surf, NULL); @@ -514,10 +520,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe, /* get new surface (view into texture) */ if (tc->tex_surf_map) - pipe_surface_unmap(tc->tex_surf); + tc->screen->surface_unmap(tc->screen, tc->tex_surf); - tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z); - tc->tex_surf_map = pipe_surface_map(tc->tex_surf); + tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z, + PIPE_BUFFER_USAGE_CPU_READ); + tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf, + PIPE_BUFFER_USAGE_CPU_READ); tc->tex_face = face; tc->tex_level = level; diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h index 2631e29a3a6..bc96c941f61 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tile_cache.h @@ -61,7 +61,7 @@ struct softpipe_cached_tile extern struct softpipe_tile_cache * -sp_create_tile_cache(void); +sp_create_tile_cache( struct pipe_screen *screen ); extern void sp_destroy_tile_cache(struct softpipe_tile_cache *tc); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index f3a9c2cd8b2..0f68f592f77 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -198,12 +198,6 @@ struct pipe_context { /*@}*/ - /** Called when texture data is changed */ - void (*texture_update)(struct pipe_context *pipe, - struct pipe_texture *texture, - uint face, uint dirtyLevelsMask); - - /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */ void (*flush)( struct pipe_context *pipe, unsigned flags, diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 7a7312ea122..0af635be573 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -313,6 +313,28 @@ void debug_memory_end(unsigned long beginning); +#if defined(PROFILE) && defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) + +void +debug_profile_start(void); + +void +debug_profile_stop(void); + +#endif + + +#ifdef DEBUG +void debug_dump_image(const char *prefix, + unsigned format, unsigned cpp, + unsigned width, unsigned height, + unsigned pitch, + const void *data); +#else +#define debug_dump_image(prefix, format, cpp, width, height, pitch, data) ((void)0) +#endif + + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 46a355daa21..83330ef22fe 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -174,6 +174,12 @@ enum pipe_texture_target { /** + * Surface layout + */ +#define PIPE_SURFACE_LAYOUT_LINEAR 0 + + +/** * Surface status */ #define PIPE_SURFACE_STATUS_UNDEFINED 0 diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index a4bd23c302a..9ba00f8d7b6 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -307,6 +307,9 @@ enum pipe_format { PIPE_FORMAT_R8G8B8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R8G8B8A8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R8G8B8X8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_B6G5R5_SNORM = _PIPE_FORMAT_RGBAZS_1 ( _PIPE_FORMAT_BGR1, 6, 5, 5, 0, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_A8B8G8R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_BGRA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), + PIPE_FORMAT_X8B8G8R8_SNORM = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SNORM ), PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R001, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG01, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ), PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB1, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ), diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h index 8eb604e73f1..1e4b98edb48 100644 --- a/src/gallium/include/pipe/p_inlines.h +++ b/src/gallium/include/pipe/p_inlines.h @@ -39,21 +39,40 @@ extern "C" { #endif +/* XXX: these are a kludge. will fix when all surfaces are views into + * textures, and free-floating winsys surfaces go away. + */ static INLINE void * -pipe_surface_map(struct pipe_surface *surface) +pipe_surface_map( struct pipe_surface *surf, unsigned flags ) { - return (char *)surface->winsys->buffer_map( surface->winsys, surface->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_CPU_READ ) - + surface->offset; + if (surf->texture) { + struct pipe_screen *screen = surf->texture->screen; + return surf->texture->screen->surface_map( screen, surf, flags ); + } + else { + struct pipe_winsys *winsys = surf->winsys; + char *map = (char *)winsys->buffer_map( winsys, surf->buffer, flags ); + if (map == NULL) + return NULL; + return (void *)(map + surf->offset); + } } static INLINE void -pipe_surface_unmap(struct pipe_surface *surface) +pipe_surface_unmap( struct pipe_surface *surf ) { - surface->winsys->buffer_unmap( surface->winsys, surface->buffer ); + if (surf->texture) { + struct pipe_screen *screen = surf->texture->screen; + surf->texture->screen->surface_unmap( screen, surf ); + } + else { + struct pipe_winsys *winsys = surf->winsys; + winsys->buffer_unmap( winsys, surf->buffer ); + } } + + /** * Set 'ptr' to point to 'surf' and update reference counting. * The old thing pointed to, if any, will be unreferenced first. @@ -66,9 +85,20 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) if (surf) surf->refcount++; - if (*ptr /* && --(*ptr)->refcount == 0 */) { - struct pipe_winsys *winsys = (*ptr)->winsys; - winsys->surface_release(winsys, ptr); + if (*ptr) { + + /* There are currently two sorts of surfaces... This needs to be + * fixed so that all surfaces are views into a texture. + */ + if ((*ptr)->texture) { + struct pipe_screen *screen = (*ptr)->texture->screen; + screen->tex_surface_release( screen, ptr ); + } + else { + struct pipe_winsys *winsys = (*ptr)->winsys; + winsys->surface_release(winsys, ptr); + } + assert(!*ptr); } diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 26ac99d287d..cc8430dae16 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -89,6 +89,18 @@ struct pipe_screen { struct pipe_texture * (*texture_create)(struct pipe_screen *, const struct pipe_texture *templat); + /** + * Create a new texture object, using the given template info, but on top of + * existing memory. + * + * It is assumed that the buffer data is layed out according to the expected + * by the hardware. NULL will be returned if any inconsistency is found. + */ + struct pipe_texture * (*texture_blanket)(struct pipe_screen *, + const struct pipe_texture *templat, + const unsigned *pitch, + struct pipe_buffer *buffer); + void (*texture_release)(struct pipe_screen *, struct pipe_texture **pt); @@ -96,7 +108,22 @@ struct pipe_screen { struct pipe_surface *(*get_tex_surface)(struct pipe_screen *, struct pipe_texture *texture, unsigned face, unsigned level, - unsigned zslice); + unsigned zslice, + unsigned usage ); + + /* Surfaces allocated by the above must be released here: + */ + void (*tex_surface_release)( struct pipe_screen *, + struct pipe_surface ** ); + + + void *(*surface_map)( struct pipe_screen *, + struct pipe_surface *surface, + unsigned flags ); + + void (*surface_unmap)( struct pipe_screen *, + struct pipe_surface *surface ); + }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 912d84e7b99..e7ee8c97ed7 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -271,12 +271,26 @@ struct pipe_surface unsigned width; unsigned height; unsigned pitch; /**< in pixels */ + unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */ unsigned offset; /**< offset from start of buffer, in bytes */ unsigned refcount; + unsigned usage; /**< PIPE_BUFFER_USAGE_* */ + struct pipe_winsys *winsys; /**< winsys which owns/created the surface */ + + struct pipe_texture *texture; /**< optional texture into which this is a view */ + unsigned face; + unsigned level; + unsigned zslice; }; +#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 +#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ +#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */ +#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8 +#define PIPE_TEXTURE_USAGE_SAMPLER 0x10 + /** * Texture object. */ @@ -292,6 +306,8 @@ struct pipe_texture unsigned cpp:8; unsigned last_level:8; /**< Index of last mipmap level present/defined */ unsigned compressed:1; + + unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */ /* These are also refcounted: */ diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index a66ab765f72..597354ca96c 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -204,7 +204,6 @@ mem_dup(const void *src, uint size) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) -/* JB stop warnings */ #ifndef Elements #define Elements(x) (sizeof(x)/sizeof((x)[0])) #endif diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 3005ec2d941..7ebc2851928 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -86,11 +86,12 @@ struct pipe_winsys struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags); + unsigned flags, + unsigned tex_usage); void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s); - + /** * Buffer management. Buffer attributes are mostly fixed over its lifetime. * diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 6a42c790337..10e1a84cc12 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -220,7 +220,8 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; //int ret; diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h index f1fd3939ab9..f84f4533093 100644 --- a/src/gallium/winsys/dri/intel/server/i830_common.h +++ b/src/gallium/winsys/dri/intel/server/i830_common.h @@ -26,7 +26,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ #ifndef _I830_COMMON_H_ #define _I830_COMMON_H_ diff --git a/src/gallium/winsys/dri/intel/server/i830_dri.h b/src/gallium/winsys/dri/intel/server/i830_dri.h index c2a3af8cbf7..685de4a551b 100644 --- a/src/gallium/winsys/dri/intel/server/i830_dri.h +++ b/src/gallium/winsys/dri/intel/server/i830_dri.h @@ -1,4 +1,3 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ #ifndef _I830_DRI_H #define _I830_DRI_H diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 14c3892559b..b14758f3336 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -489,7 +489,8 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; @@ -498,6 +499,7 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys, surf->format = format; surf->cpp = pf_get_size(format); surf->pitch = round_up(width, alignment / surf->cpp); + surf->usage = flags; #ifdef GALLIUM_CELL /* XXX a bit of a hack */ height = round_up(height, TILE_SIZE); @@ -551,6 +553,7 @@ static void xm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) { struct pipe_surface *surf = *s; + assert(!surf->texture); surf->refcount--; if (surf->refcount == 0) { if (surf->buffer) diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index f42f7fcc5f1..77376099f0d 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -276,7 +276,8 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys, struct pipe_surface *surf, unsigned width, unsigned height, enum pipe_format format, - unsigned flags) + unsigned flags, + unsigned tex_usage) { const unsigned alignment = 64; |