From 401a18a0c64bf8995c2c888b155a711b6187eba5 Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Thu, 11 Dec 2008 13:54:05 +0100 Subject: draw: Silencium compiler warnings on Windows. --- src/gallium/auxiliary/draw/draw_pipe_offset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/auxiliary') diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index 8ddc4ee617..62c31532d0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -123,7 +123,7 @@ static void offset_first_tri( struct draw_stage *stage, { struct offset_stage *offset = offset_stage(stage); - offset->units = stage->draw->rasterizer->offset_units * stage->draw->mrd; + offset->units = (float) (stage->draw->rasterizer->offset_units * stage->draw->mrd); offset->scale = stage->draw->rasterizer->offset_scale; stage->tri = offset_tri; -- cgit v1.2.3 From 71051f1f40206dd9d86d64cfdc20cc744a15f12c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 12 Dec 2008 12:05:21 +0000 Subject: Revert "pipebuffer: Fix buffer overflow." This reverts commit 55839ae064d64b7fcc180fcddb364bf31ab760dc. --- src/gallium/auxiliary/pipebuffer/pb_validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium/auxiliary') diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c index 94532bb4ce..726ae1688e 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.c +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -182,7 +182,7 @@ pb_validate_create() return NULL; vl->size = PB_VALIDATE_INITIAL_SIZE; - vl->entries = (struct pb_validate_entry *)CALLOC(vl->size, sizeof(struct pb_validate_entry)); + vl->entries = (struct pb_validate_entry *)CALLOC(vl->size, sizeof(struct pb_buffer *)); if(!vl->entries) { FREE(vl); return NULL; -- cgit v1.2.3 From 9b3bce6bed36a37293cd67ed4e9a05dd6e1c9d80 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 12 Dec 2008 12:05:30 +0000 Subject: Revert "pipebuffer: Ondemand buffer manager." This reverts commit 17849eafaacfbb2124d86f561a91b707317d3b31. --- src/gallium/auxiliary/pipebuffer/Makefile | 1 - src/gallium/auxiliary/pipebuffer/SConscript | 1 - src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 14 - .../auxiliary/pipebuffer/pb_bufmgr_ondemand.c | 303 --------------------- 4 files changed, 319 deletions(-) delete mode 100644 src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c (limited to 'src/gallium/auxiliary') diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile index 4bcf08f8a5..f9b39d9ce0 100644 --- a/src/gallium/auxiliary/pipebuffer/Makefile +++ b/src/gallium/auxiliary/pipebuffer/Makefile @@ -11,7 +11,6 @@ C_SOURCES = \ pb_bufmgr_debug.c \ pb_bufmgr_fenced.c \ pb_bufmgr_mm.c \ - pb_bufmgr_ondemand.c \ pb_bufmgr_pool.c \ pb_bufmgr_slab.c \ pb_validate.c \ diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript index 4acf721808..56a40dda0d 100644 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ b/src/gallium/auxiliary/pipebuffer/SConscript @@ -10,7 +10,6 @@ pipebuffer = env.ConvenienceLibrary( 'pb_bufmgr_debug.c', 'pb_bufmgr_fenced.c', 'pb_bufmgr_mm.c', - 'pb_bufmgr_ondemand.c', 'pb_bufmgr_pool.c', 'pb_bufmgr_slab.c', 'pb_validate.c', diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 0a8264a924..8fe2704708 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -182,20 +182,6 @@ pb_alt_manager_create(struct pb_manager *provider1, struct pb_manager *provider2); -/** - * Ondemand buffer manager. - * - * Buffers are created in malloc'ed memory (fast and cached), and the constents - * is transfered to a buffer from the provider (typically in slow uncached - * memory) when there is an attempt to validate the buffer. - * - * Ideal for situations where one does not know before hand whether a given - * buffer will effectively be used by the hardware or not. - */ -struct pb_manager * -pb_ondemand_manager_create(struct pb_manager *provider); - - /** * Debug buffer manager to detect buffer under- and overflows. * diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c deleted file mode 100644 index ba02a84e62..0000000000 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_ondemand.c +++ /dev/null @@ -1,303 +0,0 @@ -/************************************************************************** - * - * 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 - * A variation of malloc buffers which get transferred to real graphics memory - * when there is an attempt to validate them. - * - * @author Jose Fonseca - */ - - -#include "pipe/p_debug.h" -#include "util/u_memory.h" -#include "pb_buffer.h" -#include "pb_bufmgr.h" - - -struct pb_ondemand_manager; - - -struct pb_ondemand_buffer -{ - struct pb_buffer base; - - struct pb_ondemand_manager *mgr; - - /** Regular malloc'ed memory */ - void *data; - unsigned mapcount; - - /** Real buffer */ - struct pb_buffer *buffer; - size_t size; - struct pb_desc desc; -}; - - -struct pb_ondemand_manager -{ - struct pb_manager base; - - struct pb_manager *provider; -}; - - -extern const struct pb_vtbl pb_ondemand_buffer_vtbl; - -static INLINE struct pb_ondemand_buffer * -pb_ondemand_buffer(struct pb_buffer *buf) -{ - assert(buf); - assert(buf->vtbl == &pb_ondemand_buffer_vtbl); - return (struct pb_ondemand_buffer *)buf; -} - -static INLINE struct pb_ondemand_manager * -pb_ondemand_manager(struct pb_manager *mgr) -{ - assert(mgr); - return (struct pb_ondemand_manager *)mgr; -} - - -static void -pb_ondemand_buffer_destroy(struct pb_buffer *_buf) -{ - struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf); - - pb_reference(&buf->buffer, NULL); - - align_free(buf->data); - - FREE(buf); -} - - -static void * -pb_ondemand_buffer_map(struct pb_buffer *_buf, - unsigned flags) -{ - struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf); - - if(buf->buffer) { - assert(!buf->data); - return pb_map(buf->buffer, flags); - } - else { - assert(buf->data); - ++buf->mapcount; - return buf->data; - } -} - - -static void -pb_ondemand_buffer_unmap(struct pb_buffer *_buf) -{ - struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf); - - if(buf->buffer) { - assert(!buf->data); - pb_unmap(buf->buffer); - } - else { - assert(buf->data); - assert(buf->mapcount); - if(buf->mapcount) - --buf->mapcount; - } -} - - -static enum pipe_error -pb_ondemand_buffer_instantiate(struct pb_ondemand_buffer *buf) -{ - if(!buf->buffer) { - struct pb_manager *provider = buf->mgr->provider; - uint8_t *map; - - assert(!buf->mapcount); - - buf->buffer = provider->create_buffer(provider, buf->size, &buf->desc); - if(!buf->buffer) - return PIPE_ERROR_OUT_OF_MEMORY; - - map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ); - if(!map) { - pb_reference(&buf->buffer, NULL); - return PIPE_ERROR; - } - - memcpy(map, buf->data, buf->size); - - pb_unmap(buf->buffer); - - if(!buf->mapcount) { - FREE(buf->data); - buf->data = NULL; - } - } - - return PIPE_OK; -} - -static enum pipe_error -pb_ondemand_buffer_validate(struct pb_buffer *_buf, - struct pb_validate *vl, - unsigned flags) -{ - struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf); - enum pipe_error ret; - - assert(!buf->mapcount); - if(buf->mapcount) - return PIPE_ERROR; - - ret = pb_ondemand_buffer_instantiate(buf); - if(ret != PIPE_OK) - return ret; - - return pb_validate(buf->buffer, vl, flags); -} - - -static void -pb_ondemand_buffer_fence(struct pb_buffer *_buf, - struct pipe_fence_handle *fence) -{ - struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf); - - assert(buf->buffer); - if(!buf->buffer) - return; - - pb_fence(buf->buffer, fence); -} - - -static void -pb_ondemand_buffer_get_base_buffer(struct pb_buffer *_buf, - struct pb_buffer **base_buf, - unsigned *offset) -{ - struct pb_ondemand_buffer *buf = pb_ondemand_buffer(_buf); - - if(pb_ondemand_buffer_instantiate(buf) != PIPE_OK) { - assert(0); - *base_buf = &buf->base; - *offset = 0; - return; - } - - pb_get_base_buffer(buf->buffer, base_buf, offset); -} - - -const struct pb_vtbl -pb_ondemand_buffer_vtbl = { - pb_ondemand_buffer_destroy, - pb_ondemand_buffer_map, - pb_ondemand_buffer_unmap, - pb_ondemand_buffer_validate, - pb_ondemand_buffer_fence, - pb_ondemand_buffer_get_base_buffer -}; - - -static struct pb_buffer * -pb_ondemand_manager_create_buffer(struct pb_manager *_mgr, - size_t size, - const struct pb_desc *desc) -{ - struct pb_ondemand_manager *mgr = pb_ondemand_manager(_mgr); - struct pb_ondemand_buffer *buf; - - buf = CALLOC_STRUCT(pb_ondemand_buffer); - if(!buf) - return NULL; - - buf->base.base.refcount = 1; - buf->base.base.alignment = desc->alignment; - buf->base.base.usage = desc->usage; - buf->base.base.size = size; - buf->base.vtbl = &pb_ondemand_buffer_vtbl; - - buf->mgr = mgr; - - buf->data = align_malloc(size, desc->alignment < sizeof(void*) ? sizeof(void*) : desc->alignment); - if(!buf->data) { - FREE(buf); - return NULL; - } - - buf->size = size; - buf->desc = *desc; - - return &buf->base; -} - - -static void -pb_ondemand_manager_flush(struct pb_manager *_mgr) -{ - struct pb_ondemand_manager *mgr = pb_ondemand_manager(_mgr); - - mgr->provider->flush(mgr->provider); -} - - -static void -pb_ondemand_manager_destroy(struct pb_manager *_mgr) -{ - struct pb_ondemand_manager *mgr = pb_ondemand_manager(_mgr); - - FREE(mgr); -} - - -struct pb_manager * -pb_ondemand_manager_create(struct pb_manager *provider) -{ - struct pb_ondemand_manager *mgr; - - if(!provider) - return NULL; - - mgr = CALLOC_STRUCT(pb_ondemand_manager); - if(!mgr) - return NULL; - - mgr->base.destroy = pb_ondemand_manager_destroy; - mgr->base.create_buffer = pb_ondemand_manager_create_buffer; - mgr->base.flush = pb_ondemand_manager_flush; - - mgr->provider = provider; - - return &mgr->base; -} -- cgit v1.2.3 From aef455c4a7bbd7df97a6444ae332cb5fb976e627 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 12 Dec 2008 12:05:39 +0000 Subject: Revert "pipebuffer: Implement proper buffer validation." This reverts commit a6d866f72c88d48d2bcfb3e3c882fdb639b5a8ce. --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 36 +---- .../auxiliary/pipebuffer/pb_buffer_fenced.c | 158 ++++++++------------- .../auxiliary/pipebuffer/pb_buffer_fenced.h | 21 ++- .../auxiliary/pipebuffer/pb_buffer_malloc.c | 20 --- src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 23 +-- src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 26 +--- .../auxiliary/pipebuffer/pb_bufmgr_fenced.c | 2 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 25 +--- src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 25 +--- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 21 --- src/gallium/auxiliary/pipebuffer/pb_validate.c | 84 +++-------- src/gallium/auxiliary/pipebuffer/pb_validate.h | 10 +- src/gallium/auxiliary/pipebuffer/pb_winsys.c | 22 +-- 14 files changed, 108 insertions(+), 367 deletions(-) (limited to 'src/gallium/auxiliary') diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index c9570d7be2..8505d333bd 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -37,7 +37,7 @@ * There is no obligation of a winsys driver to use this library. And a pipe * driver should be completly agnostic about it. * - * \author Jose Fonseca + * \author Jos� Fonseca */ #ifndef PB_BUFFER_H_ @@ -46,7 +46,6 @@ #include "pipe/p_compiler.h" #include "pipe/p_debug.h" -#include "pipe/p_error.h" #include "pipe/p_state.h" #include "pipe/p_inlines.h" @@ -57,8 +56,6 @@ extern "C" { struct pb_vtbl; -struct pb_validate; - /** * Buffer description. @@ -107,13 +104,6 @@ struct pb_vtbl void (*unmap)( struct pb_buffer *buf ); - enum pipe_error (*validate)( struct pb_buffer *buf, - struct pb_validate *vl, - unsigned flags ); - - void (*fence)( struct pb_buffer *buf, - struct pipe_fence_handle *fence ); - /** * Get the base buffer and the offset. * @@ -128,7 +118,6 @@ struct pb_vtbl void (*get_base_buffer)( struct pb_buffer *buf, struct pb_buffer **base_buf, unsigned *offset ); - }; @@ -184,33 +173,10 @@ pb_get_base_buffer( struct pb_buffer *buf, offset = 0; return; } - assert(buf->vtbl->get_base_buffer); buf->vtbl->get_base_buffer(buf, base_buf, offset); } -static INLINE enum pipe_error -pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned flags) -{ - assert(buf); - if(!buf) - return PIPE_ERROR; - assert(buf->vtbl->validate); - return buf->vtbl->validate(buf, vl, flags); -} - - -static INLINE void -pb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence) -{ - assert(buf); - if(!buf) - return; - assert(buf->vtbl->fence); - buf->vtbl->fence(buf, fence); -} - - static INLINE void pb_destroy(struct pb_buffer *buf) { diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 17300cb553..17b2781052 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -29,7 +29,7 @@ * \file * Implementation of fenced buffers. * - * \author Jose Fonseca + * \author José Fonseca * \author Thomas Hellström */ @@ -59,6 +59,13 @@ */ #define SUPER(__derived) (&(__derived)->base) +#define PIPE_BUFFER_USAGE_CPU_READ_WRITE \ + ( PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE ) +#define PIPE_BUFFER_USAGE_GPU_READ_WRITE \ + ( PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ) +#define PIPE_BUFFER_USAGE_WRITE \ + ( PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE ) + struct fenced_buffer_list { @@ -90,8 +97,6 @@ struct fenced_buffer unsigned flags; unsigned mapcount; - struct pb_validate *vl; - unsigned validation_flags; struct pipe_fence_handle *fence; struct list_head head; @@ -103,6 +108,7 @@ static INLINE struct fenced_buffer * fenced_buffer(struct pb_buffer *buf) { assert(buf); + assert(buf->vtbl == &fenced_buffer_vtbl); return (struct fenced_buffer *)buf; } @@ -268,7 +274,6 @@ 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); assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE)); flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE; @@ -310,101 +315,6 @@ fenced_buffer_unmap(struct pb_buffer *buf) } -static enum pipe_error -fenced_buffer_validate(struct pb_buffer *buf, - struct pb_validate *vl, - unsigned flags) -{ - struct fenced_buffer *fenced_buf = fenced_buffer(buf); - enum pipe_error ret; - - if(!vl) { - /* invalidate */ - fenced_buf->vl = NULL; - fenced_buf->validation_flags = 0; - return PIPE_OK; - } - - assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); - assert(!(flags & ~PIPE_BUFFER_USAGE_GPU_READ_WRITE)); - flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE; - - /* Buffer cannot be validated in two different lists */ - if(fenced_buf->vl && fenced_buf->vl != vl) - return PIPE_ERROR_RETRY; - - /* Do not validate if buffer is still mapped */ - if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { - /* TODO: wait for the thread that mapped the buffer to unmap it */ - return PIPE_ERROR_RETRY; - } - - /* Allow concurrent GPU reads, but serialize GPU writes */ - if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE) { - if((fenced_buf->flags | flags) & PIPE_BUFFER_USAGE_GPU_WRITE) { - _fenced_buffer_finish(fenced_buf); - } - } - - if(fenced_buf->vl == vl && - (fenced_buf->validation_flags & flags) == flags) { - /* Nothing to do -- buffer already validated */ - return PIPE_OK; - } - - /* Final sanity checking */ - assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE)); - assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE)); - assert(!fenced_buf->mapcount); - - ret = pb_validate(fenced_buf->buffer, vl, flags); - if (ret != PIPE_OK) - return ret; - - fenced_buf->vl = vl; - fenced_buf->validation_flags |= flags; - - return PIPE_OK; -} - - -static void -fenced_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ - struct fenced_buffer *fenced_buf; - struct fenced_buffer_list *fenced_list; - struct pipe_winsys *winsys; - - fenced_buf = fenced_buffer(buf); - fenced_list = fenced_buf->list; - winsys = fenced_list->winsys; - - if(fence == fenced_buf->fence) { - /* Nothing to do */ - return; - } - - assert(fenced_buf->vl); - assert(fenced_buf->validation_flags); - - pipe_mutex_lock(fenced_list->mutex); - if (fenced_buf->fence) - _fenced_buffer_remove(fenced_list, fenced_buf); - if (fence) { - winsys->fence_reference(winsys, &fenced_buf->fence, fence); - fenced_buf->flags |= fenced_buf->validation_flags; - _fenced_buffer_add(fenced_buf); - } - pipe_mutex_unlock(fenced_list->mutex); - - pb_fence(fenced_buf->buffer, fence); - - fenced_buf->vl = NULL; - fenced_buf->validation_flags = 0; -} - - static void fenced_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, @@ -415,13 +325,11 @@ fenced_buffer_get_base_buffer(struct pb_buffer *buf, } -static const struct pb_vtbl +const struct pb_vtbl fenced_buffer_vtbl = { fenced_buffer_destroy, fenced_buffer_map, fenced_buffer_unmap, - fenced_buffer_validate, - fenced_buffer_fence, fenced_buffer_get_base_buffer }; @@ -454,6 +362,52 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list, } +void +buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence) +{ + struct fenced_buffer *fenced_buf; + struct fenced_buffer_list *fenced_list; + struct pipe_winsys *winsys; + /* FIXME: receive this as a parameter */ + unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0; + + /* This is a public function, so be extra cautious with the buffer passed, + * as happens frequently to receive null buffers, or pointer to buffers + * other than fenced buffers. */ + assert(buf); + if(!buf) + return; + assert(buf->vtbl == &fenced_buffer_vtbl); + if(buf->vtbl != &fenced_buffer_vtbl) + return; + + fenced_buf = fenced_buffer(buf); + fenced_list = fenced_buf->list; + winsys = fenced_list->winsys; + + 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 + * any benefit. + */ + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; + return; + } + + pipe_mutex_lock(fenced_list->mutex); + if (fenced_buf->fence) + _fenced_buffer_remove(fenced_list, fenced_buf); + if (fence) { + winsys->fence_reference(winsys, &fenced_buf->fence, fence); + fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; + _fenced_buffer_add(fenced_buf); + } + pipe_mutex_unlock(fenced_list->mutex); +} + + struct fenced_buffer_list * fenced_buffer_list_create(struct pipe_winsys *winsys) { diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h index b15c676194..50d5891bdb 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h @@ -44,7 +44,7 @@ * Between the handle's destruction, and the fence signalling, the buffer is * stored in a fenced buffer list. * - * \author Jose Fonseca + * \author José Fonseca */ #ifndef PB_BUFFER_FENCED_H_ @@ -70,6 +70,14 @@ struct pipe_fence_handle; struct fenced_buffer_list; +/** + * The fenced buffer's virtual function table. + * + * NOTE: Made public for debugging purposes. + */ +extern const struct pb_vtbl fenced_buffer_vtbl; + + /** * Create a fenced buffer list. * @@ -100,6 +108,17 @@ fenced_buffer_create(struct fenced_buffer_list *fenced, struct pb_buffer *buffer); +/** + * Set a buffer's fence. + * + * NOTE: Although it takes a generic pb_buffer argument, it will fail + * on everything but buffers returned by fenced_buffer_create. + */ +void +buffer_fence(struct pb_buffer *buf, + struct pipe_fence_handle *fence); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c index 53f497cfb0..1bf22a2ec0 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -81,24 +81,6 @@ malloc_buffer_unmap(struct pb_buffer *buf) } -static enum pipe_error -malloc_buffer_validate(struct pb_buffer *buf, - struct pb_validate *vl, - unsigned flags) -{ - assert(0); - return PIPE_ERROR; -} - - -static void -malloc_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ - assert(0); -} - - static void malloc_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, @@ -114,8 +96,6 @@ malloc_buffer_vtbl = { malloc_buffer_destroy, malloc_buffer_map, malloc_buffer_unmap, - malloc_buffer_validate, - malloc_buffer_fence, malloc_buffer_get_base_buffer }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index 8fe2704708..cafbee045a 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -43,7 +43,7 @@ * - the fenced buffer manager, which will delay buffer destruction until the * the moment the card finishing processing it. * - * \author Jose Fonseca + * \author José Fonseca */ #ifndef PB_BUFMGR_H_ diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index f57a7bffd7..8f118874ec 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -29,7 +29,7 @@ * \file * Buffer cache. * - * \author Jose Fonseca + * \author José Fonseca * \author Thomas Hellström */ @@ -183,25 +183,6 @@ pb_cache_buffer_unmap(struct pb_buffer *_buf) } -static enum pipe_error -pb_cache_buffer_validate(struct pb_buffer *_buf, - struct pb_validate *vl, - unsigned flags) -{ - struct pb_cache_buffer *buf = pb_cache_buffer(_buf); - return pb_validate(buf->buffer, vl, flags); -} - - -static void -pb_cache_buffer_fence(struct pb_buffer *_buf, - struct pipe_fence_handle *fence) -{ - struct pb_cache_buffer *buf = pb_cache_buffer(_buf); - pb_fence(buf->buffer, fence); -} - - static void pb_cache_buffer_get_base_buffer(struct pb_buffer *_buf, struct pb_buffer **base_buf, @@ -217,8 +198,6 @@ pb_cache_buffer_vtbl = { pb_cache_buffer_destroy, pb_cache_buffer_map, pb_cache_buffer_unmap, - pb_cache_buffer_validate, - pb_cache_buffer_fence, pb_cache_buffer_get_base_buffer }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index 62639fe1c8..1675e6e182 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -29,7 +29,7 @@ * \file * Debug buffer manager to detect buffer under- and overflows. * - * \author Jose Fonseca + * \author José Fonseca */ @@ -255,35 +255,11 @@ pb_debug_buffer_get_base_buffer(struct pb_buffer *_buf, } -static enum pipe_error -pb_debug_buffer_validate(struct pb_buffer *_buf, - struct pb_validate *vl, - unsigned flags) -{ - struct pb_debug_buffer *buf = pb_debug_buffer(_buf); - - pb_debug_buffer_check(buf); - - return pb_validate(buf->buffer, vl, flags); -} - - -static void -pb_debug_buffer_fence(struct pb_buffer *_buf, - struct pipe_fence_handle *fence) -{ - struct pb_debug_buffer *buf = pb_debug_buffer(_buf); - pb_fence(buf->buffer, fence); -} - - const struct pb_vtbl pb_debug_buffer_vtbl = { pb_debug_buffer_destroy, pb_debug_buffer_map, pb_debug_buffer_unmap, - pb_debug_buffer_validate, - pb_debug_buffer_fence, pb_debug_buffer_get_base_buffer }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index f8fd2cd531..633ee70a75 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -30,7 +30,7 @@ * \file * A buffer manager that wraps buffers in fenced buffers. * - * \author Jose Fonseca + * \author José Fonseca */ diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 607f10bc73..fe80ca30ee 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -29,7 +29,7 @@ * \file * Buffer manager using the old texture memory manager. * - * \author Jose Fonseca + * \author José Fonseca */ @@ -124,27 +124,6 @@ mm_buffer_unmap(struct pb_buffer *buf) } -static enum pipe_error -mm_buffer_validate(struct pb_buffer *buf, - struct pb_validate *vl, - unsigned flags) -{ - struct mm_buffer *mm_buf = mm_buffer(buf); - struct mm_pb_manager *mm = mm_buf->mgr; - return pb_validate(mm->buffer, vl, flags); -} - - -static void -mm_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ - struct mm_buffer *mm_buf = mm_buffer(buf); - struct mm_pb_manager *mm = mm_buf->mgr; - pb_fence(mm->buffer, fence); -} - - static void mm_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, @@ -162,8 +141,6 @@ mm_buffer_vtbl = { mm_buffer_destroy, mm_buffer_map, mm_buffer_unmap, - mm_buffer_validate, - mm_buffer_fence, mm_buffer_get_base_buffer }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index a6ff37653e..61ac291ed7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -30,7 +30,7 @@ * \file * Batch buffer pool management. * - * \author Jose Fonseca + * \author José Fonseca * \author Thomas Hellström */ @@ -138,27 +138,6 @@ pool_buffer_unmap(struct pb_buffer *buf) } -static enum pipe_error -pool_buffer_validate(struct pb_buffer *buf, - struct pb_validate *vl, - unsigned flags) -{ - struct pool_buffer *pool_buf = pool_buffer(buf); - struct pool_pb_manager *pool = pool_buf->mgr; - return pb_validate(pool->buffer, vl, flags); -} - - -static void -pool_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ - struct pool_buffer *pool_buf = pool_buffer(buf); - struct pool_pb_manager *pool = pool_buf->mgr; - pb_fence(pool->buffer, fence); -} - - static void pool_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, @@ -176,8 +155,6 @@ pool_buffer_vtbl = { pool_buffer_destroy, pool_buffer_map, pool_buffer_unmap, - pool_buffer_validate, - pool_buffer_fence, pool_buffer_get_base_buffer }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 9b9fedccb4..2a80154920 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -248,25 +248,6 @@ pb_slab_buffer_unmap(struct pb_buffer *_buf) } -static enum pipe_error -pb_slab_buffer_validate(struct pb_buffer *_buf, - struct pb_validate *vl, - unsigned flags) -{ - struct pb_slab_buffer *buf = pb_slab_buffer(_buf); - return pb_validate(buf->slab->bo, vl, flags); -} - - -static void -pb_slab_buffer_fence(struct pb_buffer *_buf, - struct pipe_fence_handle *fence) -{ - struct pb_slab_buffer *buf = pb_slab_buffer(_buf); - pb_fence(buf->slab->bo, fence); -} - - static void pb_slab_buffer_get_base_buffer(struct pb_buffer *_buf, struct pb_buffer **base_buf, @@ -283,8 +264,6 @@ pb_slab_buffer_vtbl = { pb_slab_buffer_destroy, pb_slab_buffer_map, pb_slab_buffer_unmap, - pb_slab_buffer_validate, - pb_slab_buffer_fence, pb_slab_buffer_get_base_buffer }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c index 726ae1688e..1e54fc39d4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.c +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -46,16 +46,9 @@ #define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */ -struct pb_validate_entry -{ - struct pb_buffer *buf; - unsigned flags; -}; - - struct pb_validate { - struct pb_validate_entry *entries; + struct pb_buffer **buffers; unsigned used; unsigned size; }; @@ -63,87 +56,54 @@ struct pb_validate enum pipe_error pb_validate_add_buffer(struct pb_validate *vl, - struct pb_buffer *buf, - unsigned flags) + struct pb_buffer *buf) { assert(buf); if(!buf) return PIPE_ERROR; - assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); - assert(!(flags & ~PIPE_BUFFER_USAGE_GPU_READ_WRITE)); - flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE; - /* We only need to store one reference for each buffer, so avoid storing - * consecutive references for the same buffer. It might not be the most - * common pattern, but it is easy to implement. + * consecutive references for the same buffer. It might not be the more + * common pasttern, but it is easy to implement. */ - if(vl->used && vl->entries[vl->used - 1].buf == buf) { - vl->entries[vl->used - 1].flags |= flags; + 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_validate_entry *new_entries; + struct pb_buffer **new_buffers; new_size = vl->size * 2; if(!new_size) return PIPE_ERROR_OUT_OF_MEMORY; - new_entries = (struct pb_validate_entry *)REALLOC(vl->entries, - vl->size*sizeof(struct pb_validate_entry), - new_size*sizeof(struct pb_validate_entry)); - if(!new_entries) + 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_entries + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_validate_entry)); + memset(new_buffers + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_buffer *)); vl->size = new_size; - vl->entries = new_entries; + vl->buffers = new_buffers; } - assert(!vl->entries[vl->used].buf); - pb_reference(&vl->entries[vl->used].buf, buf); - vl->entries[vl->used].flags = flags; + assert(!vl->buffers[vl->used]); + pb_reference(&vl->buffers[vl->used], buf); ++vl->used; return PIPE_OK; } -enum pipe_error -pb_validate_foreach(struct pb_validate *vl, - enum pipe_error (*callback)(struct pb_buffer *buf, void *data), - void *data) -{ - unsigned i; - for(i = 0; i < vl->used; ++i) { - enum pipe_error ret; - ret = callback(vl->entries[i].buf, data); - if(ret != PIPE_OK) - return ret; - } - return PIPE_OK; -} - - enum pipe_error pb_validate_validate(struct pb_validate *vl) { - unsigned i; - - for(i = 0; i < vl->used; ++i) { - enum pipe_error ret; - ret = pb_validate(vl->entries[i].buf, vl, vl->entries[i].flags); - if(ret != PIPE_OK) { - while(i--) - pb_validate(vl->entries[i].buf, NULL, 0); - return ret; - } - } - + /* FIXME: go through each buffer, ensure its not mapped, its address is + * available -- requires a new pb_buffer interface */ return PIPE_OK; } @@ -154,8 +114,8 @@ pb_validate_fence(struct pb_validate *vl, { unsigned i; for(i = 0; i < vl->used; ++i) { - pb_fence(vl->entries[i].buf, fence); - pb_reference(&vl->entries[i].buf, NULL); + buffer_fence(vl->buffers[i], fence); + pb_reference(&vl->buffers[i], NULL); } vl->used = 0; } @@ -166,8 +126,8 @@ pb_validate_destroy(struct pb_validate *vl) { unsigned i; for(i = 0; i < vl->used; ++i) - pb_reference(&vl->entries[i].buf, NULL); - FREE(vl->entries); + pb_reference(&vl->buffers[i], NULL); + FREE(vl->buffers); FREE(vl); } @@ -182,8 +142,8 @@ pb_validate_create() return NULL; vl->size = PB_VALIDATE_INITIAL_SIZE; - vl->entries = (struct pb_validate_entry *)CALLOC(vl->size, sizeof(struct pb_buffer *)); - if(!vl->entries) { + vl->buffers = (struct pb_buffer **)CALLOC(vl->size, sizeof(struct pb_buffer *)); + if(!vl->buffers) { FREE(vl); return NULL; } diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h b/src/gallium/auxiliary/pipebuffer/pb_validate.h index dfb84df1ce..3db1d5330b 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.h +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.h @@ -58,13 +58,7 @@ struct pb_validate; enum pipe_error pb_validate_add_buffer(struct pb_validate *vl, - struct pb_buffer *buf, - unsigned flags); - -enum pipe_error -pb_validate_foreach(struct pb_validate *vl, - enum pipe_error (*callback)(struct pb_buffer *buf, void *data), - void *data); + struct pb_buffer *buf); /** * Validate all buffers for hardware access. @@ -77,7 +71,7 @@ pb_validate_validate(struct pb_validate *vl); /** * Fence all buffers and clear the list. * - * Should be called right after issuing commands to the hardware. + * Should be called right before issuing commands to the hardware. */ void pb_validate_fence(struct pb_validate *vl, diff --git a/src/gallium/auxiliary/pipebuffer/pb_winsys.c b/src/gallium/auxiliary/pipebuffer/pb_winsys.c index 45a883e532..28d137dbc4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_winsys.c +++ b/src/gallium/auxiliary/pipebuffer/pb_winsys.c @@ -30,7 +30,7 @@ * Implementation of client buffer (also designated as "user buffers"), which * are just state-tracker owned data masqueraded as buffers. * - * \author Jose Fonseca + * \author José Fonseca */ @@ -91,24 +91,6 @@ pb_user_buffer_unmap(struct pb_buffer *buf) } -static enum pipe_error -pb_user_buffer_validate(struct pb_buffer *buf, - struct pb_validate *vl, - unsigned flags) -{ - assert(0); - return PIPE_ERROR; -} - - -static void -pb_user_buffer_fence(struct pb_buffer *buf, - struct pipe_fence_handle *fence) -{ - assert(0); -} - - static void pb_user_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, @@ -124,8 +106,6 @@ pb_user_buffer_vtbl = { pb_user_buffer_destroy, pb_user_buffer_map, pb_user_buffer_unmap, - pb_user_buffer_validate, - pb_user_buffer_fence, pb_user_buffer_get_base_buffer }; -- cgit v1.2.3 From d2c2e9316d043ab584794a3524f22776deb4c777 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 12 Dec 2008 16:46:34 +0000 Subject: gallium: avoid mapping same vertex buffer in subsequent frames Quite a few util modules were maintaining a single vertex buffer over multiple frames, and potentially reusing it in subsequent frames. Unfortunately that would force us into syncrhonous rendering as the buffer manager would be forced to wait for the previous rendering to complete prior to allowing the map. This resolves that issue, but requires the state tracker to issue a few new flush() calls at the end of each frame. --- src/gallium/auxiliary/util/u_blit.c | 88 ++++++++++++++++++++++--------- src/gallium/auxiliary/util/u_blit.h | 4 ++ src/gallium/auxiliary/util/u_draw_quad.c | 5 +- src/gallium/auxiliary/util/u_draw_quad.h | 2 +- src/gallium/auxiliary/util/u_gen_mipmap.c | 51 +++++++++++++++--- src/gallium/auxiliary/util/u_gen_mipmap.h | 5 ++ 6 files changed, 120 insertions(+), 35 deletions(-) (limited to 'src/gallium/auxiliary') diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index d28201ac8d..2cef3338b5 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -66,6 +66,8 @@ struct blit_state void *fs; struct pipe_buffer *vbuf; /**< quad vertices */ + unsigned vbuf_slot; + float vertices[4][2][4]; /**< vertex/texcoords for quad */ }; @@ -138,17 +140,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) /* fragment shader */ ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader); - - ctx->vbuf = pipe_buffer_create(pipe->screen, - 32, - PIPE_BUFFER_USAGE_VERTEX, - sizeof(ctx->vertices)); - if (!ctx->vbuf) { - FREE(ctx); - ctx->pipe->delete_fs_state(ctx->pipe, ctx->fs); - ctx->pipe->delete_vs_state(ctx->pipe, ctx->vs); - return NULL; - } + ctx->vbuf = NULL; /* init vertex data that doesn't change */ for (i = 0; i < 4; i++) { @@ -181,15 +173,35 @@ util_destroy_blit(struct blit_state *ctx) } +static unsigned get_next_slot( struct blit_state *ctx ) +{ + const unsigned max_slots = 4096 / sizeof ctx->vertices; + + if (ctx->vbuf_slot >= max_slots) + util_blit_flush( ctx ); + + if (!ctx->vbuf) { + ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, + 32, + PIPE_BUFFER_USAGE_VERTEX, + max_slots * sizeof ctx->vertices); + } + + return ctx->vbuf_slot++ * sizeof ctx->vertices; +} + + + /** * Setup vertex data for the textured quad we'll draw. * Note: y=0=top */ -static void +static unsigned setup_vertex_data(struct blit_state *ctx, float x0, float y0, float x1, float y1, float z) { void *buf; + unsigned offset; ctx->vertices[0][0][0] = x0; ctx->vertices[0][0][1] = y0; @@ -215,12 +227,16 @@ setup_vertex_data(struct blit_state *ctx, ctx->vertices[3][1][0] = 0.0f; ctx->vertices[3][1][1] = 1.0f; + offset = get_next_slot( ctx ); + buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); - memcpy(buf, ctx->vertices, sizeof(ctx->vertices)); + memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices)); pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf); + + return offset; } @@ -228,13 +244,14 @@ setup_vertex_data(struct blit_state *ctx, * Setup vertex data for the textured quad we'll draw. * Note: y=0=top */ -static void +static unsigned setup_vertex_data_tex(struct blit_state *ctx, float x0, float y0, float x1, float y1, float s0, float t0, float s1, float t1, float z) { void *buf; + unsigned offset; ctx->vertices[0][0][0] = x0; ctx->vertices[0][0][1] = y0; @@ -260,12 +277,16 @@ setup_vertex_data_tex(struct blit_state *ctx, ctx->vertices[3][1][0] = s0; ctx->vertices[3][1][1] = t1; + offset = get_next_slot( ctx ); + buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); - memcpy(buf, ctx->vertices, sizeof(ctx->vertices)); + memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices)); pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf); + + return offset; } /** * Copy pixel block from src surface to dst surface. @@ -291,6 +312,7 @@ util_blit_pixels(struct blit_state *ctx, const int srcH = abs(srcY1 - srcY0); const int srcLeft = MIN2(srcX0, srcX1); const int srcTop = MIN2(srcY0, srcY1); + unsigned offset; assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); @@ -398,11 +420,11 @@ util_blit_pixels(struct blit_state *ctx, cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ - setup_vertex_data(ctx, - (float) dstX0, (float) dstY0, - (float) dstX1, (float) dstY1, z); + offset = setup_vertex_data(ctx, + (float) dstX0, (float) dstY0, + (float) dstX1, (float) dstY1, z); - util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, + util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, offset, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ 2); /* attribs/vert */ @@ -421,6 +443,18 @@ util_blit_pixels(struct blit_state *ctx, screen->texture_release(screen, &tex); } + +/* Release vertex buffer at end of frame to avoid synchronous + * rendering. + */ +void util_blit_flush( struct blit_state *ctx ) +{ + pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL); + ctx->vbuf_slot = 0; +} + + + /** * Copy pixel block from src texture to dst surface. * Overlapping regions are acceptable. @@ -442,6 +476,7 @@ util_blit_pixels_tex(struct blit_state *ctx, struct pipe_screen *screen = pipe->screen; struct pipe_framebuffer_state fb; float s0, t0, s1, t1; + unsigned offset; assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); @@ -496,13 +531,14 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ - setup_vertex_data_tex(ctx, - (float) dstX0, (float) dstY0, - (float) dstX1, (float) dstY1, - s0, t0, s1, t1, - z); - - util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, + offset = setup_vertex_data_tex(ctx, + (float) dstX0, (float) dstY0, + (float) dstX1, (float) dstY1, + s0, t0, s1, t1, + z); + + util_draw_vertex_buffer(ctx->pipe, + ctx->vbuf, offset, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ 2); /* attribs/vert */ diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index 308075698f..c35beceda8 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -70,6 +70,10 @@ util_blit_pixels_tex(struct blit_state *ctx, int dstX1, int dstY1, float z, uint filter); +/* Call at end of frame to avoid synchronous rendering. + */ +extern void +util_blit_flush( struct blit_state *ctx ); #ifdef __cplusplus } diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index 8ecae71b64..d7bb74b87b 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -40,6 +40,7 @@ void util_draw_vertex_buffer(struct pipe_context *pipe, struct pipe_buffer *vbuf, + uint offset, uint prim_type, uint num_verts, uint num_attribs) @@ -53,7 +54,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe, /* tell pipe about the vertex buffer */ vbuffer.buffer = vbuf; vbuffer.pitch = num_attribs * 4 * sizeof(float); /* vertex size */ - vbuffer.buffer_offset = 0; + vbuffer.buffer_offset = offset; pipe->set_vertex_buffers(pipe, 1, &vbuffer); /* tell pipe about the vertex attributes */ @@ -124,7 +125,7 @@ util_draw_texquad(struct pipe_context *pipe, v[29] = 1.0; pipe_buffer_unmap(pipe->screen, vbuf); - util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2); + util_draw_vertex_buffer(pipe, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2); } pipe_buffer_reference(pipe->screen, &vbuf, NULL); diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h index ec4862ead3..00d3f5b715 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.h +++ b/src/gallium/auxiliary/util/u_draw_quad.h @@ -37,7 +37,7 @@ struct pipe_buffer; extern void util_draw_vertex_buffer(struct pipe_context *pipe, - struct pipe_buffer *vbuf, + struct pipe_buffer *vbuf, uint offset, uint num_attribs, uint num_verts, uint prim_type); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 9d305ad763..5f395ec6e9 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -69,6 +69,8 @@ struct gen_mipmap_state void *fs; struct pipe_buffer *vbuf; /**< quad vertices */ + unsigned vbuf_slot; + float vertices[4][2][4]; /**< vertex/texcoords for quad */ }; @@ -779,10 +781,28 @@ util_create_gen_mipmap(struct pipe_context *pipe, } -static void +static unsigned get_next_slot( struct gen_mipmap_state *ctx ) +{ + const unsigned max_slots = 4096 / sizeof ctx->vertices; + + if (ctx->vbuf_slot >= max_slots) + util_gen_mipmap_flush( ctx ); + + if (!ctx->vbuf) { + ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, + 32, + PIPE_BUFFER_USAGE_VERTEX, + max_slots * sizeof ctx->vertices); + } + + return ctx->vbuf_slot++ * sizeof ctx->vertices; +} + +static unsigned set_vertex_data(struct gen_mipmap_state *ctx, float width, float height) { void *buf; + unsigned offset; ctx->vertices[0][0][0] = 0.0f; /*x*/ ctx->vertices[0][0][1] = 0.0f; /*y*/ @@ -804,12 +824,16 @@ set_vertex_data(struct gen_mipmap_state *ctx, float width, float height) ctx->vertices[3][1][0] = 0.0f; ctx->vertices[3][1][1] = 1.0f; + offset = get_next_slot( ctx ); + buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); - memcpy(buf, ctx->vertices, sizeof(ctx->vertices)); + memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices)); pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf); + + return offset; } @@ -834,6 +858,17 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) } + +/* Release vertex buffer at end of frame to avoid synchronous + * rendering. + */ +void util_gen_mipmap_flush( struct gen_mipmap_state *ctx ) +{ + pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL); + ctx->vbuf_slot = 0; +} + + /** * Generate mipmap images. It's assumed all needed texture memory is * already allocated. @@ -855,6 +890,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_framebuffer_state fb; uint dstLevel; uint zslice = 0; + uint offset; /* check if we can render in the texture's format */ if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D, @@ -925,10 +961,13 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_sampler_textures(ctx->cso, 1, &pt); /* quad coords in window coords (bypassing clipping, viewport mapping) */ - set_vertex_data(ctx, - (float) pt->width[dstLevel], - (float) pt->height[dstLevel]); - util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, + offset = set_vertex_data(ctx, + (float) pt->width[dstLevel], + (float) pt->height[dstLevel]); + + util_draw_vertex_buffer(ctx->pipe, + ctx->vbuf, + offset, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ 2); /* attribs/vert */ diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h index 3277024f07..54608f9466 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -50,6 +50,11 @@ util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso); extern void util_destroy_gen_mipmap(struct gen_mipmap_state *ctx); +/* Release vertex buffer at end of frame to avoid synchronous + * rendering. + */ +extern void +util_gen_mipmap_flush( struct gen_mipmap_state *ctx ); extern void -- cgit v1.2.3