From a175e15f20b2a231cc9d09099e7b6d8aea6c624e Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 12:34:33 +0900 Subject: gallium: Allow to use a single slab. We often want to use a pool of equally sized buffers, so this makes the slab suballocator a drop-in replacement. --- src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 22 +- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 315 +++++++++++++--------- 2 files changed, 209 insertions(+), 128 deletions(-) diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index b2d2520b67..96f9af3825 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -118,13 +118,21 @@ mm_bufmgr_create_from_buffer(struct pb_buffer *buffer, * Slab sub-allocator. */ struct pb_manager * -pb_slab_manager_create(struct pb_manager *provider, - const struct pb_desc *desc, - size_t smallestSize, - size_t numSizes, - size_t desiredNumBuffers, - size_t maxSlabSize, - size_t pageAlignment); +pb_slab_manager_create(struct pb_manager *provider, + size_t bufSize, + size_t slabSize, + const struct pb_desc *desc); + +/** + * Allow a range of buffer size, by aggregating multiple slabs sub-allocators + * with different bucket sizes. + */ +struct pb_manager * +pb_slab_range_manager_create(struct pb_manager *provider, + size_t minBufSize, + size_t maxBufSize, + size_t slabSize, + const struct pb_desc *desc); /** diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 676e8e29b9..9506ac9ae1 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -70,19 +70,24 @@ struct pb_slab size_t numBuffers; size_t numFree; struct pb_slab_buffer *buffers; - struct pb_slab_size_header *header; + struct pb_slab_manager *mgr; struct pb_buffer *bo; - size_t pageAlignment; void *virtual; }; -struct pb_slab_size_header +struct pb_slab_manager { + struct pb_manager base; + + struct pb_manager *provider; + size_t bufSize; + size_t slabSize; + struct pb_desc desc; + struct list_head slabs; struct list_head freeSlabs; - struct pb_slab_manager *pool; - size_t bufSize; + _glthread_Mutex mutex; }; @@ -90,19 +95,18 @@ struct pb_slab_size_header * The data of this structure remains constant after * initialization and thus needs no mutex protection. */ -struct pb_slab_manager +struct pb_slab_range_manager { struct pb_manager base; + struct pb_manager *provider; + size_t minBufSize; + size_t maxBufSize; struct pb_desc desc; + + unsigned numBuckets; size_t *bucketSizes; - size_t numBuckets; - size_t pageSize; - struct pb_manager *provider; - unsigned pageAlignment; - unsigned maxSlabSize; - unsigned desiredNumBuffers; - struct pb_slab_size_header *headers; + struct pb_manager **buckets; }; @@ -122,8 +126,16 @@ pb_slab_manager(struct pb_manager *mgr) } +static INLINE struct pb_slab_range_manager * +pb_slab_range_manager(struct pb_manager *mgr) +{ + assert(mgr); + return (struct pb_slab_range_manager *)mgr; +} + + /** - * Delete a buffer from the slab header delayed list and put + * Delete a buffer from the slab delayed list and put * it on the slab FREE list. */ static void @@ -131,10 +143,10 @@ pb_slab_buffer_destroy(struct pb_buffer *_buf) { struct pb_slab_buffer *buf = pb_slab_buffer(_buf); struct pb_slab *slab = buf->slab; - struct pb_slab_size_header *header = slab->header; + struct pb_slab_manager *mgr = slab->mgr; struct list_head *list = &buf->head; - _glthread_LOCK_MUTEX(header->mutex); + _glthread_LOCK_MUTEX(mgr->mutex); assert(buf->base.base.refcount == 0); @@ -145,21 +157,21 @@ pb_slab_buffer_destroy(struct pb_buffer *_buf) slab->numFree++; if (slab->head.next == &slab->head) - LIST_ADDTAIL(&slab->head, &header->slabs); + LIST_ADDTAIL(&slab->head, &mgr->slabs); if (slab->numFree == slab->numBuffers) { list = &slab->head; LIST_DEL(list); - LIST_ADDTAIL(list, &header->freeSlabs); + LIST_ADDTAIL(list, &mgr->freeSlabs); } - if (header->slabs.next == &header->slabs || slab->numFree + if (mgr->slabs.next == &mgr->slabs || slab->numFree != slab->numBuffers) { struct list_head *next; - for (list = header->freeSlabs.next, next = list->next; list - != &header->freeSlabs; list = next, next = list->next) { + for (list = mgr->freeSlabs.next, next = list->next; list + != &mgr->freeSlabs; list = next, next = list->next) { slab = LIST_ENTRY(struct pb_slab, list, head); @@ -170,7 +182,7 @@ pb_slab_buffer_destroy(struct pb_buffer *_buf) } } - _glthread_UNLOCK_MUTEX(header->mutex); + _glthread_UNLOCK_MUTEX(mgr->mutex); } @@ -217,15 +229,13 @@ pb_slab_buffer_vtbl = { static enum pipe_error -pb_slab_create(struct pb_slab_size_header *header) +pb_slab_create(struct pb_slab_manager *mgr) { - struct pb_slab_manager *pool = header->pool; - size_t size = header->bufSize * pool->desiredNumBuffers; struct pb_slab *slab; struct pb_slab_buffer *buf; - size_t numBuffers; - int ret; + unsigned numBuffers; unsigned i; + enum pipe_error ret; slab = CALLOC_STRUCT(pb_slab); if (!slab) @@ -236,22 +246,23 @@ pb_slab_create(struct pb_slab_size_header *header) * to efficiently reuse slabs. */ - size = (size <= pool->maxSlabSize) ? size : pool->maxSlabSize; - size = (size + pool->pageSize - 1) & ~(pool->pageSize - 1); - - slab->bo = pool->provider->create_buffer(pool->provider, size, &pool->desc); - if(!slab->bo) + slab->bo = mgr->provider->create_buffer(mgr->provider, mgr->slabSize, &mgr->desc); + if(!slab->bo) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto out_err0; + } slab->virtual = pb_map(slab->bo, - PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE); - if(!slab->virtual) + PIPE_BUFFER_USAGE_CPU_READ | + PIPE_BUFFER_USAGE_CPU_WRITE); + if(!slab->virtual) { + ret = PIPE_ERROR_OUT_OF_MEMORY; goto out_err1; + } pb_unmap(slab->bo); - numBuffers = slab->bo->base.size / header->bufSize; + numBuffers = slab->bo->base.size / mgr->bufSize; slab->buffers = CALLOC(numBuffers, sizeof(*slab->buffers)); if (!slab->buffers) { @@ -263,17 +274,17 @@ pb_slab_create(struct pb_slab_size_header *header) LIST_INITHEAD(&slab->freeBuffers); slab->numBuffers = numBuffers; slab->numFree = 0; - slab->header = header; + slab->mgr = mgr; buf = slab->buffers; for (i=0; i < numBuffers; ++i) { buf->base.base.refcount = 0; - buf->base.base.size = header->bufSize; + buf->base.base.size = mgr->bufSize; buf->base.base.alignment = 0; buf->base.base.usage = 0; buf->base.vtbl = &pb_slab_buffer_vtbl; buf->slab = slab; - buf->start = i* header->bufSize; + buf->start = i* mgr->bufSize; buf->mapCount = 0; _glthread_INIT_COND(buf->event); LIST_ADDTAIL(&buf->head, &slab->freeBuffers); @@ -281,7 +292,7 @@ pb_slab_create(struct pb_slab_size_header *header) buf++; } - LIST_ADDTAIL(&slab->head, &header->slabs); + LIST_ADDTAIL(&slab->head, &mgr->slabs); return PIPE_OK; @@ -293,51 +304,55 @@ out_err0: } +static int +check_alignment(size_t requested, size_t provided) +{ + return requested <= provided && (provided % requested) == 0; +} + + static struct pb_buffer * -pb_slab_manager_create_buffer(struct pb_manager *_pool, +pb_slab_manager_create_buffer(struct pb_manager *_mgr, size_t size, const struct pb_desc *desc) { - struct pb_slab_manager *pool = pb_slab_manager(_pool); - struct pb_slab_size_header *header; - unsigned i; + struct pb_slab_manager *mgr = pb_slab_manager(_mgr); static struct pb_slab_buffer *buf; struct pb_slab *slab; struct list_head *list; int count = DRI_SLABPOOL_ALLOC_RETRIES; - /* - * FIXME: Check for compatibility. - */ - - header = pool->headers; - for (i=0; inumBuckets; ++i) { - if (header->bufSize >= size) - break; - header++; - } - - if (i >= pool->numBuckets) - /* Fall back to allocate a buffer object directly from the provider. */ - return pool->provider->create_buffer(pool->provider, size, desc); - + /* check size */ + assert(size == mgr->bufSize); + if(size != mgr->bufSize) + return NULL; + + /* check if we can provide the requested alignment */ + assert(check_alignment(desc->alignment, mgr->desc.alignment)); + if(!check_alignment(desc->alignment, mgr->desc.alignment)) + return NULL; + assert(check_alignment(desc->alignment, mgr->bufSize)); + if(!check_alignment(desc->alignment, mgr->bufSize)) + return NULL; - _glthread_LOCK_MUTEX(header->mutex); - while (header->slabs.next == &header->slabs && count > 0) { - if (header->slabs.next != &header->slabs) + /* 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(header->mutex); + _glthread_UNLOCK_MUTEX(mgr->mutex); if (count != DRI_SLABPOOL_ALLOC_RETRIES) util_time_sleep(1); - _glthread_LOCK_MUTEX(header->mutex); - (void) pb_slab_create(header); + _glthread_LOCK_MUTEX(mgr->mutex); + (void) pb_slab_create(mgr); count--; } - list = header->slabs.next; - if (list == &header->slabs) { - _glthread_UNLOCK_MUTEX(header->mutex); + list = mgr->slabs.next; + if (list == &mgr->slabs) { + _glthread_UNLOCK_MUTEX(mgr->mutex); return NULL; } slab = LIST_ENTRY(struct pb_slab, list, head); @@ -347,83 +362,141 @@ pb_slab_manager_create_buffer(struct pb_manager *_pool, list = slab->freeBuffers.next; LIST_DELINIT(list); - _glthread_UNLOCK_MUTEX(header->mutex); + _glthread_UNLOCK_MUTEX(mgr->mutex); buf = LIST_ENTRY(struct pb_slab_buffer, list, head); + ++buf->base.base.refcount; + buf->base.base.alignment = desc->alignment; + buf->base.base.usage = desc->usage; + return &buf->base; } static void -pb_slab_manager_destroy(struct pb_manager *_pool) +pb_slab_manager_destroy(struct pb_manager *_mgr) { - struct pb_slab_manager *pool = pb_slab_manager(_pool); + struct pb_slab_manager *mgr = pb_slab_manager(_mgr); - FREE(pool->headers); - FREE(pool->bucketSizes); - FREE(pool); + /* TODO: cleanup all allocated buffers */ + FREE(mgr); } struct pb_manager * -pb_slab_manager_create(struct pb_manager *provider, - const struct pb_desc *desc, - size_t smallestSize, - size_t numSizes, - size_t desiredNumBuffers, - size_t maxSlabSize, - size_t pageAlignment) +pb_slab_manager_create(struct pb_manager *provider, + size_t bufSize, + size_t slabSize, + const struct pb_desc *desc) +{ + struct pb_slab_manager *mgr; + + mgr = CALLOC_STRUCT(pb_slab_manager); + if (!mgr) + return NULL; + + mgr->base.destroy = pb_slab_manager_destroy; + mgr->base.create_buffer = pb_slab_manager_create_buffer; + + mgr->provider = provider; + mgr->bufSize = bufSize; + mgr->slabSize = slabSize; + mgr->desc = *desc; + + LIST_INITHEAD(&mgr->slabs); + LIST_INITHEAD(&mgr->freeSlabs); + + _glthread_INIT_MUTEX(mgr->mutex); + + return &mgr->base; +} + + +static struct pb_buffer * +pb_slab_range_manager_create_buffer(struct pb_manager *_mgr, + size_t size, + const struct pb_desc *desc) { - struct pb_slab_manager *pool; - size_t i; + struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); + size_t bufSize; + unsigned i; - pool = CALLOC_STRUCT(pb_slab_manager); - if (!pool) + bufSize = mgr->minBufSize; + for (i = 0; i < mgr->numBuckets; ++i) { + if(bufSize >= size) + return mgr->buckets[i]->create_buffer(mgr->buckets[i], size, desc); + bufSize *= 2; + } + + /* Fall back to allocate a buffer object directly from the provider. */ + return mgr->provider->create_buffer(mgr->provider, size, desc); +} + + +static void +pb_slab_range_manager_destroy(struct pb_manager *_mgr) +{ + struct pb_slab_range_manager *mgr = pb_slab_range_manager(_mgr); + unsigned i; + + for (i = 0; i < mgr->numBuckets; ++i) + mgr->buckets[i]->destroy(mgr->buckets[i]); + FREE(mgr->buckets); + FREE(mgr->bucketSizes); + FREE(mgr); +} + + +struct pb_manager * +pb_slab_range_manager_create(struct pb_manager *provider, + size_t minBufSize, + size_t maxBufSize, + size_t slabSize, + const struct pb_desc *desc) +{ + struct pb_slab_range_manager *mgr; + size_t bufSize; + unsigned i; + + mgr = CALLOC_STRUCT(pb_slab_range_manager); + if (!mgr) goto out_err0; - pool->bucketSizes = CALLOC(numSizes, sizeof(*pool->bucketSizes)); - if (!pool->bucketSizes) - goto out_err1; + mgr->base.destroy = pb_slab_range_manager_destroy; + mgr->base.create_buffer = pb_slab_range_manager_create_buffer; - pool->headers = CALLOC(numSizes, sizeof(*pool->headers)); - if (!pool->headers) - goto out_err2; - - pool->desc = *desc; - pool->numBuckets = numSizes; -#ifdef WIN32 - pool->pageSize = 4096; -#else - pool->pageSize = getpagesize(); -#endif - pool->provider = provider; - pool->pageAlignment = pageAlignment; - pool->maxSlabSize = maxSlabSize; - pool->desiredNumBuffers = desiredNumBuffers; - - for (i=0; inumBuckets; ++i) { - struct pb_slab_size_header *header = &pool->headers[i]; - - pool->bucketSizes[i] = (smallestSize << i); - - _glthread_INIT_MUTEX(header->mutex); - - LIST_INITHEAD(&header->slabs); - LIST_INITHEAD(&header->freeSlabs); - - header->pool = pool; - header->bufSize = (smallestSize << i); + mgr->provider = provider; + mgr->minBufSize = minBufSize; + mgr->maxBufSize = maxBufSize; + + mgr->numBuckets = 1; + bufSize = minBufSize; + while(bufSize < maxBufSize) { + bufSize *= 2; + ++mgr->numBuckets; } + + mgr->buckets = CALLOC(mgr->numBuckets, sizeof(*mgr->buckets)); + if (!mgr->buckets) + goto out_err1; - pool->base.destroy = pb_slab_manager_destroy; - pool->base.create_buffer = pb_slab_manager_create_buffer; + bufSize = minBufSize; + for (i = 0; i < mgr->numBuckets; ++i) { + mgr->buckets[i] = pb_slab_manager_create(provider, bufSize, slabSize, desc); + if(!mgr->buckets[i]) + goto out_err2; + bufSize *= 2; + } - return &pool->base; + return &mgr->base; out_err2: - FREE(pool->bucketSizes); + for (i = 0; i < mgr->numBuckets; ++i) + if(mgr->buckets[i]) + mgr->buckets[i]->destroy(mgr->buckets[i]); + FREE(mgr->buckets); out_err1: - FREE(pool); + FREE(mgr); out_err0: return NULL; } -- cgit v1.2.3 From 0b995b44e5a02dd4a3abdb6b2a0821a32e597e7c Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 12:35:00 +0900 Subject: gallium: Fix mismatching prototypes. --- src/gallium/auxiliary/util/u_time.c | 2 +- src/gallium/auxiliary/util/u_time.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index e6c0b19ff6..04f85c42ef 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -133,7 +133,7 @@ util_time_timeout(const struct util_time *start, #ifdef WIN32 -void util_time_usleep(unsigned usecs) +void util_time_sleep(unsigned usecs) { LONGLONG start, curr, end; diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index 32035cceb5..2133958446 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -87,7 +87,7 @@ util_time_timeout(const struct util_time *start, #ifndef WIN32 #define util_time_sleep usleep #else -int +void util_time_sleep(unsigned usecs); #endif -- cgit v1.2.3 From 50bbbbe581edd6b8d4fe9f8ba7f134e17dc80a0b Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 14:58:32 +0900 Subject: gallium: Remove middle of scope declarations. --- src/gallium/drivers/softpipe/sp_quad_fs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index 8dbdbe5764..625d0f9b48 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -77,7 +77,8 @@ shade_quad( struct quad_shade_stage *qss = quad_shade_stage( qs ); struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = &qss->machine; - + boolean z_written; + /* Consts do not require 16 byte alignment. */ machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT]; @@ -89,7 +90,7 @@ shade_quad( quad ); /* store outputs */ - boolean z_written = FALSE; + z_written = FALSE; { const ubyte *sem_name = softpipe->fs->info.output_semantic_name; const ubyte *sem_index = softpipe->fs->info.output_semantic_index; -- cgit v1.2.3 From d005befcb9e191ae90619fbdd3c37e262ae3b03e Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 15:40:35 +0900 Subject: gallium: Less confusing interface for timeouts. --- src/gallium/auxiliary/util/u_time.c | 6 +++--- src/gallium/auxiliary/util/u_time.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c index 04f85c42ef..01112ebe5a 100644 --- a/src/gallium/auxiliary/util/u_time.c +++ b/src/gallium/auxiliary/util/u_time.c @@ -120,15 +120,15 @@ util_time_compare(const struct util_time *t1, } -int +boolean util_time_timeout(const struct util_time *start, const struct util_time *end, const struct util_time *curr) { if(util_time_compare(start, end) <= 0) - return util_time_compare(start, curr) <= 0 && util_time_compare(curr, end) < 0; + return !(util_time_compare(start, curr) <= 0 && util_time_compare(curr, end) < 0); else - return util_time_compare(start, curr) <= 0 || util_time_compare(curr, end) < 0; + return !(util_time_compare(start, curr) <= 0 || util_time_compare(curr, end) < 0); } diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h index 2133958446..c8836c137f 100644 --- a/src/gallium/auxiliary/util/u_time.h +++ b/src/gallium/auxiliary/util/u_time.h @@ -77,9 +77,9 @@ util_time_diff(const struct util_time *t1, const struct util_time *t2); /** - * Returns zero when the timeout expires, non zero otherwise. + * Returns non-zero when the timeout expires. */ -int +boolean util_time_timeout(const struct util_time *start, const struct util_time *end, const struct util_time *curr); -- cgit v1.2.3 From 95aeeb6d746e57473116ef4d72c05330902f68a5 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 15:41:08 +0900 Subject: gallium: Several fixes to buffer caching. --- src/gallium/auxiliary/pipebuffer/pb_buffer.h | 11 ++++ src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 67 +++++++++++++++++----- src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 15 ++--- 3 files changed, 68 insertions(+), 25 deletions(-) diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index 4b09c80b2a..49705cb862 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -192,6 +192,17 @@ pb_reference(struct pb_buffer **dst, } +/** + * Utility function to check whether a requested alignment is consistent with + * the provided alignment or not. + */ +static INLINE int +pb_check_alignment(size_t requested, size_t provided) +{ + return requested <= provided && (provided % requested) == 0; +} + + /** * Malloc-based buffer to store data that can't be used by the graphics * hardware. diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 06de0bb6c3..543fd51253 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -136,7 +136,7 @@ _pb_cache_buffer_list_check_free(struct pb_cache_manager *mgr) while(curr != &mgr->delayed) { buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); - if(util_time_timeout(&buf->start, &buf->end, &now) != 0) + if(!util_time_timeout(&buf->start, &buf->end, &now)) break; _pb_cache_buffer_destroy(buf); @@ -202,6 +202,24 @@ pb_cache_buffer_vtbl = { }; +static INLINE boolean +pb_cache_is_buffer_compat(struct pb_cache_buffer *buf, + size_t size, + const struct pb_desc *desc) +{ + /* TODO: be more lenient with size */ + if(buf->base.base.size != size) + return FALSE; + + if(!pb_check_alignment(desc->alignment, buf->base.base.alignment)) + return FALSE; + + /* XXX: check usage too? */ + + return TRUE; +} + + static struct pb_buffer * pb_cache_manager_create_buffer(struct pb_manager *_mgr, size_t size, @@ -209,29 +227,45 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr, { struct pb_cache_manager *mgr = pb_cache_manager(_mgr); struct pb_cache_buffer *buf; + struct pb_cache_buffer *curr_buf; struct list_head *curr, *next; struct util_time now; - util_time_get(&now); + _glthread_LOCK_MUTEX(mgr->mutex); + + buf = NULL; curr = mgr->delayed.next; next = curr->next; + + /* search in the expired buffers, freeing them in the process */ + util_time_get(&now); while(curr != &mgr->delayed) { - buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); - - if(buf->base.base.size == size && - buf->base.base.alignment >= desc->alignment && - (buf->base.base.alignment % desc->alignment) == 0 && - /* buf->base.base.usage == usage */ 1) { - ++buf->base.base.refcount; - return &buf->base; - } - - if(util_time_timeout(&buf->start, &buf->end, &now) != 0) - _pb_cache_buffer_destroy(buf); + curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); + if(!buf && pb_cache_is_buffer_compat(curr_buf, size, desc)) + buf = curr_buf; + else if(util_time_timeout(&curr_buf->start, &curr_buf->end, &now)) + _pb_cache_buffer_destroy(curr_buf); + curr = next; + next = curr->next; + } + /* keep searching in the hot buffers */ + while(!buf && curr != &mgr->delayed) { + curr_buf = LIST_ENTRY(struct pb_cache_buffer, curr, head); + if(pb_cache_is_buffer_compat(curr_buf, size, desc)) + buf = curr_buf; curr = next; next = curr->next; } + + if(buf) { + LIST_DEL(&buf->head); + _glthread_UNLOCK_MUTEX(mgr->mutex); + ++buf->base.base.refcount; + return &buf->base; + } + + _glthread_UNLOCK_MUTEX(mgr->mutex); buf = CALLOC_STRUCT(pb_cache_buffer); if(!buf) @@ -243,6 +277,11 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr, return NULL; } + assert(buf->buffer->base.refcount >= 1); + assert(pb_check_alignment(desc->alignment, buf->buffer->base.alignment)); + assert((buf->buffer->base.usage & desc->usage) == desc->usage); + assert(buf->buffer->base.size >= size); + buf->base.base.refcount = 1; buf->base.base.alignment = buf->buffer->base.alignment; buf->base.base.usage = buf->buffer->base.usage; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 9506ac9ae1..b931455056 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -304,13 +304,6 @@ out_err0: } -static int -check_alignment(size_t requested, size_t provided) -{ - return requested <= provided && (provided % requested) == 0; -} - - static struct pb_buffer * pb_slab_manager_create_buffer(struct pb_manager *_mgr, size_t size, @@ -328,11 +321,11 @@ pb_slab_manager_create_buffer(struct pb_manager *_mgr, return NULL; /* check if we can provide the requested alignment */ - assert(check_alignment(desc->alignment, mgr->desc.alignment)); - if(!check_alignment(desc->alignment, mgr->desc.alignment)) + assert(pb_check_alignment(desc->alignment, mgr->desc.alignment)); + if(!pb_check_alignment(desc->alignment, mgr->desc.alignment)) return NULL; - assert(check_alignment(desc->alignment, mgr->bufSize)); - if(!check_alignment(desc->alignment, mgr->bufSize)) + assert(pb_check_alignment(desc->alignment, mgr->bufSize)); + if(!pb_check_alignment(desc->alignment, mgr->bufSize)) return NULL; /* XXX: check for compatible buffer usage too? */ -- cgit v1.2.3 From 7619240cc0c24d3ad4d2424e65110c0326a12dad Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 15:58:14 +0900 Subject: gallium: Fix seg fault (James Vogt). --- src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index bffca5b244..9d809e2f9b 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 José Fonseca + * \author José Fonseca */ @@ -101,7 +101,8 @@ fenced_bufmgr_destroy(struct pb_manager *mgr) fenced_buffer_list_destroy(fenced_mgr->fenced_list); - fenced_mgr->provider->destroy(fenced_mgr->provider); + if(fenced_mgr->provider) + fenced_mgr->provider->destroy(fenced_mgr->provider); FREE(fenced_mgr); } @@ -113,6 +114,9 @@ fenced_bufmgr_create(struct pb_manager *provider, { struct fenced_pb_manager *fenced_mgr; + if(!provider) + return NULL; + fenced_mgr = (struct fenced_pb_manager *)CALLOC(1, sizeof(*fenced_mgr)); if (!fenced_mgr) return NULL; -- cgit v1.2.3 From 3c4f1ba5a2edefd69b2c47abaf534fb3af3f259d Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 17:08:10 +0900 Subject: gallium: Eliminate stdio file usage. Remove unused stuff. --- src/gallium/auxiliary/tgsi/util/tgsi_dump.c | 334 +++------------------------- src/gallium/auxiliary/tgsi/util/tgsi_dump.h | 10 - 2 files changed, 34 insertions(+), 310 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c index ff6a2c4194..26bfc2051f 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c @@ -25,8 +25,6 @@ * **************************************************************************/ -#include - #include "pipe/p_debug.h" #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" @@ -35,196 +33,28 @@ #include "tgsi_parse.h" #include "tgsi_build.h" -struct gen_dump -{ - unsigned tabs; - void (* write)( - struct gen_dump *dump, - const void *data, - unsigned size ); -}; - -struct text_dump -{ - struct gen_dump base; - char *text; - unsigned length; - unsigned capacity; -}; - -static void -_text_dump_write( - struct gen_dump *dump, - const void *data, - unsigned size ) -{ - struct text_dump *td = (struct text_dump *) dump; - unsigned new_length = td->length + size; - - if( new_length >= td->capacity ) { - unsigned new_capacity = td->capacity; - - do { - if( new_capacity == 0 ) { - new_capacity = 256; - } - else { - new_capacity *= 2; - } - } while( new_length >= new_capacity ); - td->text = (char *) REALLOC( - td->text, - td->capacity, - new_capacity ); - td->capacity = new_capacity; - } - memcpy( - &td->text[td->length], - data, - size ); - td->length = new_length; - td->text[td->length] = '\0'; -} - -struct file_dump -{ - struct gen_dump base; - FILE *file; -}; - -static void -_file_dump_write( - struct gen_dump *dump, - const void *data, - unsigned size ) -{ - struct file_dump *fd = (struct file_dump *) dump; - -#if 0 - fwrite( data, 1, size, fd->file ); -#else - { - unsigned i; - - for (i = 0; i < size; i++ ) { - fprintf( fd->file, "%c", ((const char *) data)[i] ); - } - } -#endif -} - -static void -gen_dump_str( - struct gen_dump *dump, - const char *str ) -{ - unsigned i; - size_t len = strlen( str ); - - for (i = 0; i < len; i++) { - dump->write( dump, &str[i], 1 ); - if (str[i] == '\n') { - unsigned i; - - for (i = 0; i < dump->tabs; i++) { - dump->write( dump, " ", 4 ); - } - } - } -} - -static void -gen_dump_chr( - struct gen_dump *dump, - const char chr ) -{ - dump->write( dump, &chr, 1 ); -} - -static void -gen_dump_uix( - struct gen_dump *dump, - const unsigned ui ) -{ - char str[36]; - - util_snprintf( str, sizeof(str), "0x%x", ui ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_uid( - struct gen_dump *dump, - const unsigned ui ) -{ - char str[16]; - - util_snprintf( str, sizeof(str), "%u", ui ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_sid( - struct gen_dump *dump, - const int si ) -{ - char str[16]; - - util_snprintf( str, sizeof(str), "%d", si ); - gen_dump_str( dump, str ); -} - static void -gen_dump_flt( - struct gen_dump *dump, - const float flt ) -{ - char str[48]; - - util_snprintf( str, sizeof(str), "%10.4f", flt ); - gen_dump_str( dump, str ); -} - -static void -gen_dump_enum( - struct gen_dump *dump, +dump_enum( const unsigned e, const char **enums, const unsigned enums_count ) { if (e >= enums_count) { - gen_dump_uid( dump, e ); + debug_printf( "%u", e ); } else { - gen_dump_str( dump, enums[e] ); + debug_printf( "%s", enums[e] ); } } -static void -gen_dump_tab( - struct gen_dump *dump ) -{ - ++dump->tabs; -} - -static void -gen_dump_untab( - struct gen_dump *dump ) -{ - assert( dump->tabs > 0 ); - - --dump->tabs; -} - -#define TXT(S) gen_dump_str( dump, S ) -#define CHR(C) gen_dump_chr( dump, C ) -#define UIX(I) gen_dump_uix( dump, I ) -#define UID(I) gen_dump_uid( dump, I ) -#define SID(I) gen_dump_sid( dump, I ) -#define FLT(F) gen_dump_flt( dump, F ) -#define TAB() gen_dump_tab( dump ) -#define UNT() gen_dump_untab( dump ) -#define ENM(E,ENUMS) gen_dump_enum( dump, E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) +#define EOL() debug_printf( "\n" ) +#define TXT(S) debug_printf( "%s", S ) +#define CHR(C) debug_printf( "%c", C ) +#define UIX(I) debug_printf( "0x%x", I ) +#define UID(I) debug_printf( "%u", I ) +#define SID(I) debug_printf( "%d", I ) +#define FLT(F) debug_printf( "%10.4f", F ) +#define ENM(E,ENUMS) dump_enum( E, ENUMS, sizeof( ENUMS ) / sizeof( *ENUMS ) ) static const char *TGSI_PROCESSOR_TYPES[] = { @@ -711,7 +541,6 @@ static const char *TGSI_MODULATES[] = static void dump_declaration_short( - struct gen_dump *dump, struct tgsi_full_declaration *decl ) { TXT( "\nDCL " ); @@ -765,7 +594,6 @@ dump_declaration_short( static void dump_declaration_verbose( - struct gen_dump *dump, struct tgsi_full_declaration *decl, unsigned ignored, unsigned deflt, @@ -803,7 +631,7 @@ dump_declaration_verbose( UIX( decl->Declaration.Padding ); } - CHR( '\n' ); + EOL(); switch( decl->Declaration.Declare ) { case TGSI_DECLARE_RANGE: TXT( "\nFirst: " ); @@ -822,7 +650,7 @@ dump_declaration_verbose( } if( decl->Declaration.Interpolate ) { - CHR( '\n' ); + EOL(); TXT( "\nInterpolate: " ); ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES ); if( ignored ) { @@ -832,7 +660,7 @@ dump_declaration_verbose( } if( decl->Declaration.Semantic ) { - CHR( '\n' ); + EOL(); TXT( "\nSemanticName : " ); ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS ); TXT( "\nSemanticIndex: " ); @@ -846,7 +674,6 @@ dump_declaration_verbose( static void dump_immediate_short( - struct gen_dump *dump, struct tgsi_full_immediate *imm ) { unsigned i; @@ -874,7 +701,6 @@ dump_immediate_short( static void dump_immediate_verbose( - struct gen_dump *dump, struct tgsi_full_immediate *imm, unsigned ignored ) { @@ -888,7 +714,7 @@ dump_immediate_verbose( } for( i = 0; i < imm->Immediate.Size - 1; i++ ) { - CHR( '\n' ); + EOL(); switch( imm->Immediate.DataType ) { case TGSI_IMM_FLOAT32: TXT( "\nFloat: " ); @@ -903,14 +729,13 @@ dump_immediate_verbose( static void dump_instruction_short( - struct gen_dump *dump, struct tgsi_full_instruction *inst, unsigned instno ) { unsigned i; boolean first_reg = TRUE; - CHR( '\n' ); + EOL(); UID( instno ); CHR( ':' ); ENM( inst->Instruction.Opcode, TGSI_OPCODES_SHORT ); @@ -1042,7 +867,6 @@ dump_instruction_short( static void dump_instruction_verbose( - struct gen_dump *dump, struct tgsi_full_instruction *inst, unsigned ignored, unsigned deflt, @@ -1070,7 +894,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_instruction_ext_nv( inst->InstructionExtNv, fi->InstructionExtNv ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( inst->InstructionExtNv.Type, TGSI_INSTRUCTION_EXTS ); if( deflt || fi->InstructionExtNv.Precision != inst->InstructionExtNv.Precision ) { @@ -1124,7 +948,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_instruction_ext_label( inst->InstructionExtLabel, fi->InstructionExtLabel ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( inst->InstructionExtLabel.Type, TGSI_INSTRUCTION_EXTS ); if( deflt || fi->InstructionExtLabel.Label != inst->InstructionExtLabel.Label ) { @@ -1142,7 +966,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_instruction_ext_texture( inst->InstructionExtTexture, fi->InstructionExtTexture ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( inst->InstructionExtTexture.Type, TGSI_INSTRUCTION_EXTS ); if( deflt || fi->InstructionExtTexture.Texture != inst->InstructionExtTexture.Texture ) { @@ -1163,7 +987,7 @@ dump_instruction_verbose( struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; struct tgsi_full_dst_register *fd = &fi->FullDstRegisters[i]; - CHR( '\n' ); + EOL(); TXT( "\nFile : " ); ENM( dst->DstRegister.File, TGSI_FILES ); if( deflt || fd->DstRegister.WriteMask != dst->DstRegister.WriteMask ) { @@ -1194,7 +1018,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_dst_register_ext_concode( dst->DstRegisterExtConcode, fd->DstRegisterExtConcode ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( dst->DstRegisterExtConcode.Type, TGSI_DST_REGISTER_EXTS ); if( deflt || fd->DstRegisterExtConcode.CondMask != dst->DstRegisterExtConcode.CondMask ) { @@ -1232,7 +1056,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_dst_register_ext_modulate( dst->DstRegisterExtModulate, fd->DstRegisterExtModulate ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( dst->DstRegisterExtModulate.Type, TGSI_DST_REGISTER_EXTS ); if( deflt || fd->DstRegisterExtModulate.Modulate != dst->DstRegisterExtModulate.Modulate ) { @@ -1254,7 +1078,7 @@ dump_instruction_verbose( struct tgsi_full_src_register *src = &inst->FullSrcRegisters[i]; struct tgsi_full_src_register *fs = &fi->FullSrcRegisters[i]; - CHR( '\n' ); + EOL(); TXT( "\nFile : "); ENM( src->SrcRegister.File, TGSI_FILES ); if( deflt || fs->SrcRegister.SwizzleX != src->SrcRegister.SwizzleX ) { @@ -1299,7 +1123,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_src_register_ext_swz( src->SrcRegisterExtSwz, fs->SrcRegisterExtSwz ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( src->SrcRegisterExtSwz.Type, TGSI_SRC_REGISTER_EXTS ); if( deflt || fs->SrcRegisterExtSwz.ExtSwizzleX != src->SrcRegisterExtSwz.ExtSwizzleX ) { @@ -1345,7 +1169,7 @@ dump_instruction_verbose( } if( deflt || tgsi_compare_src_register_ext_mod( src->SrcRegisterExtMod, fs->SrcRegisterExtMod ) ) { - CHR( '\n' ); + EOL(); TXT( "\nType : " ); ENM( src->SrcRegisterExtMod.Type, TGSI_SRC_REGISTER_EXTS ); if( deflt || fs->SrcRegisterExtMod.Complement != src->SrcRegisterExtMod.Complement ) { @@ -1380,9 +1204,8 @@ dump_instruction_verbose( } } -static void -dump_gen( - struct gen_dump *dump, +void +tgsi_dump( const struct tgsi_token *tokens, unsigned flags ) { @@ -1394,16 +1217,16 @@ dump_gen( unsigned deflt = !(flags & TGSI_DUMP_NO_DEFAULT); unsigned instno = 0; - dump->tabs = 0; - - /* sanity check */ + /* sanity checks */ assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_CONT], "OPCODE_CONT") == 0); + assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); + assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); tgsi_parse_init( &parse, tokens ); TXT( "tgsi-dump begin -----------------" ); - CHR( '\n' ); + EOL(); ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES_SHORT ); UID( parse.FullVersion.Version.MajorVersion ); CHR( '.' ); @@ -1414,7 +1237,7 @@ dump_gen( UID( parse.FullVersion.Version.MajorVersion ); TXT( "\nMinorVersion: " ); UID( parse.FullVersion.Version.MinorVersion ); - CHR( '\n' ); + EOL(); TXT( "\nHeaderSize: " ); UID( parse.FullHeader.Header.HeaderSize ); @@ -1422,7 +1245,7 @@ dump_gen( UID( parse.FullHeader.Header.BodySize ); TXT( "\nProcessor : " ); ENM( parse.FullHeader.Processor.Processor, TGSI_PROCESSOR_TYPES ); - CHR( '\n' ); + EOL(); } fi = tgsi_default_full_instruction(); @@ -1434,19 +1257,16 @@ dump_gen( switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: dump_declaration_short( - dump, &parse.FullToken.FullDeclaration ); break; case TGSI_TOKEN_TYPE_IMMEDIATE: dump_immediate_short( - dump, &parse.FullToken.FullImmediate ); break; case TGSI_TOKEN_TYPE_INSTRUCTION: dump_instruction_short( - dump, &parse.FullToken.FullInstruction, instno ); instno++; @@ -1471,7 +1291,6 @@ dump_gen( switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: dump_declaration_verbose( - dump, &parse.FullToken.FullDeclaration, ignored, deflt, @@ -1480,14 +1299,12 @@ dump_gen( case TGSI_TOKEN_TYPE_IMMEDIATE: dump_immediate_verbose( - dump, &parse.FullToken.FullImmediate, ignored ); break; case TGSI_TOKEN_TYPE_INSTRUCTION: dump_instruction_verbose( - dump, &parse.FullToken.FullInstruction, ignored, deflt, @@ -1498,7 +1315,7 @@ dump_gen( assert( 0 ); } - CHR( '\n' ); + EOL(); } } @@ -1506,86 +1323,3 @@ dump_gen( tgsi_parse_free( &parse ); } - - -static void -sanity_checks(void) -{ - assert(strcmp(TGSI_OPCODES[TGSI_OPCODE_END], "OPCODE_END") == 0); - assert(strcmp(TGSI_OPCODES_SHORT[TGSI_OPCODE_END], "END") == 0); -} - - -void -tgsi_dump( - const struct tgsi_token *tokens, - unsigned flags ) -{ - struct file_dump dump; - - sanity_checks(); - - dump.base.write = _file_dump_write; -#if 0 - { - static unsigned counter = 0; - char buffer[64]; - sprintf( buffer, "tgsi-dump-%.4u.txt", counter++ ); - dump.file = fopen( buffer, "wt" ); - } -#else - dump.file = stderr; -#endif - - dump_gen( - &dump.base, - tokens, - flags ); - -#if 0 - fclose( dump.file ); -#endif -} - -void -tgsi_dump_str( - char **str, - const struct tgsi_token *tokens, - unsigned flags ) -{ - struct text_dump dump; - - dump.base.write = _text_dump_write; - dump.text = NULL; - dump.length = 0; - dump.capacity = 0; - - dump_gen( - &dump.base, - tokens, - flags ); - - *str = dump.text; -} - - -void tgsi_debug_dump( struct tgsi_token *tokens ) -{ - char *str, *p; - - tgsi_dump_str( &str, tokens, 0 ); - - p = str; - while (p != NULL) - { - char *end = strchr( p, '\n' ); - if (end != NULL) - { - *end++ = '\0'; - } - debug_printf( "%s\n", p ); - p = end; - } - - FREE( str ); -} diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h index 51d79a0362..beb0155d56 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.h @@ -14,16 +14,6 @@ tgsi_dump( const struct tgsi_token *tokens, unsigned flags ); -void -tgsi_dump_str( - char **str, - const struct tgsi_token *tokens, - unsigned flags ); - -/* Dump to debug_printf() - */ -void tgsi_debug_dump( struct tgsi_token *tokens ); - #if defined __cplusplus } #endif -- cgit v1.2.3 From a68f664124592829a3b715388e6cfa43f82900c8 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 15 Apr 2008 18:11:47 +0900 Subject: gallium: Cache one line worth of debug output on windows. The windbg connection seems synchronous, so this speeds up when printing little text at a time (e.g., tgsi output). --- src/gallium/auxiliary/util/p_debug.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index f9366467cd..c195f61820 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -59,10 +59,15 @@ void _debug_vprintf(const char *format, va_list ap) #ifdef WIN32 #ifndef WINCE /* EngDebugPrint does not handle float point arguments, so we need to use - * our own vsnprintf implementation */ - char buf[512 + 1]; - util_vsnprintf(buf, sizeof(buf), format, ap); - _EngDebugPrint("%s", buf); + * our own vsnprintf implementation. It is also very slow, so buffer until + * we find a newline. */ + 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')) { + _EngDebugPrint("%s", buf); + buf[0] = '\0'; + } #else /* TODO: Implement debug print for WINCE */ #endif -- cgit v1.2.3 From 6a26a9c58cc38ff636ee88ce01fed40eea500fc0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:28:41 +0100 Subject: draw: fetch_shade_pipeline needs to translate to hw vertex format (from get_vertex_info) --- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 158 +++++++++++++-------- 1 file changed, 102 insertions(+), 56 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 04b3d2c4cf..557cd43f5b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -36,52 +36,60 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; + const ubyte *input_buf[2]; + struct { - const ubyte *ptr; - unsigned pitch; - void (*fetch)( const void *from, float *attrib); - void (*emit)( const float *attrib, float **out ); - } fetch[PIPE_MAX_ATTRIBS]; + const ubyte **input_buf; + unsigned input_offset; + unsigned output_offset; + + void (*emit)( const float *attrib, void *ptr ); + } translate[PIPE_MAX_ATTRIBS]; + unsigned nr_translate; - unsigned nr_fetch; unsigned pipeline_vertex_size; unsigned hw_vertex_size; unsigned prim; }; -#if 0 + +static void emit_NULL( const float *attrib, + void *ptr ) +{ +} + static void emit_R32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out) += 1; + float *out = (float *)ptr; + out[0] = attrib[0]; } static void emit_R32G32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out) += 2; + float *out = (float *)ptr; + out[0] = attrib[0]; + out[1] = attrib[1]; } static void emit_R32G32B32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out) += 3; + float *out = (float *)ptr; + out[0] = attrib[0]; + out[1] = attrib[1]; + out[2] = attrib[2]; } -#endif + static void emit_R32G32B32A32_FLOAT( const float *attrib, - float **out ) + void *ptr ) { - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out)[3] = attrib[3]; - (*out) += 4; + float *out = (float *)ptr; + out[0] = attrib[0]; + out[1] = attrib[1]; + out[2] = attrib[2]; + out[3] = attrib[3]; } static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, @@ -89,9 +97,10 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; - unsigned i, nr = 0; + unsigned i; boolean ok; const struct vertex_info *vinfo; + unsigned dst_offset; fpme->prim = prim; @@ -100,33 +109,63 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, assert(0); return; } + /* Must do this after set_primitive() above: */ vinfo = draw->render->get_vertex_info(draw->render); - /* Need to look at vertex shader inputs (we know it is a - * passthrough shader, so these define the outputs too). If we - * were running a shader, we'd still be looking at the inputs at - * this point. - */ - for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - enum pipe_format format = draw->vertex_element[i].src_format; - - fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset); - fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch; - fpme->fetch[nr].fetch = draw_get_fetch_func( format ); + /* In passthrough mode, need to translate from vertex shader + * outputs to hw vertices. + */ + dst_offset = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned src_offset = (sizeof(struct vertex_header) + + vinfo->src_index[i] * 4 * sizeof(float) ); + + + + switch (vinfo->emit[i]) { + case EMIT_4F: + fpme->translate[i].emit = emit_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + fpme->translate[i].emit = emit_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + fpme->translate[i].emit = emit_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + fpme->translate[i].emit = emit_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + fpme->translate[i].emit = emit_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + default: + assert(0); + fpme->translate[i].emit = emit_NULL; + emit_sz = 0; + break; + } - /* Always do this -- somewhat redundant... - */ - fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT; - nr++; + fpme->translate[i].input_buf = &fpme->input_buf[src_buffer]; + fpme->translate[i].input_offset = src_offset; + fpme->translate[i].output_offset = dst_offset; + dst_offset += emit_sz; } - fpme->nr_fetch = nr; + fpme->nr_translate = vinfo->num_attribs; + fpme->hw_vertex_size = vinfo->size * 4; + //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; fpme->hw_vertex_size = vinfo->size * 4; @@ -171,7 +210,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, } else { unsigned i, j; void *hw_verts; - float *out; + char *out_buf; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ @@ -185,22 +224,29 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, return; } - out = (float *)hw_verts; + out_buf = (char *)hw_verts; + fpme->input_buf[0] = (const ubyte *)pipeline_verts; + fpme->input_buf[1] = (const ubyte *)&fpme->draw->rasterizer->point_size; + for (i = 0; i < fetch_count; i++) { - struct vertex_header *header = - (struct vertex_header*)(pipeline_verts + (fpme->pipeline_vertex_size * i)); - for (j = 0; j < fpme->nr_fetch; j++) { - float *attrib = header->data[j]; + for (j = 0; j < fpme->nr_translate; j++) { + + const float *attrib = (const float *)( (*fpme->translate[i].input_buf) + + fpme->translate[i].input_offset ); + + char *dest = out_buf + fpme->translate[i].output_offset; + /*debug_printf("emiting [%f, %f, %f, %f]\n", attrib[0], attrib[1], attrib[2], attrib[3]);*/ - fpme->fetch[j].emit(attrib, &out); + + fpme->translate[j].emit(attrib, dest); } + + fpme->input_buf[0] += fpme->pipeline_vertex_size; } - /* XXX: Draw arrays path to avoid re-emitting index list again and - * again. - */ + draw->render->draw(draw->render, draw_elts, draw_count); -- cgit v1.2.3 From c81bbab6f6c0413996799800cac6fb49a698e765 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:35:29 +0100 Subject: gallium: add a generic vertex (or other) buffer translation module --- src/gallium/auxiliary/translate/Makefile | 12 + src/gallium/auxiliary/translate/SConscript | 9 + src/gallium/auxiliary/translate/translate.h | 82 +++ .../auxiliary/translate/translate_generic.c | 630 +++++++++++++++++++++ 4 files changed, 733 insertions(+) create mode 100644 src/gallium/auxiliary/translate/Makefile create mode 100644 src/gallium/auxiliary/translate/SConscript create mode 100644 src/gallium/auxiliary/translate/translate.h create mode 100644 src/gallium/auxiliary/translate/translate_generic.c diff --git a/src/gallium/auxiliary/translate/Makefile b/src/gallium/auxiliary/translate/Makefile new file mode 100644 index 0000000000..051987bb7e --- /dev/null +++ b/src/gallium/auxiliary/translate/Makefile @@ -0,0 +1,12 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = translate + +C_SOURCES = \ + translate_generic.c + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript new file mode 100644 index 0000000000..947b9438cb --- /dev/null +++ b/src/gallium/auxiliary/translate/SConscript @@ -0,0 +1,9 @@ +Import('*') + +cso_cache = env.ConvenienceLibrary( + target = 'translate', + source = [ + 'translate_generic.c', + ]) + +auxiliaries.insert(0, translate) diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h new file mode 100644 index 0000000000..ac6bc7088b --- /dev/null +++ b/src/gallium/auxiliary/translate/translate.h @@ -0,0 +1,82 @@ +/* + * Copyright 2008 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on 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 THEIR 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. + */ + + +/** + * Vertex fetch/store/convert code. This functionality is used in two places: + * 1. Vertex fetch/convert - to grab vertex data from incoming vertex + * arrays and convert to format needed by vertex shaders. + * 2. Vertex store/emit - to convert simple float[][4] vertex attributes + * (which is the organization used throughout the draw/prim pipeline) to + * hardware-specific formats and emit into hardware vertex buffers. + * + * + * Authors: + * Keith Whitwell + */ + +#ifndef _TRANSLATE_H +#define _TRANSLATE_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" + +struct translate_element +{ + enum pipe_format input_format; + unsigned input_buffer; + unsigned input_offset; + + enum pipe_format output_format; + unsigned output_offset; +}; + + +struct translate { + void (*destroy)( struct translate * ); + + void (*set_buffer)( struct translate *, + unsigned i, + const void *ptr, + unsigned stride ); + + void (*run_elts)( struct translate *, + const unsigned *elts, + unsigned count, + void *output_buffer); +}; + + + +struct translate *translate_sse2_create( unsigned output_stride, + const struct translate_element *elements, + unsigned nr_elements ); + +struct translate *translate_generic_create( unsigned output_stride, + const struct translate_element *elements, + unsigned nr_elements ); + + +#endif diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c new file mode 100644 index 0000000000..643f6430c5 --- /dev/null +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -0,0 +1,630 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "translate.h" + + +#define DRAW_DBG 0 + +typedef void (*fetch_func)(const void *ptr, float *attrib); +typedef void (*emit_func)(const float *attrib, void *ptr); + + + +struct translate_generic { + struct translate translate; + + struct { + fetch_func fetch; + unsigned buffer; + unsigned input_offset; + + emit_func emit; + unsigned output_offset; + + char *input_ptr; + unsigned input_stride; + + } attrib[PIPE_MAX_ATTRIBS]; + + unsigned nr_attrib; + unsigned output_stride; +}; + + +static struct translate_generic *translate_generic( struct translate *translate ) +{ + return (struct translate_generic *)translate; +} + +/** + * Fetch a float[4] vertex attribute from memory, doing format/type + * conversion as needed. + * + * This is probably needed/dupliocated elsewhere, eg format + * conversion, texture sampling etc. + */ +#define ATTRIB( NAME, SZ, TYPE, FROM, TO ) \ +static void \ +fetch_##NAME(const void *ptr, float *attrib) \ +{ \ + const float defaults[4] = { 0,0,0,1 }; \ + int i; \ + \ + for (i = 0; i < SZ; i++) { \ + attrib[i] = FROM(i); \ + } \ + \ + for (; i < 4; i++) { \ + attrib[i] = defaults[i]; \ + } \ +} \ + \ +static void \ +emit_##NAME(const float *attrib, void *ptr) \ +{ \ + unsigned i; \ + TYPE *out = (TYPE *)ptr; \ + \ + for (i = 0; i < SZ; i++) { \ + out[i] = TO(attrib[i]); \ + } \ +} + + +#define FROM_64_FLOAT(i) ((float) ((double *) ptr)[i]) +#define FROM_32_FLOAT(i) (((float *) ptr)[i]) + +#define FROM_8_USCALED(i) ((float) ((unsigned char *) ptr)[i]) +#define FROM_16_USCALED(i) ((float) ((unsigned short *) ptr)[i]) +#define FROM_32_USCALED(i) ((float) ((unsigned int *) ptr)[i]) + +#define FROM_8_SSCALED(i) ((float) ((char *) ptr)[i]) +#define FROM_16_SSCALED(i) ((float) ((short *) ptr)[i]) +#define FROM_32_SSCALED(i) ((float) ((int *) ptr)[i]) + +#define FROM_8_UNORM(i) ((float) ((unsigned char *) ptr)[i] / 255.0f) +#define FROM_16_UNORM(i) ((float) ((unsigned short *) ptr)[i] / 65535.0f) +#define FROM_32_UNORM(i) ((float) ((unsigned int *) ptr)[i] / 4294967295.0f) + +#define FROM_8_SNORM(i) ((float) ((char *) ptr)[i] / 127.0f) +#define FROM_16_SNORM(i) ((float) ((short *) ptr)[i] / 32767.0f) +#define FROM_32_SNORM(i) ((float) ((int *) ptr)[i] / 2147483647.0f) + +#define TO_64_FLOAT(f) ((double) f) +#define TO_32_FLOAT(f) (f) + +#define TO_8_USCALED(f) ((unsigned char) f) +#define TO_16_USCALED(f) ((unsigned short) f) +#define TO_32_USCALED(f) ((unsigned int) f) + +#define TO_8_SSCALED(f) ((char) f) +#define TO_16_SSCALED(f) ((short) f) +#define TO_32_SSCALED(f) ((int) f) + +#define TO_8_UNORM(f) ((unsigned char) (f * 255.0f)) +#define TO_16_UNORM(f) ((unsigned short) (f * 65535.0f)) +#define TO_32_UNORM(f) ((unsigned int) (f * 4294967295.0f)) + +#define TO_8_SNORM(f) ((char) (f * 127.0f)) +#define TO_16_SNORM(f) ((short) (f * 32767.0f)) +#define TO_32_SNORM(f) ((int) (f * 2147483647.0f)) + + + +ATTRIB( R64G64B64A64_FLOAT, 4, double, FROM_64_FLOAT, TO_64_FLOAT ) +ATTRIB( R64G64B64_FLOAT, 3, double, FROM_64_FLOAT, TO_64_FLOAT ) +ATTRIB( R64G64_FLOAT, 2, double, FROM_64_FLOAT, TO_64_FLOAT ) +ATTRIB( R64_FLOAT, 1, double, FROM_64_FLOAT, TO_64_FLOAT ) + +ATTRIB( R32G32B32A32_FLOAT, 4, float, FROM_32_FLOAT, TO_32_FLOAT ) +ATTRIB( R32G32B32_FLOAT, 3, float, FROM_32_FLOAT, TO_32_FLOAT ) +ATTRIB( R32G32_FLOAT, 2, float, FROM_32_FLOAT, TO_32_FLOAT ) +ATTRIB( R32_FLOAT, 1, float, FROM_32_FLOAT, TO_32_FLOAT ) + +ATTRIB( R32G32B32A32_USCALED, 4, unsigned, FROM_32_USCALED, TO_32_USCALED ) +ATTRIB( R32G32B32_USCALED, 3, unsigned, FROM_32_USCALED, TO_32_USCALED ) +ATTRIB( R32G32_USCALED, 2, unsigned, FROM_32_USCALED, TO_32_USCALED ) +ATTRIB( R32_USCALED, 1, unsigned, FROM_32_USCALED, TO_32_USCALED ) + +ATTRIB( R32G32B32A32_SSCALED, 4, int, FROM_32_SSCALED, TO_32_SSCALED ) +ATTRIB( R32G32B32_SSCALED, 3, int, FROM_32_SSCALED, TO_32_SSCALED ) +ATTRIB( R32G32_SSCALED, 2, int, FROM_32_SSCALED, TO_32_SSCALED ) +ATTRIB( R32_SSCALED, 1, int, FROM_32_SSCALED, TO_32_SSCALED ) + +ATTRIB( R32G32B32A32_UNORM, 4, unsigned, FROM_32_UNORM, TO_32_UNORM ) +ATTRIB( R32G32B32_UNORM, 3, unsigned, FROM_32_UNORM, TO_32_UNORM ) +ATTRIB( R32G32_UNORM, 2, unsigned, FROM_32_UNORM, TO_32_UNORM ) +ATTRIB( R32_UNORM, 1, unsigned, FROM_32_UNORM, TO_32_UNORM ) + +ATTRIB( R32G32B32A32_SNORM, 4, int, FROM_32_SNORM, TO_32_SNORM ) +ATTRIB( R32G32B32_SNORM, 3, int, FROM_32_SNORM, TO_32_SNORM ) +ATTRIB( R32G32_SNORM, 2, int, FROM_32_SNORM, TO_32_SNORM ) +ATTRIB( R32_SNORM, 1, int, FROM_32_SNORM, TO_32_SNORM ) + +ATTRIB( R16G16B16A16_USCALED, 4, ushort, FROM_16_USCALED, TO_16_USCALED ) +ATTRIB( R16G16B16_USCALED, 3, ushort, FROM_16_USCALED, TO_16_USCALED ) +ATTRIB( R16G16_USCALED, 2, ushort, FROM_16_USCALED, TO_16_USCALED ) +ATTRIB( R16_USCALED, 1, ushort, FROM_16_USCALED, TO_16_USCALED ) + +ATTRIB( R16G16B16A16_SSCALED, 4, short, FROM_16_SSCALED, TO_16_SSCALED ) +ATTRIB( R16G16B16_SSCALED, 3, short, FROM_16_SSCALED, TO_16_SSCALED ) +ATTRIB( R16G16_SSCALED, 2, short, FROM_16_SSCALED, TO_16_SSCALED ) +ATTRIB( R16_SSCALED, 1, short, FROM_16_SSCALED, TO_16_SSCALED ) + +ATTRIB( R16G16B16A16_UNORM, 4, ushort, FROM_16_UNORM, TO_16_UNORM ) +ATTRIB( R16G16B16_UNORM, 3, ushort, FROM_16_UNORM, TO_16_UNORM ) +ATTRIB( R16G16_UNORM, 2, ushort, FROM_16_UNORM, TO_16_UNORM ) +ATTRIB( R16_UNORM, 1, ushort, FROM_16_UNORM, TO_16_UNORM ) + +ATTRIB( R16G16B16A16_SNORM, 4, short, FROM_16_SNORM, TO_16_SNORM ) +ATTRIB( R16G16B16_SNORM, 3, short, FROM_16_SNORM, TO_16_SNORM ) +ATTRIB( R16G16_SNORM, 2, short, FROM_16_SNORM, TO_16_SNORM ) +ATTRIB( R16_SNORM, 1, short, FROM_16_SNORM, TO_16_SNORM ) + +ATTRIB( R8G8B8A8_USCALED, 4, ubyte, FROM_8_USCALED, TO_8_USCALED ) +ATTRIB( R8G8B8_USCALED, 3, ubyte, FROM_8_USCALED, TO_8_USCALED ) +ATTRIB( R8G8_USCALED, 2, ubyte, FROM_8_USCALED, TO_8_USCALED ) +ATTRIB( R8_USCALED, 1, ubyte, FROM_8_USCALED, TO_8_USCALED ) + +ATTRIB( R8G8B8A8_SSCALED, 4, char, FROM_8_SSCALED, TO_8_SSCALED ) +ATTRIB( R8G8B8_SSCALED, 3, char, FROM_8_SSCALED, TO_8_SSCALED ) +ATTRIB( R8G8_SSCALED, 2, char, FROM_8_SSCALED, TO_8_SSCALED ) +ATTRIB( R8_SSCALED, 1, char, FROM_8_SSCALED, TO_8_SSCALED ) + +ATTRIB( R8G8B8A8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) +ATTRIB( R8G8B8_UNORM, 3, ubyte, FROM_8_UNORM, TO_8_UNORM ) +ATTRIB( R8G8_UNORM, 2, ubyte, FROM_8_UNORM, TO_8_UNORM ) +ATTRIB( R8_UNORM, 1, ubyte, FROM_8_UNORM, TO_8_UNORM ) + +ATTRIB( R8G8B8A8_SNORM, 4, char, FROM_8_SNORM, TO_8_SNORM ) +ATTRIB( R8G8B8_SNORM, 3, char, FROM_8_SNORM, TO_8_SNORM ) +ATTRIB( R8G8_SNORM, 2, char, FROM_8_SNORM, TO_8_SNORM ) +ATTRIB( R8_SNORM, 1, char, FROM_8_SNORM, TO_8_SNORM ) + +ATTRIB( A8R8G8B8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) +//ATTRIB( R8G8B8A8_UNORM, 4, ubyte, FROM_8_UNORM, TO_8_UNORM ) + + + +static void +fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) +{ + attrib[2] = FROM_8_UNORM(0); + attrib[1] = FROM_8_UNORM(1); + attrib[0] = FROM_8_UNORM(2); + attrib[3] = FROM_8_UNORM(3); +} + +static void +emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) +{ + ubyte *out = (ubyte *)ptr; + out[2] = TO_8_UNORM(out[0]); + out[1] = TO_8_UNORM(out[1]); + out[0] = TO_8_UNORM(out[2]); + out[3] = TO_8_UNORM(out[3]); +} + +static void +fetch_NULL( const void *ptr, float *attrib ) +{ + attrib[0] = 0; + attrib[1] = 0; + attrib[2] = 0; + attrib[3] = 1; +} + +static void +emit_NULL( const float *attrib, void *ptr ) +{ + /* do nothing is the only sensible option */ +} + +static fetch_func get_fetch_func( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return fetch_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return fetch_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return fetch_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return fetch_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return fetch_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return fetch_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return fetch_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return fetch_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return fetch_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return fetch_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return fetch_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return fetch_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return fetch_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return fetch_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return fetch_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return fetch_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return fetch_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return fetch_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return fetch_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return fetch_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return fetch_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return fetch_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return fetch_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return fetch_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return fetch_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return fetch_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return fetch_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return fetch_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return fetch_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return fetch_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return fetch_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return fetch_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return fetch_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return fetch_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return fetch_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return fetch_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return fetch_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return fetch_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return fetch_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return fetch_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return fetch_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return fetch_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return fetch_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return fetch_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return fetch_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return fetch_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return fetch_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return fetch_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return fetch_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return fetch_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return fetch_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return fetch_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return fetch_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return fetch_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return fetch_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return fetch_R8G8B8A8_SSCALED; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + return fetch_A8R8G8B8_UNORM; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + return fetch_B8G8R8A8_UNORM; + + default: + assert(0); + return fetch_NULL; + } +} + + + + +static emit_func get_emit_func( enum pipe_format format ) +{ + switch (format) { + case PIPE_FORMAT_R64_FLOAT: + return emit_R64_FLOAT; + case PIPE_FORMAT_R64G64_FLOAT: + return emit_R64G64_FLOAT; + case PIPE_FORMAT_R64G64B64_FLOAT: + return emit_R64G64B64_FLOAT; + case PIPE_FORMAT_R64G64B64A64_FLOAT: + return emit_R64G64B64A64_FLOAT; + + case PIPE_FORMAT_R32_FLOAT: + return emit_R32_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return emit_R32G32_FLOAT; + case PIPE_FORMAT_R32G32B32_FLOAT: + return emit_R32G32B32_FLOAT; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return emit_R32G32B32A32_FLOAT; + + case PIPE_FORMAT_R32_UNORM: + return emit_R32_UNORM; + case PIPE_FORMAT_R32G32_UNORM: + return emit_R32G32_UNORM; + case PIPE_FORMAT_R32G32B32_UNORM: + return emit_R32G32B32_UNORM; + case PIPE_FORMAT_R32G32B32A32_UNORM: + return emit_R32G32B32A32_UNORM; + + case PIPE_FORMAT_R32_USCALED: + return emit_R32_USCALED; + case PIPE_FORMAT_R32G32_USCALED: + return emit_R32G32_USCALED; + case PIPE_FORMAT_R32G32B32_USCALED: + return emit_R32G32B32_USCALED; + case PIPE_FORMAT_R32G32B32A32_USCALED: + return emit_R32G32B32A32_USCALED; + + case PIPE_FORMAT_R32_SNORM: + return emit_R32_SNORM; + case PIPE_FORMAT_R32G32_SNORM: + return emit_R32G32_SNORM; + case PIPE_FORMAT_R32G32B32_SNORM: + return emit_R32G32B32_SNORM; + case PIPE_FORMAT_R32G32B32A32_SNORM: + return emit_R32G32B32A32_SNORM; + + case PIPE_FORMAT_R32_SSCALED: + return emit_R32_SSCALED; + case PIPE_FORMAT_R32G32_SSCALED: + return emit_R32G32_SSCALED; + case PIPE_FORMAT_R32G32B32_SSCALED: + return emit_R32G32B32_SSCALED; + case PIPE_FORMAT_R32G32B32A32_SSCALED: + return emit_R32G32B32A32_SSCALED; + + case PIPE_FORMAT_R16_UNORM: + return emit_R16_UNORM; + case PIPE_FORMAT_R16G16_UNORM: + return emit_R16G16_UNORM; + case PIPE_FORMAT_R16G16B16_UNORM: + return emit_R16G16B16_UNORM; + case PIPE_FORMAT_R16G16B16A16_UNORM: + return emit_R16G16B16A16_UNORM; + + case PIPE_FORMAT_R16_USCALED: + return emit_R16_USCALED; + case PIPE_FORMAT_R16G16_USCALED: + return emit_R16G16_USCALED; + case PIPE_FORMAT_R16G16B16_USCALED: + return emit_R16G16B16_USCALED; + case PIPE_FORMAT_R16G16B16A16_USCALED: + return emit_R16G16B16A16_USCALED; + + case PIPE_FORMAT_R16_SNORM: + return emit_R16_SNORM; + case PIPE_FORMAT_R16G16_SNORM: + return emit_R16G16_SNORM; + case PIPE_FORMAT_R16G16B16_SNORM: + return emit_R16G16B16_SNORM; + case PIPE_FORMAT_R16G16B16A16_SNORM: + return emit_R16G16B16A16_SNORM; + + case PIPE_FORMAT_R16_SSCALED: + return emit_R16_SSCALED; + case PIPE_FORMAT_R16G16_SSCALED: + return emit_R16G16_SSCALED; + case PIPE_FORMAT_R16G16B16_SSCALED: + return emit_R16G16B16_SSCALED; + case PIPE_FORMAT_R16G16B16A16_SSCALED: + return emit_R16G16B16A16_SSCALED; + + case PIPE_FORMAT_R8_UNORM: + return emit_R8_UNORM; + case PIPE_FORMAT_R8G8_UNORM: + return emit_R8G8_UNORM; + case PIPE_FORMAT_R8G8B8_UNORM: + return emit_R8G8B8_UNORM; + case PIPE_FORMAT_R8G8B8A8_UNORM: + return emit_R8G8B8A8_UNORM; + + case PIPE_FORMAT_R8_USCALED: + return emit_R8_USCALED; + case PIPE_FORMAT_R8G8_USCALED: + return emit_R8G8_USCALED; + case PIPE_FORMAT_R8G8B8_USCALED: + return emit_R8G8B8_USCALED; + case PIPE_FORMAT_R8G8B8A8_USCALED: + return emit_R8G8B8A8_USCALED; + + case PIPE_FORMAT_R8_SNORM: + return emit_R8_SNORM; + case PIPE_FORMAT_R8G8_SNORM: + return emit_R8G8_SNORM; + case PIPE_FORMAT_R8G8B8_SNORM: + return emit_R8G8B8_SNORM; + case PIPE_FORMAT_R8G8B8A8_SNORM: + return emit_R8G8B8A8_SNORM; + + case PIPE_FORMAT_R8_SSCALED: + return emit_R8_SSCALED; + case PIPE_FORMAT_R8G8_SSCALED: + return emit_R8G8_SSCALED; + case PIPE_FORMAT_R8G8B8_SSCALED: + return emit_R8G8B8_SSCALED; + case PIPE_FORMAT_R8G8B8A8_SSCALED: + return emit_R8G8B8A8_SSCALED; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + return emit_A8R8G8B8_UNORM; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + return emit_B8G8R8A8_UNORM; + + default: + assert(0); + return emit_NULL; + } +} + + + +/** + * Fetch vertex attributes for 'count' vertices. + */ +static void generic_run_elts( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ) +{ + struct translate_generic *tg = translate_generic(translate); + char *vert = output_buffer; + unsigned nr_attrs = tg->nr_attrib; + unsigned attr; + unsigned i; + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + unsigned elt = *elts++; + + for (attr = 0; attr < nr_attrs; attr++) { + float data[4]; + + const char *src = (tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * elt); + + char *dst = (vert + + tg->attrib[attr].output_offset); + + tg->attrib[attr].fetch( src, data ); + tg->attrib[attr].emit( data, dst ); + } + + vert += tg->output_stride; + } +} + + + +static void generic_set_buffer( struct translate *translate, + unsigned buf, + const void *ptr, + unsigned stride ) +{ + struct translate_generic *tg = translate_generic(translate); + unsigned i; + + for (i = 0; i < tg->nr_attrib; i++) { + if (tg->attrib[i].buffer == buf) { + tg->attrib[i].input_ptr = ((char *)ptr + + tg->attrib[i].input_offset); + tg->attrib[i].input_stride = stride; + } + } +} + + +static void generic_destroy( struct translate *translate ) +{ + FREE(translate); +} + +struct translate *translate_generic_create( unsigned output_stride, + const struct translate_element *elements, + unsigned nr_elements ) +{ + struct translate_generic *tg = CALLOC_STRUCT(translate_generic); + unsigned i; + + if (tg == NULL) + return NULL; + + tg->translate.destroy = generic_destroy; + tg->translate.set_buffer = generic_set_buffer; + tg->translate.run_elts = generic_run_elts; + + for (i = 0; i < nr_elements; i++) { + tg->attrib[i].fetch = get_fetch_func(elements[i].input_format); + tg->attrib[i].buffer = elements[i].input_buffer; + tg->attrib[i].input_offset = elements[i].input_offset; + + tg->attrib[i].emit = get_emit_func(elements[i].output_format); + tg->attrib[i].output_offset = elements[i].output_offset; + } + + tg->nr_attrib = nr_elements; + + + return &tg->translate; +} -- cgit v1.2.3 From 59f68f36c4ad37496e3ed5d7d3142e3ae35dd351 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:40:16 +0100 Subject: translate: typo in emit_B8G8R8A8_UNORM --- src/gallium/auxiliary/translate/translate_generic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 643f6430c5..7e75ba8365 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -231,10 +231,10 @@ static void emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) { ubyte *out = (ubyte *)ptr; - out[2] = TO_8_UNORM(out[0]); - out[1] = TO_8_UNORM(out[1]); - out[0] = TO_8_UNORM(out[2]); - out[3] = TO_8_UNORM(out[3]); + out[2] = TO_8_UNORM(attrib[0]); + out[1] = TO_8_UNORM(attrib[1]); + out[0] = TO_8_UNORM(attrib[2]); + out[3] = TO_8_UNORM(attrib[3]); } static void -- cgit v1.2.3 From 7eb6f130a1dfb8179ff371eb4e75b47d6ee45d2a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:44:39 +0100 Subject: draw: fix first glitch in vertex emit --- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 557cd43f5b..889cab700c 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -92,6 +92,16 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib, out[3] = attrib[3]; } +static void +emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) +{ + ubyte *out = (ubyte *)ptr; + out[2] = float_to_ubyte(attrib[0]); + out[1] = float_to_ubyte(attrib[1]); + out[0] = float_to_ubyte(attrib[2]); + out[3] = float_to_ubyte(attrib[3]); +} + static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned prim ) { @@ -150,6 +160,9 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, src_buffer = 1; src_offset = 0; break; + case EMIT_4UB: + fpme->translate[i].emit = emit_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); default: assert(0); fpme->translate[i].emit = emit_NULL; @@ -232,10 +245,10 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, for (j = 0; j < fpme->nr_translate; j++) { - const float *attrib = (const float *)( (*fpme->translate[i].input_buf) + - fpme->translate[i].input_offset ); + const float *attrib = (const float *)( (*fpme->translate[j].input_buf) + + fpme->translate[j].input_offset ); - char *dest = out_buf + fpme->translate[i].output_offset; + char *dest = out_buf + fpme->translate[j].output_offset; /*debug_printf("emiting [%f, %f, %f, %f]\n", attrib[0], attrib[1], -- cgit v1.2.3 From 8cac6f3fcf9d6c08959efc20f8fce9eddbdcd0ef Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 14:52:56 +0100 Subject: draw: increment output vertex properly --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 889cab700c..75bbcc8d41 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -250,14 +250,16 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, char *dest = out_buf + fpme->translate[j].output_offset; - /*debug_printf("emiting [%f, %f, %f, %f]\n", - attrib[0], attrib[1], - attrib[2], attrib[3]);*/ + if (0) + debug_printf("emiting [%f, %f, %f, %f]\n", + attrib[0], attrib[1], + attrib[2], attrib[3]); fpme->translate[j].emit(attrib, dest); } fpme->input_buf[0] += fpme->pipeline_vertex_size; + out_buf += fpme->hw_vertex_size; } draw->render->draw(draw->render, -- cgit v1.2.3 From 08861688d3ca7a798345747a549597a52dcb6f98 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 15:07:50 +0100 Subject: gallium: add translate directory --- configs/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/default b/configs/default index f0146c50ce..462e06d770 100644 --- a/configs/default +++ b/configs/default @@ -68,7 +68,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos # Gallium directories and -GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util sct +GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util sct translate GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) -- cgit v1.2.3 From a5a7dc24ba2dcf9bbdd73709c4c182e324bdc3a5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 15 Apr 2008 19:14:31 +0100 Subject: gallium: Switch one vertex path over to new translate module Will eventually do this for all instances where we are converting vertices from one format to another. --- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 146 +++++++-------------- src/gallium/auxiliary/translate/translate.h | 36 ++++- .../auxiliary/translate/translate_generic.c | 66 ++++++++-- 3 files changed, 128 insertions(+), 120 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 75bbcc8d41..2d83e11940 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -31,77 +31,20 @@ #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "translate/translate.h" + struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - const ubyte *input_buf[2]; - - struct { - const ubyte **input_buf; - unsigned input_offset; - unsigned output_offset; - - void (*emit)( const float *attrib, void *ptr ); - } translate[PIPE_MAX_ATTRIBS]; - unsigned nr_translate; + struct translate *translate; unsigned pipeline_vertex_size; - unsigned hw_vertex_size; unsigned prim; }; -static void emit_NULL( const float *attrib, - void *ptr ) -{ -} - -static void emit_R32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; -} - -static void emit_R32G32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; - out[1] = attrib[1]; -} - -static void emit_R32G32B32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; - out[1] = attrib[1]; - out[2] = attrib[2]; -} - -static void emit_R32G32B32A32_FLOAT( const float *attrib, - void *ptr ) -{ - float *out = (float *)ptr; - out[0] = attrib[0]; - out[1] = attrib[1]; - out[2] = attrib[2]; - out[3] = attrib[3]; -} - -static void -emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) -{ - ubyte *out = (ubyte *)ptr; - out[2] = float_to_ubyte(attrib[0]); - out[1] = float_to_ubyte(attrib[1]); - out[0] = float_to_ubyte(attrib[2]); - out[3] = float_to_ubyte(attrib[3]); -} - static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned prim ) { @@ -111,6 +54,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, boolean ok; const struct vertex_info *vinfo; unsigned dst_offset; + struct translate_key hw_key; fpme->prim = prim; @@ -132,6 +76,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, for (i = 0; i < vinfo->num_attribs; i++) { unsigned emit_sz = 0; unsigned src_buffer = 0; + unsigned output_format; unsigned src_offset = (sizeof(struct vertex_header) + vinfo->src_index[i] * 4 * sizeof(float) ); @@ -139,49 +84,64 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, switch (vinfo->emit[i]) { case EMIT_4F: - fpme->translate[i].emit = emit_R32G32B32A32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; emit_sz = 4 * sizeof(float); break; case EMIT_3F: - fpme->translate[i].emit = emit_R32G32B32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32_FLOAT; emit_sz = 3 * sizeof(float); break; case EMIT_2F: - fpme->translate[i].emit = emit_R32G32_FLOAT; + output_format = PIPE_FORMAT_R32G32_FLOAT; emit_sz = 2 * sizeof(float); break; case EMIT_1F: - fpme->translate[i].emit = emit_R32_FLOAT; + output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); break; case EMIT_1F_PSIZE: - fpme->translate[i].emit = emit_R32_FLOAT; + output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); src_buffer = 1; src_offset = 0; break; case EMIT_4UB: - fpme->translate[i].emit = emit_B8G8R8A8_UNORM; + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; emit_sz = 4 * sizeof(ubyte); default: assert(0); - fpme->translate[i].emit = emit_NULL; + output_format = PIPE_FORMAT_NONE; emit_sz = 0; break; } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; - fpme->translate[i].input_buf = &fpme->input_buf[src_buffer]; - fpme->translate[i].input_offset = src_offset; - fpme->translate[i].output_offset = dst_offset; dst_offset += emit_sz; } - fpme->nr_translate = vinfo->num_attribs; - fpme->hw_vertex_size = vinfo->size * 4; + hw_key.nr_elements = vinfo->num_attribs; + hw_key.output_stride = vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!fpme->translate || + memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (fpme->translate) + fpme->translate->release(fpme->translate); + + fpme->translate = translate_generic_create( &hw_key ); + } + + //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; - fpme->hw_vertex_size = vinfo->size * 4; } @@ -221,46 +181,34 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw_elts, draw_count ); } else { - unsigned i, j; + struct translate *translate = fpme->translate; void *hw_verts; - char *out_buf; /* XXX: need to flush to get prim_vbuf.c to release its allocation?? */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); hw_verts = draw->render->allocate_vertices(draw->render, - (ushort)fpme->hw_vertex_size, + (ushort)fpme->translate->key.output_stride, (ushort)fetch_count); if (!hw_verts) { assert(0); return; } - out_buf = (char *)hw_verts; - fpme->input_buf[0] = (const ubyte *)pipeline_verts; - fpme->input_buf[1] = (const ubyte *)&fpme->draw->rasterizer->point_size; - - for (i = 0; i < fetch_count; i++) { - - for (j = 0; j < fpme->nr_translate; j++) { + translate->set_buffer(translate, + 0, + pipeline_verts, + fpme->pipeline_vertex_size ); - const float *attrib = (const float *)( (*fpme->translate[j].input_buf) + - fpme->translate[j].input_offset ); + translate->set_buffer(translate, + 1, + &fpme->draw->rasterizer->point_size, + 0); - char *dest = out_buf + fpme->translate[j].output_offset; - - if (0) - debug_printf("emiting [%f, %f, %f, %f]\n", - attrib[0], attrib[1], - attrib[2], attrib[3]); - - fpme->translate[j].emit(attrib, dest); - } - - fpme->input_buf[0] += fpme->pipeline_vertex_size; - out_buf += fpme->hw_vertex_size; - } + translate->run( translate, + 0, fetch_count, + hw_verts ); draw->render->draw(draw->render, draw_elts, @@ -268,7 +216,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw->render->release_vertices(draw->render, hw_verts, - fpme->hw_vertex_size, + fpme->translate->key.output_stride, fetch_count); } diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index ac6bc7088b..4f9f40e51a 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -54,8 +54,17 @@ struct translate_element }; +struct translate_key { + unsigned output_stride; + unsigned nr_elements; + struct translate_element element[PIPE_MAX_ATTRIBS]; +}; + + struct translate { - void (*destroy)( struct translate * ); + struct translate_key key; + + void (*release)( struct translate * ); void (*set_buffer)( struct translate *, unsigned i, @@ -66,17 +75,30 @@ struct translate { const unsigned *elts, unsigned count, void *output_buffer); + + void (*run)( struct translate *, + unsigned start, + unsigned count, + void *output_buffer); }; -struct translate *translate_sse2_create( unsigned output_stride, - const struct translate_element *elements, - unsigned nr_elements ); +#if 0 +struct translate_context *translate_context_create( void ); +void translate_context_destroy( struct translate_context * ); + +struct translate *translate_lookup_or_create( struct translate_context *tctx, + const struct translate_key *key ); +#endif + + +/******************************************************************************* + * Private: + */ +struct translate *translate_sse2_create( const struct translate_key *key ); -struct translate *translate_generic_create( unsigned output_stride, - const struct translate_element *elements, - unsigned nr_elements ); +struct translate *translate_generic_create( const struct translate_key *key ); #endif diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 7e75ba8365..fc9060900b 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -59,7 +59,6 @@ struct translate_generic { } attrib[PIPE_MAX_ATTRIBS]; unsigned nr_attrib; - unsigned output_stride; }; @@ -571,7 +570,42 @@ static void generic_run_elts( struct translate *translate, tg->attrib[attr].emit( data, dst ); } - vert += tg->output_stride; + vert += tg->translate.key.output_stride; + } +} + + + +static void generic_run( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ) +{ + struct translate_generic *tg = translate_generic(translate); + char *vert = output_buffer; + unsigned nr_attrs = tg->nr_attrib; + unsigned attr; + unsigned i; + + /* loop over vertex attributes (vertex shader inputs) + */ + for (i = 0; i < count; i++) { + unsigned elt = start + i; + + for (attr = 0; attr < nr_attrs; attr++) { + float data[4]; + + const char *src = (tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * elt); + + char *dst = (vert + + tg->attrib[attr].output_offset); + + tg->attrib[attr].fetch( src, data ); + tg->attrib[attr].emit( data, dst ); + } + + vert += tg->translate.key.output_stride; } } @@ -595,14 +629,14 @@ static void generic_set_buffer( struct translate *translate, } -static void generic_destroy( struct translate *translate ) +static void generic_release( struct translate *translate ) { + /* Refcount? + */ FREE(translate); } -struct translate *translate_generic_create( unsigned output_stride, - const struct translate_element *elements, - unsigned nr_elements ) +struct translate *translate_generic_create( const struct translate_key *key ) { struct translate_generic *tg = CALLOC_STRUCT(translate_generic); unsigned i; @@ -610,20 +644,24 @@ struct translate *translate_generic_create( unsigned output_stride, if (tg == NULL) return NULL; - tg->translate.destroy = generic_destroy; + tg->translate.key = *key; + tg->translate.release = generic_release; tg->translate.set_buffer = generic_set_buffer; tg->translate.run_elts = generic_run_elts; + tg->translate.run = generic_run; + + for (i = 0; i < key->nr_elements; i++) { + + tg->attrib[i].fetch = get_fetch_func(key->element[i].input_format); + tg->attrib[i].buffer = key->element[i].input_buffer; + tg->attrib[i].input_offset = key->element[i].input_offset; - for (i = 0; i < nr_elements; i++) { - tg->attrib[i].fetch = get_fetch_func(elements[i].input_format); - tg->attrib[i].buffer = elements[i].input_buffer; - tg->attrib[i].input_offset = elements[i].input_offset; + tg->attrib[i].emit = get_emit_func(key->element[i].output_format); + tg->attrib[i].output_offset = key->element[i].output_offset; - tg->attrib[i].emit = get_emit_func(elements[i].output_format); - tg->attrib[i].output_offset = elements[i].output_offset; } - tg->nr_attrib = nr_elements; + tg->nr_attrib = key->nr_elements; return &tg->translate; -- cgit v1.2.3 From e2269e94c0ecaa97c7153815489e59c9ca64c243 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 16 Apr 2008 11:39:22 +0900 Subject: gallium: Build and link the translate module. --- src/gallium/SConscript | 1 + src/gallium/auxiliary/translate/SConscript | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gallium/SConscript b/src/gallium/SConscript index f09778ce99..2653f91bd2 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -18,6 +18,7 @@ SConscript([ 'auxiliary/rtasm/SConscript', 'auxiliary/tgsi/SConscript', 'auxiliary/cso_cache/SConscript', + 'auxiliary/translate/SConscript', 'auxiliary/draw/SConscript', 'auxiliary/pipebuffer/SConscript', ]) diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript index 947b9438cb..42513ba3b0 100644 --- a/src/gallium/auxiliary/translate/SConscript +++ b/src/gallium/auxiliary/translate/SConscript @@ -1,6 +1,6 @@ Import('*') -cso_cache = env.ConvenienceLibrary( +translate = env.ConvenienceLibrary( target = 'translate', source = [ 'translate_generic.c', -- cgit v1.2.3 From fd6acabd2f62fe006b078ae7640a944c7f65903c Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 16 Apr 2008 11:42:08 +0900 Subject: gallium: Get the translate module to build on msvc. Appearently MSVC c-preprocessor parses "255.0f" as two tokens: "255.0" and "f", and performs variable substitution on "f". --- .../auxiliary/translate/translate_generic.c | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index fc9060900b..e7fb1dcb2d 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -78,8 +78,8 @@ static struct translate_generic *translate_generic( struct translate *translate static void \ fetch_##NAME(const void *ptr, float *attrib) \ { \ - const float defaults[4] = { 0,0,0,1 }; \ - int i; \ + const float defaults[4] = { 0.0f,0.0f,0.0f,1.0f }; \ + unsigned i; \ \ for (i = 0; i < SZ; i++) { \ attrib[i] = FROM(i); \ @@ -121,24 +121,24 @@ emit_##NAME(const float *attrib, void *ptr) \ #define FROM_16_SNORM(i) ((float) ((short *) ptr)[i] / 32767.0f) #define FROM_32_SNORM(i) ((float) ((int *) ptr)[i] / 2147483647.0f) -#define TO_64_FLOAT(f) ((double) f) -#define TO_32_FLOAT(f) (f) +#define TO_64_FLOAT(x) ((double) x) +#define TO_32_FLOAT(x) (x) -#define TO_8_USCALED(f) ((unsigned char) f) -#define TO_16_USCALED(f) ((unsigned short) f) -#define TO_32_USCALED(f) ((unsigned int) f) +#define TO_8_USCALED(x) ((unsigned char) x) +#define TO_16_USCALED(x) ((unsigned short) x) +#define TO_32_USCALED(x) ((unsigned int) x) -#define TO_8_SSCALED(f) ((char) f) -#define TO_16_SSCALED(f) ((short) f) -#define TO_32_SSCALED(f) ((int) f) +#define TO_8_SSCALED(x) ((char) x) +#define TO_16_SSCALED(x) ((short) x) +#define TO_32_SSCALED(x) ((int) x) -#define TO_8_UNORM(f) ((unsigned char) (f * 255.0f)) -#define TO_16_UNORM(f) ((unsigned short) (f * 65535.0f)) -#define TO_32_UNORM(f) ((unsigned int) (f * 4294967295.0f)) +#define TO_8_UNORM(x) ((unsigned char) (x * 255.0f)) +#define TO_16_UNORM(x) ((unsigned short) (x * 65535.0f)) +#define TO_32_UNORM(x) ((unsigned int) (x * 4294967295.0f)) -#define TO_8_SNORM(f) ((char) (f * 127.0f)) -#define TO_16_SNORM(f) ((short) (f * 32767.0f)) -#define TO_32_SNORM(f) ((int) (f * 2147483647.0f)) +#define TO_8_SNORM(x) ((char) (x * 127.0f)) +#define TO_16_SNORM(x) ((short) (x * 32767.0f)) +#define TO_32_SNORM(x) ((int) (x * 2147483647.0f)) -- cgit v1.2.3 From a8582efaca35d09c8ca18918a243a9284583356d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 10:03:18 +0100 Subject: draw: make pt run pipeline when need_pipeline is true, not just when clipped --- src/gallium/auxiliary/draw/draw_private.h | 13 +- src/gallium/auxiliary/draw/draw_pt.c | 182 +++++---------------- src/gallium/auxiliary/draw/draw_pt.h | 6 +- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 3 +- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 3 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 18 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 5 +- 7 files changed, 75 insertions(+), 155 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index c8cb96c8ba..8ac061cc9f 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -182,6 +182,12 @@ typedef void (*pt_fetch_func)( struct draw_context *draw, struct vbuf_render; + +#define PT_SHADE 0x1 +#define PT_CLIPTEST 0x2 +#define PT_PIPELINE 0x4 +#define PT_MAX_MIDDLE 0x8 + /** * Private context for the drawing module. */ @@ -219,15 +225,10 @@ struct draw_context unsigned hw_vertex_size; /* XXX: to be removed */ struct { - struct draw_pt_middle_end *fetch_emit; - struct draw_pt_middle_end *fetch_pipeline; - struct draw_pt_middle_end *fetch_shade_emit; - struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit; + struct draw_pt_middle_end *opt[PT_MAX_MIDDLE]; } middle; struct { - struct draw_pt_front_end *noop; - struct draw_pt_front_end *split_arrays; struct draw_pt_front_end *vcache; } front; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 3d2e7bf7b8..895224c952 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -36,146 +36,58 @@ #include "draw/draw_pt.h" -#if 0 -static boolean too_many_elts( struct draw_context *draw, - unsigned elts ) -{ - return elts > (8 * 1024); -} -#endif - -static INLINE unsigned reduced_prim(unsigned prim) -{ - /*FIXME*/ - return prim; -} -static INLINE boolean good_prim(unsigned prim) -{ - /*FIXME*/ - return FALSE; -} +/* Overall we split things into: + * - frontend -- prepare fetch_elts, draw_elts - eg vcache + * - middle -- fetch, shade, cliptest, viewport + * - pipeline -- the prim pipeline: clipping, wide lines, etc + * - backend -- the vbuf_render provided by the driver. + */ boolean draw_pt_arrays(struct draw_context *draw, unsigned prim, unsigned start, unsigned count) { - const boolean pipeline = draw_need_pipeline(draw, prim); - const boolean cliptest = !draw->rasterizer->bypass_clipping; - const boolean shading = !draw->rasterizer->bypass_vs; struct draw_pt_front_end *frontend = NULL; struct draw_pt_middle_end *middle = NULL; + unsigned opt = 0; if (!draw->render) return FALSE; /*debug_printf("XXXXXXXXXX needs_pipeline = %d\n", pipeline);*/ - /* Overall we do: - * - frontend -- prepare fetch_elts, draw_elts - eg vcache - * - middle -- fetch, shade, cliptest, viewport - * - pipeline -- the prim pipeline: clipping, wide lines, etc - * - backend -- the vbuf_render provided by the driver. - */ - - if (shading && !draw->use_pt_shaders) - return FALSE; - - if (!cliptest && !pipeline && !shading) { - /* This is the 'passthrough' path: - */ - /* Fetch user verts, emit hw verts: - */ - middle = draw->pt.middle.fetch_emit; - } - else if (!cliptest && !shading) { - /* This is the 'passthrough' path targetting the pipeline backend. - */ - /* Fetch user verts, emit pipeline verts, run pipeline: - */ - middle = draw->pt.middle.fetch_pipeline; - } - else if (!cliptest && !pipeline) { - /* Fetch user verts, run vertex shader, emit hw verts: - */ - middle = draw->pt.middle.fetch_shade_emit; - } - else if (!pipeline) { - /* Even though !pipeline, we have to run it to get clipping. We - * do know that the pipeline is just the clipping operation, but - * that probably doesn't help much. - * - * This is going to be the most important path for a lot of - * swtnl cards. - */ - /* Fetch user verts, - * run vertex shader, - * cliptest and viewport trasform - * if no clipped vertices, - * emit hw verts - * else - * run pipline - */ - middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit; - } - else { - /* This is what we're currently always doing: - */ - /* Fetch user verts, run vertex shader, cliptest, run pipeline - * or - * Fetch user verts, run vertex shader, run pipeline - */ - middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit; + if (draw_need_pipeline(draw, prim)) { + opt |= PT_PIPELINE; } + if (!draw->rasterizer->bypass_clipping) { + opt |= PT_CLIPTEST; + } - /* If !pipeline, need to make sure we respect the driver's limited - * capabilites to receive blocks of vertex data and elements. - */ -#if 0 - if (!pipeline) { - unsigned vertex_mode = passthrough; - unsigned nr_verts = count_vertices( draw, start, count ); - unsigned hw_prim = prim; - - if (is_elts(draw)) { - frontend = draw->pt.front.vcache; - hw_prim = reduced_prim(prim); - } -#if 0 - if (too_many_verts(nr_verts)) { - /* if (is_verts(draw) && can_split(prim)) { - draw = draw_arrays_split; - } - else */ { - frontend = draw->pt.front.vcache; - hw_prim = reduced_prim(prim); - } - } -#endif + if (!draw->rasterizer->bypass_vs) { + opt |= PT_SHADE; - if (too_many_elts(count)) { + if (!draw->use_pt_shaders) + return FALSE; + } - /* if (is_elts(draw) && can_split(prim)) { - draw = draw_elts_split; - } - else */ { - frontend = draw->pt.front.vcache; - hw_prim = reduced_prim(prim); - } - } - if (!good_prim(hw_prim)) { - frontend = draw->pt.front.vcache; - } + if (draw->pt.middle.opt[opt] == NULL) { + opt = PT_PIPELINE | PT_CLIPTEST | PT_SHADE; } -#else + + middle = draw->pt.middle.opt[opt]; + assert(middle); + + /* May create a short-circuited version of this for small primitives: + */ frontend = draw->pt.front.vcache; -#endif - frontend->prepare( frontend, prim, middle ); + + frontend->prepare( frontend, prim, middle, opt ); frontend->run( frontend, draw_pt_elt_func( draw ), @@ -190,21 +102,19 @@ draw_pt_arrays(struct draw_context *draw, boolean draw_pt_init( struct draw_context *draw ) { - draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); - if (!draw->pt.middle.fetch_emit) - return FALSE; - - draw->pt.middle.fetch_pipeline = draw_pt_fetch_pipeline( draw ); - if (!draw->pt.middle.fetch_pipeline) + draw->pt.front.vcache = draw_pt_vcache( draw ); + if (!draw->pt.front.vcache) return FALSE; - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = + draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw ); + draw->pt.middle.opt[PT_PIPELINE] = draw_pt_fetch_pipeline( draw ); +// draw->pt.middle.opt[PT_SHADE] = draw_pt_shade_emit( draw ); +// draw->pt.middle.opt[PT_SHADE | PT_PIPELINE] = draw_pt_shade_pipeline( draw ); +// draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST] = draw_pt_shade_clip_either( draw ); + draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] = draw_pt_fetch_pipeline_or_emit( draw ); - if (!draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit) - return FALSE; - draw->pt.front.vcache = draw_pt_vcache( draw ); - if (!draw->pt.front.vcache) + if (!draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE]) return FALSE; return TRUE; @@ -213,21 +123,13 @@ boolean draw_pt_init( struct draw_context *draw ) void draw_pt_destroy( struct draw_context *draw ) { - if (draw->pt.middle.fetch_emit) { - draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit ); - draw->pt.middle.fetch_emit = NULL; - } + int i; - if (draw->pt.middle.fetch_pipeline) { - draw->pt.middle.fetch_pipeline->destroy( draw->pt.middle.fetch_pipeline ); - draw->pt.middle.fetch_pipeline = NULL; - } - - if (draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit) { - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit->destroy( - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit ); - draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = NULL; - } + for (i = 0; i < PT_MAX_MIDDLE; i++) + if (draw->pt.middle.opt[i]) { + draw->pt.middle.opt[i]->destroy( draw->pt.middle.opt[i] ); + draw->pt.middle.opt[i] = NULL; + } if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 48413b648a..08afb60645 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -64,7 +64,8 @@ struct draw_context; struct draw_pt_front_end { void (*prepare)( struct draw_pt_front_end *, unsigned prim, - struct draw_pt_middle_end * ); + struct draw_pt_middle_end *, + unsigned opt ); void (*run)( struct draw_pt_front_end *, pt_elt_func elt_func, @@ -90,7 +91,8 @@ struct draw_pt_front_end { */ struct draw_pt_middle_end { void (*prepare)( struct draw_pt_middle_end *, - unsigned prim ); + unsigned prim, + unsigned opt ); void (*run)( struct draw_pt_middle_end *, const unsigned *fetch_elts, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 3a26a5d712..1a9d331a06 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -164,7 +164,8 @@ fetch_store_general( struct fetch_emit_middle_end *feme, static void fetch_emit_prepare( struct draw_pt_middle_end *middle, - unsigned prim ) + unsigned prim, + unsigned opt ) { struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index a70d129c93..db6d6c76ea 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -209,7 +209,8 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme, * */ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned prim ) + unsigned prim, + unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 2d83e11940..52be4a64aa 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -42,11 +42,13 @@ struct fetch_pipeline_middle_end { unsigned pipeline_vertex_size; unsigned prim; + unsigned opt; }; static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned prim ) + unsigned prim, + unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; @@ -57,6 +59,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, struct translate_key hw_key; fpme->prim = prim; + fpme->opt = opt; ok = draw->render->set_primitive(draw->render, prim); if (!ok) { @@ -157,6 +160,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vertex_shader; char *pipeline_verts; + unsigned pipeline = PT_PIPELINE; pipeline_verts = MALLOC(fpme->pipeline_vertex_size * fetch_count); @@ -170,9 +174,17 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, /* Shade */ shader->prepare(shader, draw); + if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts, - fpme->pipeline_vertex_size)) { - /* Run the pipeline */ + fpme->pipeline_vertex_size)) + { + pipeline |= PT_CLIPTEST; + } + + + /* Do we need to run the pipeline? + */ + if (fpme->opt & pipeline) { draw_pt_run_pipeline( fpme->draw, fpme->prim, pipeline_verts, diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 107dcfc269..5561f2b6fb 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -448,7 +448,8 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { static void vcache_prepare( struct draw_pt_front_end *frontend, unsigned prim, - struct draw_pt_middle_end *middle ) + struct draw_pt_middle_end *middle, + unsigned opt ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; @@ -464,7 +465,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, vcache->output_prim = reduced_prim[prim]; vcache->middle = middle; - middle->prepare( middle, vcache->output_prim ); + middle->prepare( middle, vcache->output_prim, opt ); } -- cgit v1.2.3 From 909e8ce543a6c1e97d55791d2069cbdc56ea9db6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 10:12:12 +0100 Subject: draw: update debug code --- src/gallium/auxiliary/draw/draw_vbuf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index e3216ff711..eeb194afaa 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -113,12 +113,12 @@ check_space( struct vbuf_stage *vbuf, unsigned nr ) } -#if 0 +#if 1 static INLINE void dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) { - assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - unsigned i, j, k; +// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + unsigned i, j; for (i = 0; i < vinfo->num_attribs; i++) { j = vinfo->src_index[i]; @@ -264,6 +264,8 @@ emit_vertex( struct vbuf_stage *vbuf, } else { draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); vbuf->vertex_ptr += vbuf->vertex_size/4; } -- cgit v1.2.3 From 8b607f42d094e61432c5718b8baa0a68268ec150 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 12:20:39 +0100 Subject: softpipe: call setup_prepare earlier so that vertex info is correct when queried --- src/gallium/drivers/softpipe/sp_prim_vbuf.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 4fed19ecb6..e063fe82ef 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -106,6 +106,16 @@ static boolean sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); + + /* XXX: break this dependency - make setup_context live under + * softpipe, rename the old "setup" draw stage to something else. + */ + struct setup_context *setup_ctx = sp_draw_setup_context(cvbr->softpipe->setup); + + setup_prepare( setup_ctx ); + + + if (prim == PIPE_PRIM_TRIANGLES || prim == PIPE_PRIM_LINES || prim == PIPE_PRIM_POINTS) { @@ -136,10 +146,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr_indices) */ struct draw_stage *setup = softpipe->setup; struct setup_context *setup_ctx = sp_draw_setup_context(softpipe->setup); - - /* XXX: call this from allocate_vertices: - */ - setup_prepare( setup_ctx ); switch (cvbr->prim) { -- cgit v1.2.3 From d8c389171872b69af3c94ebab02ad5f4bcd2d4df Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 12:31:19 +0100 Subject: draw: remove vbuf non-vf debug path, fix some failure modes in draw_vbuf_create() --- src/gallium/auxiliary/draw/draw_vbuf.c | 106 ++++++--------------------------- 1 file changed, 19 insertions(+), 87 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index eeb194afaa..59b63f5bfa 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -113,7 +113,6 @@ check_space( struct vbuf_stage *vbuf, unsigned nr ) } -#if 1 static INLINE void dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) { @@ -167,7 +166,6 @@ dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) } debug_printf("\n"); } -#endif /** @@ -181,94 +179,22 @@ static INLINE void emit_vertex( struct vbuf_stage *vbuf, struct vertex_header *vertex ) { -#if 0 - debug_printf("emit vertex %d to %p\n", - vbuf->nr_vertices, vbuf->vertex_ptr); -#endif - if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { if(vertex->vertex_id < vbuf->nr_vertices) return; else debug_printf("Bad vertex id 0x%04x (>= 0x%04x)\n", - vertex->vertex_id, vbuf->nr_vertices); + vertex->vertex_id, vbuf->nr_vertices); return; } vertex->vertex_id = vbuf->nr_vertices++; - if(!vbuf->vf) { - const struct vertex_info *vinfo = vbuf->vinfo; - uint i; - uint count = 0; /* for debug/sanity */ - - assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - - for (i = 0; i < vinfo->num_attribs; i++) { - uint j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; - case EMIT_1F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - count++; - break; - case EMIT_1F_PSIZE: - *vbuf->vertex_ptr++ = fui(vbuf->stage.draw->rasterizer->point_size); - count++; - break; - case EMIT_2F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - count += 2; - break; - case EMIT_3F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); - count += 3; - break; - case EMIT_4F: - *vbuf->vertex_ptr++ = fui(vertex->data[j][0]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][1]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][2]); - *vbuf->vertex_ptr++ = fui(vertex->data[j][3]); - count += 4; - break; - case EMIT_4UB: - *vbuf->vertex_ptr++ = pack_ub4(float_to_ubyte( vertex->data[j][2] ), - float_to_ubyte( vertex->data[j][1] ), - float_to_ubyte( vertex->data[j][0] ), - float_to_ubyte( vertex->data[j][3] )); - count += 1; - break; - default: - assert(0); - } - } - assert(count == vinfo->size); -#if 0 - { - static float data[256]; - draw_vf_emit_vertex(vbuf->vf, vertex, data); - if(memcmp((uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size, data, vbuf->vertex_size)) { - debug_printf("With VF:\n"); - dump_emitted_vertex(vbuf->vinfo, (uint8_t *)data); - debug_printf("Without VF:\n"); - dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr - vbuf->vertex_size); - assert(0); - } - } -#endif - } - else { - draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - vbuf->vertex_ptr += vbuf->vertex_size/4; - } + vbuf->vertex_ptr += vbuf->vertex_size/4; } @@ -526,7 +452,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); if(!vbuf) - return NULL; + goto fail; vbuf->stage.draw = draw; vbuf->stage.point = vbuf_first_point; @@ -537,21 +463,27 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->stage.destroy = vbuf_destroy; vbuf->render = render; + vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1); - assert(render->max_indices < UNDEFINED_VERTEX_ID); - vbuf->max_indices = render->max_indices; - vbuf->indices = (ushort *) - align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); + vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * + sizeof(vbuf->indices[0]), + 16 ); if(!vbuf->indices) - vbuf_destroy(&vbuf->stage); + goto fail; vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; vbuf->prim = ~0; - - if(!GETENV("GALLIUM_NOVF")) - vbuf->vf = draw_vf_create(); + vbuf->vf = draw_vf_create(); + if (!vbuf->vf) + goto fail; return &vbuf->stage; + + fail: + if (vbuf) + vbuf_destroy(&vbuf->stage); + + return NULL; } -- cgit v1.2.3 From 3be453bf7fcffd945ee0238e66ff4247a4491f1c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 16 Apr 2008 12:55:47 +0100 Subject: draw: allow pt paths to run without a vbuf render stage --- src/gallium/auxiliary/draw/draw_pt.c | 7 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 137 +++++++++++---------- 2 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 895224c952..c0125c906f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -54,10 +54,9 @@ draw_pt_arrays(struct draw_context *draw, struct draw_pt_middle_end *middle = NULL; unsigned opt = 0; - if (!draw->render) - return FALSE; - /*debug_printf("XXXXXXXXXX needs_pipeline = %d\n", pipeline);*/ - + if (!draw->render) { + opt |= PT_PIPELINE; + } if (draw_need_pipeline(draw, prim)) { opt |= PT_PIPELINE; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 52be4a64aa..a66e8b0ba2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -61,88 +61,89 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, fpme->prim = prim; fpme->opt = opt; - ok = draw->render->set_primitive(draw->render, prim); - if (!ok) { - assert(0); - return; - } + if (!(opt & PT_PIPELINE)) { + ok = draw->render->set_primitive(draw->render, prim); + if (!ok) { + assert(0); + return; + } - /* Must do this after set_primitive() above: - */ - vinfo = draw->render->get_vertex_info(draw->render); + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); - /* In passthrough mode, need to translate from vertex shader - * outputs to hw vertices. - */ - dst_offset = 0; - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned src_buffer = 0; - unsigned output_format; - unsigned src_offset = (sizeof(struct vertex_header) + - vinfo->src_index[i] * 4 * sizeof(float) ); + /* In passthrough mode, need to translate from vertex shader + * outputs to hw vertices. + */ + dst_offset = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (sizeof(struct vertex_header) + + vinfo->src_index[i] * 4 * sizeof(float) ); - switch (vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - src_buffer = 1; - src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; - emit_sz = 4 * sizeof(ubyte); - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; - } + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } - hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - hw_key.element[i].input_buffer = src_buffer; - hw_key.element[i].input_offset = src_offset; - hw_key.element[i].output_format = output_format; - hw_key.element[i].output_offset = dst_offset; + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; - dst_offset += emit_sz; - } + dst_offset += emit_sz; + } - hw_key.nr_elements = vinfo->num_attribs; - hw_key.output_stride = vinfo->size * 4; + hw_key.nr_elements = vinfo->num_attribs; + hw_key.output_stride = vinfo->size * 4; - /* Don't bother with caching at this stage: - */ - if (!fpme->translate || - memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) - { - if (fpme->translate) - fpme->translate->release(fpme->translate); + /* Don't bother with caching at this stage: + */ + if (!fpme->translate || + memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (fpme->translate) + fpme->translate->release(fpme->translate); - fpme->translate = translate_generic_create( &hw_key ); + fpme->translate = translate_generic_create( &hw_key ); + } } - //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; } -- cgit v1.2.3 From 3a765bbe00940c4dffce72b659f625d97ea17971 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 16 Apr 2008 22:32:10 +0900 Subject: gallium: Use debug_get_bool_option for controlling assert failure behaviour. Add GALLIUM_ABORT_ON_ASSERT=no to C:\gallium.cfg instead. --- src/gallium/auxiliary/util/p_debug.c | 47 +++--------------------------------- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c index c195f61820..25b132b40c 100644 --- a/src/gallium/auxiliary/util/p_debug.c +++ b/src/gallium/auxiliary/util/p_debug.c @@ -200,6 +200,8 @@ debug_get_bool_option(const char *name, boolean dfault) if(str == NULL) result = dfault; + else if(!strcmp(str, "n")) + result = FALSE; else if(!strcmp(str, "no")) result = FALSE; else if(!strcmp(str, "0")) @@ -251,57 +253,16 @@ debug_get_flags_option(const char *name, } -#if defined(WIN32) -ULONG_PTR debug_config_file = 0; -void *mapped_config_file = 0; - -enum { - eAssertAbortEn = 0x1, -}; - -/* Check for aborts enabled. */ -static unsigned abort_en(void) -{ - if (!mapped_config_file) - { - /* Open an 8 byte file for configuration data. */ - mapped_config_file = EngMapFile(L"\\??\\c:\\gaDebug.cfg", 8, &debug_config_file); - } - - /* A value of "0" (ascii) in the configuration file will clear the - * first 8 bits in the test byte. - * - * A value of "1" (ascii) in the configuration file will set the - * first bit in the test byte. - * - * A value of "2" (ascii) in the configuration file will set the - * second bit in the test byte. - * - * Currently the only interesting values are 0 and 1, which clear - * and set abort-on-assert behaviour respectively. - */ - return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn; -} -#else /* WIN32 */ -static unsigned abort_en(void) -{ - return !GETENV("GALLIUM_ABORT_ON_ASSERT"); -} -#endif - void _debug_assert_fail(const char *expr, const char *file, unsigned line, const char *function) { _debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr); - if (abort_en()) - { + if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE)) debug_break(); - } else - { + else _debug_printf("continuing...\n"); - } } -- cgit v1.2.3 From 302daeb2ec62c59bd28d0c53cdc0fb07dc9d0f58 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Apr 2008 09:04:39 -0600 Subject: mesa: added internal post color matrix scale/bias vars --- src/mesa/shader/prog_statevars.c | 12 ++++++++++++ src/mesa/shader/prog_statevars.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 6cc490bc77..45352d30b5 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -450,6 +450,12 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], value[2] = ctx->Pixel.BlueBias; value[3] = ctx->Pixel.AlphaBias; break; + case STATE_PCM_SCALE: + COPY_4V(value, ctx->Pixel.PostColorMatrixScale); + break; + case STATE_PCM_BIAS: + COPY_4V(value, ctx->Pixel.PostColorMatrixBias); + break; default: /* unknown state indexes are silently ignored * should be handled by the driver. @@ -697,6 +703,12 @@ append_token(char *dst, gl_state_index k) case STATE_PT_BIAS: append(dst, "PTbias"); break; + case STATE_PCM_SCALE: + append(dst, "PCMscale"); + break; + case STATE_PCM_BIAS: + append(dst, "PCMbias"); + break; default: ; } diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h index 9fedcfab8a..d12142055f 100644 --- a/src/mesa/shader/prog_statevars.h +++ b/src/mesa/shader/prog_statevars.h @@ -111,6 +111,8 @@ typedef enum gl_state_index_ { STATE_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */ STATE_PT_SCALE, /**< Pixel transfer RGBA scale */ STATE_PT_BIAS, /**< Pixel transfer RGBA bias */ + STATE_PCM_SCALE, /**< Post color matrix RGBA scale */ + STATE_PCM_BIAS, /**< Post color matrix RGBA bias */ STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ } gl_state_index; -- cgit v1.2.3 From e38f677e8f5596d92a6756e13f41f6523de737c2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Apr 2008 09:09:08 -0600 Subject: gallium: finish-up and fix support for GL_COLOR matrix on pixel xfer path --- src/mesa/state_tracker/st_atom_pixeltransfer.c | 75 ++++++++++++++++++-------- src/mesa/state_tracker/st_extensions.c | 1 + 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 6410e7cb24..efb92b735e 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -50,6 +50,7 @@ struct state_key { GLuint scaleAndBias:1; GLuint colorMatrix:1; + GLuint colorMatrixPostScaleBias:1; #if 0 GLfloat Maps[3][256][4]; @@ -80,6 +81,9 @@ is_identity(const GLfloat m[16]) static void make_state_key(GLcontext *ctx, struct state_key *key) { + static const GLfloat zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + static const GLfloat one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + memset(key, 0, sizeof(*key)); if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 || @@ -92,8 +96,12 @@ make_state_key(GLcontext *ctx, struct state_key *key) if (!is_identity(ctx->ColorMatrixStack.Top->m)) { key->colorMatrix = 1; } -} + if (!TEST_EQ_4V(ctx->Pixel.PostColorMatrixScale, one) || + !TEST_EQ_4V(ctx->Pixel.PostColorMatrixBias, zero)) { + key->colorMatrixPostScaleBias = 1; + } +} @@ -182,64 +190,87 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) GLint row3_p = _mesa_add_state_reference(params, row3_state); const GLuint temp = 1; - /* MOV temp, colorTemp; */ - _mesa_init_instructions(inst + ic, 1); - inst[ic].Opcode = OPCODE_MOV; - inst[ic].DstReg.File = PROGRAM_TEMPORARY; - inst[ic].DstReg.Index = temp; - inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - inst[ic].SrcReg[0].Index = colorTemp; - ic++; - /* XXX reimplement in terms of MUL/MAD (see t_vp_build.c) */ - /* DP4 colorTemp.x, temp, matrow0; */ + /* DP4 temp.x, colorTemp, matrow0; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_DP4; inst[ic].DstReg.File = PROGRAM_TEMPORARY; - inst[ic].DstReg.Index = colorTemp; + inst[ic].DstReg.Index = temp; inst[ic].DstReg.WriteMask = WRITEMASK_X; inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - inst[ic].SrcReg[0].Index = temp; + inst[ic].SrcReg[0].Index = colorTemp; inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; inst[ic].SrcReg[1].Index = row0_p; ic++; - /* DP4 colorTemp.y, temp, matrow1; */ + /* DP4 temp.y, colorTemp, matrow1; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_DP4; inst[ic].DstReg.File = PROGRAM_TEMPORARY; - inst[ic].DstReg.Index = colorTemp; + inst[ic].DstReg.Index = temp; inst[ic].DstReg.WriteMask = WRITEMASK_Y; inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - inst[ic].SrcReg[0].Index = temp; + inst[ic].SrcReg[0].Index = colorTemp; inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; inst[ic].SrcReg[1].Index = row1_p; ic++; - /* DP4 colorTemp.z, temp, matrow2; */ + /* DP4 temp.z, colorTemp, matrow2; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_DP4; inst[ic].DstReg.File = PROGRAM_TEMPORARY; - inst[ic].DstReg.Index = colorTemp; + inst[ic].DstReg.Index = temp; inst[ic].DstReg.WriteMask = WRITEMASK_Z; inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - inst[ic].SrcReg[0].Index = temp; + inst[ic].SrcReg[0].Index = colorTemp; inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; inst[ic].SrcReg[1].Index = row2_p; ic++; - /* DP4 colorTemp.w, temp, matrow3; */ + /* DP4 temp.w, colorTemp, matrow3; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_DP4; inst[ic].DstReg.File = PROGRAM_TEMPORARY; - inst[ic].DstReg.Index =colorTemp; + inst[ic].DstReg.Index = temp; inst[ic].DstReg.WriteMask = WRITEMASK_W; inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - inst[ic].SrcReg[0].Index = temp; + inst[ic].SrcReg[0].Index = colorTemp; inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; inst[ic].SrcReg[1].Index = row3_p; ic++; + + /* MOV colorTemp, temp; */ + _mesa_init_instructions(inst + ic, 1); + inst[ic].Opcode = OPCODE_MOV; + inst[ic].DstReg.File = PROGRAM_TEMPORARY; + inst[ic].DstReg.Index = colorTemp; + inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + inst[ic].SrcReg[0].Index = temp; + ic++; + } + + if (key->colorMatrixPostScaleBias) { + static const gl_state_index scale_state[STATE_LENGTH] = + { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 }; + static const gl_state_index bias_state[STATE_LENGTH] = + { STATE_INTERNAL, STATE_PT_BIAS, 0, 0, 0 }; + GLint scale_param, bias_param; + + scale_param = _mesa_add_state_reference(params, scale_state); + bias_param = _mesa_add_state_reference(params, bias_state); + + _mesa_init_instructions(inst + ic, 1); + inst[ic].Opcode = OPCODE_MAD; + inst[ic].DstReg.File = PROGRAM_TEMPORARY; + inst[ic].DstReg.Index = colorTemp; + inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + inst[ic].SrcReg[0].Index = colorTemp; + inst[ic].SrcReg[1].File = PROGRAM_STATE_VAR; + inst[ic].SrcReg[1].Index = scale_param; + inst[ic].SrcReg[2].File = PROGRAM_STATE_VAR; + inst[ic].SrcReg[2].Index = bias_param; + ic++; } /* Modify last instruction's dst reg to write to result.color */ diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 2f7ac074da..f2d40e84b3 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -164,6 +164,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.NV_blend_square = GL_TRUE; ctx->Extensions.NV_texgen_reflection = GL_TRUE; + ctx->Extensions.SGI_color_matrix = GL_TRUE; ctx->Extensions.SGIS_generate_mipmap = GL_TRUE; /* XXX temp */ /* -- cgit v1.2.3 From dc5a853c85d2daa8b7b0e6d32e00c4976746d704 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Apr 2008 09:45:56 -0600 Subject: gallium: make choose_format() non-static: st_choose_format() --- src/mesa/state_tracker/st_format.c | 9 +++++---- src/mesa/state_tracker/st_format.h | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index cd41dc4684..3d15a03cab 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -354,8 +354,9 @@ default_depth_format(struct pipe_screen *screen, uint type) * Given an OpenGL internalFormat value for a texture or surface, return * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match. */ -static enum pipe_format -choose_format(struct pipe_context *pipe, GLint internalFormat, uint surfType) +enum pipe_format +st_choose_format(struct pipe_context *pipe, GLint internalFormat, + uint surfType) { struct pipe_screen *screen = pipe->screen; @@ -530,7 +531,7 @@ choose_format(struct pipe_context *pipe, GLint internalFormat, uint surfType) enum pipe_format st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat) { - return choose_format(pipe, internalFormat, PIPE_SURFACE); + return st_choose_format(pipe, internalFormat, PIPE_SURFACE); } @@ -594,7 +595,7 @@ st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat, (void) format; (void) type; - pFormat = choose_format(ctx->st->pipe, internalFormat, PIPE_TEXTURE); + pFormat = st_choose_format(ctx->st->pipe, internalFormat, PIPE_TEXTURE); if (pFormat == PIPE_FORMAT_NONE) return NULL; diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index c9a11de504..ff0fd042db 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -63,6 +63,10 @@ extern enum pipe_format st_mesa_format_to_pipe_format(GLuint mesaFormat); +extern enum pipe_format +st_choose_format(struct pipe_context *pipe, GLint internalFormat, + uint surfType); + extern enum pipe_format st_choose_renderbuffer_format(struct pipe_context *pipe, GLint internalFormat); -- cgit v1.2.3 From 52544aa23bebe68d6fc9b13dc55f6bb8c03430ff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Apr 2008 09:46:38 -0600 Subject: gallium: added util_pack_color_ub() --- src/gallium/auxiliary/util/u_pack_color.h | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index cd13823985..1f6604c554 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -39,6 +39,45 @@ #include "pipe/p_format.h" +/** + * Pack ubyte R,G,B,A into dest pixel. + */ +static INLINE void +util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, + enum pipe_format format, void *dest) +{ + switch (format) { + case PIPE_FORMAT_R8G8B8A8_UNORM: + { + uint *d = (uint *) dest; + *d = (r << 24) | (g << 16) | (b << 8) | a; + } + return; + case PIPE_FORMAT_A8R8G8B8_UNORM: + { + uint *d = (uint *) dest; + *d = (a << 24) | (r << 16) | (g << 8) | b; + } + return; + case PIPE_FORMAT_B8G8R8A8_UNORM: + { + uint *d = (uint *) dest; + *d = (b << 24) | (g << 16) | (r << 8) | a; + } + return; + case PIPE_FORMAT_R5G6B5_UNORM: + { + ushort *d = (ushort *) dest; + *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); + } + return; + /* XXX lots more cases to add */ + default: + debug_printf("gallium: unhandled format in util_pack_color_ub()"); + } +} + + /** * Note rgba outside [0,1] will be clamped for int pixel formats. */ -- cgit v1.2.3 From 4b822a101680532ce6df52904af91194b78a16ba Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Apr 2008 16:52:12 -0600 Subject: gallium: implement RGBA pixel maps in the pixel transfer fragment program --- src/mesa/state_tracker/st_atom_pixeltransfer.c | 136 ++++++++++++++++++++++++- src/mesa/state_tracker/st_cb_drawpixels.c | 13 ++- src/mesa/state_tracker/st_context.h | 2 + 3 files changed, 146 insertions(+), 5 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index efb92b735e..76356bbad7 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -42,8 +42,14 @@ #include "shader/prog_print.h" #include "st_context.h" +#include "st_format.h" #include "st_program.h" +#include "st_texture.h" +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_pack_color.h" struct state_key @@ -51,6 +57,7 @@ struct state_key GLuint scaleAndBias:1; GLuint colorMatrix:1; GLuint colorMatrixPostScaleBias:1; + GLuint pixelMaps:1; #if 0 GLfloat Maps[3][256][4]; @@ -101,6 +108,69 @@ make_state_key(GLcontext *ctx, struct state_key *key) !TEST_EQ_4V(ctx->Pixel.PostColorMatrixBias, zero)) { key->colorMatrixPostScaleBias = 1; } + + key->pixelMaps = ctx->Pixel.MapColorFlag; +} + + +static struct pipe_texture * +create_color_map_texture(GLcontext *ctx) +{ + struct pipe_context *pipe = ctx->st->pipe; + struct pipe_texture *pt; + enum pipe_format format; + const uint texSize = 256; /* simple, and usually perfect */ + + /* find an RGBA texture format */ + format = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE); + + /* create texture for color map/table */ + pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, + texSize, texSize, 1, 0); + return pt; +} + + +/** + * Update the pixelmap texture with the contents of the R/G/B/A pixel maps. + */ +static void +load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) +{ + struct pipe_context *pipe = ctx->st->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *surface; + const GLuint rSize = ctx->PixelMaps.RtoR.Size; + const GLuint gSize = ctx->PixelMaps.GtoG.Size; + const GLuint bSize = ctx->PixelMaps.BtoB.Size; + const GLuint aSize = ctx->PixelMaps.AtoA.Size; + const uint texSize = pt->width[0]; + uint *dest; + uint i, j; + + surface = screen->get_tex_surface(screen, pt, 0, 0, 0); + dest = (uint *) pipe_surface_map(surface); + + /* Pack four 1D maps into a 2D texture: + * R map is placed horizontally, indexed by S, in channel 0 + * G map is placed vertically, indexed by T, in channel 1 + * B map is placed horizontally, indexed by S, in channel 2 + * A map is placed vertically, indexed by T, in channel 3 + */ + for (i = 0; i < texSize; i++) { + for (j = 0; j < texSize; j++) { + int k = (i * texSize + j); + ubyte r = ctx->PixelMaps.RtoR.Map8[j * rSize / texSize]; + ubyte g = ctx->PixelMaps.GtoG.Map8[i * gSize / texSize]; + ubyte b = ctx->PixelMaps.BtoB.Map8[j * bSize / texSize]; + ubyte a = ctx->PixelMaps.AtoA.Map8[i * aSize / texSize]; + util_pack_color_ub(r, g, b, a, pt->format, dest + k); + } + } + + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, pt, 0, 0x1); } @@ -113,6 +183,7 @@ make_state_key(GLcontext *ctx, struct state_key *key) static struct gl_fragment_program * get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) { + struct st_context *st = ctx->st; struct prog_instruction inst[MAX_INST]; struct gl_program_parameter_list *params; struct gl_fragment_program *fp; @@ -126,7 +197,10 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) params = _mesa_new_parameter_list(); - /* TEX colorTemp, fragment.texcoord[0], texture[0], 2D; */ + /* + * Get initial pixel color from the texture. + * TEX colorTemp, fragment.texcoord[0], texture[0], 2D; + */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_TEX; inst[ic].DstReg.File = PROGRAM_TEMPORARY; @@ -140,7 +214,6 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) fp->Base.OutputsWritten = (1 << FRAG_RESULT_COLR); fp->Base.SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ - /* MAD colorTemp, colorTemp, scale, bias; */ if (key->scaleAndBias) { static const gl_state_index scale_state[STATE_LENGTH] = { STATE_INTERNAL, STATE_PT_SCALE, 0, 0, 0 }; @@ -161,6 +234,7 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) scale_p = _mesa_add_state_reference(params, scale_state); bias_p = _mesa_add_state_reference(params, bias_state); + /* MAD colorTemp, colorTemp, scale, bias; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_MAD; inst[ic].DstReg.File = PROGRAM_TEMPORARY; @@ -174,6 +248,56 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) ic++; } + if (key->pixelMaps) { + const GLuint temp = 1; + + /* create the colormap/texture now if not already done */ + if (!st->pixel_xfer.pixelmap_texture) { + st->pixel_xfer.pixelmap_texture = create_color_map_texture(ctx); + } + + /* with a little effort, we can do four pixel map look-ups with + * two TEX instructions: + */ + + /* TEX temp.rg, colorTemp.rgba, texture[1], 2D; */ + _mesa_init_instructions(inst + ic, 1); + inst[ic].Opcode = OPCODE_TEX; + inst[ic].DstReg.File = PROGRAM_TEMPORARY; + inst[ic].DstReg.Index = temp; + inst[ic].DstReg.WriteMask = WRITEMASK_XY; /* write R,G */ + inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + inst[ic].SrcReg[0].Index = colorTemp; + inst[ic].TexSrcUnit = 1; + inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; + ic++; + + /* TEX temp.ba, colorTemp.baba, texture[1], 2D; */ + _mesa_init_instructions(inst + ic, 1); + inst[ic].Opcode = OPCODE_TEX; + inst[ic].DstReg.File = PROGRAM_TEMPORARY; + inst[ic].DstReg.Index = temp; + inst[ic].DstReg.WriteMask = WRITEMASK_ZW; /* write B,A */ + inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + inst[ic].SrcReg[0].Index = colorTemp; + inst[ic].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, + SWIZZLE_Z, SWIZZLE_W); + inst[ic].TexSrcUnit = 1; + inst[ic].TexSrcTarget = TEXTURE_2D_INDEX; + ic++; + + /* MOV colorTemp, temp; */ + _mesa_init_instructions(inst + ic, 1); + inst[ic].Opcode = OPCODE_MOV; + inst[ic].DstReg.File = PROGRAM_TEMPORARY; + inst[ic].DstReg.Index = colorTemp; + inst[ic].SrcReg[0].File = PROGRAM_TEMPORARY; + inst[ic].SrcReg[0].Index = temp; + ic++; + + fp->Base.SamplersUsed |= (1 << 1); /* sampler 1 is used */ + } + if (key->colorMatrix) { static const gl_state_index row0_state[STATE_LENGTH] = { STATE_COLOR_MATRIX, 0, 0, 0, 0 }; @@ -190,8 +314,6 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) GLint row3_p = _mesa_add_state_reference(params, row3_state); const GLuint temp = 1; - /* XXX reimplement in terms of MUL/MAD (see t_vp_build.c) */ - /* DP4 temp.x, colorTemp, matrow0; */ _mesa_init_instructions(inst + ic, 1); inst[ic].Opcode = OPCODE_DP4; @@ -316,6 +438,7 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) static void update_pixel_transfer(struct st_context *st) { + GLcontext *ctx = st->ctx; struct state_key key; struct gl_fragment_program *fp; @@ -329,6 +452,11 @@ update_pixel_transfer(struct st_context *st) &key, sizeof(key), &fp->Base); } + if (ctx->Pixel.MapColorFlag) { + load_color_map_texture(ctx, st->pixel_xfer.pixelmap_texture); + } + st->pixel_xfer.pixelmap_enabled = ctx->Pixel.MapColorFlag; + st->pixel_xfer.program = (struct st_fragment_program *) fp; } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 5f8c90cbba..67f468c689 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -562,6 +562,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, sampler.normalized_coords = 1; cso_single_sampler(cso, 0, &sampler); + if (st->pixel_xfer.pixelmap_enabled) { + cso_single_sampler(cso, 1, &sampler); + } cso_single_sampler_done(cso); } @@ -582,7 +585,15 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* texture state: */ - pipe->set_sampler_textures(pipe, 1, &pt); + if (st->pixel_xfer.pixelmap_enabled) { + struct pipe_texture *textures[2]; + textures[0] = pt; + textures[1] = st->pixel_xfer.pixelmap_texture; + pipe->set_sampler_textures(pipe, 2, textures); + } + else { + pipe->set_sampler_textures(pipe, 1, &pt); + } /* Compute window coords (y=0=bottom) with pixel zoom. * Recall that these coords are transformed by the current diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index d89e54c43c..ae1ba41d4f 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -138,6 +138,8 @@ struct st_context GLuint user_prog_sn; /**< user fragment program serial no. */ struct st_fragment_program *combined_prog; GLuint combined_prog_sn; + struct pipe_texture *pixelmap_texture; + boolean pixelmap_enabled; /**< use the pixelmap texture? */ } pixel_xfer; /** for glBitmap */ -- cgit v1.2.3 From 8abfcea690c66f75d61905f0ec5497b8fd7950d4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 10:37:53 +0100 Subject: draw: remove misleading comments --- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index e70e63d08f..17ce6febec 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -36,11 +36,6 @@ #include "draw/draw_vertex.h" #include "draw/draw_pt.h" - -/** - * Add a point to the primitive queue. - * \param i0 index into user's vertex arrays - */ static void do_point( struct draw_context *draw, const char *v0 ) { @@ -55,11 +50,6 @@ static void do_point( struct draw_context *draw, } -/** - * Add a line to the primitive queue. - * \param i0 index into user's vertex arrays - * \param i1 index into user's vertex arrays - */ static void do_line( struct draw_context *draw, const char *v0, const char *v1 ) @@ -75,9 +65,7 @@ static void do_line( struct draw_context *draw, draw->pipeline.first->line( draw->pipeline.first, &prim ); } -/** - * Add a triangle to the primitive queue. - */ + static void do_triangle( struct draw_context *draw, char *v0, char *v1, -- cgit v1.2.3 From c96d565643de271c6bda066e892b25d0a97ea4d0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 13:14:22 +0100 Subject: draw: keep record of number of active vertex buffers --- src/gallium/auxiliary/draw/draw_context.c | 1 + src/gallium/auxiliary/draw/draw_private.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 0c314f6e1d..cdcbfdc323 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -249,6 +249,7 @@ draw_set_vertex_buffers(struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0])); + draw->nr_vertex_buffers = count; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 8ac061cc9f..359a8b8a3d 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -245,7 +245,10 @@ struct draw_context /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_buffers; + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; struct draw_vertex_shader *vertex_shader; -- cgit v1.2.3 From 49becd2d7c751e563ce6be9051dd8e6dad88d1f7 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 13:14:55 +0100 Subject: draw: add comment --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 1a9d331a06..d696afa1aa 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -185,6 +185,11 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, */ vinfo = draw->render->get_vertex_info(draw->render); + + /* This is unique as it transforms straight from API vertex + * information to HW vertices. All other cases go through our + * intermediate float[4] format. + */ for (i = 0; i < vinfo->num_attribs; i++) { unsigned src_element = vinfo->src_index[i]; unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; -- cgit v1.2.3 From 938ec19210c5b4e19dcb2b606c9ade415f2c1f84 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:19:03 +0100 Subject: tsgi: make Consts const --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h index 45c49dd007..92e2e5e985 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.h @@ -166,7 +166,7 @@ struct tgsi_exec_machine float Imms[TGSI_EXEC_NUM_IMMEDIATES][4]; unsigned ImmLimit; - float (*Consts)[4]; + const float (*Consts)[4]; struct tgsi_exec_vector *Inputs; struct tgsi_exec_vector *Outputs; const struct tgsi_token *Tokens; -- cgit v1.2.3 From 280bcff1fa200b790d8712946a4ffbaa47a67433 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:20:00 +0100 Subject: draw: add vertex shader run_linear function --- src/gallium/auxiliary/draw/draw_aapoint.c | 2 +- src/gallium/auxiliary/draw/draw_clip.c | 2 +- src/gallium/auxiliary/draw/draw_context.c | 17 +++- src/gallium/auxiliary/draw/draw_flatshade.c | 2 +- src/gallium/auxiliary/draw/draw_private.h | 28 +------ .../auxiliary/draw/draw_pt_fetch_pipeline.c | 2 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 +- src/gallium/auxiliary/draw/draw_twoside.c | 2 +- src/gallium/auxiliary/draw/draw_vertex_fetch.c | 2 +- src/gallium/auxiliary/draw/draw_vertex_shader.c | 7 +- src/gallium/auxiliary/draw/draw_vs.h | 40 ++++++++- src/gallium/auxiliary/draw/draw_vs_exec.c | 95 +++++++++++++++++++--- src/gallium/auxiliary/draw/draw_vs_llvm.c | 66 ++++++++++++++- src/gallium/auxiliary/draw/draw_vs_sse.c | 76 ++++++++++++++++- src/gallium/auxiliary/draw/draw_wide_point.c | 2 +- 15 files changed, 286 insertions(+), 59 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c index fcebe3e7a0..e84d380e50 100644 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_aapoint.c @@ -48,7 +48,7 @@ #include "tgsi/util/tgsi_dump.h" #include "draw_context.h" -#include "draw_private.h" +#include "draw_vs.h" /* diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c index e24c5d8032..0ac3a240e5 100644 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ b/src/gallium/auxiliary/draw/draw_clip.c @@ -36,7 +36,7 @@ #include "pipe/p_shader_tokens.h" #include "draw_context.h" -#include "draw_private.h" +#include "draw_vs.h" #ifndef IS_NEGATIVE diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index cdcbfdc323..9b2dcc0b57 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -33,8 +33,8 @@ #include "pipe/p_util.h" #include "draw_context.h" -#include "draw_private.h" #include "draw_vbuf.h" +#include "draw_vs.h" struct draw_context *draw_create( void ) @@ -108,6 +108,8 @@ struct draw_context *draw_create( void ) draw_vertex_cache_invalidate( draw ); draw_set_mapped_element_buffer( draw, 0, NULL ); + tgsi_exec_machine_init(&draw->machine); + if (!draw_pt_init( draw )) goto fail; @@ -460,3 +462,16 @@ boolean draw_get_edgeflag( struct draw_context *draw, else return 1; } + + +#if 0 +/* Crufty init function. Fix me. + */ +boolean draw_init_machine( struct draw_context *draw ) +{ + ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); + ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); + machine->Inputs = ALIGN16_ASSIGN(inputs); + machine->Outputs = ALIGN16_ASSIGN(outputs); +} +#endif diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c index af2cb05c98..54baa1fbc9 100644 --- a/src/gallium/auxiliary/draw/draw_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_flatshade.c @@ -30,7 +30,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" /** subclass of draw_stage */ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 359a8b8a3d..7953dbb7d9 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -55,6 +55,7 @@ struct gallivm_cpu_engine; struct draw_pt_middle_end; struct draw_pt_front_end; +struct draw_vertex_shader; #define MAX_SHADER_VERTICES 128 @@ -132,33 +133,6 @@ struct draw_stage #define VCACHE_OVERFLOW 4 #define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ -/** - * Private version of the compiled vertex_shader - */ -struct draw_vertex_shader { - - /* This member will disappear shortly: - */ - struct pipe_shader_state state; - - struct tgsi_shader_info info; - - void (*prepare)( struct draw_vertex_shader *shader, - struct draw_context *draw ); - - /* Run the shader - this interface will get cleaned up in the - * future: - */ - boolean (*run)( struct draw_vertex_shader *shader, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *out, - unsigned vertex_size); - - - void (*delete)( struct draw_vertex_shader * ); -}; /* Internal function for vertex fetch. diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index db6d6c76ea..79548d4156 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -32,9 +32,9 @@ #include "pipe/p_util.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "draw/draw_vs.h" /* The simplest 'middle end' in the new vertex code. * diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index a66e8b0ba2..cf37493eb6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -27,10 +27,10 @@ #include "pipe/p_util.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "draw/draw_vs.h" #include "translate/translate.h" diff --git a/src/gallium/auxiliary/draw/draw_twoside.c b/src/gallium/auxiliary/draw/draw_twoside.c index 3debaac282..01d905c153 100644 --- a/src/gallium/auxiliary/draw/draw_twoside.c +++ b/src/gallium/auxiliary/draw/draw_twoside.c @@ -31,7 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" struct twoside_stage { diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index 9041041006..0bc2fcb424 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -32,7 +32,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" #include "draw_context.h" diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 8572a6d40c..c0c17c116e 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -95,10 +95,8 @@ draw_create_vertex_shader(struct draw_context *draw, vs = draw_create_vs_exec( draw, shader ); } } - assert(vs); - - tgsi_scan_shader(shader->tokens, &vs->info); + assert(vs); return vs; } @@ -113,9 +111,6 @@ draw_bind_vertex_shader(struct draw_context *draw, { draw->vertex_shader = dvs; draw->num_vs_outputs = dvs->info.num_outputs; - - tgsi_exec_machine_init(&draw->machine); - dvs->prepare( dvs, draw ); } else { diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index 33ce1e335e..e88d00e247 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -35,10 +35,46 @@ #include "draw_private.h" -struct draw_vertex_shader; struct draw_context; struct pipe_shader_state; +/** + * Private version of the compiled vertex_shader + */ +struct draw_vertex_shader { + + /* This member will disappear shortly: + */ + struct pipe_shader_state state; + + struct tgsi_shader_info info; + + void (*prepare)( struct draw_vertex_shader *shader, + struct draw_context *draw ); + + /* Run the shader - this interface will get cleaned up in the + * future: + */ + boolean (*run)( struct draw_vertex_shader *shader, + struct draw_context *draw, + const unsigned *elts, + unsigned count, + void *out, + unsigned vertex_size); + + void (*run_linear)( struct draw_vertex_shader *shader, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ); + + + void (*delete)( struct draw_vertex_shader * ); +}; + + struct draw_vertex_shader * draw_create_vs_exec(struct draw_context *draw, const struct pipe_shader_state *templ); @@ -79,5 +115,7 @@ compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) return mask; } +#define MAX_TGSI_VERTICES 4 + #endif diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 5c88c2e24e..0e05b79715 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -40,8 +40,20 @@ #include "tgsi/util/tgsi_parse.h" -#define MAX_TGSI_VERTICES 4 +struct exec_vertex_shader { + struct draw_vertex_shader base; + struct tgsi_exec_machine *machine; +}; + +static struct exec_vertex_shader *exec_vertex_shader( struct draw_vertex_shader *vs ) +{ + return (struct exec_vertex_shader *)vs; +} + + +/* Not required for run_linear. + */ static void vs_exec_prepare( struct draw_vertex_shader *shader, struct draw_context *draw ) @@ -81,10 +93,9 @@ vs_exec_run( struct draw_vertex_shader *shader, const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; - assert(draw->vertex_shader->info.output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); + assert(shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - machine->Consts = (float (*)[4]) draw->user.constants; + machine->Consts = (const float (*)[4]) draw->user.constants; machine->Inputs = ALIGN16_ASSIGN(inputs); if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ @@ -179,6 +190,64 @@ vs_exec_run( struct draw_vertex_shader *shader, +/* Simplified vertex shader interface for the pt paths. Given the + * complexity of code-generating all the above operations together, + * it's time to try doing all the other stuff separately. + */ +static void +vs_exec_run_linear( struct draw_vertex_shader *shader, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ) +{ + struct exec_vertex_shader *evs = exec_vertex_shader(shader); + struct tgsi_exec_machine *machine = evs->machine; + unsigned int i, j; + unsigned slot; + + machine->Consts = constants; + + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + + /* Swizzle inputs. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < shader->info.num_inputs; slot++) { + machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; + machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; + machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; + machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; + } + } + + /* run interpreter */ + tgsi_exec_machine_run( machine ); + + /* Unswizzle all output results. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < shader->info.num_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + } + + /* Advance input, output pointers: + */ + input = (const float (*)[4])((const char *)input + input_stride); + output = (float (*)[4])((char *)output + output_stride); + } +} + + + + static void vs_exec_delete( struct draw_vertex_shader *dvs ) { @@ -191,17 +260,23 @@ struct draw_vertex_shader * draw_create_vs_exec(struct draw_context *draw, const struct pipe_shader_state *state) { - struct draw_vertex_shader *vs = CALLOC_STRUCT( draw_vertex_shader ); + struct exec_vertex_shader *vs = CALLOC_STRUCT( exec_vertex_shader ); uint nt = tgsi_num_tokens(state->tokens); if (vs == NULL) return NULL; /* we make a private copy of the tokens */ - vs->state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0])); - vs->prepare = vs_exec_prepare; - vs->run = vs_exec_run; - vs->delete = vs_exec_delete; + vs->base.state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0])); + tgsi_scan_shader(state->tokens, &vs->base.info); + + + vs->base.prepare = vs_exec_prepare; + vs->base.run = vs_exec_run; + vs->base.run_linear = vs_exec_run_linear; + vs->base.delete = vs_exec_delete; + vs->machine = &draw->machine; + - return vs; + return &vs->base; } diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 73076d2467..d0baca715e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -88,8 +88,7 @@ vs_llvm_run( struct draw_vertex_shader *base, assert(count <= 4); - assert(draw->vertex_shader->state->output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); + assert(base->state->output_semantic_name[0] == TGSI_SEMANTIC_POSITION); /* Consts does not require 16 byte alignment. */ machine->Consts = (float (*)[4]) draw->user.constants; @@ -169,6 +168,65 @@ vs_llvm_run( struct draw_vertex_shader *base, return clipped != 0; } + + + +static void +vs_llvm_run_linear( struct draw_vertex_shader *base, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ) +{ + struct draw_llvm_vertex_shader *shader = + (struct draw_llvm_vertex_shader *)base; + + struct tgsi_exec_machine *machine = &draw->machine; + unsigned int j; + + + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + + /* Swizzle inputs. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < draw->num_vs_inputs; slot++) { + machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; + machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; + machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; + machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; + } + } + + /* run shader */ + gallivm_cpu_vs_exec(shader->llvm_prog, + machine->Inputs, + machine->Outputs, + (float (*)[4]) constants, + machine->Temps); + + + /* Unswizzle all output results + */ + for (slot = 1; slot < draw->num_vs_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + + /* Advance input, output pointers: + */ + input = (const float (*)[4])((const char *)input + input_stride); + output = (float (*)[4])((char *)output + output_stride); + } +} + + + static void vs_llvm_delete( struct draw_vertex_shader *base ) { @@ -198,8 +256,12 @@ draw_create_vs_llvm(struct draw_context *draw, /* we make a private copy of the tokens */ vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); + + tgsi_scan_shader(shader->tokens, &vs->base.info); + vs->base.prepare = vs_llvm_prepare; vs->base.run = vs_llvm_run; + vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; { diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index ee0a3105b9..873ecfdc5d 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -58,7 +58,11 @@ typedef void (XSTDCALL *codegen_function) ( struct draw_sse_vertex_shader { struct draw_vertex_shader base; struct x86_function sse2_program; + codegen_function func; + + struct tgsi_exec_machine *machine; + float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -96,11 +100,10 @@ vs_sse_run( struct draw_vertex_shader *base, const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; - assert(draw->vertex_shader->info.output_semantic_name[0] - == TGSI_SEMANTIC_POSITION); + assert(base->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); /* Consts does not require 16 byte alignment. */ - machine->Consts = (float (*)[4]) draw->user.constants; + machine->Consts = (const float (*)[4]) draw->user.constants; machine->Inputs = ALIGN16_ASSIGN(inputs); if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ @@ -124,7 +127,7 @@ vs_sse_run( struct draw_vertex_shader *base, */ shader->func(machine->Inputs, machine->Outputs, - machine->Consts, + (float (*)[4])machine->Consts, machine->Temps, shader->immediates); } @@ -200,6 +203,67 @@ vs_sse_run( struct draw_vertex_shader *base, } +/* Simplified vertex shader interface for the pt paths. Given the + * complexity of code-generating all the above operations together, + * it's time to try doing all the other stuff separately. + */ +static void +vs_sse_run_linear( struct draw_vertex_shader *base, + const float (*input)[4], + float (*output)[4], + const float (*constants)[4], + unsigned count, + unsigned input_stride, + unsigned output_stride ) +{ + struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; + struct tgsi_exec_machine *machine = shader->machine; + unsigned int i, j; + unsigned slot; + + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { + unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); + + /* Swizzle inputs. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < base->info.num_inputs; slot++) { + machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; + machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; + machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; + machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; + } + } + + /* run compiled shader + */ + shader->func(machine->Inputs, + machine->Outputs, + (float (*)[4])constants, + machine->Temps, + shader->immediates); + + + /* Unswizzle all output results. + */ + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < base->info.num_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + } + + /* Advance input, output pointers: + */ + input = (const float (*)[4])((const char *)input + input_stride); + output = (float (*)[4])((char *)output + output_stride); + } +} + + + static void vs_sse_delete( struct draw_vertex_shader *base ) @@ -229,8 +293,12 @@ draw_create_vs_sse(struct draw_context *draw, /* we make a private copy of the tokens */ vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); + + tgsi_scan_shader(templ->tokens, &vs->base.info); + vs->base.prepare = vs_sse_prepare; vs->base.run = vs_sse_run; + vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; x86_init_func( &vs->sse2_program ); diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 6fc7c9fcd7..0fa7c9313c 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -31,7 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_vs.h" struct widepoint_stage { -- cgit v1.2.3 From fe8af141246bdfc0e98beec0089acdb92407bcfa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:42:05 +0100 Subject: draw: don't always run pipeline if clipping --- src/gallium/auxiliary/draw/draw_pt.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c0125c906f..60a47f3911 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -74,11 +74,11 @@ draw_pt_arrays(struct draw_context *draw, } - if (draw->pt.middle.opt[opt] == NULL) { - opt = PT_PIPELINE | PT_CLIPTEST | PT_SHADE; + middle = draw->pt.middle.opt[opt]; + if (middle == NULL) { + middle = draw->pt.middle.opt[PT_PIPELINE | PT_CLIPTEST | PT_SHADE]; } - middle = draw->pt.middle.opt[opt]; assert(middle); /* May create a short-circuited version of this for small primitives: -- cgit v1.2.3 From c503e55d74cf84f87f82b3dab3cb4d38b201d47a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:43:40 +0100 Subject: draw: move hw vertex emit to a new module --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_private.h | 8 - src/gallium/auxiliary/draw/draw_pt.h | 33 ++++ src/gallium/auxiliary/draw/draw_pt_emit.c | 208 +++++++++++++++++++++ .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 161 +++------------- 5 files changed, 270 insertions(+), 141 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_emit.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 5ab3cfe5ce..836e98f086 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -21,6 +21,7 @@ C_SOURCES = \ draw_pt_fetch_pipeline.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_pipeline.c \ + draw_pt_emit.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 7953dbb7d9..9407217fd3 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -376,14 +376,6 @@ boolean draw_pt_arrays( struct draw_context *draw, unsigned count ); void draw_pt_reset_vertex_ids( struct draw_context *draw ); -void draw_pt_run_pipeline( struct draw_context *draw, - unsigned prim, - char *verts, - unsigned vertex_stride, - unsigned vertex_count, - const ushort *elts, - unsigned count ); - #define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ #define DRAW_FLUSH_PRIM_QUEUE 0x2 diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 08afb60645..31d18ec62b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -128,4 +128,37 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); +/* More helpers: + */ +void draw_pt_run_pipeline( struct draw_context *draw, + unsigned prim, + char *verts, + unsigned vertex_stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); + + +/* HW vertex emit: + */ +struct pt_emit; + +void draw_pt_emit_prepare( struct pt_emit *emit, + unsigned prim, + unsigned opt ); + +void draw_pt_emit( struct pt_emit *emit, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); + +void draw_pt_emit_destroy( struct pt_emit *emit ); + +struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); + + + + #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c new file mode 100644 index 0000000000..e9ed29450a --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -0,0 +1,208 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "translate/translate.h" + + +struct pt_emit { + struct draw_context *draw; + + struct translate *translate; + + unsigned pipeline_vertex_size; + unsigned prim; + unsigned opt; +}; + + +void draw_pt_emit_prepare( struct pt_emit *emit, + unsigned prim, + unsigned opt ) +{ + struct draw_context *draw = emit->draw; + const struct vertex_info *vinfo; + unsigned dst_offset; + struct translate_key hw_key; + unsigned i; + boolean ok; + + ok = draw->render->set_primitive(draw->render, prim); + if (!ok) { + assert(0); + return; + } + + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); + + + /* In passthrough mode, need to translate from vertex shader + * outputs to hw vertices. + */ + dst_offset = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (sizeof(struct vertex_header) + + vinfo->src_index[i] * 4 * sizeof(float) ); + + + + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; + } + + hw_key.nr_elements = vinfo->num_attribs; + hw_key.output_stride = vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!emit->translate || + memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (emit->translate) + emit->translate->release(emit->translate); + + emit->translate = translate_generic_create( &hw_key ); + } +} + + +void draw_pt_emit( struct pt_emit *emit, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ) +{ + struct draw_context *draw = emit->draw; + struct translate *translate = emit->translate; + struct vbuf_render *render = draw->render; + void *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = render->allocate_vertices(render, + (ushort)translate->key.output_stride, + (ushort)count); + if (!hw_verts) { + assert(0); + return; + } + + translate->set_buffer(translate, + 0, + verts, + stride ); + + translate->set_buffer(translate, + 1, + &draw->rasterizer->point_size, + 0); + + translate->run( translate, + 0, + vertex_count, + hw_verts ); + + render->draw(render, + elts, + count); + + render->release_vertices(render, + hw_verts, + translate->key.output_stride, + vertex_count); +} + + +struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) +{ + struct pt_emit *emit = CALLOC_STRUCT(pt_emit); + if (!emit) + return NULL; + + emit->draw = draw; + + return emit; +} + +void draw_pt_emit_destroy( struct pt_emit *emit ) +{ + if (emit->translate) + emit->translate->release( emit->translate ); + + FREE(emit); +} diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index cf37493eb6..8db9e31e2d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -38,7 +38,7 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - struct translate *translate; + struct pt_emit *emit; unsigned pipeline_vertex_size; unsigned prim; @@ -51,98 +51,12 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - struct draw_context *draw = fpme->draw; - unsigned i; - boolean ok; - const struct vertex_info *vinfo; - unsigned dst_offset; - struct translate_key hw_key; fpme->prim = prim; fpme->opt = opt; - if (!(opt & PT_PIPELINE)) { - ok = draw->render->set_primitive(draw->render, prim); - if (!ok) { - assert(0); - return; - } - - /* Must do this after set_primitive() above: - */ - vinfo = draw->render->get_vertex_info(draw->render); - - - /* In passthrough mode, need to translate from vertex shader - * outputs to hw vertices. - */ - dst_offset = 0; - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned src_buffer = 0; - unsigned output_format; - unsigned src_offset = (sizeof(struct vertex_header) + - vinfo->src_index[i] * 4 * sizeof(float) ); - - - - switch (vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - src_buffer = 1; - src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; - emit_sz = 4 * sizeof(ubyte); - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; - } - - hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - hw_key.element[i].input_buffer = src_buffer; - hw_key.element[i].input_offset = src_offset; - hw_key.element[i].output_format = output_format; - hw_key.element[i].output_offset = dst_offset; - - dst_offset += emit_sz; - } - - hw_key.nr_elements = vinfo->num_attribs; - hw_key.output_stride = vinfo->size * 4; - - /* Don't bother with caching at this stage: - */ - if (!fpme->translate || - memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) - { - if (fpme->translate) - fpme->translate->release(fpme->translate); - - fpme->translate = translate_generic_create( &hw_key ); - } - } - + if (!(opt & PT_PIPELINE)) + draw_pt_emit_prepare( fpme->emit, prim, opt ); //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; @@ -194,43 +108,12 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw_elts, draw_count ); } else { - struct translate *translate = fpme->translate; - void *hw_verts; - - /* XXX: need to flush to get prim_vbuf.c to release its allocation?? - */ - draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - - hw_verts = draw->render->allocate_vertices(draw->render, - (ushort)fpme->translate->key.output_stride, - (ushort)fetch_count); - if (!hw_verts) { - assert(0); - return; - } - - translate->set_buffer(translate, - 0, - pipeline_verts, - fpme->pipeline_vertex_size ); - - translate->set_buffer(translate, - 1, - &fpme->draw->rasterizer->point_size, - 0); - - translate->run( translate, - 0, fetch_count, - hw_verts ); - - draw->render->draw(draw->render, - draw_elts, - draw_count); - - draw->render->release_vertices(draw->render, - hw_verts, - fpme->translate->key.output_stride, - fetch_count); + draw_pt_emit( fpme->emit, + pipeline_verts, + fpme->pipeline_vertex_size, + fetch_count, + draw_elts, + draw_count ); } @@ -252,14 +135,26 @@ static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *draw ) { - struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); + struct fetch_pipeline_middle_end *fpme = CALLOC_STRUCT( fetch_pipeline_middle_end ); + if (!fpme) + goto fail; + + fpme->base.prepare = fetch_pipeline_prepare; + fpme->base.run = fetch_pipeline_run; + fpme->base.finish = fetch_pipeline_finish; + fpme->base.destroy = fetch_pipeline_destroy; + + fpme->draw = draw; + + fpme->emit = draw_pt_emit_create( draw ); + if (!fpme->emit) + goto fail; - fetch_pipeline->base.prepare = fetch_pipeline_prepare; - fetch_pipeline->base.run = fetch_pipeline_run; - fetch_pipeline->base.finish = fetch_pipeline_finish; - fetch_pipeline->base.destroy = fetch_pipeline_destroy; + return &fpme->base; - fetch_pipeline->draw = draw; + fail: + if (fpme) + fetch_pipeline_destroy( &fpme->base ); - return &fetch_pipeline->base; + return NULL; } -- cgit v1.2.3 From 4dcb09d48981f07a82d7f609fe492453c8fdbcf4 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 17 Apr 2008 17:53:33 +0100 Subject: gallium: Add new file to scons build. --- src/gallium/auxiliary/draw/SConscript | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index a7fb5dbd61..62e0cd9e50 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -16,6 +16,7 @@ draw = env.ConvenienceLibrary( 'draw_offset.c', 'draw_pt.c', 'draw_pt_vcache.c', + 'draw_pt_emit.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_pipeline.c', 'draw_pt_fetch_shade_pipeline.c', -- cgit v1.2.3 From f2b3f6cbdfc4799a0f742c06d2ce0755582c50c4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Apr 2008 11:12:44 -0600 Subject: gallium: reorder some of the destroy context code --- src/mesa/state_tracker/st_context.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 154327239d..dadc524b51 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -170,10 +170,6 @@ static void st_destroy_context_priv( struct st_context *st ) _vbo_DestroyContext(st->ctx); - cso_destroy_context(st->cso_context); - - _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache); - for (i = 0; i < Elements(st->state.constants); i++) { if (st->state.constants[i].buffer) { pipe_buffer_reference(ws, &st->state.constants[i].buffer, NULL); @@ -188,6 +184,12 @@ static void st_destroy_context_priv( struct st_context *st ) void st_destroy_context( struct st_context *st ) { GLcontext *ctx = st->ctx; + + /* need to unbind and destroy CSO objects before anything else */ + cso_destroy_context(st->cso_context); + + _mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache); + _mesa_free_context_data(ctx); st_destroy_context_priv(st); free(ctx); -- cgit v1.2.3 From ce454d2192918ae4b2535d0e76c68ebde3c4653f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Apr 2008 11:13:05 -0600 Subject: gallium: assert that we're not deleting the currently bound shader --- src/gallium/drivers/softpipe/sp_state_fs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 4eefd1d61f..2921066ce3 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -82,7 +82,10 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { + struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; + + assert(fs != softpipe->fs); state->delete( state ); } -- cgit v1.2.3 From 211170c192dfac5c2b39a6f34056255712fdfed6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Apr 2008 11:31:14 -0600 Subject: gallium: plug in a select_destroy() function (fixes segfault on exit) --- src/mesa/state_tracker/st_cb_feedback.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c index 5315294c07..605bfee743 100644 --- a/src/mesa/state_tracker/st_cb_feedback.c +++ b/src/mesa/state_tracker/st_cb_feedback.c @@ -238,6 +238,12 @@ select_reset_stipple_counter( struct draw_stage *stage ) /* no-op */ } +static void +select_destroy( struct draw_stage *stage ) +{ + /* no-op */ +} + /** * Create GL selection mode drawing stage. @@ -254,6 +260,7 @@ draw_glselect_stage(GLcontext *ctx, struct draw_context *draw) fs->stage.tri = select_tri; fs->stage.flush = select_flush; fs->stage.reset_stipple_counter = select_reset_stipple_counter; + fs->stage.destroy = select_destroy; fs->ctx = ctx; return &fs->stage; -- cgit v1.2.3 From 5af9a690b2afc4c8f0f1118dad891b5ab53db597 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Apr 2008 13:21:26 -0600 Subject: gallium: add missing pipe_surface_unmap() call --- src/mesa/state_tracker/st_cb_accum.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index 4f9a22161c..1636bed91a 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -173,6 +173,8 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, default: _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } + + pipe_surface_unmap(acc_ps); } -- cgit v1.2.3 From 01b6354e72a84f8c3c22be1f77eab8d9c05920a3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 17 Apr 2008 15:26:37 -0600 Subject: gallium: tweak x/ybias values --- src/gallium/auxiliary/draw/draw_wide_point.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 0fa7c9313c..3d0add0c1a 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -199,7 +199,7 @@ static void widepoint_first_point( struct draw_stage *stage, wide->ybias = 0.0; if (draw->rasterizer->gl_rasterization_rules) { - wide->ybias = -0.125; + wide->xbias = 0.125; } /* XXX we won't know the real size if it's computed by the vertex shader! */ -- cgit v1.2.3 From a773f06e969a3992451dd7fe6fd55ea96b2774fa Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 23:44:32 +0100 Subject: draw: split off all the extra functionality in the vertex shader This will at least allow us to make the initial gains to get decent vertex performance much more quickly & with higher confidence of getting it right. At some later point can look again at code-generating all the fetch/cliptest/viewport extras in the same block as the vertex shader. For now, just need to get some decent baseline performance. --- src/gallium/auxiliary/draw/Makefile | 4 +- src/gallium/auxiliary/draw/draw_context.c | 26 +-- src/gallium/auxiliary/draw/draw_private.h | 2 + src/gallium/auxiliary/draw/draw_pt.h | 51 +++++- src/gallium/auxiliary/draw/draw_pt_emit.c | 16 +- src/gallium/auxiliary/draw/draw_pt_fetch.c | 175 ++++++++++++++++++ .../auxiliary/draw/draw_pt_fetch_pipeline.c | 4 +- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 109 +++++++++-- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 5 +- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 202 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vs_exec.c | 82 ++++++--- src/gallium/auxiliary/draw/draw_vs_llvm.c | 39 ++-- src/gallium/auxiliary/draw/draw_vs_sse.c | 38 ++-- 13 files changed, 635 insertions(+), 118 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch.c create mode 100644 src/gallium/auxiliary/draw/draw_pt_post_vs.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 836e98f086..154c8a99b5 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -20,8 +20,10 @@ C_SOURCES = \ draw_pt_fetch_emit.c \ draw_pt_fetch_pipeline.c \ draw_pt_fetch_shade_pipeline.c \ - draw_pt_pipeline.c \ + draw_pt_fetch.c \ + draw_pt_post_vs.c \ draw_pt_emit.c \ + draw_pt_pipeline.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 9b2dcc0b57..4838b68ed1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -110,6 +110,12 @@ struct draw_context *draw_create( void ) tgsi_exec_machine_init(&draw->machine); + /* FIXME: give this machine thing a proper constructor: + */ + draw->machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + draw->machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + + if (!draw_pt_init( draw )) goto fail; @@ -155,8 +161,13 @@ void draw_destroy( struct draw_context *draw ) if (draw->pipeline.rasterize) draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); + if (draw->machine.Inputs) + align_free(draw->machine.Inputs); + if (draw->machine.Outputs) + align_free(draw->machine.Outputs); tgsi_exec_machine_free_data(&draw->machine); - + + if (draw->vs.vertex_cache) align_free( draw->vs.vertex_cache ); /* Frees all the vertices. */ @@ -265,6 +276,7 @@ draw_set_vertex_elements(struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); memcpy(draw->vertex_element, elements, count * sizeof(elements[0])); + draw->nr_vertex_elements = count; } @@ -463,15 +475,3 @@ boolean draw_get_edgeflag( struct draw_context *draw, return 1; } - -#if 0 -/* Crufty init function. Fix me. - */ -boolean draw_init_machine( struct draw_context *draw ) -{ - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); - machine->Inputs = ALIGN16_ASSIGN(inputs); - machine->Outputs = ALIGN16_ASSIGN(outputs); -} -#endif diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 9407217fd3..da94e69781 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -224,6 +224,8 @@ struct draw_context unsigned nr_vertex_buffers; struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_elements; + struct draw_vertex_shader *vertex_shader; boolean identity_viewport; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 31d18ec62b..316289969b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -112,6 +112,7 @@ struct draw_pt_middle_end { * mode... */ struct vbuf_render; +struct vertex_header; /* Helper functions. @@ -132,25 +133,25 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *d */ void draw_pt_run_pipeline( struct draw_context *draw, unsigned prim, - char *verts, - unsigned vertex_stride, + struct vertex_header *verts, unsigned vertex_count, + unsigned vertex_stride, const ushort *elts, unsigned count ); -/* HW vertex emit: +/******************************************************************************* + * HW vertex emit: */ struct pt_emit; void draw_pt_emit_prepare( struct pt_emit *emit, - unsigned prim, - unsigned opt ); + unsigned prim ); void draw_pt_emit( struct pt_emit *emit, - char *verts, - unsigned stride, + const float (*vertex_data)[4], unsigned vertex_count, + unsigned stride, const ushort *elts, unsigned count ); @@ -159,6 +160,42 @@ void draw_pt_emit_destroy( struct pt_emit *emit ); struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); +/******************************************************************************* + * API vertex fetch: + */ + +struct pt_fetch; +void draw_pt_fetch_prepare( struct pt_fetch *fetch, + boolean emit_header, + unsigned vertex_size ); + +void draw_pt_fetch_run( struct pt_fetch *fetch, + const unsigned *elts, + unsigned count, + char *verts ); + +void draw_pt_fetch_destroy( struct pt_fetch *fetch ); + +struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ); + +/******************************************************************************* + * Post-VS: cliptest, rhw, viewport + */ +struct pt_post_vs; + +boolean draw_pt_post_vs_run( struct pt_post_vs *pvs, + struct vertex_header *pipeline_verts, + unsigned stride, + unsigned count ); + +void draw_pt_post_vs_prepare( struct pt_post_vs *pvs, + boolean bypass_clipping, + boolean identity_viewport, + boolean opengl ); + +struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw ); + +void draw_pt_post_vs_destroy( struct pt_post_vs *pvs ); #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index e9ed29450a..ef9db70a02 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -38,16 +38,11 @@ struct pt_emit { struct draw_context *draw; struct translate *translate; - - unsigned pipeline_vertex_size; - unsigned prim; - unsigned opt; }; void draw_pt_emit_prepare( struct pt_emit *emit, - unsigned prim, - unsigned opt ) + unsigned prim ) { struct draw_context *draw = emit->draw; const struct vertex_info *vinfo; @@ -75,8 +70,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, unsigned emit_sz = 0; unsigned src_buffer = 0; unsigned output_format; - unsigned src_offset = (sizeof(struct vertex_header) + - vinfo->src_index[i] * 4 * sizeof(float) ); + unsigned src_offset = (vinfo->src_index[i] * 4 * sizeof(float) ); @@ -139,9 +133,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit, void draw_pt_emit( struct pt_emit *emit, - char *verts, - unsigned stride, + const float (*vertex_data)[4], unsigned vertex_count, + unsigned stride, const ushort *elts, unsigned count ) { @@ -164,7 +158,7 @@ void draw_pt_emit( struct pt_emit *emit, translate->set_buffer(translate, 0, - verts, + vertex_data, stride ); translate->set_buffer(translate, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c new file mode 100644 index 0000000000..a7553023b8 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.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. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "translate/translate.h" + + +struct pt_fetch { + struct draw_context *draw; + + struct translate *translate; + + unsigned vertex_size; +}; + + + +/* Perform the fetch from API vertex elements & vertex buffers, to a + * contiguous set of float[4] attributes as required for the + * vertex_shader->run_linear() method. + * + * This is used in all cases except pure passthrough + * (draw_pt_fetch_emit.c) which has its own version to translate + * directly to hw vertices. + * + */ +void draw_pt_fetch_prepare( struct pt_fetch *fetch, + boolean emit_header, + unsigned vertex_size ) +{ + struct draw_context *draw = fetch->draw; + unsigned i, nr = 0; + unsigned dst_offset = 0; + struct translate_key key; + + fetch->vertex_size = vertex_size; + + memset(&key, 0, sizeof(key)); + + /* If PT_SHADE is not set, then we are creating post-shader + * vertices, meaning that we need to emit/leave space for a vertex + * header. + * + * It's worth considering whether the vertex headers should contain + * a pointer to the 'data', rather than having it inline. + * Something to look at after we've fully switched over to the pt + * paths. + */ + if (emit_header) + { + /* Need to set header->vertex_id = 0xffff somehow. + */ + key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT; + key.element[nr].input_buffer = draw->nr_vertex_buffers; + key.element[nr].input_offset = 0; + key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT; + key.element[nr].output_offset = dst_offset; + dst_offset += 1 * sizeof(float); + nr++; + + + /* Just leave the clip[] array untouched. + */ + dst_offset += 4 * sizeof(float); + } + + + for (i = 0; i < draw->nr_vertex_elements; i++) { + key.element[nr].input_format = draw->vertex_element[i].src_format; + key.element[nr].input_buffer = draw->vertex_element[i].vertex_buffer_index; + key.element[nr].input_offset = draw->vertex_element[i].src_offset; + key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + key.element[nr].output_offset = dst_offset; + + dst_offset += 4 * sizeof(float); + nr++; + } + + assert(dst_offset <= vertex_size); + + key.nr_elements = nr; + key.output_stride = vertex_size; + + + /* Don't bother with caching at this stage: + */ + if (!fetch->translate || + memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) + { + if (fetch->translate) + fetch->translate->release(fetch->translate); + + fetch->translate = translate_generic_create( &key ); + + if (emit_header) { + static struct vertex_header vh = { 0, 0, 0, 0xffff }; + fetch->translate->set_buffer(fetch->translate, + draw->nr_vertex_buffers, + &vh, + 0); + } + } +} + + + + +void draw_pt_fetch_run( struct pt_fetch *fetch, + const unsigned *elts, + unsigned count, + char *verts ) +{ + struct draw_context *draw = fetch->draw; + struct translate *translate = fetch->translate; + unsigned i; + + for (i = 0; i < draw->nr_vertex_buffers; i++) { + translate->set_buffer(translate, + i, + ((char *)draw->user.vbuffer[i] + + draw->vertex_buffer[i].buffer_offset), + draw->vertex_buffer[i].pitch ); + } + + translate->run_elts( translate, + elts, + count, + verts ); +} + + +struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) +{ + struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch); + if (!fetch) + return NULL; + + fetch->draw = draw; + return fetch; +} + +void draw_pt_fetch_destroy( struct pt_fetch *fetch ) +{ + FREE(fetch); +} + diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c index 79548d4156..26d0b37286 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -286,9 +286,9 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, */ draw_pt_run_pipeline( fpme->draw, fpme->prim, - pipeline_verts, - fpme->pipeline_vertex_size, + (struct vertex_header *)pipeline_verts, fetch_count, + fpme->pipeline_vertex_size, draw_elts, draw_count ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 8db9e31e2d..0b9e8d15ba 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -39,8 +39,11 @@ struct fetch_pipeline_middle_end { struct draw_context *draw; struct pt_emit *emit; + struct pt_fetch *fetch; + struct pt_post_vs *post_vs; - unsigned pipeline_vertex_size; + unsigned vertex_data_offset; + unsigned vertex_size; unsigned prim; unsigned opt; }; @@ -51,15 +54,43 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + struct draw_vertex_shader *vs = draw->vertex_shader; + unsigned nr = MAX2( vs->info.num_inputs, + vs->info.num_outputs ); fpme->prim = prim; fpme->opt = opt; + /* Always leave room for the vertex header whether we need it or + * not. It's hard to get rid of it in particular because of the + * viewport code in draw_pt_post_vs.c. + */ + fpme->vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); + + + + draw_pt_fetch_prepare( fpme->fetch, + (opt & (PT_CLIPTEST | PT_PIPELINE)) != 0, + fpme->vertex_size ); + + /* XXX: it's not really gl rasterization rules we care about here, + * but gl vs dx9 clip spaces. + */ + draw_pt_post_vs_prepare( fpme->post_vs, + draw->rasterizer->bypass_clipping, + draw->identity_viewport, + draw->rasterizer->gl_rasterization_rules ); + + if (!(opt & PT_PIPELINE)) - draw_pt_emit_prepare( fpme->emit, prim, opt ); + draw_pt_emit_prepare( fpme->emit, + prim ); + + /* No need to prepare the shader. + */ + vs->prepare(vs, draw); - //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); - fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; } @@ -74,44 +105,63 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *shader = draw->vertex_shader; - char *pipeline_verts; - unsigned pipeline = PT_PIPELINE; + unsigned opt = fpme->opt; - pipeline_verts = MALLOC(fpme->pipeline_vertex_size * - fetch_count); + struct vertex_header *pipeline_verts = + (struct vertex_header *)MALLOC(fpme->vertex_size * fetch_count); if (!pipeline_verts) { assert(0); return; } - - /* Shade + /* Fetch into our vertex buffer */ - shader->prepare(shader, draw); - - if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts, - fpme->pipeline_vertex_size)) + draw_pt_fetch_run( fpme->fetch, + fetch_elts, + fetch_count, + (char *)pipeline_verts ); + + /* Run the shader, note that this overwrites the data[] parts of + * the pipeline verts. If there is no shader, ie a bypass shader, + * then the inputs == outputs, and are already in the correct + * place. + */ + if (opt & PT_SHADE) { - pipeline |= PT_CLIPTEST; + shader->run_linear(shader, + (const float (*)[4])pipeline_verts->data, + ( float (*)[4])pipeline_verts->data, + (const float (*)[4])draw->user.constants, + fetch_count, + fpme->vertex_size, + fpme->vertex_size); } + if (draw_pt_post_vs_run( fpme->post_vs, + pipeline_verts, + fetch_count, + fpme->vertex_size )) + { + opt |= PT_PIPELINE; + } /* Do we need to run the pipeline? */ - if (fpme->opt & pipeline) { + if (opt & PT_PIPELINE) { draw_pt_run_pipeline( fpme->draw, fpme->prim, pipeline_verts, - fpme->pipeline_vertex_size, fetch_count, + fpme->vertex_size, draw_elts, draw_count ); - } else { + } + else { draw_pt_emit( fpme->emit, - pipeline_verts, - fpme->pipeline_vertex_size, + (const float (*)[4])pipeline_verts->data, fetch_count, + fpme->vertex_size, draw_elts, draw_count ); } @@ -129,6 +179,17 @@ static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) { + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + + if (fpme->fetch) + draw_pt_fetch_destroy( fpme->fetch ); + + if (fpme->emit) + draw_pt_emit_destroy( fpme->emit ); + + if (fpme->post_vs) + draw_pt_post_vs_destroy( fpme->post_vs ); + FREE(middle); } @@ -146,6 +207,14 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context * fpme->draw = draw; + fpme->fetch = draw_pt_fetch_create( draw ); + if (!fpme->fetch) + goto fail; + + fpme->post_vs = draw_pt_post_vs_create( draw ); + if (!fpme->post_vs) + goto fail; + fpme->emit = draw_pt_emit_create( draw ); if (!fpme->emit) goto fail; diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index 17ce6febec..1a9a3adb03 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -117,12 +117,13 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw ) */ void draw_pt_run_pipeline( struct draw_context *draw, unsigned prim, - char *verts, - unsigned stride, + struct vertex_header *pipeline_verts, unsigned vertex_count, + unsigned stride, const ushort *elts, unsigned count ) { + char *verts = (char *)pipeline_verts; unsigned i; draw->pt.pipeline.verts = verts; diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c new file mode 100644 index 0000000000..315b02f4ee --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -0,0 +1,202 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#include "pipe/p_util.h" +#include "pipe/p_context.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + +struct pt_post_vs { + struct draw_context *draw; + + boolean (*run)( struct pt_post_vs *pvs, + struct vertex_header *vertices, + unsigned count, + unsigned stride ); +}; + + + +static INLINE unsigned +compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) +{ + unsigned mask = 0x0; + unsigned i; + + /* Do the hardwired planes first: + */ + if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; + if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; + if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; + if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; + if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; + if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + + /* Followed by any remaining ones: + */ + for (i = 6; i < nr; i++) { + if (dot4(clip, plane[i]) < 0) + mask |= (1<draw->viewport.scale; + const float *trans = pvs->draw->viewport.translate; + unsigned j; + unsigned clipped = 0; + + for (j = 0; j < count; j++) { + out->clip[0] = out->data[0][0]; + out->clip[1] = out->data[0][1]; + out->clip[2] = out->data[0][2]; + out->clip[3] = out->data[0][3]; + + out->vertex_id = 0xffff; + out->edgeflag = 1; + out->clipmask = compute_clipmask_gl(out->clip, + pvs->draw->plane, + pvs->draw->nr_planes); + clipped += out->clipmask; + + if (out->clipmask == 0) + { + /* divide by w */ + float w = 1.0f / out->data[0][3]; + + /* Viewport mapping */ + out->data[0][0] = out->data[0][0] * w * scale[0] + trans[0]; + out->data[0][1] = out->data[0][1] * w * scale[1] + trans[1]; + out->data[0][2] = out->data[0][2] * w * scale[2] + trans[2]; + out->data[0][3] = w; + } + + out = (struct vertex_header *)( (char *)out + stride ); + } + + return clipped != 0; +} + + + +/* If bypass_clipping is set, skip cliptest and rhw divide. + */ +static boolean post_vs_viewport( struct pt_post_vs *pvs, + struct vertex_header *vertices, + unsigned count, + unsigned stride ) +{ + struct vertex_header *out = vertices; + const float *scale = pvs->draw->viewport.scale; + const float *trans = pvs->draw->viewport.translate; + unsigned j; + + debug_printf("%s\n", __FUNCTION__); + for (j = 0; j < count; j++) { + /* Viewport mapping only, no cliptest/rhw divide + */ + out->data[0][0] = out->data[0][0] * scale[0] + trans[0]; + out->data[0][1] = out->data[0][1] * scale[1] + trans[1]; + out->data[0][2] = out->data[0][2] * scale[2] + trans[2]; + + out = (struct vertex_header *)((char *)out + stride); + } + + return FALSE; +} + + +/* If bypass_clipping is set and we have an identity viewport, nothing + * to do. + */ +static boolean post_vs_none( struct pt_post_vs *pvs, + struct vertex_header *vertices, + unsigned count, + unsigned stride ) +{ + debug_printf("%s\n", __FUNCTION__); + return FALSE; +} + +boolean draw_pt_post_vs_run( struct pt_post_vs *pvs, + struct vertex_header *pipeline_verts, + unsigned count, + unsigned stride ) +{ + return pvs->run( pvs, pipeline_verts, count, stride ); +} + + +void draw_pt_post_vs_prepare( struct pt_post_vs *pvs, + boolean bypass_clipping, + boolean identity_viewport, + boolean opengl ) +{ + if (bypass_clipping) { + if (identity_viewport) + pvs->run = post_vs_none; + else + pvs->run = post_vs_viewport; + } + else { + //if (opengl) + pvs->run = post_vs_cliptest_viewport_gl; + } +} + + +struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw ) +{ + struct pt_post_vs *pvs = CALLOC_STRUCT( pt_post_vs ); + if (!pvs) + return NULL; + + pvs->draw = draw; + + return pvs; +} + +void draw_pt_post_vs_destroy( struct pt_post_vs *pvs ) +{ + FREE(pvs); +} diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 0e05b79715..184151b9b1 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -58,8 +58,10 @@ static void vs_exec_prepare( struct draw_vertex_shader *shader, struct draw_context *draw ) { + struct exec_vertex_shader *evs = exec_vertex_shader(shader); + /* specify the vertex program to interpret/execute */ - tgsi_exec_machine_bind_shader(&draw->machine, + tgsi_exec_machine_bind_shader(evs->machine, shader->state.tokens, PIPE_MAX_SAMPLERS, NULL /*samplers*/ ); @@ -84,31 +86,45 @@ vs_exec_run( struct draw_vertex_shader *shader, void *vOut, unsigned vertex_size) { - struct tgsi_exec_machine *machine = &draw->machine; + struct exec_vertex_shader *evs = exec_vertex_shader(shader); + struct tgsi_exec_machine *machine = evs->machine; unsigned int i, j; unsigned int clipped = 0; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); + struct tgsi_exec_vector *outputs = 0; const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; assert(shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); machine->Consts = (const float (*)[4]) draw->user.constants; - machine->Inputs = ALIGN16_ASSIGN(inputs); + if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ - machine->Outputs = machine->Inputs; + outputs = machine->Inputs; } else { - machine->Outputs = ALIGN16_ASSIGN(outputs); + outputs = machine->Outputs; } for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); draw->vertex_fetch.fetch_func( draw, machine, &elts[i], max_vertices ); +#if 0 + for (j = 0; j < max_vertices; j++) { + unsigned slot; + debug_printf("%d) Input vert:\n", i + j); + for (slot = 0; slot < shader->info.num_inputs; slot++) { + debug_printf("\t%d: %f %f %f %f\n", slot, + machine->Inputs[slot].xyzw[0].f[j], + machine->Inputs[slot].xyzw[1].f[j], + machine->Inputs[slot].xyzw[2].f[j], + machine->Inputs[slot].xyzw[3].f[j]); + } + } +#endif + + if (!draw->rasterizer->bypass_vs) { /* run interpreter */ tgsi_exec_machine_run( machine ); @@ -127,10 +143,10 @@ vs_exec_run( struct draw_vertex_shader *shader, * program as a set of DP4 instructions appended to the * user-provided code. */ - x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = outputs[0].xyzw[0].f[j]; + y = out->clip[1] = outputs[0].xyzw[1].f[j]; + z = out->clip[2] = outputs[0].xyzw[2].f[j]; + w = out->clip[3] = outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { out->clipmask = compute_clipmask(out->clip, draw->plane, @@ -156,7 +172,8 @@ vs_exec_run( struct draw_vertex_shader *shader, out->data[0][2] = z * scale[2] + trans[2]; out->data[0][3] = w; } - else { + else + { out->data[0][0] = x; out->data[0][1] = y; out->data[0][2] = z; @@ -167,10 +184,10 @@ vs_exec_run( struct draw_vertex_shader *shader, * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = outputs[slot].xyzw[3].f[j]; } #if 0 /*DEBUG*/ @@ -216,12 +233,25 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, /* Swizzle inputs. */ for (j = 0; j < max_vertices; j++) { +#if 0 + debug_printf("%d) Input vert:\n", i + j); + for (slot = 0; slot < shader->info.num_inputs; slot++) { + debug_printf("\t%d: %f %f %f %f\n", slot, + input[slot][0], + input[slot][1], + input[slot][2], + input[slot][3]); + } +#endif + for (slot = 0; slot < shader->info.num_inputs; slot++) { machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; } + + input = (const float (*)[4])((const char *)input + input_stride); } /* run interpreter */ @@ -235,13 +265,23 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + +#if 0 + debug_printf("%d) Post xform vert:\n", i + j); + for (slot = 0; slot < shader->info.num_outputs; slot++) { + debug_printf("\t%d: %f %f %f %f\n", slot, + output[slot][0], + output[slot][1], + output[slot][2], + output[slot][3]); + } +#endif + + output = (float (*)[4])((char *)output + output_stride); } - /* Advance input, output pointers: - */ - input = (const float (*)[4])((const char *)input + input_stride); - output = (float (*)[4])((char *)output + output_stride); } } diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index d0baca715e..4dbfa955a4 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -47,6 +47,7 @@ struct draw_llvm_vertex_shader { struct draw_vertex_shader base; struct gallivm_prog *llvm_prog; + struct tgsi_exec_machine *machine; }; @@ -77,12 +78,9 @@ vs_llvm_run( struct draw_vertex_shader *base, struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; - struct tgsi_exec_machine *machine = &draw->machine; + struct tgsi_exec_machine *machine = shader->machine; unsigned int j; unsigned int clipped = 0; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; @@ -93,13 +91,12 @@ vs_llvm_run( struct draw_vertex_shader *base, /* Consts does not require 16 byte alignment. */ machine->Consts = (float (*)[4]) draw->user.constants; - machine->Inputs = ALIGN16_ASSIGN(inputs); if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ - machine->Outputs = machine->Inputs; + outputs = machine->Inputs; } else { - machine->Outputs = ALIGN16_ASSIGN(outputs); + outputs = machine->Outputs; } @@ -119,10 +116,10 @@ vs_llvm_run( struct draw_vertex_shader *base, unsigned slot; float x, y, z, w; - x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = vOut[j]->clip[0] = outputs[0].xyzw[0].f[j]; + y = vOut[j]->clip[1] = outputs[0].xyzw[1].f[j]; + z = vOut[j]->clip[2] = outputs[0].xyzw[2].f[j]; + w = vOut[j]->clip[3] = outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, @@ -159,10 +156,10 @@ vs_llvm_run( struct draw_vertex_shader *base, * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + vOut[j]->data[slot][0] = outputs[slot].xyzw[0].f[j]; + vOut[j]->data[slot][1] = outputs[slot].xyzw[1].f[j]; + vOut[j]->data[slot][2] = outputs[slot].xyzw[2].f[j]; + vOut[j]->data[slot][3] = outputs[slot].xyzw[3].f[j]; } } /* loop over vertices */ return clipped != 0; @@ -183,7 +180,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, struct draw_llvm_vertex_shader *shader = (struct draw_llvm_vertex_shader *)base; - struct tgsi_exec_machine *machine = &draw->machine; + struct tgsi_exec_machine *machine = shader->machine; unsigned int j; @@ -199,6 +196,8 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; } + + input = (const float (*)[4])((const char *)input + input_stride); } /* run shader */ @@ -216,12 +215,9 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - } - /* Advance input, output pointers: - */ - input = (const float (*)[4])((const char *)input + input_stride); - output = (float (*)[4])((char *)output + output_stride); + output = (float (*)[4])((char *)output + output_stride); + } } } @@ -263,6 +259,7 @@ draw_create_vs_llvm(struct draw_context *draw, vs->base.run = vs_llvm_run; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; + vs->machine = &draw->machine; { struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 873ecfdc5d..a763f3845c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -91,12 +91,10 @@ vs_sse_run( struct draw_vertex_shader *base, unsigned vertex_size ) { struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; - struct tgsi_exec_machine *machine = &draw->machine; + struct tgsi_exec_machine *machine = shader->machine; unsigned int i, j; unsigned int clipped = 0; - - ALIGN16_DECL(struct tgsi_exec_vector, inputs, PIPE_MAX_ATTRIBS); - ALIGN16_DECL(struct tgsi_exec_vector, outputs, PIPE_MAX_ATTRIBS); + struct tgsi_exec_vector *outputs = 0; const float *scale = draw->viewport.scale; const float *trans = draw->viewport.translate; @@ -104,13 +102,13 @@ vs_sse_run( struct draw_vertex_shader *base, /* Consts does not require 16 byte alignment. */ machine->Consts = (const float (*)[4]) draw->user.constants; - machine->Inputs = ALIGN16_ASSIGN(inputs); + if (draw->rasterizer->bypass_vs) { /* outputs are just the inputs */ - machine->Outputs = machine->Inputs; + outputs = machine->Inputs; } else { - machine->Outputs = ALIGN16_ASSIGN(outputs); + outputs = machine->Outputs; } for (i = 0; i < count; i += SSE_MAX_VERTICES) { @@ -142,10 +140,10 @@ vs_sse_run( struct draw_vertex_shader *base, struct vertex_header *out = draw_header_from_block(vOut, vertex_size, i + j); - x = out->clip[0] = machine->Outputs[0].xyzw[0].f[j]; - y = out->clip[1] = machine->Outputs[0].xyzw[1].f[j]; - z = out->clip[2] = machine->Outputs[0].xyzw[2].f[j]; - w = out->clip[3] = machine->Outputs[0].xyzw[3].f[j]; + x = out->clip[0] = outputs[0].xyzw[0].f[j]; + y = out->clip[1] = outputs[0].xyzw[1].f[j]; + z = out->clip[2] = outputs[0].xyzw[2].f[j]; + w = out->clip[3] = outputs[0].xyzw[3].f[j]; if (!draw->rasterizer->bypass_clipping) { out->clipmask = compute_clipmask(out->clip, draw->plane, @@ -182,10 +180,10 @@ vs_sse_run( struct draw_vertex_shader *base, * vertex attrib slots. */ for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + out->data[slot][0] = outputs[slot].xyzw[0].f[j]; + out->data[slot][1] = outputs[slot].xyzw[1].f[j]; + out->data[slot][2] = outputs[slot].xyzw[2].f[j]; + out->data[slot][3] = outputs[slot].xyzw[3].f[j]; } #if 0 /*DEBUG*/ printf("%d) Post xform vert:\n", i + j); @@ -233,6 +231,8 @@ vs_sse_run_linear( struct draw_vertex_shader *base, machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; machine->Inputs[slot].xyzw[3].f[j] = input[slot][3]; } + + input = (const float (*)[4])((const char *)input + input_stride); } /* run compiled shader @@ -253,12 +253,9 @@ vs_sse_run_linear( struct draw_vertex_shader *base, output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; } - } - /* Advance input, output pointers: - */ - input = (const float (*)[4])((const char *)input + input_stride); - output = (float (*)[4])((char *)output + output_stride); + output = (float (*)[4])((char *)output + output_stride); + } } } @@ -300,6 +297,7 @@ draw_create_vs_sse(struct draw_context *draw, vs->base.run = vs_sse_run; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; + vs->machine = &draw->machine; x86_init_func( &vs->sse2_program ); -- cgit v1.2.3 From da9079b936684f88da79425a810d7902e4d6e7ad Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 18 Apr 2008 20:59:28 +0900 Subject: gallium: Add missing files to scons. --- src/gallium/auxiliary/draw/SConscript | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 62e0cd9e50..0274d48e7f 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -6,24 +6,23 @@ draw = env.ConvenienceLibrary( 'draw_aaline.c', 'draw_aapoint.c', 'draw_clip.c', - 'draw_vs_exec.c', - 'draw_vs_sse.c', - 'draw_vs_llvm.c', 'draw_context.c', 'draw_cull.c', 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', + 'draw_prim.c', + 'draw_pstipple.c', 'draw_pt.c', - 'draw_pt_vcache.c', + 'draw_pt_elts.c', 'draw_pt_emit.c', + 'draw_pt_fetch.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_pipeline.c', 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_pipeline.c', - 'draw_pt_elts.c', - 'draw_prim.c', - 'draw_pstipple.c', + 'draw_pt_post_vs.c', + 'draw_pt_vcache.c', 'draw_stipple.c', 'draw_twoside.c', 'draw_unfilled.c', @@ -36,8 +35,11 @@ draw = env.ConvenienceLibrary( 'draw_vf.c', 'draw_vf_generic.c', 'draw_vf_sse.c', + 'draw_vs_exec.c', + 'draw_vs_llvm.c', + 'draw_vs_sse.c', + 'draw_wide_line.c', 'draw_wide_point.c', - 'draw_wide_line.c' ]) auxiliaries.insert(0, draw) -- cgit v1.2.3 From 073d9a28c2dc955956c940be6fcc4b3ab354cc6c Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 18 Apr 2008 13:38:06 +0100 Subject: gallium: Always pass colour clear value to driver as A8R8G8B8. --- src/mesa/state_tracker/st_cb_clear.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index fa9f986f11..6469511c6f 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -406,7 +406,7 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) /* clear whole buffer w/out masking */ struct st_renderbuffer *strb = st_renderbuffer(rb); uint clearValue; - util_pack_color(ctx->Color.ClearColor, strb->surface->format, &clearValue); + util_pack_color(ctx->Color.ClearColor, PIPE_FORMAT_A8R8G8B8_UNORM, &clearValue); ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue); } } -- cgit v1.2.3 From 5b97c762ed9882dd922f48c2fbf13b14ad86a96e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 17:32:39 +0100 Subject: rtasm: add a couple more insns, clean up x86_mul --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 34 ++++++++++++++++++++++++------ src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 2 ++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index aea8b28e58..5c25fa155d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -33,11 +33,6 @@ #define DISASSEM 0 #define X86_TWOB 0x0f -static unsigned char *cptr( void (*label)() ) -{ - return (unsigned char *) label; -} - static void do_realloc( struct x86_function *p ) { @@ -304,6 +299,11 @@ void x86_jmp( struct x86_function *p, unsigned char *label) } #if 0 +static unsigned char *cptr( void (*label)() ) +{ + return (unsigned char *) label; +} + /* This doesn't work once we start reallocating & copying the * generated code on buffer fills, because the call is relative to the * current pc. @@ -417,11 +417,14 @@ void x86_add( struct x86_function *p, emit_op_modrm(p, 0x03, 0x01, dst, src ); } +/* Calculate EAX * src, results in EDX:EAX. + */ void x86_mul( struct x86_function *p, struct x86_reg src ) { - assert (src.file == file_REG32 && src.mod == mod_REG); - emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); +// assert (src.file == file_REG32 && src.mod == mod_REG); + emit_1ub(p, 0xf7); + emit_modrm_noreg(p, 4, src ); } void x86_sub( struct x86_function *p, @@ -646,6 +649,14 @@ void sse_cvtps2pi( struct x86_function *p, emit_modrm( p, dst, src ); } +void sse2_cvtdq2ps( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0x5b); + emit_modrm( p, dst, src ); +} + /* Shufps can also be used to implement a reduced swizzle when dest == * arg0. @@ -735,6 +746,15 @@ void sse2_packuswb( struct x86_function *p, emit_modrm( p, dst, src ); } +void sse2_punpcklbw( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_3ub(p, 0x66, X86_TWOB, 0x60); + emit_modrm( p, dst, src ); +} + + void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 606b41eb35..dfde661f46 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -165,6 +165,7 @@ void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg sr void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void sse2_cvtdq2ps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); @@ -202,6 +203,7 @@ void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, unsigned char shuf ); void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src ); +void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -- cgit v1.2.3 From 59ba8ea00b0d80c48678f6e22d33ca638e19be75 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 17:33:49 +0100 Subject: gallium: reorder libs so that translate can see rtasm --- configs/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/default b/configs/default index 462e06d770..04604f8006 100644 --- a/configs/default +++ b/configs/default @@ -68,7 +68,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos # Gallium directories and -GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util sct translate +GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi sct translate rtasm util GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) -- cgit v1.2.3 From f631bebe1a05c8af863e514546763433343b7c53 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 17:34:55 +0100 Subject: softpipe: fix const-related compiler warnings --- src/gallium/drivers/softpipe/sp_fs_sse.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 5ef02a7142..f857d26143 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -49,7 +49,7 @@ typedef void (XSTDCALL *codegen_function)( const struct tgsi_exec_vector *input, struct tgsi_exec_vector *output, - float (*constant)[4], + const float (*constant)[4], struct tgsi_exec_vector *temporary, const struct tgsi_interp_coef *coef, float (*immediates)[4] @@ -67,9 +67,9 @@ struct sp_sse_fragment_shader { static void -fs_sse_prepare( struct sp_fragment_shader *base, - struct tgsi_exec_machine *machine, - struct tgsi_sampler *samplers ) +fs_sse_prepare( const struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct tgsi_sampler *samplers ) { } @@ -80,9 +80,9 @@ fs_sse_prepare( struct sp_fragment_shader *base, * TODO: process >1 quad at a time */ static unsigned -fs_sse_run( struct sp_fragment_shader *base, - struct tgsi_exec_machine *machine, - struct quad_header *quad ) +fs_sse_run( const struct sp_fragment_shader *base, + struct tgsi_exec_machine *machine, + struct quad_header *quad ) { struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base; -- cgit v1.2.3 From c5f0158a9179463593d63b33cf3b5490167faac9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 17:35:32 +0100 Subject: tgsi: add const qualifier to tokens on sse emit --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 2 +- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index c37e201b2b..0a3a7559ca 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -2332,7 +2332,7 @@ emit_declaration( */ unsigned tgsi_emit_sse2( - struct tgsi_token *tokens, + const struct tgsi_token *tokens, struct x86_function *func, float (*immediates)[4]) { diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index d56bf7f98a..063287dc5e 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -10,7 +10,7 @@ struct x86_function; unsigned tgsi_emit_sse2( - struct tgsi_token *tokens, + const struct tgsi_token *tokens, struct x86_function *function, float (*immediates)[4] ); -- cgit v1.2.3 From 363f7abf2000c1cf5993ae8f83ba81b2054bf6e0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:30:41 +0100 Subject: rtasm: add x86_imul --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 11 ++++++++++- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 5c25fa155d..7f8cc23d15 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -422,11 +422,20 @@ void x86_add( struct x86_function *p, void x86_mul( struct x86_function *p, struct x86_reg src ) { -// assert (src.file == file_REG32 && src.mod == mod_REG); emit_1ub(p, 0xf7); emit_modrm_noreg(p, 4, src ); } + +void x86_imul( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_2ub(p, X86_TWOB, 0xAF); + emit_modrm(p, dst, src); +} + + void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index dfde661f46..5e99ceea70 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -213,6 +213,7 @@ void x86_inc( struct x86_function *p, struct x86_reg reg ); void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_mul( struct x86_function *p, struct x86_reg src ); +void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_pop( struct x86_function *p, struct x86_reg reg ); void x86_push( struct x86_function *p, struct x86_reg reg ); -- cgit v1.2.3 From 7400bc4b6fb0c20a935cd108afa92814eeafec6d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:31:45 +0100 Subject: translate: add sse version based on old draw_vf_sse.c --- src/gallium/auxiliary/draw/draw_pt_emit.c | 2 +- src/gallium/auxiliary/draw/draw_pt_fetch.c | 2 +- src/gallium/auxiliary/translate/Makefile | 4 +- src/gallium/auxiliary/translate/SConscript | 2 + src/gallium/auxiliary/translate/translate.h | 4 + src/gallium/auxiliary/translate/translate_sse.c | 615 ++++++++++++++++++++++++ 6 files changed, 626 insertions(+), 3 deletions(-) create mode 100644 src/gallium/auxiliary/translate/translate_sse.c diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index ef9db70a02..a6a3ff6cac 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -127,7 +127,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, if (emit->translate) emit->translate->release(emit->translate); - emit->translate = translate_generic_create( &hw_key ); + emit->translate = translate_create( &hw_key ); } } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index a7553023b8..1aed251c85 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -119,7 +119,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, if (fetch->translate) fetch->translate->release(fetch->translate); - fetch->translate = translate_generic_create( &key ); + fetch->translate = translate_create( &key ); if (emit_header) { static struct vertex_header vh = { 0, 0, 0, 0xffff }; diff --git a/src/gallium/auxiliary/translate/Makefile b/src/gallium/auxiliary/translate/Makefile index 051987bb7e..39dfb0de30 100644 --- a/src/gallium/auxiliary/translate/Makefile +++ b/src/gallium/auxiliary/translate/Makefile @@ -4,7 +4,9 @@ include $(TOP)/configs/current LIBNAME = translate C_SOURCES = \ - translate_generic.c + translate_generic.c \ + translate_sse.c \ + translate.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/translate/SConscript b/src/gallium/auxiliary/translate/SConscript index 42513ba3b0..7608908915 100644 --- a/src/gallium/auxiliary/translate/SConscript +++ b/src/gallium/auxiliary/translate/SConscript @@ -4,6 +4,8 @@ translate = env.ConvenienceLibrary( target = 'translate', source = [ 'translate_generic.c', + 'translate_sse.c', + 'translate.c', ]) auxiliaries.insert(0, translate) diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index 4f9f40e51a..d95d1ac4f3 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -42,6 +42,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" +#include "pipe/p_state.h" struct translate_element { @@ -93,6 +94,9 @@ struct translate *translate_lookup_or_create( struct translate_context *tctx, #endif +struct translate *translate_create( const struct translate_key *key ); + + /******************************************************************************* * Private: */ diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c new file mode 100644 index 0000000000..cb8815c173 --- /dev/null +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -0,0 +1,615 @@ +/* + * Copyright 2003 Tungsten Graphics, inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on 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 THEIR 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 + */ + + +#include "pipe/p_compiler.h" +#include "pipe/p_util.h" +#include "util/u_simple_list.h" + +#include "translate.h" + + +#if defined(__i386__) || defined(__386__) || defined(i386) + +#include "rtasm/rtasm_cpu.h" +#include "rtasm/rtasm_x86sse.h" + + +#define X 0 +#define Y 1 +#define Z 2 +#define W 3 + + +typedef void (*run_func)( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ); + +typedef void (*run_elts_func)( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ); + + + +struct translate_sse { + struct translate translate; + + struct x86_function linear_func; + struct x86_function elt_func; + struct x86_function *func; + + boolean loaded_identity; + boolean loaded_255; + boolean loaded_inv_255; + + float identity[4]; + float float_255[4]; + float inv_255[4]; + + struct { + char *input_ptr; + unsigned input_stride; + } attrib[PIPE_MAX_ATTRIBS]; + + run_func gen_run; + run_elts_func gen_run_elts; + +}; + +static int get_offset( const void *a, const void *b ) +{ + return (const char *)b - (const char *)a; +} + + + +static struct x86_reg get_identity( struct translate_sse *p ) +{ + struct x86_reg reg = x86_make_reg(file_XMM, 6); + + if (!p->loaded_identity) { + /* Nasty: + */ + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + + p->loaded_identity = TRUE; + p->identity[0] = 0; + p->identity[1] = 0; + p->identity[2] = 0; + p->identity[3] = 1; + + sse_movups(p->func, reg, + x86_make_disp(translateESI, + get_offset(p, &p->identity[0]))); + } + + return reg; +} + +static struct x86_reg get_255( struct translate_sse *p ) +{ + struct x86_reg reg = x86_make_reg(file_XMM, 6); + + if (!p->loaded_255) { + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + + p->loaded_255 = TRUE; + p->float_255[0] = + p->float_255[1] = + p->float_255[2] = + p->float_255[3] = 255.0f; + + sse_movups(p->func, reg, + x86_make_disp(translateESI, + get_offset(p, &p->float_255[0]))); + } + + return reg; + return x86_make_reg(file_XMM, 7); +} + +static struct x86_reg get_inv_255( struct translate_sse *p ) +{ + struct x86_reg reg = x86_make_reg(file_XMM, 5); + + if (!p->loaded_inv_255) { + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + + p->loaded_inv_255 = TRUE; + p->inv_255[0] = + p->inv_255[1] = + p->inv_255[2] = + p->inv_255[3] = 1.0 / 255.0f; + + sse_movups(p->func, reg, + x86_make_disp(translateESI, + get_offset(p, &p->inv_255[0]))); + } + + return reg; +} + + +static void emit_load_R32G32B32A32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + sse_movups(p->func, data, arg0); +} + +static void emit_load_R32G32B32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + /* Have to jump through some hoops: + * + * c 0 0 0 + * c 0 0 1 + * 0 0 c 1 + * a b c 1 + */ + sse_movss(p->func, data, x86_make_disp(arg0, 8)); + sse_shufps(p->func, data, get_identity(p), SHUF(X,Y,Z,W) ); + sse_shufps(p->func, data, data, SHUF(Y,Z,X,W) ); + sse_movlps(p->func, data, arg0); +} + +static void emit_load_R32G32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + /* 0 0 0 1 + * a b 0 1 + */ + sse_movups(p->func, data, get_identity(p) ); + sse_movlps(p->func, data, arg0); +} + + +static void emit_load_R32( struct translate_sse *p, + struct x86_reg data, + struct x86_reg arg0 ) +{ + /* a 0 0 0 + * a 0 0 1 + */ + sse_movss(p->func, data, arg0); + sse_orps(p->func, data, get_identity(p) ); +} + + +static void emit_load_R8G8B8A8_UNORM( struct translate_sse *p, + struct x86_reg data, + struct x86_reg src ) +{ + + /* Load and unpack twice: + */ + sse_movss(p->func, data, src); + sse2_punpcklbw(p->func, src, get_identity(p)); + sse2_punpcklbw(p->func, src, get_identity(p)); + + /* Convert to float: + */ + sse2_cvtdq2ps(p->func, src, src); + + + /* Scale by 1/255.0 + */ + sse_mulps(p->func, src, get_inv_255(p)); +} + + + + +static void emit_store_R32G32B32A32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + sse_movups(p->func, dest, dataXMM); +} + +static void emit_store_R32G32B32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + /* Emit two, shuffle, emit one. + */ + sse_movlps(p->func, dest, dataXMM); + sse_shufps(p->func, dataXMM, dataXMM, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ + sse_movss(p->func, x86_make_disp(dest,8), dataXMM); +} + +static void emit_store_R32G32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + sse_movlps(p->func, dest, dataXMM); +} + +static void emit_store_R32( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + sse_movss(p->func, dest, dataXMM); +} + + + +static void emit_store_R8G8B8A8_UNORM( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg dataXMM ) +{ + /* Scale by 255.0 + */ + sse_mulps(p->func, dataXMM, get_255(p)); + + /* Pack and emit: + */ + sse2_cvtps2dq(p->func, dataXMM, dataXMM); + sse2_packssdw(p->func, dataXMM, dataXMM); + sse2_packuswb(p->func, dataXMM, dataXMM); + sse_movss(p->func, dest, dataXMM); +} + + + + + +static void get_src_ptr( struct translate_sse *p, + struct x86_reg srcEAX, + struct x86_reg translateREG, + struct x86_reg eltREG, + unsigned a ) +{ + struct x86_reg input_ptr = + x86_make_disp(translateREG, + get_offset(p, &p->attrib[a].input_ptr)); + + struct x86_reg input_stride = + x86_make_disp(translateREG, + get_offset(p, &p->attrib[a].input_stride)); + + /* Calculate pointer to current attrib: + */ + x86_mov(p->func, srcEAX, input_stride); + x86_imul(p->func, srcEAX, eltREG); + x86_add(p->func, srcEAX, input_ptr); +} + + +/* Extended swizzles? Maybe later. + */ +static void emit_swizzle( struct translate_sse *p, + struct x86_reg dest, + struct x86_reg src, + unsigned shuffle ) +{ + sse_shufps(p->func, dest, src, shuffle); +} + + +static boolean translate_attr( struct translate_sse *p, + const struct translate_element *a, + struct x86_reg srcECX, + struct x86_reg dstEAX) +{ + struct x86_reg dataXMM = x86_make_reg(file_XMM, 0); + + switch (a->input_format) { + case PIPE_FORMAT_R32_FLOAT: + emit_load_R32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_R32G32_FLOAT: + emit_load_R32G32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + emit_load_R32G32B32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + emit_load_R32G32B32A32(p, dataXMM, srcECX); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + emit_load_R8G8B8A8_UNORM(p, dataXMM, srcECX); + emit_swizzle(p, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + emit_load_R8G8B8A8_UNORM(p, dataXMM, srcECX); + break; + default: + return FALSE; + } + + switch (a->output_format) { + case PIPE_FORMAT_R32_FLOAT: + emit_store_R32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R32G32_FLOAT: + emit_store_R32G32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R32G32B32_FLOAT: + emit_store_R32G32B32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R32G32B32A32_FLOAT: + emit_store_R32G32B32A32(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + emit_swizzle(p, dataXMM, dataXMM, SHUF(Z,Y,X,W)); + emit_store_R8G8B8A8_UNORM(p, dstEAX, dataXMM); + break; + case PIPE_FORMAT_R8G8B8A8_UNORM: + emit_store_R8G8B8A8_UNORM(p, dstEAX, dataXMM); + break; + default: + return FALSE; + } + + return TRUE; +} + +/* Build run( struct translate *translate, + * unsigned start, + * unsigned count, + * void *output_buffer ) + * or + * run_elts( struct translate *translate, + * unsigned *elts, + * unsigned count, + * void *output_buffer ) + * + * Lots of hardcoding + * + * EAX -- pointer to current output vertex + * ECX -- pointer to current attribute + * + */ +static boolean build_vertex_emit( struct translate_sse *p, + struct x86_function *func, + boolean linear ) +{ + struct x86_reg vertexECX = x86_make_reg(file_REG32, reg_AX); + struct x86_reg idxEBX = x86_make_reg(file_REG32, reg_BX); + struct x86_reg srcEAX = x86_make_reg(file_REG32, reg_CX); + struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); + struct x86_reg translateESI = x86_make_reg(file_REG32, reg_SI); + uint8_t *fixup, *label; + unsigned j; + + p->func = func; + p->loaded_inv_255 = FALSE; + p->loaded_255 = FALSE; + p->loaded_identity = FALSE; + + x86_init_func(p->func); + + /* Push a few regs? + */ + x86_push(p->func, countEBP); + x86_push(p->func, translateESI); + x86_push(p->func, idxEBX); + + /* Get vertex count, compare to zero + */ + x86_xor(p->func, idxEBX, idxEBX); + x86_mov(p->func, countEBP, x86_fn_arg(p->func, 3)); + x86_cmp(p->func, countEBP, idxEBX); + fixup = x86_jcc_forward(p->func, cc_E); + + /* If linear, idx is the current element, otherwise it is a pointer + * to the current element. + */ + x86_mov(p->func, idxEBX, x86_fn_arg(p->func, 2)); + + /* Initialize destination register. + */ + x86_mov(p->func, vertexECX, x86_fn_arg(p->func, 4)); + + /* Move argument 1 (translate_sse pointer) into a reg: + */ + x86_mov(p->func, translateESI, x86_fn_arg(p->func, 1)); + + + /* always load, needed or not: + */ + + /* Note address for loop jump */ + label = x86_get_label(p->func); + + + for (j = 0; j < p->translate.key.nr_elements; j++) { + const struct translate_element *a = &p->translate.key.element[j]; + + struct x86_reg destEAX = x86_make_disp(vertexECX, + a->output_offset); + + /* Figure out source pointer address: + */ + if (linear) { + get_src_ptr(p, srcEAX, translateESI, idxEBX, j); + } + else { + get_src_ptr(p, srcEAX, translateESI, x86_deref(idxEBX), j); + } + + if (!translate_attr( p, a, x86_deref(srcEAX), destEAX )) + return FALSE; + } + + /* Next vertex: + */ + x86_lea(p->func, vertexECX, x86_make_disp(vertexECX, p->translate.key.output_stride)); + + /* Incr index + */ /* Emit code for each of the attributes. Currently routes + * everything through SSE registers, even when it might be more + * efficient to stick with regular old x86. No optimization or + * other tricks - enough new ground to cover here just getting + * things working. + */ + + if (linear) { + x86_inc(p->func, idxEBX); + } + else { + x86_lea(p->func, idxEBX, x86_make_disp(idxEBX, 4)); + } + + /* decr count, loop if not zero + */ + x86_dec(p->func, countEBP); + x86_test(p->func, countEBP, countEBP); + x86_jcc(p->func, cc_NZ, label); + + /* Exit mmx state? + */ + if (p->func->need_emms) + mmx_emms(p->func); + + /* Land forward jump here: + */ + x86_fixup_fwd_jump(p->func, fixup); + + /* Pop regs and return + */ + + x86_pop(p->func, idxEBX); + x86_pop(p->func, translateESI); + x86_pop(p->func, countEBP); + x86_ret(p->func); + + return TRUE; +} + + + + + + + +static void translate_sse_set_buffer( struct translate *translate, + unsigned buf, + const void *ptr, + unsigned stride ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + unsigned i; + + for (i = 0; i < p->translate.key.nr_elements; i++) { + if (p->translate.key.element[i].input_buffer == buf) { + p->attrib[i].input_ptr = ((char *)ptr + + p->translate.key.element[i].input_offset); + p->attrib[i].input_stride = stride; + } + } +} + + +static void translate_sse_release( struct translate *translate ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + + x86_release_func( &p->linear_func ); + x86_release_func( &p->elt_func ); + + FREE(p); +} + +static void translate_sse_run_elts( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + + p->gen_run_elts( translate, + elts, + count, + output_buffer ); + +} + +static void translate_sse_run( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ) +{ + struct translate_sse *p = (struct translate_sse *)translate; + + p->gen_run( translate, + start, + count, + output_buffer ); +} + + +struct translate *translate_sse2_create( const struct translate_key *key ) +{ + struct translate_sse *p = CALLOC_STRUCT( translate_sse ); + + if (p == NULL) + goto fail; + + if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) + goto fail; + + + p->translate.key = *key; + p->translate.release = translate_sse_release; + p->translate.set_buffer = translate_sse_set_buffer; + p->translate.run_elts = translate_sse_run_elts; + p->translate.run = translate_sse_run; + + if (!build_vertex_emit(p, &p->linear_func, TRUE)) + goto fail; + + if (!build_vertex_emit(p, &p->elt_func, FALSE)) + goto fail; + + p->gen_run = (run_func)x86_get_func(&p->linear_func); + p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); + + return &p->translate; + + fail: + if (p) + p->translate.release( &p->translate ); + + return NULL; +} + + + +#else + +void translate_create_sse( const struct translate_key *key ) +{ + return NULL; +} + +#endif -- cgit v1.2.3 From 26c27f6636069ca849a740c3969c577d841484e2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:42:41 +0100 Subject: draw: remove fetch_pipeline middle end -- just use the general path --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_pt.c | 4 - src/gallium/auxiliary/draw/draw_pt.h | 26 +- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 327 --------------------- 5 files changed, 15 insertions(+), 344 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 154c8a99b5..916e134719 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -18,7 +18,6 @@ C_SOURCES = \ draw_pt.c \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ - draw_pt_fetch_pipeline.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_fetch.c \ draw_pt_post_vs.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 0274d48e7f..6dc0195d93 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -18,7 +18,6 @@ draw = env.ConvenienceLibrary( 'draw_pt_emit.c', 'draw_pt_fetch.c', 'draw_pt_fetch_emit.c', - 'draw_pt_fetch_pipeline.c', 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_pipeline.c', 'draw_pt_post_vs.c', diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 60a47f3911..b48d0cae9f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -106,10 +106,6 @@ boolean draw_pt_init( struct draw_context *draw ) return FALSE; draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw ); - draw->pt.middle.opt[PT_PIPELINE] = draw_pt_fetch_pipeline( draw ); -// draw->pt.middle.opt[PT_SHADE] = draw_pt_shade_emit( draw ); -// draw->pt.middle.opt[PT_SHADE | PT_PIPELINE] = draw_pt_shade_pipeline( draw ); -// draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST] = draw_pt_shade_clip_either( draw ); draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] = draw_pt_fetch_pipeline_or_emit( draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 316289969b..eb23ee1c1e 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -83,11 +83,6 @@ struct draw_pt_front_end { * Currently two versions of this: * - fetch, vertex shade, cliptest, prim-pipeline * - fetch, emit (ie passthrough) - * Later: - * - fetch, vertex shade, cliptest, maybe-pipeline, maybe-emit - * - fetch, vertex shade, emit - * - * Currenly only using the passthrough version. */ struct draw_pt_middle_end { void (*prepare)( struct draw_pt_middle_end *, @@ -106,10 +101,6 @@ struct draw_pt_middle_end { /* The "back end" - supplied by the driver, defined in draw_vbuf.h. - * - * Not sure whether to wrap the prim pipeline up as an alternate - * backend. Would be a win for everything except pure passthrough - * mode... */ struct vbuf_render; struct vertex_header; @@ -121,11 +112,24 @@ pt_elt_func draw_pt_elt_func( struct draw_context *draw ); const void *draw_pt_elt_ptr( struct draw_context *draw, unsigned start ); -/* Implementations: +/* Frontends: + * + * Currently only the general-purpose vcache implementation, could add + * a special case for tiny vertex buffers. */ struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); + +/* Middle-ends: + * + * Currently one general-purpose case which can do all possibilities, + * at the slight expense of creating a vertex_header in some cases + * unecessarily. + * + * The special case fetch_emit code avoids pipeline vertices + * altogether and builds hardware vertices directly from API + * vertex_elements. + */ struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); -struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c deleted file mode 100644 index 26d0b37286..0000000000 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c +++ /dev/null @@ -1,327 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "draw/draw_vertex.h" -#include "draw/draw_pt.h" -#include "draw/draw_vs.h" - -/* The simplest 'middle end' in the new vertex code. - * - * The responsibilities of a middle end are to: - * - perform vertex fetch using - * - draw vertex element/buffer state - * - a list of fetch indices we received as an input - * - run the vertex shader - * - cliptest, - * - clip coord calculation - * - viewport transformation - * - if necessary, run the primitive pipeline, passing it: - * - a linear array of vertex_header vertices constructed here - * - a set of draw indices we received as an input - * - otherwise, drive the hw backend, - * - allocate space for hardware format vertices - * - translate the vertex-shader output vertices to hw format - * - calling the backend draw functions. - * - * For convenience, we provide a helper function to drive the hardware - * backend given similar inputs to those required to run the pipeline. - * - * In the case of passthrough mode, many of these actions are disabled - * or noops, so we end up doing: - * - * - perform vertex fetch - * - drive the hw backend - * - * IE, basically just vertex fetch to post-vs-format vertices, - * followed by a call to the backend helper function. - */ - - -struct fetch_pipeline_middle_end { - struct draw_pt_middle_end base; - struct draw_context *draw; - - void (*header)( unsigned idx, float **out); - - struct { - const ubyte *ptr; - unsigned pitch; - void (*fetch)( const void *from, float *attrib); - void (*emit)( const float *attrib, float **out ); - } fetch[PIPE_MAX_ATTRIBS]; - - unsigned nr_fetch; - unsigned pipeline_vertex_size; - unsigned prim; -}; - - -#if 0 -static void emit_R32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out) += 1; -} - -static void emit_R32G32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out) += 2; -} - -static void emit_R32G32B32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out) += 3; -} -#endif -static void emit_R32G32B32A32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out)[3] = attrib[3]; - (*out) += 4; -} - -static void header( unsigned idx, - float **out ) -{ - struct vertex_header *header = (struct vertex_header *) (*out); - - header->clipmask = 0; - header->edgeflag = 1; - header->pad = 0; - header->vertex_id = UNDEFINED_VERTEX_ID; - - (*out)[1] = 0; - (*out)[2] = 0; - (*out)[3] = 0; - (*out)[3] = 1; - (*out) += 5; -} - - -static void header_ef( unsigned idx, - float **out ) -{ - struct vertex_header *header = (struct vertex_header *) (*out); - - /* XXX: need a reset_stipple flag in the vertex header too? - */ - header->clipmask = 0; - header->edgeflag = (idx & DRAW_PT_EDGEFLAG) != 0; - header->pad = 0; - header->vertex_id = UNDEFINED_VERTEX_ID; - - (*out)[1] = 0; - (*out)[2] = 0; - (*out)[3] = 0; - (*out)[3] = 1; - (*out) += 5; -} - - -/** - * General-purpose fetch from user's vertex arrays, emit to driver's - * vertex buffer. - * - * XXX this is totally temporary. - */ -static void -fetch_store_general( struct fetch_pipeline_middle_end *fpme, - void *out_ptr, - const unsigned *fetch_elts, - unsigned count ) -{ - float *out = (float *)out_ptr; - uint i, j; - - for (i = 0; i < count; i++) { - unsigned elt = fetch_elts[i]; - - fpme->header( elt, &out ); - elt &= ~DRAW_PT_FLAG_MASK; - - for (j = 0; j < fpme->nr_fetch; j++) { - float attrib[4]; - const ubyte *from = (fpme->fetch[j].ptr + - fpme->fetch[j].pitch * elt); - - fpme->fetch[j].fetch( from, attrib ); - fpme->fetch[j].emit( attrib, &out ); - } - } -} - - -/* We aren't running a vertex shader, but are running the pipeline. - * That means the vertices we need to build look like: - * - * dw0: vertex header (zero?) - * dw1: clip coord 0 - * dw2: clip coord 1 - * dw3: clip coord 2 - * dw4: clip coord 4 - * dw5: screen coord 0 - * dw6: screen coord 0 - * dw7: screen coord 0 - * dw8: screen coord 0 - * dw9: other attribs... - * - */ -static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, - unsigned prim, - unsigned opt ) -{ - struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - struct draw_context *draw = fpme->draw; - unsigned i, nr = 0; - - fpme->prim = prim; - - /* Emit the vertex header and empty clipspace coord field: - */ - if (draw->user.edgeflag) { - fpme->header = header_ef; - } - else { - fpme->header = header; - } - - - /* Need to look at vertex shader inputs (we know it is a - * passthrough shader, so these define the outputs too). If we - * were running a shader, we'd still be looking at the inputs at - * this point. - */ - for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - enum pipe_format format = draw->vertex_element[i].src_format; - - fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset); - - fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch; - fpme->fetch[nr].fetch = draw_get_fetch_func( format ); - - /* Always do this -- somewhat redundant... - */ - fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT; - nr++; - } - - fpme->nr_fetch = nr; - fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); -} - - - - -static void fetch_pipeline_run( struct draw_pt_middle_end *middle, - const unsigned *fetch_elts, - unsigned fetch_count, - const ushort *draw_elts, - unsigned draw_count ) -{ - struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - char *pipeline_verts; - - pipeline_verts = MALLOC( fpme->pipeline_vertex_size * - fetch_count ); - if (!pipeline_verts) { - assert(0); - return; - } - - - /* Single routine to fetch vertices and emit pipeline verts. - */ - fetch_store_general( fpme, - pipeline_verts, - fetch_elts, - fetch_count ); - - - /* Run the pipeline - */ - draw_pt_run_pipeline( fpme->draw, - fpme->prim, - (struct vertex_header *)pipeline_verts, - fetch_count, - fpme->pipeline_vertex_size, - draw_elts, - draw_count ); - - - /* Done -- that was easy, wasn't it: - */ - FREE( pipeline_verts ); -} - - - -static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) -{ - /* nothing to do */ -} - -static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) -{ - FREE(middle); -} - - -struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ) -{ - struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); - - fetch_pipeline->base.prepare = fetch_pipeline_prepare; - fetch_pipeline->base.run = fetch_pipeline_run; - fetch_pipeline->base.finish = fetch_pipeline_finish; - fetch_pipeline->base.destroy = fetch_pipeline_destroy; - - fetch_pipeline->draw = draw; - - return &fetch_pipeline->base; -} - -- cgit v1.2.3 From 19218e2195f3dffc9403f16a742ba8c63edbf8b4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 18 Apr 2008 11:15:18 -0600 Subject: gallium: implement recip sqrt() with C code for now. Some conformance lighting tests fail with the SSE rsqrt instruction. --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 0a3a7559ca..6f785be3f5 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -36,6 +36,8 @@ #if defined(__i386__) || defined(__386__) +#define HIGH_PRECISION 1 /* for 1/sqrt() */ + #define DUMP_SSE 0 #if DUMP_SSE @@ -1137,16 +1139,44 @@ emit_rcp ( make_xmm( xmm_src ) ); } +#if HIGH_PRECISION +static void XSTDCALL +rsqrt4f( + float *store ) +{ +#ifdef WIN32 + store[0] = 1.0F / (float) sqrt( (double) store[0] ); + store[1] = 1.0F / (float) sqrt( (double) store[1] ); + store[2] = 1.0F / (float) sqrt( (double) store[2] ); + store[3] = 1.0F / (float) sqrt( (double) store[3] ); +#else + const unsigned X = TEMP_R0 * 16; + store[X + 0] = 1.0F / sqrt( store[X + 0] ); + store[X + 1] = 1.0F / sqrt( store[X + 1] ); + store[X + 2] = 1.0F / sqrt( store[X + 2] ); + store[X + 3] = 1.0F / sqrt( store[X + 3] ); +#endif +} +#endif + static void emit_rsqrt( struct x86_function *func, unsigned xmm_dst, unsigned xmm_src ) { +#if HIGH_PRECISION + emit_func_call_dst_src( + func, + xmm_dst, + xmm_src, + rsqrt4f ); +#else emit_rsqrtps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); +#endif } static void -- cgit v1.2.3 From e430d885e0d819172068805b1492cb6f10eb5d7f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 18 Apr 2008 11:15:53 -0600 Subject: gallium: a few comments --- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 6f785be3f5..d47935e982 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -1598,20 +1598,25 @@ emit_instruction( STORE( func, *inst, 0, 0, CHAN_Y ); } if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { + /* XMM[1] = SrcReg[0].yyyy */ FETCH( func, *inst, 1, 0, CHAN_Y ); + /* XMM[1] = max(XMM[1], 0) */ emit_maxps( func, make_xmm( 1 ), get_temp( TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ) ); + /* XMM[2] = SrcReg[0].wwww */ FETCH( func, *inst, 2, 0, CHAN_W ); + /* XMM[2] = min(XMM[2], 128.0) */ emit_minps( func, make_xmm( 2 ), get_temp( TGSI_EXEC_TEMP_128_I, TGSI_EXEC_TEMP_128_C ) ); + /* XMM[2] = max(XMM[2], -128.0) */ emit_maxps( func, make_xmm( 2 ), -- cgit v1.2.3 From 39c06c4336ee44ad2c0ff12705a384dede050bee Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 18 Apr 2008 11:33:42 -0600 Subject: gallium: get rid of unnecessary surface mapping --- src/mesa/state_tracker/st_cb_drawpixels.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 67f468c689..5fb27857a7 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -882,7 +882,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); struct pipe_surface *psRead = rbRead->surface; struct pipe_surface *psDraw = rbDraw->surface; - ubyte *readMap, *drawMap; + ubyte *drawMap; ubyte *buffer; int i; @@ -892,14 +892,13 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, return; } - /* map the stencil buffers */ - readMap = pipe_surface_map(psRead); - drawMap = pipe_surface_map(psDraw); - /* this will do stencil pixel transfer ops */ st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); + /* map the stencil buffer */ + drawMap = pipe_surface_map(psDraw); + /* draw */ /* XXX PixelZoom not handled yet */ for (i = 0; i < height; i++) { @@ -937,8 +936,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, free(buffer); - /* unmap the stencil buffers */ - pipe_surface_unmap(psRead); + /* unmap the stencil buffer */ pipe_surface_unmap(psDraw); } -- cgit v1.2.3 From 7b34a43d1ab74974bd157a2339d7a491aed9c9b4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 18:51:43 +0100 Subject: translate: missing file --- src/gallium/auxiliary/translate/translate.c | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/gallium/auxiliary/translate/translate.c diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c new file mode 100644 index 0000000000..86ebeae2a7 --- /dev/null +++ b/src/gallium/auxiliary/translate/translate.c @@ -0,0 +1,46 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_state.h" +#include "translate.h" + +struct translate *translate_create( const struct translate_key *key ) +{ + struct translate *translate = NULL; + + translate = translate_sse2_create( key ); + if (translate) + return translate; + + return translate_generic_create( key ); +} -- cgit v1.2.3 From cb9f0a589623397c3437911aeef39f189213527a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:05:36 +0100 Subject: draw: remove draw_vf code, use translate instead --- src/gallium/auxiliary/draw/Makefile | 3 - src/gallium/auxiliary/draw/SConscript | 3 - src/gallium/auxiliary/draw/draw_pt_emit.c | 3 +- src/gallium/auxiliary/draw/draw_vbuf.c | 188 ++++---- src/gallium/auxiliary/draw/draw_vf.c | 378 ----------------- src/gallium/auxiliary/draw/draw_vf.h | 232 ---------- src/gallium/auxiliary/draw/draw_vf_generic.c | 585 ------------------------- src/gallium/auxiliary/draw/draw_vf_sse.c | 613 --------------------------- 8 files changed, 115 insertions(+), 1890 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_vf.c delete mode 100644 src/gallium/auxiliary/draw/draw_vf.h delete mode 100644 src/gallium/auxiliary/draw/draw_vf_generic.c delete mode 100644 src/gallium/auxiliary/draw/draw_vf_sse.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 916e134719..27464e5c86 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -35,9 +35,6 @@ C_SOURCES = \ draw_vertex_cache.c \ draw_vertex_fetch.c \ draw_vertex_shader.c \ - draw_vf.c \ - draw_vf_generic.c \ - draw_vf_sse.c \ draw_wide_line.c \ draw_wide_point.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 6dc0195d93..7af65c3c05 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -31,9 +31,6 @@ draw = env.ConvenienceLibrary( 'draw_vertex_cache.c', 'draw_vertex_fetch.c', 'draw_vertex_shader.c', - 'draw_vf.c', - 'draw_vf_generic.c', - 'draw_vf_sse.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index a6a3ff6cac..490da4cca3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -62,8 +62,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, vinfo = draw->render->get_vertex_info(draw->render); - /* In passthrough mode, need to translate from vertex shader - * outputs to hw vertices. + /* Translate from pipeline vertices to hw vertices. */ dst_offset = 0; for (i = 0; i < vinfo->num_attribs; i++) { diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index 59b63f5bfa..dbbcf05c3c 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -40,7 +40,7 @@ #include "draw_vbuf.h" #include "draw_private.h" #include "draw_vertex.h" -#include "draw_vf.h" +#include "translate/translate.h" /** @@ -56,7 +56,7 @@ struct vbuf_stage { /** Vertex size in bytes */ unsigned vertex_size; - struct draw_vertex_fetch *vf; + struct translate *translate; /* FIXME: we have no guarantee that 'unsigned' is 32bit */ @@ -71,8 +71,9 @@ struct vbuf_stage { unsigned max_indices; unsigned nr_indices; - /** Pipe primitive */ - unsigned prim; + /* Cache point size somewhere it's address won't change: + */ + float point_size; }; @@ -175,26 +176,25 @@ dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) * have a couple of slots at the beginning (1-dword header, 4-dword * clip pos) that we ignore here. We only use the vertex->data[] fields. */ -static INLINE void +static INLINE ushort emit_vertex( struct vbuf_stage *vbuf, struct vertex_header *vertex ) { - if(vertex->vertex_id != UNDEFINED_VERTEX_ID) { - if(vertex->vertex_id < vbuf->nr_vertices) - return; - else - debug_printf("Bad vertex id 0x%04x (>= 0x%04x)\n", - vertex->vertex_id, vbuf->nr_vertices); - return; - } + if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { + /* Hmm - vertices are emitted one at a time - better make sure + * set_buffer is efficient. Consider a special one-shot mode for + * translate. + */ + vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); + vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); + + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - vertex->vertex_id = vbuf->nr_vertices++; - - draw_vf_emit_vertex(vbuf->vf, vertex, vbuf->vertex_ptr); + vbuf->vertex_ptr += vbuf->vertex_size/4; + vertex->vertex_id = vbuf->nr_vertices++; + } - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - - vbuf->vertex_ptr += vbuf->vertex_size/4; + return vertex->vertex_id; } @@ -208,9 +208,7 @@ vbuf_tri( struct draw_stage *stage, check_space( vbuf, 3 ); for (i = 0; i < 3; i++) { - emit_vertex( vbuf, prim->v[i] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); } } @@ -225,9 +223,7 @@ vbuf_line( struct draw_stage *stage, check_space( vbuf, 2 ); for (i = 0; i < 2; i++) { - emit_vertex( vbuf, prim->v[i] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[i]->vertex_id; + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); } } @@ -240,43 +236,112 @@ vbuf_point( struct draw_stage *stage, check_space( vbuf, 1 ); - emit_vertex( vbuf, prim->v[0] ); - - vbuf->indices[vbuf->nr_indices++] = (ushort) prim->v[0]->vertex_id; + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); } + + /** * Set the prim type for subsequent vertices. * This may result in a new vertex size. The existing vbuffer (if any) * will be flushed if needed and a new one allocated. */ static void -vbuf_set_prim( struct vbuf_stage *vbuf, uint newprim ) +vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) { - const struct vertex_info *vinfo; - unsigned vertex_size; - - assert(newprim == PIPE_PRIM_POINTS || - newprim == PIPE_PRIM_LINES || - newprim == PIPE_PRIM_TRIANGLES); + struct translate_key hw_key; + unsigned dst_offset; + unsigned i; - vbuf->prim = newprim; - vbuf->render->set_primitive(vbuf->render, newprim); + vbuf->render->set_primitive(vbuf->render, prim); - vinfo = vbuf->render->get_vertex_info(vbuf->render); - vertex_size = vinfo->size * sizeof(float); + /* Must do this after set_primitive() above: + * + * XXX: need some state managment to track when this needs to be + * recalculated. The driver should tell us whether there was a + * state change. + */ + vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); - if (vertex_size != vbuf->vertex_size) + if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { vbuf_flush_vertices(vbuf); + vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); + } - vbuf->vinfo = vinfo; - vbuf->vertex_size = vertex_size; - if(vbuf->vf) - draw_vf_set_vertex_info(vbuf->vf, - vbuf->vinfo, - vbuf->stage.draw->rasterizer->point_size); - + /* Translate from pipeline vertices to hw vertices. + */ + dst_offset = 0; + memset(&hw_key, 0, sizeof(hw_key)); + + for (i = 0; i < vbuf->vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) ); + + switch (vbuf->vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; + } + + hw_key.nr_elements = vbuf->vinfo->num_attribs; + hw_key.output_stride = vbuf->vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!vbuf->translate || + memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (vbuf->translate) + vbuf->translate->release(vbuf->translate); + + vbuf->translate = translate_create( &hw_key ); + + vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); + } + + vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; + + /* Allocate new buffer? + */ if (!vbuf->vertices) vbuf_alloc_vertices(vbuf); } @@ -330,29 +395,9 @@ vbuf_flush_indices( struct vbuf_stage *vbuf ) assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); - switch(vbuf->prim) { - case PIPE_PRIM_POINTS: - break; - case PIPE_PRIM_LINES: - assert(vbuf->nr_indices % 2 == 0); - break; - case PIPE_PRIM_TRIANGLES: - assert(vbuf->nr_indices % 3 == 0); - break; - default: - assert(0); - } - vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); vbuf->nr_indices = 0; - - /* don't need to reset point/line/tri functions */ -#if 0 - stage->point = vbuf_first_point; - stage->line = vbuf_first_line; - stage->tri = vbuf_first_tri; -#endif } @@ -433,8 +478,8 @@ static void vbuf_destroy( struct draw_stage *stage ) if(vbuf->indices) align_free( vbuf->indices ); - if(vbuf->vf) - draw_vf_destroy( vbuf->vf ); + if(vbuf->translate) + vbuf->translate->release( vbuf->translate ); if (vbuf->render) vbuf->render->destroy( vbuf->render ); @@ -473,11 +518,6 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->vertices = NULL; vbuf->vertex_ptr = vbuf->vertices; - - vbuf->prim = ~0; - vbuf->vf = draw_vf_create(); - if (!vbuf->vf) - goto fail; return &vbuf->stage; diff --git a/src/gallium/auxiliary/draw/draw_vf.c b/src/gallium/auxiliary/draw/draw_vf.c deleted file mode 100644 index 9d0154c50d..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on 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 THEIR 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 - */ - - -#include - -#include "pipe/p_compiler.h" -#include "pipe/p_util.h" -#include "rtasm/rtasm_execmem.h" - -#include "draw_vf.h" - - -#define DRAW_VF_DBG 0 - - -static boolean match_fastpath( struct draw_vertex_fetch *vf, - const struct draw_vf_fastpath *fp) -{ - unsigned j; - - if (vf->attr_count != fp->attr_count) - return FALSE; - - for (j = 0; j < vf->attr_count; j++) - if (vf->attr[j].format != fp->attr[j].format || - vf->attr[j].inputsize != fp->attr[j].size || - vf->attr[j].vertoffset != fp->attr[j].offset) - return FALSE; - - if (fp->match_strides) { - if (vf->vertex_stride != fp->vertex_stride) - return FALSE; - - for (j = 0; j < vf->attr_count; j++) - if (vf->attr[j].inputstride != fp->attr[j].stride) - return FALSE; - } - - return TRUE; -} - -static boolean search_fastpath_emit( struct draw_vertex_fetch *vf ) -{ - struct draw_vf_fastpath *fp = vf->fastpath; - - for ( ; fp ; fp = fp->next) { - if (match_fastpath(vf, fp)) { - vf->emit = fp->func; - return TRUE; - } - } - - return FALSE; -} - -void draw_vf_register_fastpath( struct draw_vertex_fetch *vf, - boolean match_strides ) -{ - struct draw_vf_fastpath *fastpath = CALLOC_STRUCT(draw_vf_fastpath); - unsigned i; - - fastpath->vertex_stride = vf->vertex_stride; - fastpath->attr_count = vf->attr_count; - fastpath->match_strides = match_strides; - fastpath->func = vf->emit; - fastpath->attr = (struct draw_vf_attr_type *) - MALLOC(vf->attr_count * sizeof(fastpath->attr[0])); - - for (i = 0; i < vf->attr_count; i++) { - fastpath->attr[i].format = vf->attr[i].format; - fastpath->attr[i].stride = vf->attr[i].inputstride; - fastpath->attr[i].size = vf->attr[i].inputsize; - fastpath->attr[i].offset = vf->attr[i].vertoffset; - } - - fastpath->next = vf->fastpath; - vf->fastpath = fastpath; -} - - - - -/*********************************************************************** - * Build codegen functions or return generic ones: - */ -static void choose_emit_func( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *dest) -{ - vf->emit = NULL; - - /* Does this match an existing (hardwired, codegen or known-bad) - * fastpath? - */ - if (search_fastpath_emit(vf)) { - /* Use this result. If it is null, then it is already known - * that the current state will fail for codegen and there is no - * point trying again. - */ - } - else if (vf->codegen_emit) { - vf->codegen_emit( vf ); - } - - if (!vf->emit) { - draw_vf_generate_hardwired_emit(vf); - } - - /* Otherwise use the generic version: - */ - if (!vf->emit) - vf->emit = draw_vf_generic_emit; - - vf->emit( vf, count, dest ); -} - - - - - -/*********************************************************************** - * Public entrypoints, mostly dispatch to the above: - */ - - - -static unsigned -draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, - const struct draw_vf_attr_map *map, - unsigned nr, - unsigned vertex_stride ) -{ - unsigned offset = 0; - unsigned i, j; - - assert(nr < PIPE_MAX_ATTRIBS); - - for (j = 0, i = 0; i < nr; i++) { - const unsigned format = map[i].format; - if (format == DRAW_EMIT_PAD) { -#if (DRAW_VF_DBG) - debug_printf("%d: pad %d, offset %d\n", i, - map[i].offset, offset); -#endif - - offset += map[i].offset; - - } - else { - vf->attr[j].attrib = map[i].attrib; - vf->attr[j].format = format; - vf->attr[j].insert = draw_vf_format_info[format].insert; - vf->attr[j].vertattrsize = draw_vf_format_info[format].attrsize; - vf->attr[j].vertoffset = offset; - vf->attr[j].isconst = draw_vf_format_info[format].isconst; - if(vf->attr[j].isconst) - memcpy(vf->attr[j].data, &map[i].data, vf->attr[j].vertattrsize); - -#if (DRAW_VF_DBG) - debug_printf("%d: %s, offset %d\n", i, - draw_vf_format_info[format].name, - vf->attr[j].vertoffset); -#endif - - offset += draw_vf_format_info[format].attrsize; - j++; - } - } - - vf->attr_count = j; - vf->vertex_stride = vertex_stride ? vertex_stride : offset; - vf->emit = choose_emit_func; - - assert(vf->vertex_stride >= offset); - return vf->vertex_stride; -} - - -void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, - const struct vertex_info *vinfo, - float point_size ) -{ - unsigned i, j; - struct draw_vf_attr *a = vf->attr; - struct draw_vf_attr_map attrs[PIPE_MAX_SHADER_INPUTS]; - unsigned count = 0; /* for debug/sanity */ - unsigned nr_attrs = 0; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; - case EMIT_1F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_1F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count++; - break; - case EMIT_1F_PSIZE: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_1F_CONST; - attrs[nr_attrs].offset = 0; - attrs[nr_attrs].data.f[0] = point_size; - nr_attrs++; - count++; - break; - case EMIT_2F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_2F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 2; - break; - case EMIT_3F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_3F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 3; - break; - case EMIT_4F: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_4F; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 4; - break; - case EMIT_4UB: - attrs[nr_attrs].attrib = j; - attrs[nr_attrs].format = DRAW_EMIT_4UB_4F_BGRA; - attrs[nr_attrs].offset = 0; - nr_attrs++; - count += 1; - break; - default: - assert(0); - } - } - - assert(count == vinfo->size); - - draw_vf_set_vertex_attributes(vf, - attrs, - nr_attrs, - vinfo->size * sizeof(float) ); - - for (j = 0; j < vf->attr_count; j++) { - a[j].inputsize = 4; - a[j].do_insert = a[j].insert[4 - 1]; - if(a[j].isconst) { - a[j].inputptr = a[j].data; - a[j].inputstride = 0; - } - } -} - - -#if 0 -/* Set attribute pointers, adjusted for start position: - */ -void draw_vf_set_sources( struct draw_vertex_fetch *vf, - GLvector4f * const sources[], - unsigned start ) -{ - struct draw_vf_attr *a = vf->attr; - unsigned j; - - for (j = 0; j < vf->attr_count; j++) { - const GLvector4f *vptr = sources[a[j].attrib]; - - if ((a[j].inputstride != vptr->stride) || - (a[j].inputsize != vptr->size)) - vf->emit = choose_emit_func; - - a[j].inputstride = vptr->stride; - a[j].inputsize = vptr->size; - a[j].do_insert = a[j].insert[vptr->size - 1]; - a[j].inputptr = ((uint8_t *)vptr->data) + start * vptr->stride; - } -} -#endif - - -/** - * Emit a vertex to dest. - */ -void draw_vf_emit_vertex( struct draw_vertex_fetch *vf, - struct vertex_header *vertex, - void *dest ) -{ - struct draw_vf_attr *a = vf->attr; - unsigned j; - - for (j = 0; j < vf->attr_count; j++) { - if (!a[j].isconst) { - a[j].inputptr = (uint8_t *)&vertex->data[a[j].attrib][0]; - a[j].inputstride = 0; /* XXX: one-vertex-max ATM */ - } - } - - vf->emit( vf, 1, (uint8_t*) dest ); -} - - - -struct draw_vertex_fetch *draw_vf_create( void ) -{ - struct draw_vertex_fetch *vf = CALLOC_STRUCT(draw_vertex_fetch); - unsigned i; - - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) - vf->attr[i].vf = vf; - - vf->identity[0] = 0.0; - vf->identity[1] = 0.0; - vf->identity[2] = 0.0; - vf->identity[3] = 1.0; - - vf->codegen_emit = NULL; - -#ifdef USE_SSE_ASM - if (!GETENV("GALLIUM_NO_CODEGEN")) - vf->codegen_emit = draw_vf_generate_sse_emit; -#endif - - return vf; -} - - -void draw_vf_destroy( struct draw_vertex_fetch *vf ) -{ - struct draw_vf_fastpath *fp, *tmp; - - for (fp = vf->fastpath ; fp ; fp = tmp) { - tmp = fp->next; - FREE(fp->attr); - - /* KW: At the moment, fp->func is constrained to be allocated by - * rtasm_exec_alloc(), as the hardwired fastpaths in - * t_vertex_generic.c are handled specially. It would be nice - * to unify them, but this probably won't change until this - * module gets another overhaul. - */ - //rtasm_exec_free((void *) fp->func); - FREE(fp); - } - - vf->fastpath = NULL; - FREE(vf); -} diff --git a/src/gallium/auxiliary/draw/draw_vf.h b/src/gallium/auxiliary/draw/draw_vf.h deleted file mode 100644 index 0ef98d6257..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright 2008 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on 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 THEIR 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. - */ - - -/** - * Vertex fetch/store/convert code. This functionality is used in two places: - * 1. Vertex fetch/convert - to grab vertex data from incoming vertex - * arrays and convert to format needed by vertex shaders. - * 2. Vertex store/emit - to convert simple float[][4] vertex attributes - * (which is the organization used throughout the draw/prim pipeline) to - * hardware-specific formats and emit into hardware vertex buffers. - * - * - * Authors: - * Keith Whitwell - */ - -#ifndef DRAW_VF_H -#define DRAW_VF_H - - -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - -#include "draw_vertex.h" -#include "draw_private.h" /* for vertex_header */ - - -enum draw_vf_attr_format { - DRAW_EMIT_1F, - DRAW_EMIT_2F, - DRAW_EMIT_3F, - DRAW_EMIT_4F, - DRAW_EMIT_3F_XYW, /**< for projective texture */ - DRAW_EMIT_1UB_1F, /**< for fog coordinate */ - DRAW_EMIT_3UB_3F_RGB, /**< for specular color */ - DRAW_EMIT_3UB_3F_BGR, /**< for specular color */ - DRAW_EMIT_4UB_4F_RGBA, /**< for color */ - DRAW_EMIT_4UB_4F_BGRA, /**< for color */ - DRAW_EMIT_4UB_4F_ARGB, /**< for color */ - DRAW_EMIT_4UB_4F_ABGR, /**< for color */ - DRAW_EMIT_1F_CONST, - DRAW_EMIT_2F_CONST, - DRAW_EMIT_3F_CONST, - DRAW_EMIT_4F_CONST, - DRAW_EMIT_PAD, /**< leave a hole of 'offset' bytes */ - DRAW_EMIT_MAX -}; - -struct draw_vf_attr_map -{ - /** Input attribute number */ - unsigned attrib; - - enum draw_vf_attr_format format; - - unsigned offset; - - /** - * Constant data for DRAW_EMIT_*_CONST - */ - union { - uint8_t ub[4]; - float f[4]; - } data; -}; - -struct draw_vertex_fetch; - - - -#if 0 -unsigned -draw_vf_set_vertex_attributes( struct draw_vertex_fetch *vf, - const struct draw_vf_attr_map *map, - unsigned nr, - unsigned vertex_stride ); -#endif - -void draw_vf_set_vertex_info( struct draw_vertex_fetch *vf, - const struct vertex_info *vinfo, - float point_size ); - -#if 0 -void -draw_vf_set_sources( struct draw_vertex_fetch *vf, - GLvector4f * const attrib[], - unsigned start ); -#endif - -void -draw_vf_emit_vertex( struct draw_vertex_fetch *vf, - struct vertex_header *vertex, - void *dest ); - -struct draw_vertex_fetch * -draw_vf_create( void ); - -void -draw_vf_destroy( struct draw_vertex_fetch *vf ); - - - -/*********************************************************************** - * Internal functions and structs: - */ - -struct draw_vf_attr; - - -typedef void (*draw_vf_insert_func)( const struct draw_vf_attr *a, - uint8_t *v, - const float *in ); - -typedef void (*draw_vf_emit_func)( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *dest ); - - - -/** - * Describes how to convert/move a vertex attribute from a vertex - * array to a vertex structure. - */ -struct draw_vf_attr -{ - struct draw_vertex_fetch *vf; - - unsigned format; - unsigned inputsize; - unsigned inputstride; - unsigned vertoffset; /**< position of the attrib in the vertex struct */ - - boolean isconst; /**< read from const data below */ - uint8_t data[16]; - - unsigned attrib; /**< which vertex attrib (0=position, etc) */ - unsigned vertattrsize; /**< size of the attribute in bytes */ - - uint8_t *inputptr; - const draw_vf_insert_func *insert; - draw_vf_insert_func do_insert; -}; - -struct draw_vertex_fetch -{ - struct draw_vf_attr attr[PIPE_MAX_ATTRIBS]; - unsigned attr_count; - unsigned vertex_stride; - - draw_vf_emit_func emit; - - /* Parameters and constants for codegen: - */ - float identity[4]; - - struct draw_vf_fastpath *fastpath; - - void (*codegen_emit)( struct draw_vertex_fetch *vf ); -}; - - -struct draw_vf_attr_type { - unsigned format; - unsigned size; - unsigned stride; - unsigned offset; -}; - -/** XXX this could be moved into draw_vf.c */ -struct draw_vf_fastpath { - unsigned vertex_stride; - unsigned attr_count; - boolean match_strides; - - struct draw_vf_attr_type *attr; - - draw_vf_emit_func func; - struct draw_vf_fastpath *next; -}; - - -void -draw_vf_register_fastpath( struct draw_vertex_fetch *vtx, - boolean match_strides ); - -void -draw_vf_generic_emit( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *v ); - -void -draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ); - -void -draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ); - - -/** XXX this type and function could probably be moved into draw_vf.c */ -struct draw_vf_format_info { - const char *name; - draw_vf_insert_func insert[4]; - const unsigned attrsize; - const boolean isconst; -}; - -extern const struct draw_vf_format_info -draw_vf_format_info[DRAW_EMIT_MAX]; - - -#endif diff --git a/src/gallium/auxiliary/draw/draw_vf_generic.c b/src/gallium/auxiliary/draw/draw_vf_generic.c deleted file mode 100644 index 7a60a9db9c..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf_generic.c +++ /dev/null @@ -1,585 +0,0 @@ - -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on 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 THEIR 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 - */ - - -#include "pipe/p_compiler.h" -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_vf.h" - - - -static INLINE void insert_4f_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -static INLINE void insert_4f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = 1; -} - -static INLINE void insert_4f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; - out[3] = 1; -} - -static INLINE void insert_4f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; - out[2] = 0; - out[3] = 1; -} - -static INLINE void insert_3f_xyw_4( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[3]; -} - -static INLINE void insert_3f_xyw_err( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - (void) a; (void) v; (void) in; - assert(0); -} - -static INLINE void insert_3f_3( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; -} - -static INLINE void insert_3f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; - out[2] = 0; -} - -static INLINE void insert_3f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; - out[2] = 0; -} - - -static INLINE void insert_2f_2( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = in[1]; -} - -static INLINE void insert_2f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; - out[1] = 0; -} - -static INLINE void insert_1f_1( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - float *out = (float *)(v); - (void) a; - - out[0] = in[0]; -} - -static INLINE void insert_null( const struct draw_vf_attr *a, uint8_t *v, const float *in ) -{ - (void) a; (void) v; (void) in; -} - -static INLINE void insert_4ub_4f_rgba_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static INLINE void insert_4ub_4f_rgba_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_rgba_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_rgba_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); -} - -static INLINE void insert_4ub_4f_bgra_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_bgra_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; - v[3] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static INLINE void insert_4ub_4f_argb_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[3] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_argb_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); - v[2] = 0x00; - v[3] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_4( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); -} - -static INLINE void insert_4ub_4f_abgr_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); - v[1] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_4ub_4f_abgr_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); - v[2] = 0x00; - v[1] = 0x00; - v[0] = 0xff; -} - -static INLINE void insert_3ub_3f_rgb_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); -} - -static INLINE void insert_3ub_3f_rgb_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[2] = 0; -} - -static INLINE void insert_3ub_3f_rgb_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); - v[1] = 0; - v[2] = 0; -} - -static INLINE void insert_3ub_3f_bgr_3( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); -} - -static INLINE void insert_3ub_3f_bgr_2( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); - v[0] = 0; -} - -static INLINE void insert_3ub_3f_bgr_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); - v[1] = 0; - v[0] = 0; -} - - -static INLINE void insert_1ub_1f_1( const struct draw_vf_attr *a, uint8_t *v, - const float *in ) -{ - (void) a; - UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); -} - - -const struct draw_vf_format_info draw_vf_format_info[DRAW_EMIT_MAX] = -{ - { "1f", - { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, - sizeof(float), FALSE }, - - { "2f", - { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, - 2 * sizeof(float), FALSE }, - - { "3f", - { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, - 3 * sizeof(float), FALSE }, - - { "4f", - { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, - 4 * sizeof(float), FALSE }, - - { "3f_xyw", - { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, - insert_3f_xyw_4 }, - 3 * sizeof(float), FALSE }, - - { "1ub_1f", - { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 }, - sizeof(uint8_t), FALSE }, - - { "3ub_3f_rgb", - { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3, - insert_3ub_3f_rgb_3 }, - 3 * sizeof(uint8_t), FALSE }, - - { "3ub_3f_bgr", - { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3, - insert_3ub_3f_bgr_3 }, - 3 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_rgba", - { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, - insert_4ub_4f_rgba_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_bgra", - { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3, - insert_4ub_4f_bgra_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_argb", - { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3, - insert_4ub_4f_argb_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "4ub_4f_abgr", - { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3, - insert_4ub_4f_abgr_4 }, - 4 * sizeof(uint8_t), FALSE }, - - { "1f_const", - { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, - sizeof(float), TRUE }, - - { "2f_const", - { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, - 2 * sizeof(float), TRUE }, - - { "3f_const", - { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, - 3 * sizeof(float), TRUE }, - - { "4f_const", - { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, - 4 * sizeof(float), TRUE }, - - { "pad", - { NULL, NULL, NULL, NULL }, - 0, FALSE }, - -}; - - - - -/*********************************************************************** - * Hardwired fastpaths for emitting whole vertices or groups of - * vertices - */ -#define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \ -static void NAME( struct draw_vertex_fetch *vf, \ - unsigned count, \ - uint8_t *v ) \ -{ \ - struct draw_vf_attr *a = vf->attr; \ - unsigned i; \ - \ - for (i = 0 ; i < count ; i++, v += vf->vertex_stride) { \ - if (NR > 0) { \ - F0( &a[0], v + a[0].vertoffset, (float *)a[0].inputptr ); \ - a[0].inputptr += a[0].inputstride; \ - } \ - \ - if (NR > 1) { \ - F1( &a[1], v + a[1].vertoffset, (float *)a[1].inputptr ); \ - a[1].inputptr += a[1].inputstride; \ - } \ - \ - if (NR > 2) { \ - F2( &a[2], v + a[2].vertoffset, (float *)a[2].inputptr ); \ - a[2].inputptr += a[2].inputstride; \ - } \ - \ - if (NR > 3) { \ - F3( &a[3], v + a[3].vertoffset, (float *)a[3].inputptr ); \ - a[3].inputptr += a[3].inputstride; \ - } \ - \ - if (NR > 4) { \ - F4( &a[4], v + a[4].vertoffset, (float *)a[4].inputptr ); \ - a[4].inputptr += a[4].inputstride; \ - } \ - } \ -} - - -#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \ - insert_null, insert_null, NAME) - -#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \ - insert_null, NAME) - -#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \ - insert_null, NAME) - - -EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) - -EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) - -EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2) - - -/* Use the codegen paths to select one of a number of hardwired - * fastpaths. - */ -void draw_vf_generate_hardwired_emit( struct draw_vertex_fetch *vf ) -{ - draw_vf_emit_func func = NULL; - - /* Does it fit a hardwired fastpath? Help! this is growing out of - * control! - */ - switch (vf->attr_count) { - case 2: - if (vf->attr[0].do_insert == insert_3f_3 && - vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - func = emit_xyz3_rgba4; - } - break; - case 3: - if (vf->attr[2].do_insert == insert_2f_2) { - if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - if (vf->attr[0].do_insert == insert_4f_4) - func = emit_xyzw4_rgba4_st2; - } - } - break; - case 4: - if (vf->attr[2].do_insert == insert_2f_2 && - vf->attr[3].do_insert == insert_2f_2) { - if (vf->attr[1].do_insert == insert_4ub_4f_rgba_4) { - if (vf->attr[0].do_insert == insert_4f_4) - func = emit_xyzw4_rgba4_st2_st2; - } - } - break; - } - - vf->emit = func; -} - -/*********************************************************************** - * Generic (non-codegen) functions for whole vertices or groups of - * vertices - */ - -void draw_vf_generic_emit( struct draw_vertex_fetch *vf, - unsigned count, - uint8_t *v ) -{ - struct draw_vf_attr *a = vf->attr; - const unsigned attr_count = vf->attr_count; - const unsigned stride = vf->vertex_stride; - unsigned i, j; - - for (i = 0 ; i < count ; i++, v += stride) { - for (j = 0; j < attr_count; j++) { - float *in = (float *)a[j].inputptr; - a[j].inputptr += a[j].inputstride; - a[j].do_insert( &a[j], v + a[j].vertoffset, in ); - } - } -} - - diff --git a/src/gallium/auxiliary/draw/draw_vf_sse.c b/src/gallium/auxiliary/draw/draw_vf_sse.c deleted file mode 100644 index aff4ffd985..0000000000 --- a/src/gallium/auxiliary/draw/draw_vf_sse.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on 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 THEIR 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 - */ - - -#include "pipe/p_compiler.h" -#include "util/u_simple_list.h" - -#include "draw_vf.h" - - -#if defined(USE_SSE_ASM) - -#include "rtasm/rtasm_cpu.h" -#include "rtasm/rtasm_x86sse.h" - - -#define X 0 -#define Y 1 -#define Z 2 -#define W 3 - - -struct x86_program { - struct x86_function func; - - struct draw_vertex_fetch *vf; - boolean inputs_safe; - boolean outputs_safe; - boolean have_sse2; - - struct x86_reg identity; - struct x86_reg chan0; -}; - - -static struct x86_reg get_identity( struct x86_program *p ) -{ - return p->identity; -} - -static void emit_load4f_4( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_load4f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Have to jump through some hoops: - * - * c 0 0 0 - * c 0 0 1 - * 0 0 c 1 - * a b c 1 - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); - sse_shufps(&p->func, dest, dest, SHUF(Y,Z,X,W) ); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Initialize from identity, then pull in low two words: - */ - sse_movups(&p->func, dest, get_identity(p)); - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load4f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Pull in low word, then swizzle in identity */ - sse_movss(&p->func, dest, arg0); - sse_shufps(&p->func, dest, get_identity(p), SHUF(X,Y,Z,W) ); -} - - - -static void emit_load3f_3( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - /* Over-reads by 1 dword - potential SEGV if input is a vertex - * array. - */ - if (p->inputs_safe) { - sse_movups(&p->func, dest, arg0); - } - else { - /* c 0 0 0 - * c c c c - * a b c c - */ - sse_movss(&p->func, dest, x86_make_disp(arg0, 8)); - sse_shufps(&p->func, dest, dest, SHUF(X,X,X,X)); - sse_movlps(&p->func, dest, arg0); - } -} - -static void emit_load3f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_2(p, dest, arg0); -} - -static void emit_load3f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_1(p, dest, arg0); -} - -static void emit_load2f_2( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_load2f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - emit_load4f_1(p, dest, arg0); -} - -static void emit_load1f_1( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - -static void (*load[4][4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = { - { emit_load1f_1, - emit_load1f_1, - emit_load1f_1, - emit_load1f_1 }, - - { emit_load2f_1, - emit_load2f_2, - emit_load2f_2, - emit_load2f_2 }, - - { emit_load3f_1, - emit_load3f_2, - emit_load3f_3, - emit_load3f_3 }, - - { emit_load4f_1, - emit_load4f_2, - emit_load4f_3, - emit_load4f_4 } -}; - -static void emit_load( struct x86_program *p, - struct x86_reg dest, - unsigned sz, - struct x86_reg src, - unsigned src_sz) -{ - load[sz-1][src_sz-1](p, dest, src); -} - -static void emit_store4f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movups(&p->func, dest, arg0); -} - -static void emit_store3f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - if (p->outputs_safe) { - /* Emit the extra dword anyway. This may hurt writecombining, - * may cause other problems. - */ - sse_movups(&p->func, dest, arg0); - } - else { - /* Alternate strategy - emit two, shuffle, emit one. - */ - sse_movlps(&p->func, dest, arg0); - sse_shufps(&p->func, arg0, arg0, SHUF(Z,Z,Z,Z) ); /* NOTE! destructive */ - sse_movss(&p->func, x86_make_disp(dest,8), arg0); - } -} - -static void emit_store2f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movlps(&p->func, dest, arg0); -} - -static void emit_store1f( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) -{ - sse_movss(&p->func, dest, arg0); -} - - -static void (*store[4])( struct x86_program *p, - struct x86_reg dest, - struct x86_reg arg0 ) = -{ - emit_store1f, - emit_store2f, - emit_store3f, - emit_store4f -}; - -static void emit_store( struct x86_program *p, - struct x86_reg dest, - unsigned sz, - struct x86_reg temp ) - -{ - store[sz-1](p, dest, temp); -} - -static void emit_pack_store_4ub( struct x86_program *p, - struct x86_reg dest, - struct x86_reg temp ) -{ - /* Scale by 255.0 - */ - sse_mulps(&p->func, temp, p->chan0); - - if (p->have_sse2) { - sse2_cvtps2dq(&p->func, temp, temp); - sse2_packssdw(&p->func, temp, temp); - sse2_packuswb(&p->func, temp, temp); - sse_movss(&p->func, dest, temp); - } - else { - struct x86_reg mmx0 = x86_make_reg(file_MMX, 0); - struct x86_reg mmx1 = x86_make_reg(file_MMX, 1); - sse_cvtps2pi(&p->func, mmx0, temp); - sse_movhlps(&p->func, temp, temp); - sse_cvtps2pi(&p->func, mmx1, temp); - mmx_packssdw(&p->func, mmx0, mmx1); - mmx_packuswb(&p->func, mmx0, mmx0); - mmx_movd(&p->func, dest, mmx0); - } -} - -static int get_offset( const void *a, const void *b ) -{ - return (const char *)b - (const char *)a; -} - -/* Not much happens here. Eventually use this function to try and - * avoid saving/reloading the source pointers each vertex (if some of - * them can fit in registers). - */ -static void get_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vfREG, - struct draw_vf_attr *a ) -{ - struct draw_vertex_fetch *vf = p->vf; - struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); - - /* Load current a[j].inputptr - */ - x86_mov(&p->func, srcREG, ptr_to_src); -} - -static void update_src_ptr( struct x86_program *p, - struct x86_reg srcREG, - struct x86_reg vfREG, - struct draw_vf_attr *a ) -{ - if (a->inputstride) { - struct draw_vertex_fetch *vf = p->vf; - struct x86_reg ptr_to_src = x86_make_disp(vfREG, get_offset(vf, &a->inputptr)); - - /* add a[j].inputstride (hardcoded value - could just as easily - * pull the stride value from memory each time). - */ - x86_lea(&p->func, srcREG, x86_make_disp(srcREG, a->inputstride)); - - /* save new value of a[j].inputptr - */ - x86_mov(&p->func, ptr_to_src, srcREG); - } -} - - -/* Lots of hardcoding - * - * EAX -- pointer to current output vertex - * ECX -- pointer to current attribute - * - */ -static boolean build_vertex_emit( struct x86_program *p ) -{ - struct draw_vertex_fetch *vf = p->vf; - unsigned j = 0; - - struct x86_reg vertexEAX = x86_make_reg(file_REG32, reg_AX); - struct x86_reg srcECX = x86_make_reg(file_REG32, reg_CX); - struct x86_reg countEBP = x86_make_reg(file_REG32, reg_BP); - struct x86_reg vfESI = x86_make_reg(file_REG32, reg_SI); - struct x86_reg temp = x86_make_reg(file_XMM, 0); - uint8_t *fixup, *label; - - /* Push a few regs? - */ - x86_push(&p->func, countEBP); - x86_push(&p->func, vfESI); - - - /* Get vertex count, compare to zero - */ - x86_xor(&p->func, srcECX, srcECX); - x86_mov(&p->func, countEBP, x86_fn_arg(&p->func, 2)); - x86_cmp(&p->func, countEBP, srcECX); - fixup = x86_jcc_forward(&p->func, cc_E); - - /* Initialize destination register. - */ - x86_mov(&p->func, vertexEAX, x86_fn_arg(&p->func, 3)); - - /* Move argument 1 (vf) into a reg: - */ - x86_mov(&p->func, vfESI, x86_fn_arg(&p->func, 1)); - - - /* always load, needed or not: - */ - sse_movups(&p->func, p->identity, x86_make_disp(vfESI, get_offset(vf, &vf->identity[0]))); - - /* Note address for loop jump */ - label = x86_get_label(&p->func); - - /* Emit code for each of the attributes. Currently routes - * everything through SSE registers, even when it might be more - * efficient to stick with regular old x86. No optimization or - * other tricks - enough new ground to cover here just getting - * things working. - */ - while (j < vf->attr_count) { - struct draw_vf_attr *a = &vf->attr[j]; - struct x86_reg dest = x86_make_disp(vertexEAX, a->vertoffset); - - /* Now, load an XMM reg from src, perhaps transform, then save. - * Could be shortcircuited in specific cases: - */ - switch (a->format) { - case DRAW_EMIT_1F: - case DRAW_EMIT_1F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 1, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_2F: - case DRAW_EMIT_2F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_3F: - case DRAW_EMIT_3F_CONST: - /* Potentially the worst case - hardcode 2+1 copying: - */ - if (0) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vfESI, a); - } - else { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 2, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 2, temp); - if (a->inputsize > 2) { - emit_load(p, temp, 1, x86_make_disp(srcECX, 8), 1); - emit_store(p, x86_make_disp(dest,8), 1, temp); - } - else { - sse_movss(&p->func, x86_make_disp(dest,8), get_identity(p)); - } - update_src_ptr(p, srcECX, vfESI, a); - } - break; - case DRAW_EMIT_4F: - case DRAW_EMIT_4F_CONST: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_store(p, dest, 4, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_3F_XYW: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,Y,W,Z)); - emit_store(p, dest, 3, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - - case DRAW_EMIT_1UB_1F: - /* Test for PAD3 + 1UB: - */ - if (j > 0 && - a[-1].vertoffset + a[-1].vertattrsize <= a->vertoffset - 3) - { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 1, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(X,X,X,X)); - emit_pack_store_4ub(p, x86_make_disp(dest, -3), temp); /* overkill! */ - update_src_ptr(p, srcECX, vfESI, a); - } - else { - debug_printf("Can't emit 1ub %x %x %d\n", - a->vertoffset, a[-1].vertoffset, a[-1].vertattrsize ); - return FALSE; - } - break; - case DRAW_EMIT_3UB_3F_RGB: - case DRAW_EMIT_3UB_3F_BGR: - /* Test for 3UB + PAD1: - */ - if (j == vf->attr_count - 1 || - a[1].vertoffset >= a->vertoffset + 4) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - if (a->format == DRAW_EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - } - /* Test for 3UB + 1UB: - */ - else if (j < vf->attr_count - 1 && - a[1].format == DRAW_EMIT_1UB_1F && - a[1].vertoffset == a->vertoffset + 3) { - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 3, x86_deref(srcECX), a->inputsize); - update_src_ptr(p, srcECX, vfESI, a); - - /* Make room for incoming value: - */ - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - - get_src_ptr(p, srcECX, vfESI, &a[1]); - emit_load(p, temp, 1, x86_deref(srcECX), a[1].inputsize); - update_src_ptr(p, srcECX, vfESI, &a[1]); - - /* Rearrange and possibly do BGR conversion: - */ - if (a->format == DRAW_EMIT_3UB_3F_BGR) - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - else - sse_shufps(&p->func, temp, temp, SHUF(Y,Z,W,X)); - - emit_pack_store_4ub(p, dest, temp); - j++; /* NOTE: two attrs consumed */ - } - else { - debug_printf("Can't emit 3ub\n"); - } - return FALSE; /* add this later */ - break; - - case DRAW_EMIT_4UB_4F_RGBA: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_BGRA: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(Z,Y,X,W)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_ARGB: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,X,Y,Z)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - case DRAW_EMIT_4UB_4F_ABGR: - get_src_ptr(p, srcECX, vfESI, a); - emit_load(p, temp, 4, x86_deref(srcECX), a->inputsize); - sse_shufps(&p->func, temp, temp, SHUF(W,Z,Y,X)); - emit_pack_store_4ub(p, dest, temp); - update_src_ptr(p, srcECX, vfESI, a); - break; - default: - debug_printf("unknown a[%d].format %d\n", j, a->format); - return FALSE; /* catch any new opcodes */ - } - - /* Increment j by at least 1 - may have been incremented above also: - */ - j++; - } - - /* Next vertex: - */ - x86_lea(&p->func, vertexEAX, x86_make_disp(vertexEAX, vf->vertex_stride)); - - /* decr count, loop if not zero - */ - x86_dec(&p->func, countEBP); - x86_test(&p->func, countEBP, countEBP); - x86_jcc(&p->func, cc_NZ, label); - - /* Exit mmx state? - */ - if (p->func.need_emms) - mmx_emms(&p->func); - - /* Land forward jump here: - */ - x86_fixup_fwd_jump(&p->func, fixup); - - /* Pop regs and return - */ - x86_pop(&p->func, x86_get_base_reg(vfESI)); - x86_pop(&p->func, countEBP); - x86_ret(&p->func); - - vf->emit = (draw_vf_emit_func)x86_get_func(&p->func); - return TRUE; -} - - - -void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) -{ - struct x86_program p; - - if (!rtasm_cpu_has_sse()) { - vf->codegen_emit = NULL; - return; - } - - memset(&p, 0, sizeof(p)); - - p.vf = vf; - p.inputs_safe = 0; /* for now */ - p.outputs_safe = 1; /* for now */ - p.have_sse2 = rtasm_cpu_has_sse2(); - p.identity = x86_make_reg(file_XMM, 6); - p.chan0 = x86_make_reg(file_XMM, 7); - - x86_init_func(&p.func); - - if (build_vertex_emit(&p)) { - draw_vf_register_fastpath( vf, TRUE ); - } - else { - /* Note the failure so that we don't keep trying to codegen an - * impossible state: - */ - draw_vf_register_fastpath( vf, FALSE ); - x86_release_func(&p.func); - } -} - -#else - -void draw_vf_generate_sse_emit( struct draw_vertex_fetch *vf ) -{ - /* Dummy version for when USE_SSE_ASM not defined */ -} - -#endif -- cgit v1.2.3 From a41c05b20a36d2160aa232d08ed57d3095438025 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:11:16 +0100 Subject: draw: switch over to draw_pt paths, will remove old code shortly --- src/gallium/auxiliary/draw/draw_context.c | 2 -- src/gallium/auxiliary/draw/draw_private.h | 1 - src/gallium/auxiliary/draw/draw_pt.c | 3 --- 3 files changed, 6 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 4838b68ed1..5dc3358bd1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -49,8 +49,6 @@ struct draw_context *draw_create( void ) draw->use_sse = FALSE; #endif - draw->use_pt_shaders = GETENV( "GALLIUM_PT_SHADERS" ) != NULL; - /* create pipeline stages */ draw->pipeline.wide_line = draw_wide_line_stage( draw ); draw->pipeline.wide_point = draw_wide_point_stage( draw ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index da94e69781..18ce6c0ec5 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -258,7 +258,6 @@ struct draw_context boolean line_stipple; /**< do line stipple? */ boolean point_sprite; /**< convert points to quads for sprites? */ boolean use_sse; - boolean use_pt_shaders; /* temporary flag to switch on pt shader paths */ /* If a prim stage introduces new vertex attributes, they'll be stored here */ diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index b48d0cae9f..941f6efbe4 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -68,9 +68,6 @@ draw_pt_arrays(struct draw_context *draw, if (!draw->rasterizer->bypass_vs) { opt |= PT_SHADE; - - if (!draw->use_pt_shaders) - return FALSE; } -- cgit v1.2.3 From b11d89dc6d230f7f945f9eb420d39921c648ec20 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:36:38 +0100 Subject: draw: remove draw_prim.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_prim.c | 23 -------------- src/gallium/auxiliary/draw/draw_pt.c | 55 ++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 27464e5c86..080311a667 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -24,7 +24,6 @@ C_SOURCES = \ draw_pt_emit.c \ draw_pt_pipeline.c \ draw_pt_elts.c \ - draw_prim.c \ draw_pstipple.c \ draw_stipple.c \ draw_twoside.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 7af65c3c05..238e3f7d28 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -11,7 +11,6 @@ draw = env.ConvenienceLibrary( 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', - 'draw_prim.c', 'draw_pstipple.c', 'draw_pt.c', 'draw_pt_elts.c', diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c index 51b6950334..d61cd25243 100644 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ b/src/gallium/auxiliary/draw/draw_prim.c @@ -497,27 +497,4 @@ draw_prim( struct draw_context *draw, -/** - * Draw vertex arrays - * This is the main entrypoint into the drawing module. - * \param prim one of PIPE_PRIM_x - * \param start index of first vertex to draw - * \param count number of vertices to draw - */ -void -draw_arrays(struct draw_context *draw, unsigned prim, - unsigned start, unsigned count) -{ - if (reduced_prim[prim] != draw->reduced_prim) { - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->reduced_prim = reduced_prim[prim]; - } - - /* drawing done here: */ - if (!draw_pt_arrays(draw, prim, start, count)) { - /* we have to run the whole pipeline */ - draw_prim(draw, prim, start, count); - } -} - diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 941f6efbe4..ecaed84070 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -128,3 +128,58 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.front.vcache = NULL; } } + + + +static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { + PIPE_PRIM_POINTS, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_LINES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES, + PIPE_PRIM_TRIANGLES +}; + + +/** + * Draw vertex arrays + * This is the main entrypoint into the drawing module. + * \param prim one of PIPE_PRIM_x + * \param start index of first vertex to draw + * \param count number of vertices to draw + */ +void +draw_arrays(struct draw_context *draw, unsigned prim, + unsigned start, unsigned count) +{ + if (reduced_prim[prim] != draw->reduced_prim) { + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw->reduced_prim = reduced_prim[prim]; + } + + /* drawing done here: */ + draw_pt_arrays(draw, prim, start, count); +} + + +/* Revamp me please: + */ +void draw_do_flush( struct draw_context *draw, unsigned flags ) +{ + if (!draw->flushing) + { + draw->flushing = TRUE; + + if (flags >= DRAW_FLUSH_STATE_CHANGE) { + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; + draw->reduced_prim = ~0; + } + + draw->flushing = FALSE; + } +} -- cgit v1.2.3 From 66891826421d5b774e081f7a2a85580cd0523fab Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:39:13 +0100 Subject: draw: remove draw_vertex_cache.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/draw_context.c | 20 +- src/gallium/auxiliary/draw/draw_prim.c | 500 ------------------------- src/gallium/auxiliary/draw/draw_vertex_cache.c | 219 ----------- 4 files changed, 18 insertions(+), 722 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_prim.c delete mode 100644 src/gallium/auxiliary/draw/draw_vertex_cache.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 080311a667..03210f6a4a 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -31,7 +31,6 @@ C_SOURCES = \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ - draw_vertex_cache.c \ draw_vertex_fetch.c \ draw_vertex_shader.c \ draw_wide_line.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 5dc3358bd1..c611300841 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -103,7 +103,6 @@ struct draw_context *draw_create( void ) draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ - draw_vertex_cache_invalidate( draw ); draw_set_mapped_element_buffer( draw, 0, NULL ); tgsi_exec_machine_init(&draw->machine); @@ -446,7 +445,6 @@ void draw_reset_vertex_ids(struct draw_context *draw) stage = stage->next; } - draw_vertex_cache_reset_vertex_ids(draw); /* going away soon */ draw_pt_reset_vertex_ids(draw); } @@ -473,3 +471,21 @@ boolean draw_get_edgeflag( struct draw_context *draw, return 1; } + +/** + * Tell the drawing context about the index/element buffer to use + * (ala glDrawElements) + * If no element buffer is to be used (i.e. glDrawArrays) then this + * should be called with eltSize=0 and elements=NULL. + * + * \param draw the drawing context + * \param eltSize size of each element (1, 2 or 4 bytes) + * \param elements the element buffer ptr + */ +void +draw_set_mapped_element_buffer( struct draw_context *draw, + unsigned eltSize, void *elements ) +{ + draw->user.elts = elements; + draw->user.eltSize = eltSize; +} diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c deleted file mode 100644 index d61cd25243..0000000000 --- a/src/gallium/auxiliary/draw/draw_prim.c +++ /dev/null @@ -1,500 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_private.h" -#include "draw_context.h" - - - -#define RP_NONE 0 -#define RP_POINT 1 -#define RP_LINE 2 -#define RP_TRI 3 - - -static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { - RP_POINT, - RP_LINE, - RP_LINE, - RP_LINE, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI, - RP_TRI -}; - - -static void draw_prim_queue_flush( struct draw_context *draw ) -{ - unsigned i; - - if (0) - debug_printf("Flushing with %d prims, %d verts\n", - draw->pq.queue_nr, draw->vs.queue_nr); - - assert (draw->pq.queue_nr != 0); - - /* NOTE: we cannot save draw->pipeline->first in a local var because - * draw->pipeline->first is often changed by the first call to tri(), - * line(), etc. - */ - if (draw->rasterizer->line_stipple_enable) { - switch (draw->reduced_prim) { - case RP_TRI: - for (i = 0; i < draw->pq.queue_nr; i++) { - if (draw->pq.queue[i].reset_line_stipple) - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - - draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); - } - break; - case RP_LINE: - for (i = 0; i < draw->pq.queue_nr; i++) { - if (draw->pq.queue[i].reset_line_stipple) - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - - draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); - } - break; - case RP_POINT: - draw->pipeline.first->reset_stipple_counter( draw->pipeline.first ); - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); - break; - } - } - else { - switch (draw->reduced_prim) { - case RP_TRI: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->tri( draw->pipeline.first, &draw->pq.queue[i] ); - break; - case RP_LINE: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->line( draw->pipeline.first, &draw->pq.queue[i] ); - break; - case RP_POINT: - for (i = 0; i < draw->pq.queue_nr; i++) - draw->pipeline.first->point( draw->pipeline.first, &draw->pq.queue[i] ); - break; - } - } - - draw->pq.queue_nr = 0; - draw->vs.post_nr = 0; - draw_vertex_cache_unreference( draw ); -} - -void draw_do_flush( struct draw_context *draw, unsigned flags ) -{ - if (0) - debug_printf("Flushing with %d verts, %d prims\n", - draw->vs.queue_nr, - draw->pq.queue_nr ); - - if (draw->flushing) - return; - - draw->flushing = TRUE; - - if (flags >= DRAW_FLUSH_SHADER_QUEUE) { - if (draw->vs.queue_nr) { - (*draw->shader_queue_flush)(draw); - } - - if (flags >= DRAW_FLUSH_PRIM_QUEUE) { - if (draw->pq.queue_nr) - draw_prim_queue_flush(draw); - - if (flags >= DRAW_FLUSH_VERTEX_CACHE) { - draw_vertex_cache_invalidate(draw); - - if (flags >= DRAW_FLUSH_STATE_CHANGE) { - draw->pipeline.first->flush( draw->pipeline.first, flags ); - draw->pipeline.first = draw->pipeline.validate; - draw->reduced_prim = ~0; - } - } - } - } - - draw->flushing = FALSE; -} - - - -/* Return a pointer to a freshly queued primitive header. Ensure that - * there is room in the vertex cache for a maximum of "nr_verts" new - * vertices. Flush primitive and/or vertex queues if necessary to - * make space. - */ -static struct prim_header *get_queued_prim( struct draw_context *draw, - unsigned nr_verts ) -{ - if (!draw_vertex_cache_check_space( draw, nr_verts )) { -// debug_printf("v"); - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE ); - } - else if (draw->pq.queue_nr == PRIM_QUEUE_LENGTH) { -// debug_printf("p"); - draw_do_flush( draw, DRAW_FLUSH_PRIM_QUEUE ); - } - - assert(draw->pq.queue_nr < PRIM_QUEUE_LENGTH); - - return &draw->pq.queue[draw->pq.queue_nr++]; -} - - - -/** - * Add a point to the primitive queue. - * \param i0 index into user's vertex arrays - */ -static void do_point( struct draw_context *draw, - unsigned i0 ) -{ - struct prim_header *prim = get_queued_prim( draw, 1 ); - - prim->reset_line_stipple = 0; - prim->edgeflags = 1; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); -} - - -/** - * Add a line to the primitive queue. - * \param i0 index into user's vertex arrays - * \param i1 index into user's vertex arrays - */ -static void do_line( struct draw_context *draw, - boolean reset_stipple, - unsigned i0, - unsigned i1 ) -{ - struct prim_header *prim = get_queued_prim( draw, 2 ); - - prim->reset_line_stipple = reset_stipple; - prim->edgeflags = 1; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); - prim->v[1] = draw->vcache.get_vertex( draw, i1 ); -} - -/** - * Add a triangle to the primitive queue. - */ -static void do_triangle( struct draw_context *draw, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - struct prim_header *prim = get_queued_prim( draw, 3 ); - -// _mesa_printf("tri %d %d %d\n", i0, i1, i2); - prim->reset_line_stipple = 1; - prim->edgeflags = ~0; - prim->pad = 0; - prim->v[0] = draw->vcache.get_vertex( draw, i0 ); - prim->v[1] = draw->vcache.get_vertex( draw, i1 ); - prim->v[2] = draw->vcache.get_vertex( draw, i2 ); -} - -static void do_ef_triangle( struct draw_context *draw, - boolean reset_stipple, - unsigned ef_mask, - unsigned i0, - unsigned i1, - unsigned i2 ) -{ - struct prim_header *prim = get_queued_prim( draw, 3 ); - struct vertex_header *v0 = draw->vcache.get_vertex( draw, i0 ); - struct vertex_header *v1 = draw->vcache.get_vertex( draw, i1 ); - struct vertex_header *v2 = draw->vcache.get_vertex( draw, i2 ); - - prim->reset_line_stipple = reset_stipple; - - prim->edgeflags = ef_mask & ((v0->edgeflag << 0) | - (v1->edgeflag << 1) | - (v2->edgeflag << 2)); - prim->pad = 0; - prim->v[0] = v0; - prim->v[1] = v1; - prim->v[2] = v2; -} - - -static void do_ef_quad( struct draw_context *draw, - unsigned v0, - unsigned v1, - unsigned v2, - unsigned v3 ) -{ - const unsigned omitEdge2 = ~(1 << 1); - const unsigned omitEdge3 = ~(1 << 2); - do_ef_triangle( draw, 1, omitEdge2, v0, v1, v3 ); - do_ef_triangle( draw, 0, omitEdge3, v1, v2, v3 ); -} - -static void do_quad( struct draw_context *draw, - unsigned v0, - unsigned v1, - unsigned v2, - unsigned v3 ) -{ - do_triangle( draw, v0, v1, v3 ); - do_triangle( draw, v1, v2, v3 ); -} - - -/** - * Main entrypoint to draw some number of points/lines/triangles - */ -static void -draw_prim( struct draw_context *draw, - unsigned prim, unsigned start, unsigned count ) -{ - unsigned i; - boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL); - boolean flatfirst = - (draw->rasterizer->flatshade & draw->rasterizer->flatshade_first) ? TRUE : FALSE; - -// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count ); - - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - do_point( draw, - start + i ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - do_line( draw, - TRUE, - start + i + 0, - start + i + 1); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, /* XXX: only if vb not split */ - start + i - 1, - start + i ); - } - - do_line( draw, - 0, - start + count - 1, - start + 0 ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - do_line( draw, - i == 1, - start + i - 1, - start + i ); - } - break; - - case PIPE_PRIM_TRIANGLES: - if (unfilled) { - for (i = 0; i+2 < count; i += 3) { - do_ef_triangle( draw, - 1, - ~0, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - else { - for (i = 0; i+2 < count; i += 3) { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - if (i & 1) { - do_triangle( draw, - start + i + 0, - start + i + 2, - start + i + 1 ); - } - else { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - } - else { - for (i = 0; i+2 < count; i++) { - if (i & 1) { - do_triangle( draw, - start + i + 1, - start + i + 0, - start + i + 2 ); - } - else { - do_triangle( draw, - start + i + 0, - start + i + 1, - start + i + 2 ); - } - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + i + 1, - start + i + 2, - start + 0 ); - } - } - else { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + 0, - start + i + 1, - start + i + 2 ); - } - } - } - break; - - - case PIPE_PRIM_QUADS: - if (unfilled) { - for (i = 0; i+3 < count; i += 4) { - do_ef_quad( draw, - start + i + 0, - start + i + 1, - start + i + 2, - start + i + 3); - } - } - else { - for (i = 0; i+3 < count; i += 4) { - do_quad( draw, - start + i + 0, - start + i + 1, - start + i + 2, - start + i + 3); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - if (unfilled) { - for (i = 0; i+3 < count; i += 2) { - do_ef_quad( draw, - start + i + 2, - start + i + 0, - start + i + 1, - start + i + 3); - } - } - else { - for (i = 0; i+3 < count; i += 2) { - do_quad( draw, - start + i + 2, - start + i + 0, - start + i + 1, - start + i + 3); - } - } - break; - - case PIPE_PRIM_POLYGON: - if (unfilled) { - unsigned ef_mask = (1<<2) | (1<<0); - - for (i = 0; i+2 < count; i++) { - - if (i + 3 >= count) - ef_mask |= (1<<1); - - do_ef_triangle( draw, - i == 0, - ef_mask, - start + i + 1, - start + i + 2, - start + 0); - - ef_mask &= ~(1<<2); - } - } - else { - for (i = 0; i+2 < count; i++) { - do_triangle( draw, - start + i + 1, - start + i + 2, - start + 0); - } - } - break; - - default: - assert(0); - break; - } -} - - - - - diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c deleted file mode 100644 index 730c18bcb3..0000000000 --- a/src/gallium/auxiliary/draw/draw_vertex_cache.c +++ /dev/null @@ -1,219 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "draw_private.h" -#include "draw_context.h" - - -void draw_vertex_cache_invalidate( struct draw_context *draw ) -{ - assert(draw->pq.queue_nr == 0); - assert(draw->vs.queue_nr == 0); - assert(draw->vcache.referenced == 0); - - /* There's an error somewhere in the vcache code that requires this - * memset. The bug is exposed in q3demo demo001, but probably - * elsewhere as well. Will track it down later. - */ - memset(draw->vcache.idx, ~0, sizeof(draw->vcache.idx)); -} - - -/** - * Check if vertex is in cache, otherwise add it. It won't go through - * VS yet, not until there is a flush operation or the VS queue fills up. - * - * Note that cache entries are basically just two pointers: the first - * an index into the user's vertex arrays, the second a location in - * the vertex shader cache for the post-transformed vertex. - * - * \return pointer to location of (post-transformed) vertex header in the cache - */ -static struct vertex_header *get_vertex( struct draw_context *draw, - unsigned i ) -{ - unsigned slot = (i + (i>>5)) % VCACHE_SIZE; - - assert(slot < 32); /* so we don't exceed the bitfield size below */ - - if (draw->vcache.referenced & (1<vcache.idx[slot].in == i) { - /*debug_printf("HIT %d %d\n", slot, i);*/ - assert(draw->vcache.idx[slot].out < draw->vs.queue_nr); - return draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, - draw->vcache.idx[slot].out); - } - - /* Otherwise a collision - */ - slot = VCACHE_SIZE + draw->vcache.overflow++; - /*debug_printf("XXX %d --> %d\n", i, slot);*/ - } - - /* Deal with the cache miss: - */ - { - unsigned out; - struct vertex_header *header; - - assert(slot < Elements(draw->vcache.idx)); - - /*debug_printf("NEW %d %d\n", slot, i);*/ - draw->vcache.idx[slot].in = i; - draw->vcache.idx[slot].out = out = draw->vs.queue_nr++; - draw->vcache.referenced |= (1 << slot); - - - /* Add to vertex shader queue: - */ - assert(draw->vs.queue_nr < VS_QUEUE_LENGTH); - - header = draw_header_from_block(draw->vs.vertex_cache, MAX_VERTEX_ALLOCATION, - out); - draw->vs.elts[out] = i; - header->clipmask = 0; - header->edgeflag = draw_get_edgeflag(draw, i); - header->pad = 0; - header->vertex_id = UNDEFINED_VERTEX_ID; - - /* Need to set the vertex's edge flag here. If we're being called - * by do_ef_triangle(), that function needs edge flag info! - */ - - return draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, - draw->vcache.idx[slot].out); - } -} - - -static struct vertex_header *get_uint_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const unsigned *elts = (const unsigned *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -static struct vertex_header *get_ushort_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const ushort *elts = (const ushort *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -static struct vertex_header *get_ubyte_elt_vertex( struct draw_context *draw, - unsigned i ) -{ - const ubyte *elts = (const ubyte *) draw->user.elts; - return get_vertex( draw, elts[i] ); -} - - -void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ) -{ - unsigned i; - - for (i = 0; i < draw->vs.post_nr; i++) { - struct vertex_header * header = - draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, i); - header->vertex_id = UNDEFINED_VERTEX_ID; - } -} - - -void draw_vertex_cache_unreference( struct draw_context *draw ) -{ - draw->vcache.referenced = 0; - draw->vcache.overflow = 0; -} - - -int draw_vertex_cache_check_space( struct draw_context *draw, - unsigned nr_verts ) -{ - if (draw->vcache.overflow + nr_verts < VCACHE_OVERFLOW) { - /* The vs queue is sized so that this can never happen: - */ - assert(draw->vs.queue_nr + nr_verts < VS_QUEUE_LENGTH); - return TRUE; - } - else - return FALSE; -} - - - -/** - * Tell the drawing context about the index/element buffer to use - * (ala glDrawElements) - * If no element buffer is to be used (i.e. glDrawArrays) then this - * should be called with eltSize=0 and elements=NULL. - * - * \param draw the drawing context - * \param eltSize size of each element (1, 2 or 4 bytes) - * \param elements the element buffer ptr - */ -void -draw_set_mapped_element_buffer( struct draw_context *draw, - unsigned eltSize, void *elements ) -{ -// draw_statechange( draw ); - - /* choose the get_vertex() function to use */ - switch (eltSize) { - case 0: - draw->vcache.get_vertex = get_vertex; - break; - case 1: - draw->vcache.get_vertex = get_ubyte_elt_vertex; - break; - case 2: - draw->vcache.get_vertex = get_ushort_elt_vertex; - break; - case 4: - draw->vcache.get_vertex = get_uint_elt_vertex; - break; - default: - assert(0); - } - draw->user.elts = elements; - draw->user.eltSize = eltSize; -} - -- cgit v1.2.3 From dd903d83b3ff8dd19f75ac7542b96bc8f1387fe6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:41:39 +0100 Subject: draw: remove old vertex_shader->run() functions --- src/gallium/auxiliary/draw/draw_vertex_shader.c | 2 +- src/gallium/auxiliary/draw/draw_vs.h | 7 -- src/gallium/auxiliary/draw/draw_vs_exec.c | 137 ------------------------ src/gallium/auxiliary/draw/draw_vs_llvm.c | 108 ------------------- src/gallium/auxiliary/draw/draw_vs_sse.c | 126 ---------------------- 5 files changed, 1 insertion(+), 379 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index c0c17c116e..118664d619 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -74,7 +74,7 @@ draw_vertex_shader_queue_flush(struct draw_context *draw) assert(n > 0); assert(n <= MAX_SHADER_VERTICES); - shader->run(shader, draw, elts, n, dests, MAX_VERTEX_ALLOCATION); +// shader->run(shader, draw, elts, n, dests, MAX_VERTEX_ALLOCATION); } draw->vs.post_nr = draw->vs.queue_nr; diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index e88d00e247..b6f3bbdaea 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -55,13 +55,6 @@ struct draw_vertex_shader { /* Run the shader - this interface will get cleaned up in the * future: */ - boolean (*run)( struct draw_vertex_shader *shader, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *out, - unsigned vertex_size); - void (*run_linear)( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 184151b9b1..54a2b2ab04 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -66,145 +66,9 @@ vs_exec_prepare( struct draw_vertex_shader *shader, PIPE_MAX_SAMPLERS, NULL /*samplers*/ ); - draw_update_vertex_fetch( draw ); } -/** - * Transform vertices with the current vertex program/shader - * Up to four vertices can be shaded at a time. - * \param vbuffer the input vertex data - * \param elts indexes of four input vertices - * \param count number of vertices to shade [1..4] - * \param vOut array of pointers to four output vertices - */ -static boolean -vs_exec_run( struct draw_vertex_shader *shader, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *vOut, - unsigned vertex_size) -{ - struct exec_vertex_shader *evs = exec_vertex_shader(shader); - struct tgsi_exec_machine *machine = evs->machine; - unsigned int i, j; - unsigned int clipped = 0; - struct tgsi_exec_vector *outputs = 0; - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - assert(shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - - machine->Consts = (const float (*)[4]) draw->user.constants; - - if (draw->rasterizer->bypass_vs) { - /* outputs are just the inputs */ - outputs = machine->Inputs; - } - else { - outputs = machine->Outputs; - } - - for (i = 0; i < count; i += MAX_TGSI_VERTICES) { - unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); - draw->vertex_fetch.fetch_func( draw, machine, &elts[i], max_vertices ); - -#if 0 - for (j = 0; j < max_vertices; j++) { - unsigned slot; - debug_printf("%d) Input vert:\n", i + j); - for (slot = 0; slot < shader->info.num_inputs; slot++) { - debug_printf("\t%d: %f %f %f %f\n", slot, - machine->Inputs[slot].xyzw[0].f[j], - machine->Inputs[slot].xyzw[1].f[j], - machine->Inputs[slot].xyzw[2].f[j], - machine->Inputs[slot].xyzw[3].f[j]); - } - } -#endif - - - if (!draw->rasterizer->bypass_vs) { - /* run interpreter */ - tgsi_exec_machine_run( machine ); - } - - /* store machine results */ - for (j = 0; j < max_vertices; j++) { - unsigned slot; - float x, y, z, w; - struct vertex_header *out = - draw_header_from_block(vOut, vertex_size, i + j); - - /* Handle attr[0] (position) specially: - * - * XXX: Computing the clipmask should be done in the vertex - * program as a set of DP4 instructions appended to the - * user-provided code. - */ - x = out->clip[0] = outputs[0].xyzw[0].f[j]; - y = out->clip[1] = outputs[0].xyzw[1].f[j]; - z = out->clip[2] = outputs[0].xyzw[2].f[j]; - w = out->clip[3] = outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - out->clipmask = compute_clipmask(out->clip, draw->plane, - draw->nr_planes); - clipped += out->clipmask; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - out->clipmask = 0; - } - out->edgeflag = 1; - out->vertex_id = UNDEFINED_VERTEX_ID; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - out->data[0][0] = x * scale[0] + trans[0]; - out->data[0][1] = y * scale[1] + trans[1]; - out->data[0][2] = z * scale[2] + trans[2]; - out->data[0][3] = w; - } - else - { - out->data[0][0] = x; - out->data[0][1] = y; - out->data[0][2] = z; - out->data[0][3] = w; - } - - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = outputs[slot].xyzw[3].f[j]; - } - -#if 0 /*DEBUG*/ - printf("%d) Post xform vert:\n", i + j); - for (slot = 0; slot < draw->num_vs_outputs; slot++) { - printf("\t%d: %f %f %f %f\n", slot, - out->data[slot][0], - out->data[slot][1], - out->data[slot][2], - out->data[slot][3]); - } -#endif - } /* loop over vertices */ - } - return clipped != 0; -} - /* Simplified vertex shader interface for the pt paths. Given the @@ -312,7 +176,6 @@ draw_create_vs_exec(struct draw_context *draw, vs->base.prepare = vs_exec_prepare; - vs->base.run = vs_exec_run; vs->base.run_linear = vs_exec_run_linear; vs->base.delete = vs_exec_delete; vs->machine = &draw->machine; diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 4dbfa955a4..5e27bc9ff0 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -60,113 +60,6 @@ vs_llvm_prepare( struct draw_vertex_shader *base, -/** - * Transform vertices with the current vertex program/shader - * Up to four vertices can be shaded at a time. - * \param vbuffer the input vertex data - * \param elts indexes of four input vertices - * \param count number of vertices to shade [1..4] - * \param vOut array of pointers to four output vertices - */ -static boolean -vs_llvm_run( struct draw_vertex_shader *base, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *vOut ) -{ - struct draw_llvm_vertex_shader *shader = - (struct draw_llvm_vertex_shader *)base; - - struct tgsi_exec_machine *machine = shader->machine; - unsigned int j; - unsigned int clipped = 0; - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - - assert(count <= 4); - assert(base->state->output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - - /* Consts does not require 16 byte alignment. */ - machine->Consts = (float (*)[4]) draw->user.constants; - - if (draw->rasterizer->bypass_vs) { - /* outputs are just the inputs */ - outputs = machine->Inputs; - } - else { - outputs = machine->Outputs; - } - - - draw->vertex_fetch.fetch_func( draw, machine, elts, count ); - - if (!draw->rasterizer->bypass_vs) { - /* run shader */ - gallivm_cpu_vs_exec(shader->llvm_prog, - machine->Inputs, - machine->Outputs, - machine->Consts, - machine->Temps); - } - - /* store machine results */ - for (j = 0; j < count; j++) { - unsigned slot; - float x, y, z, w; - - x = vOut[j]->clip[0] = outputs[0].xyzw[0].f[j]; - y = vOut[j]->clip[1] = outputs[0].xyzw[1].f[j]; - z = vOut[j]->clip[2] = outputs[0].xyzw[2].f[j]; - w = vOut[j]->clip[3] = outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, - draw->nr_planes); - clipped += vOut[j]->clipmask; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - vOut[j]->clipmask = 0; - } - vOut[j]->edgeflag = 1; - vOut[j]->vertex_id = UNDEFINED_VERTEX_ID; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - vOut[j]->data[0][0] = x * scale[0] + trans[0]; - vOut[j]->data[0][1] = y * scale[1] + trans[1]; - vOut[j]->data[0][2] = z * scale[2] + trans[2]; - vOut[j]->data[0][3] = w; - } - else { - vOut[j]->data[0][0] = x; - vOut[j]->data[0][1] = y; - vOut[j]->data[0][2] = z; - vOut[j]->data[0][3] = w; - } - - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - vOut[j]->data[slot][0] = outputs[slot].xyzw[0].f[j]; - vOut[j]->data[slot][1] = outputs[slot].xyzw[1].f[j]; - vOut[j]->data[slot][2] = outputs[slot].xyzw[2].f[j]; - vOut[j]->data[slot][3] = outputs[slot].xyzw[3].f[j]; - } - } /* loop over vertices */ - return clipped != 0; -} - - - static void vs_llvm_run_linear( struct draw_vertex_shader *base, @@ -256,7 +149,6 @@ draw_create_vs_llvm(struct draw_context *draw, tgsi_scan_shader(shader->tokens, &vs->base.info); vs->base.prepare = vs_llvm_prepare; - vs->base.run = vs_llvm_run; vs->base.run_linear = vs_llvm_run_linear; vs->base.delete = vs_llvm_delete; vs->machine = &draw->machine; diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index a763f3845c..60f60a5b53 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -74,131 +74,6 @@ vs_sse_prepare( struct draw_vertex_shader *base, draw_update_vertex_fetch( draw ); } -/** - * Transform vertices with the current vertex program/shader - * Up to four vertices can be shaded at a time. - * \param vbuffer the input vertex data - * \param elts indexes of four input vertices - * \param count number of vertices to shade [1..4] - * \param vOut array of pointers to four output vertices - */ -static boolean -vs_sse_run( struct draw_vertex_shader *base, - struct draw_context *draw, - const unsigned *elts, - unsigned count, - void *vOut, - unsigned vertex_size ) -{ - struct draw_sse_vertex_shader *shader = (struct draw_sse_vertex_shader *)base; - struct tgsi_exec_machine *machine = shader->machine; - unsigned int i, j; - unsigned int clipped = 0; - struct tgsi_exec_vector *outputs = 0; - const float *scale = draw->viewport.scale; - const float *trans = draw->viewport.translate; - - assert(base->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION); - - /* Consts does not require 16 byte alignment. */ - machine->Consts = (const float (*)[4]) draw->user.constants; - - if (draw->rasterizer->bypass_vs) { - /* outputs are just the inputs */ - outputs = machine->Inputs; - } - else { - outputs = machine->Outputs; - } - - for (i = 0; i < count; i += SSE_MAX_VERTICES) { - unsigned int max_vertices = MIN2(SSE_MAX_VERTICES, count - i); - /* Fetch vertices. This may at some point be integrated into the - * compiled shader -- that would require a reorganization where - * multiple versions of the compiled shader might exist, - * specialized for each fetch state. - */ - draw->vertex_fetch.fetch_func(draw, machine, &elts[i], max_vertices); - - if (!draw->rasterizer->bypass_vs) { - /* run compiled shader - */ - shader->func(machine->Inputs, - machine->Outputs, - (float (*)[4])machine->Consts, - machine->Temps, - shader->immediates); - } - - /* XXX: Computing the clipmask and emitting results should be done - * in the vertex program as a set of instructions appended to - * the user-provided code. - */ - for (j = 0; j < max_vertices; j++) { - unsigned slot; - float x, y, z, w; - struct vertex_header *out = - draw_header_from_block(vOut, vertex_size, i + j); - - x = out->clip[0] = outputs[0].xyzw[0].f[j]; - y = out->clip[1] = outputs[0].xyzw[1].f[j]; - z = out->clip[2] = outputs[0].xyzw[2].f[j]; - w = out->clip[3] = outputs[0].xyzw[3].f[j]; - - if (!draw->rasterizer->bypass_clipping) { - out->clipmask = compute_clipmask(out->clip, draw->plane, - draw->nr_planes); - clipped += out->clipmask; - - /* divide by w */ - w = 1.0f / w; - x *= w; - y *= w; - z *= w; - } - else { - out->clipmask = 0; - } - out->edgeflag = 1; - out->vertex_id = UNDEFINED_VERTEX_ID; - - if (!draw->identity_viewport) { - /* Viewport mapping */ - out->data[0][0] = x * scale[0] + trans[0]; - out->data[0][1] = y * scale[1] + trans[1]; - out->data[0][2] = z * scale[2] + trans[2]; - out->data[0][3] = w; - } - else { - out->data[0][0] = x; - out->data[0][1] = y; - out->data[0][2] = z; - out->data[0][3] = w; - } - - /* Remaining attributes are packed into sequential post-transform - * vertex attrib slots. - */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { - out->data[slot][0] = outputs[slot].xyzw[0].f[j]; - out->data[slot][1] = outputs[slot].xyzw[1].f[j]; - out->data[slot][2] = outputs[slot].xyzw[2].f[j]; - out->data[slot][3] = outputs[slot].xyzw[3].f[j]; - } -#if 0 /*DEBUG*/ - printf("%d) Post xform vert:\n", i + j); - for (slot = 0; slot < draw->num_vs_outputs; slot++) { - printf("\t%d: %f %f %f %f\n", slot, - out->data[slot][0], - out->data[slot][1], - out->data[slot][2], - out->data[slot][3]); - } -#endif - } - } - return clipped != 0; -} /* Simplified vertex shader interface for the pt paths. Given the @@ -294,7 +169,6 @@ draw_create_vs_sse(struct draw_context *draw, tgsi_scan_shader(templ->tokens, &vs->base.info); vs->base.prepare = vs_sse_prepare; - vs->base.run = vs_sse_run; vs->base.run_linear = vs_sse_run_linear; vs->base.delete = vs_sse_delete; vs->machine = &draw->machine; -- cgit v1.2.3 From 709e33cf0bfd552220e46f44e8cfa2063c3cef69 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:44:13 +0100 Subject: draw: remove old draw_vertex_shader_queue_flush function --- src/gallium/auxiliary/draw/draw_context.c | 2 -- src/gallium/auxiliary/draw/draw_private.h | 6 ---- src/gallium/auxiliary/draw/draw_vertex_shader.c | 43 ------------------------- 3 files changed, 51 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index c611300841..9c3ae9bc0d 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -93,8 +93,6 @@ struct draw_context *draw_create( void ) draw->vs.vertex_cache = tmp; } - draw->shader_queue_flush = draw_vertex_shader_queue_flush; - /* these defaults are oriented toward the needs of softpipe */ draw->wide_point_threshold = 1000000.0; /* infinity */ draw->wide_line_threshold = 1.0; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 18ce6c0ec5..93add257a3 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -309,11 +309,6 @@ struct draw_context unsigned post_nr; } vs; - /** - * Run the vertex shader on all vertices in the vertex queue. - */ - void (*shader_queue_flush)(struct draw_context *draw); - /* Prim pipeline queue: */ struct { @@ -359,7 +354,6 @@ extern void draw_vertex_cache_invalidate( struct draw_context *draw ); extern void draw_vertex_cache_unreference( struct draw_context *draw ); extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); -extern void draw_vertex_shader_queue_flush( struct draw_context *draw ); extern void draw_update_vertex_fetch( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c index 118664d619..03fe00a951 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ b/src/gallium/auxiliary/draw/draw_vertex_shader.c @@ -37,49 +37,6 @@ #include "draw_context.h" #include "draw_vs.h" -/** - * Run the vertex shader on all vertices in the vertex queue. - * Called by the draw module when the vertx cache needs to be flushed. - */ -void -draw_vertex_shader_queue_flush(struct draw_context *draw) -{ - struct draw_vertex_shader *shader = draw->vertex_shader; - unsigned i; - - assert(draw->vs.queue_nr != 0); - - /* XXX: do this on statechange: - */ - shader->prepare( shader, draw ); - -// fprintf(stderr, "%s %d\n", __FUNCTION__, draw->vs.queue_nr ); - - /* run vertex shader on vertex cache entries, four per invokation */ - for (i = 0; i < draw->vs.queue_nr; i += MAX_SHADER_VERTICES) { - unsigned elts[MAX_SHADER_VERTICES]; - int j, n = MIN2(MAX_SHADER_VERTICES, draw->vs.queue_nr - i); - struct vertex_header *dests = - draw_header_from_block(draw->vs.vertex_cache, - MAX_VERTEX_ALLOCATION, i); - - for (j = 0; j < n; j++) { - elts[j] = draw->vs.elts[i + j]; - } - - for ( ; j < MAX_SHADER_VERTICES; j++) { - elts[j] = elts[0]; - } - - assert(n > 0); - assert(n <= MAX_SHADER_VERTICES); - -// shader->run(shader, draw, elts, n, dests, MAX_VERTEX_ALLOCATION); - } - - draw->vs.post_nr = draw->vs.queue_nr; - draw->vs.queue_nr = 0; -} struct draw_vertex_shader * -- cgit v1.2.3 From 415e8e039ba38716336e8de3d7b3cdc23b9a9d8e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 18 Apr 2008 20:46:06 +0100 Subject: draw: remove draw_vertex_fetch.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 2 - src/gallium/auxiliary/draw/draw_vertex_fetch.c | 528 ------------------------- src/gallium/auxiliary/draw/draw_vs_llvm.c | 1 - src/gallium/auxiliary/draw/draw_vs_sse.c | 1 - 5 files changed, 533 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_vertex_fetch.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 03210f6a4a..60bb9dfe88 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -31,7 +31,6 @@ C_SOURCES = \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ - draw_vertex_fetch.c \ draw_vertex_shader.c \ draw_wide_line.c \ draw_wide_point.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 238e3f7d28..246083a962 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -27,8 +27,6 @@ draw = env.ConvenienceLibrary( 'draw_validate.c', 'draw_vbuf.c', 'draw_vertex.c', - 'draw_vertex_cache.c', - 'draw_vertex_fetch.c', 'draw_vertex_shader.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c deleted file mode 100644 index 0bc2fcb424..0000000000 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ /dev/null @@ -1,528 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" -#include "draw_context.h" - - -#define DRAW_DBG 0 - - -/** - * Fetch a float[4] vertex attribute from memory, doing format/type - * conversion as needed. - * - * This is probably needed/dupliocated elsewhere, eg format - * conversion, texture sampling etc. - */ -#define FETCH_ATTRIB( NAME, SZ, CVT ) \ -static void \ -fetch_##NAME(const void *ptr, float *attrib) \ -{ \ - static const float defaults[4] = { 0,0,0,1 }; \ - int i; \ - \ - for (i = 0; i < SZ; i++) { \ - attrib[i] = CVT(i); \ - } \ - \ - for (; i < 4; i++) { \ - attrib[i] = defaults[i]; \ - } \ -} - -#define CVT_64_FLOAT(i) (float) ((double *) ptr)[i] -#define CVT_32_FLOAT(i) ((float *) ptr)[i] - -#define CVT_8_USCALED(i) (float) ((unsigned char *) ptr)[i] -#define CVT_16_USCALED(i) (float) ((unsigned short *) ptr)[i] -#define CVT_32_USCALED(i) (float) ((unsigned int *) ptr)[i] - -#define CVT_8_SSCALED(i) (float) ((char *) ptr)[i] -#define CVT_16_SSCALED(i) (float) ((short *) ptr)[i] -#define CVT_32_SSCALED(i) (float) ((int *) ptr)[i] - -#define CVT_8_UNORM(i) (float) ((unsigned char *) ptr)[i] / 255.0f -#define CVT_16_UNORM(i) (float) ((unsigned short *) ptr)[i] / 65535.0f -#define CVT_32_UNORM(i) (float) ((unsigned int *) ptr)[i] / 4294967295.0f - -#define CVT_8_SNORM(i) (float) ((char *) ptr)[i] / 127.0f -#define CVT_16_SNORM(i) (float) ((short *) ptr)[i] / 32767.0f -#define CVT_32_SNORM(i) (float) ((int *) ptr)[i] / 2147483647.0f - -FETCH_ATTRIB( R64G64B64A64_FLOAT, 4, CVT_64_FLOAT ) -FETCH_ATTRIB( R64G64B64_FLOAT, 3, CVT_64_FLOAT ) -FETCH_ATTRIB( R64G64_FLOAT, 2, CVT_64_FLOAT ) -FETCH_ATTRIB( R64_FLOAT, 1, CVT_64_FLOAT ) - -FETCH_ATTRIB( R32G32B32A32_FLOAT, 4, CVT_32_FLOAT ) -FETCH_ATTRIB( R32G32B32_FLOAT, 3, CVT_32_FLOAT ) -FETCH_ATTRIB( R32G32_FLOAT, 2, CVT_32_FLOAT ) -FETCH_ATTRIB( R32_FLOAT, 1, CVT_32_FLOAT ) - -FETCH_ATTRIB( R32G32B32A32_USCALED, 4, CVT_32_USCALED ) -FETCH_ATTRIB( R32G32B32_USCALED, 3, CVT_32_USCALED ) -FETCH_ATTRIB( R32G32_USCALED, 2, CVT_32_USCALED ) -FETCH_ATTRIB( R32_USCALED, 1, CVT_32_USCALED ) - -FETCH_ATTRIB( R32G32B32A32_SSCALED, 4, CVT_32_SSCALED ) -FETCH_ATTRIB( R32G32B32_SSCALED, 3, CVT_32_SSCALED ) -FETCH_ATTRIB( R32G32_SSCALED, 2, CVT_32_SSCALED ) -FETCH_ATTRIB( R32_SSCALED, 1, CVT_32_SSCALED ) - -FETCH_ATTRIB( R32G32B32A32_UNORM, 4, CVT_32_UNORM ) -FETCH_ATTRIB( R32G32B32_UNORM, 3, CVT_32_UNORM ) -FETCH_ATTRIB( R32G32_UNORM, 2, CVT_32_UNORM ) -FETCH_ATTRIB( R32_UNORM, 1, CVT_32_UNORM ) - -FETCH_ATTRIB( R32G32B32A32_SNORM, 4, CVT_32_SNORM ) -FETCH_ATTRIB( R32G32B32_SNORM, 3, CVT_32_SNORM ) -FETCH_ATTRIB( R32G32_SNORM, 2, CVT_32_SNORM ) -FETCH_ATTRIB( R32_SNORM, 1, CVT_32_SNORM ) - -FETCH_ATTRIB( R16G16B16A16_USCALED, 4, CVT_16_USCALED ) -FETCH_ATTRIB( R16G16B16_USCALED, 3, CVT_16_USCALED ) -FETCH_ATTRIB( R16G16_USCALED, 2, CVT_16_USCALED ) -FETCH_ATTRIB( R16_USCALED, 1, CVT_16_USCALED ) - -FETCH_ATTRIB( R16G16B16A16_SSCALED, 4, CVT_16_SSCALED ) -FETCH_ATTRIB( R16G16B16_SSCALED, 3, CVT_16_SSCALED ) -FETCH_ATTRIB( R16G16_SSCALED, 2, CVT_16_SSCALED ) -FETCH_ATTRIB( R16_SSCALED, 1, CVT_16_SSCALED ) - -FETCH_ATTRIB( R16G16B16A16_UNORM, 4, CVT_16_UNORM ) -FETCH_ATTRIB( R16G16B16_UNORM, 3, CVT_16_UNORM ) -FETCH_ATTRIB( R16G16_UNORM, 2, CVT_16_UNORM ) -FETCH_ATTRIB( R16_UNORM, 1, CVT_16_UNORM ) - -FETCH_ATTRIB( R16G16B16A16_SNORM, 4, CVT_16_SNORM ) -FETCH_ATTRIB( R16G16B16_SNORM, 3, CVT_16_SNORM ) -FETCH_ATTRIB( R16G16_SNORM, 2, CVT_16_SNORM ) -FETCH_ATTRIB( R16_SNORM, 1, CVT_16_SNORM ) - -FETCH_ATTRIB( R8G8B8A8_USCALED, 4, CVT_8_USCALED ) -FETCH_ATTRIB( R8G8B8_USCALED, 3, CVT_8_USCALED ) -FETCH_ATTRIB( R8G8_USCALED, 2, CVT_8_USCALED ) -FETCH_ATTRIB( R8_USCALED, 1, CVT_8_USCALED ) - -FETCH_ATTRIB( R8G8B8A8_SSCALED, 4, CVT_8_SSCALED ) -FETCH_ATTRIB( R8G8B8_SSCALED, 3, CVT_8_SSCALED ) -FETCH_ATTRIB( R8G8_SSCALED, 2, CVT_8_SSCALED ) -FETCH_ATTRIB( R8_SSCALED, 1, CVT_8_SSCALED ) - -FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) -FETCH_ATTRIB( R8G8B8_UNORM, 3, CVT_8_UNORM ) -FETCH_ATTRIB( R8G8_UNORM, 2, CVT_8_UNORM ) -FETCH_ATTRIB( R8_UNORM, 1, CVT_8_UNORM ) - -FETCH_ATTRIB( R8G8B8A8_SNORM, 4, CVT_8_SNORM ) -FETCH_ATTRIB( R8G8B8_SNORM, 3, CVT_8_SNORM ) -FETCH_ATTRIB( R8G8_SNORM, 2, CVT_8_SNORM ) -FETCH_ATTRIB( R8_SNORM, 1, CVT_8_SNORM ) - -FETCH_ATTRIB( A8R8G8B8_UNORM, 4, CVT_8_UNORM ) -//FETCH_ATTRIB( R8G8B8A8_UNORM, 4, CVT_8_UNORM ) - - - -static void -fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) -{ - attrib[2] = CVT_8_UNORM(0); - attrib[1] = CVT_8_UNORM(1); - attrib[0] = CVT_8_UNORM(2); - attrib[3] = CVT_8_UNORM(3); -} - - -fetch_func draw_get_fetch_func( enum pipe_format format ) -{ -#if 0 - { - char tmp[80]; - pf_sprint_name(tmp, format); - debug_printf("%s: %s\n", __FUNCTION__, tmp); - } -#endif - - switch (format) { - case PIPE_FORMAT_R64_FLOAT: - return fetch_R64_FLOAT; - case PIPE_FORMAT_R64G64_FLOAT: - return fetch_R64G64_FLOAT; - case PIPE_FORMAT_R64G64B64_FLOAT: - return fetch_R64G64B64_FLOAT; - case PIPE_FORMAT_R64G64B64A64_FLOAT: - return fetch_R64G64B64A64_FLOAT; - - case PIPE_FORMAT_R32_FLOAT: - return fetch_R32_FLOAT; - case PIPE_FORMAT_R32G32_FLOAT: - return fetch_R32G32_FLOAT; - case PIPE_FORMAT_R32G32B32_FLOAT: - return fetch_R32G32B32_FLOAT; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return fetch_R32G32B32A32_FLOAT; - - case PIPE_FORMAT_R32_UNORM: - return fetch_R32_UNORM; - case PIPE_FORMAT_R32G32_UNORM: - return fetch_R32G32_UNORM; - case PIPE_FORMAT_R32G32B32_UNORM: - return fetch_R32G32B32_UNORM; - case PIPE_FORMAT_R32G32B32A32_UNORM: - return fetch_R32G32B32A32_UNORM; - - case PIPE_FORMAT_R32_USCALED: - return fetch_R32_USCALED; - case PIPE_FORMAT_R32G32_USCALED: - return fetch_R32G32_USCALED; - case PIPE_FORMAT_R32G32B32_USCALED: - return fetch_R32G32B32_USCALED; - case PIPE_FORMAT_R32G32B32A32_USCALED: - return fetch_R32G32B32A32_USCALED; - - case PIPE_FORMAT_R32_SNORM: - return fetch_R32_SNORM; - case PIPE_FORMAT_R32G32_SNORM: - return fetch_R32G32_SNORM; - case PIPE_FORMAT_R32G32B32_SNORM: - return fetch_R32G32B32_SNORM; - case PIPE_FORMAT_R32G32B32A32_SNORM: - return fetch_R32G32B32A32_SNORM; - - case PIPE_FORMAT_R32_SSCALED: - return fetch_R32_SSCALED; - case PIPE_FORMAT_R32G32_SSCALED: - return fetch_R32G32_SSCALED; - case PIPE_FORMAT_R32G32B32_SSCALED: - return fetch_R32G32B32_SSCALED; - case PIPE_FORMAT_R32G32B32A32_SSCALED: - return fetch_R32G32B32A32_SSCALED; - - case PIPE_FORMAT_R16_UNORM: - return fetch_R16_UNORM; - case PIPE_FORMAT_R16G16_UNORM: - return fetch_R16G16_UNORM; - case PIPE_FORMAT_R16G16B16_UNORM: - return fetch_R16G16B16_UNORM; - case PIPE_FORMAT_R16G16B16A16_UNORM: - return fetch_R16G16B16A16_UNORM; - - case PIPE_FORMAT_R16_USCALED: - return fetch_R16_USCALED; - case PIPE_FORMAT_R16G16_USCALED: - return fetch_R16G16_USCALED; - case PIPE_FORMAT_R16G16B16_USCALED: - return fetch_R16G16B16_USCALED; - case PIPE_FORMAT_R16G16B16A16_USCALED: - return fetch_R16G16B16A16_USCALED; - - case PIPE_FORMAT_R16_SNORM: - return fetch_R16_SNORM; - case PIPE_FORMAT_R16G16_SNORM: - return fetch_R16G16_SNORM; - case PIPE_FORMAT_R16G16B16_SNORM: - return fetch_R16G16B16_SNORM; - case PIPE_FORMAT_R16G16B16A16_SNORM: - return fetch_R16G16B16A16_SNORM; - - case PIPE_FORMAT_R16_SSCALED: - return fetch_R16_SSCALED; - case PIPE_FORMAT_R16G16_SSCALED: - return fetch_R16G16_SSCALED; - case PIPE_FORMAT_R16G16B16_SSCALED: - return fetch_R16G16B16_SSCALED; - case PIPE_FORMAT_R16G16B16A16_SSCALED: - return fetch_R16G16B16A16_SSCALED; - - case PIPE_FORMAT_R8_UNORM: - return fetch_R8_UNORM; - case PIPE_FORMAT_R8G8_UNORM: - return fetch_R8G8_UNORM; - case PIPE_FORMAT_R8G8B8_UNORM: - return fetch_R8G8B8_UNORM; - case PIPE_FORMAT_R8G8B8A8_UNORM: - return fetch_R8G8B8A8_UNORM; - - case PIPE_FORMAT_R8_USCALED: - return fetch_R8_USCALED; - case PIPE_FORMAT_R8G8_USCALED: - return fetch_R8G8_USCALED; - case PIPE_FORMAT_R8G8B8_USCALED: - return fetch_R8G8B8_USCALED; - case PIPE_FORMAT_R8G8B8A8_USCALED: - return fetch_R8G8B8A8_USCALED; - - case PIPE_FORMAT_R8_SNORM: - return fetch_R8_SNORM; - case PIPE_FORMAT_R8G8_SNORM: - return fetch_R8G8_SNORM; - case PIPE_FORMAT_R8G8B8_SNORM: - return fetch_R8G8B8_SNORM; - case PIPE_FORMAT_R8G8B8A8_SNORM: - return fetch_R8G8B8A8_SNORM; - - case PIPE_FORMAT_R8_SSCALED: - return fetch_R8_SSCALED; - case PIPE_FORMAT_R8G8_SSCALED: - return fetch_R8G8_SSCALED; - case PIPE_FORMAT_R8G8B8_SSCALED: - return fetch_R8G8B8_SSCALED; - case PIPE_FORMAT_R8G8B8A8_SSCALED: - return fetch_R8G8B8A8_SSCALED; - - case PIPE_FORMAT_A8R8G8B8_UNORM: - return fetch_A8R8G8B8_UNORM; - - - case PIPE_FORMAT_B8G8R8A8_UNORM: - return fetch_B8G8R8A8_UNORM; - - case 0: - return NULL; /* not sure why this is needed */ - - default: - /* This can get hit because draw-state-validation is too eager, - and can jump in here validating stuff before the state tracker has set - up everything. - */ - /* assert(0); */ - return NULL; - } -} - - -static void -transpose_4x4( float *out, const float *in ) -{ - /* This can be achieved in 12 sse instructions, plus the final - * stores I guess. This is probably a bit more than that - maybe - * 32 or so? - */ - out[0] = in[0]; out[1] = in[4]; out[2] = in[8]; out[3] = in[12]; - out[4] = in[1]; out[5] = in[5]; out[6] = in[9]; out[7] = in[13]; - out[8] = in[2]; out[9] = in[6]; out[10] = in[10]; out[11] = in[14]; - out[12] = in[3]; out[13] = in[7]; out[14] = in[11]; out[15] = in[15]; -} - - - -static void fetch_xyz_rgb( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - int i; - - assert(count <= 4); - -// debug_printf("%s\n", __FUNCTION__); - - /* loop over vertex attributes (vertex shader inputs) - */ - - for (i = 0; i < 4; i++) { - { - const float *in = (const float *)(src[0] + elts[i] * pitch[0]); - float *out = &machine->Inputs[0].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[1] + elts[i] * pitch[1]); - float *out = &machine->Inputs[1].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - } -} - - - - -static void fetch_xyz_rgb_st( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - const unsigned *pitch = draw->vertex_fetch.pitch; - const ubyte **src = draw->vertex_fetch.src_ptr; - int i; - - assert(count <= 4); - - /* loop over vertex attributes (vertex shader inputs) - */ - - for (i = 0; i < 4; i++) { - { - const float *in = (const float *)(src[0] + elts[i] * pitch[0]); - float *out = &machine->Inputs[0].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[1] + elts[i] * pitch[1]); - float *out = &machine->Inputs[1].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = in[2]; - out[12] = 1.0f; - } - - { - const float *in = (const float *)(src[2] + elts[i] * pitch[2]); - float *out = &machine->Inputs[2].xyzw[0].f[i]; - out[0] = in[0]; - out[4] = in[1]; - out[8] = 0.0f; - out[12] = 1.0f; - } - } -} - - - - -/** - * Fetch vertex attributes for 'count' vertices. - */ -static void generic_vertex_fetch( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ) -{ - unsigned nr_attrs = draw->vertex_fetch.nr_attrs; - unsigned attr; - - assert(count <= 4); - -// debug_printf("%s %d\n", __FUNCTION__, count); - - /* loop over vertex attributes (vertex shader inputs) - */ - for (attr = 0; attr < nr_attrs; attr++) { - - const unsigned pitch = draw->vertex_fetch.pitch[attr]; - const ubyte *src = draw->vertex_fetch.src_ptr[attr]; - const fetch_func fetch = draw->vertex_fetch.fetch[attr]; - unsigned i; - float p[4][4]; - - - /* Fetch four attributes for four vertices. - * - * Could fetch directly into AOS format, but this is meant to be - * a prototype for an sse implementation, which would have - * difficulties doing that. - */ - for (i = 0; i < count; i++) - fetch( src + elts[i] * pitch, p[i] ); - - /* Be nice and zero out any missing vertices: - */ - for ( ; i < 4; i++) - p[i][0] = p[i][1] = p[i][2] = p[i][3] = 0; - - /* Transpose/swizzle into sse-friendly format. Currently - * assuming that all vertex shader inputs are float[4], but this - * isn't true -- if the vertex shader only wants tex0.xy, we - * could optimize for that. - * - * To do so fully without codegen would probably require an - * excessive number of fetch functions, but we could at least - * minimize the transpose step: - */ - transpose_4x4( (float *)&machine->Inputs[attr].xyzw[0].f[0], (float *)p ); - } -} - - - -void draw_update_vertex_fetch( struct draw_context *draw ) -{ - unsigned nr_attrs, i; - -// debug_printf("%s\n", __FUNCTION__); - - /* this may happend during context init */ - if (!draw->vertex_shader) - return; - - nr_attrs = draw->vertex_shader->info.num_inputs; - - for (i = 0; i < nr_attrs; i++) { - unsigned buf = draw->vertex_element[i].vertex_buffer_index; - enum pipe_format format = draw->vertex_element[i].src_format; - - draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + - draw->vertex_buffer[buf].buffer_offset + - draw->vertex_element[i].src_offset; - - draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; - draw->vertex_fetch.fetch[i] = draw_get_fetch_func( format ); - } - - draw->vertex_fetch.nr_attrs = nr_attrs; - - draw->vertex_fetch.fetch_func = generic_vertex_fetch; - - switch (nr_attrs) { - case 2: - if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT) - draw->vertex_fetch.fetch_func = fetch_xyz_rgb; - break; - case 3: - if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT && - draw->vertex_element[2].src_format == PIPE_FORMAT_R32G32_FLOAT) - draw->vertex_fetch.fetch_func = fetch_xyz_rgb_st; - break; - default: - break; - } - -} diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 5e27bc9ff0..c219a91156 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -55,7 +55,6 @@ static void vs_llvm_prepare( struct draw_vertex_shader *base, struct draw_context *draw ) { - draw_update_vertex_fetch( draw ); } diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 60f60a5b53..8e2d381f14 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -71,7 +71,6 @@ static void vs_sse_prepare( struct draw_vertex_shader *base, struct draw_context *draw ) { - draw_update_vertex_fetch( draw ); } -- cgit v1.2.3 From 6094e79f4e3350d123c7532b1c73faa60834a62d Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:27:12 +0100 Subject: draw: remove dead data structures --- src/gallium/auxiliary/draw/draw_context.c | 20 ----------- src/gallium/auxiliary/draw/draw_private.h | 59 ------------------------------- 2 files changed, 79 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 9c3ae9bc0d..6012bc155e 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -83,16 +83,6 @@ struct draw_context *draw_create( void ) ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */ draw->nr_planes = 6; - /* Statically allocate maximum sized vertices for the cache - could be cleverer... - */ - { - char *tmp = align_malloc(VS_QUEUE_LENGTH * MAX_VERTEX_ALLOCATION, 16); - if (!tmp) - goto fail; - - draw->vs.vertex_cache = tmp; - } - /* these defaults are oriented toward the needs of softpipe */ draw->wide_point_threshold = 1000000.0; /* infinity */ draw->wide_line_threshold = 1.0; @@ -162,10 +152,6 @@ void draw_destroy( struct draw_context *draw ) align_free(draw->machine.Outputs); tgsi_exec_machine_free_data(&draw->machine); - - if (draw->vs.vertex_cache) - align_free( draw->vs.vertex_cache ); /* Frees all the vertices. */ - /* Not so fast -- we're just borrowing this at the moment. * if (draw->render) @@ -254,8 +240,6 @@ draw_set_vertex_buffers(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0])); draw->nr_vertex_buffers = count; } @@ -268,8 +252,6 @@ draw_set_vertex_elements(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); - memcpy(draw->vertex_element, elements, count * sizeof(elements[0])); draw->nr_vertex_elements = count; } @@ -282,7 +264,6 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer) { - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); draw->user.vbuffer[attr] = buffer; } @@ -291,7 +272,6 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer) { - draw_do_flush( draw, DRAW_FLUSH_VERTEX_CACHE/*STATE_CHANGE*/ ); draw->user.constants = buffer; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 93add257a3..78265c64a6 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -195,9 +195,6 @@ struct draw_context /* Support prototype passthrough path: */ struct { - unsigned prim; /* XXX: to be removed */ - unsigned hw_vertex_size; /* XXX: to be removed */ - struct { struct draw_pt_middle_end *opt[PT_MAX_MIDDLE]; } middle; @@ -272,54 +269,6 @@ struct draw_context /** TGSI program interpreter runtime state */ struct tgsi_exec_machine machine; - /* Vertex fetch internal state - */ - struct { - const ubyte *src_ptr[PIPE_MAX_ATTRIBS]; - unsigned pitch[PIPE_MAX_ATTRIBS]; - fetch_func fetch[PIPE_MAX_ATTRIBS]; - unsigned nr_attrs; - full_fetch_func fetch_func; - pt_fetch_func pt_fetch; - } vertex_fetch; - - /* Post-tnl vertex cache: - */ - struct { - unsigned referenced; /**< bitfield */ - - struct { - unsigned in; /* client array element */ - unsigned out; /* index in vs queue/array */ - } idx[VCACHE_SIZE + VCACHE_OVERFLOW]; - - unsigned overflow; - - /** To find space in the vertex cache: */ - struct vertex_header *(*get_vertex)( struct draw_context *draw, - unsigned i ); - } vcache; - - /* Vertex shader queue: - */ - struct { - unsigned elts[VS_QUEUE_LENGTH]; /**< index into the user's vertex arrays */ - char *vertex_cache; - unsigned queue_nr; - unsigned post_nr; - } vs; - - /* Prim pipeline queue: - */ - struct { - /* Need to queue up primitives until their vertices have been - * transformed by a vs queue flush. - */ - struct prim_header queue[PRIM_QUEUE_LENGTH]; - unsigned queue_nr; - } pq; - - /* This (and the tgsi_exec_machine struct) probably need to be moved somewhere private. */ struct gallivm_cpu_engine *engine; @@ -372,9 +321,6 @@ boolean draw_pt_arrays( struct draw_context *draw, void draw_pt_reset_vertex_ids( struct draw_context *draw ); -#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ -#define DRAW_FLUSH_PRIM_QUEUE 0x2 -#define DRAW_FLUSH_VERTEX_CACHE 0x4 #define DRAW_FLUSH_STATE_CHANGE 0x8 #define DRAW_FLUSH_BACKEND 0x10 @@ -416,10 +362,5 @@ dot4(const float *a, const float *b) return result; } -static INLINE struct vertex_header * -draw_header_from_block(char *block, int size, int num) -{ - return (struct vertex_header*)(block + num * size); -} #endif /* DRAW_PRIVATE_H */ -- cgit v1.2.3 From 251ebcc175d479dda8d0d5b64fc42f44e747197e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:29:25 +0100 Subject: draw: remove more dead data structures --- src/gallium/auxiliary/draw/draw_private.h | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 78265c64a6..476b1184d4 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -128,31 +128,6 @@ struct draw_stage }; -#define PRIM_QUEUE_LENGTH 32 -#define VCACHE_SIZE 32 -#define VCACHE_OVERFLOW 4 -#define VS_QUEUE_LENGTH (VCACHE_SIZE + VCACHE_OVERFLOW + 1) /* can never fill up */ - - - -/* Internal function for vertex fetch. - */ -typedef void (*fetch_func)(const void *ptr, float *attrib); - -fetch_func draw_get_fetch_func( enum pipe_format format ); - - - -typedef void (*full_fetch_func)( struct draw_context *draw, - struct tgsi_exec_machine *machine, - const unsigned *elts, - unsigned count ); - -typedef void (*pt_fetch_func)( struct draw_context *draw, - float *out, - unsigned start, - unsigned count ); - struct vbuf_render; -- cgit v1.2.3 From 6d9132de04fc190fea56978849dfc427e5359912 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:31:06 +0100 Subject: draw: make draw_pt_fetch_emit use translate facility --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 186 +++++++++--------------- src/gallium/auxiliary/draw/draw_vbuf.c | 4 +- 2 files changed, 72 insertions(+), 118 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index d696afa1aa..6e4fea460b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -36,6 +36,7 @@ #include "draw/draw_vbuf.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "translate/translate.h" /* The simplest 'middle end' in the new vertex code. * @@ -72,94 +73,15 @@ struct fetch_emit_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - - struct { - const ubyte *ptr; - unsigned pitch; - void (*fetch)( const void *from, float *attrib); - void (*emit)( const float *attrib, float **out ); - } fetch[PIPE_MAX_ATTRIBS]; - unsigned nr_fetch; - unsigned hw_vertex_size; -}; - - - -static void fetch_R32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = 0.0; - attrib[2] = 0.0; - attrib[3] = 1.0; -} - - -static void emit_R32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out) += 1; -} - -static void emit_R32G32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out) += 2; -} - -static void emit_R32G32B32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out) += 3; -} - -static void emit_R32G32B32A32_FLOAT( const float *attrib, - float **out ) -{ - (*out)[0] = attrib[0]; - (*out)[1] = attrib[1]; - (*out)[2] = attrib[2]; - (*out)[3] = attrib[3]; - (*out) += 4; -} + struct translate *translate; + /* Cache point size somewhere it's address won't change: + */ + float point_size; -/** - * General-purpose fetch from user's vertex arrays, emit to driver's - * vertex buffer. - * - * XXX this is totally temporary. - */ -static void -fetch_store_general( struct fetch_emit_middle_end *feme, - void *out_ptr, - const unsigned *fetch_elts, - unsigned count ) -{ - float *out = (float *)out_ptr; - uint i, j; +}; - for (i = 0; i < count; i++) { - unsigned elt = fetch_elts[i] & ~DRAW_PT_FLAG_MASK; - - for (j = 0; j < feme->nr_fetch; j++) { - float attrib[4]; - const ubyte *from = (feme->fetch[j].ptr + - feme->fetch[j].pitch * elt); - - feme->fetch[j].fetch( from, attrib ); - feme->fetch[j].emit( attrib, &out ); - } - } -} @@ -170,8 +92,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; const struct vertex_info *vinfo; - unsigned i; + unsigned i, dst_offset; boolean ok; + struct translate_key key; ok = draw->render->set_primitive( draw->render, @@ -186,51 +109,82 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, vinfo = draw->render->get_vertex_info(draw->render); - /* This is unique as it transforms straight from API vertex - * information to HW vertices. All other cases go through our - * intermediate float[4] format. + + /* Transform from API vertices to HW vertices, skipping the + * pipeline_vertex intermediate step. */ - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned src_element = vinfo->src_index[i]; - unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; - - feme->fetch[i].ptr = ((const ubyte *)draw->user.vbuffer[src_buffer] + - draw->vertex_buffer[src_buffer].buffer_offset + - draw->vertex_element[src_element].src_offset); + dst_offset = 0; + memset(&key, 0, sizeof(key)); - feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch; - - feme->fetch[i].fetch = draw_get_fetch_func(draw->vertex_element[src_element].src_format); + for (i = 0; i < vinfo->num_attribs; i++) { + const struct pipe_vertex_element *src = &draw->vertex_element[vinfo->src_index[i]]; + unsigned emit_sz = 0; + unsigned input_format = src->src_format; + unsigned input_buffer = src->vertex_buffer_index; + unsigned input_offset = src->src_offset; + unsigned output_format; switch (vinfo->emit[i]) { case EMIT_4F: - feme->fetch[i].emit = emit_R32G32B32A32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); break; case EMIT_3F: - feme->fetch[i].emit = emit_R32G32B32_FLOAT; + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); break; case EMIT_2F: - feme->fetch[i].emit = emit_R32G32_FLOAT; + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); break; case EMIT_1F: - feme->fetch[i].emit = emit_R32_FLOAT; + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); break; case EMIT_1F_PSIZE: - feme->fetch[i].ptr = (const ubyte *)&feme->draw->rasterizer->point_size; - feme->fetch[i].pitch = 0; - feme->fetch[i].fetch = fetch_R32_FLOAT; - feme->fetch[i].emit = emit_R32_FLOAT; + input_format = PIPE_FORMAT_R32_FLOAT; + input_buffer = draw->nr_vertex_buffers; + input_offset = 0; + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); break; default: assert(0); - feme->fetch[i].emit = NULL; - break; + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + continue; } + + key.element[i].input_format = input_format; + key.element[i].input_buffer = input_buffer; + key.element[i].input_offset = input_offset; + key.element[i].output_format = output_format; + key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; } - feme->nr_fetch = vinfo->num_attribs; - feme->hw_vertex_size = vinfo->size * 4; + key.nr_elements = vinfo->num_attribs; + key.output_stride = vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!feme->translate || + memcmp(&feme->translate->key, &key, sizeof(key)) != 0) + { + if (feme->translate) + feme->translate->release(feme->translate); + + feme->translate = translate_create( &key ); + + feme->translate->set_buffer(feme->translate, + draw->nr_vertex_buffers, + &feme->point_size, + 0); + } + + feme->point_size = draw->rasterizer->point_size; } @@ -252,7 +206,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, draw_do_flush( draw, DRAW_FLUSH_BACKEND ); hw_verts = draw->render->allocate_vertices( draw->render, - (ushort)feme->hw_vertex_size, + (ushort)feme->translate->key.output_stride, (ushort)fetch_count ); if (!hw_verts) { assert(0); @@ -262,10 +216,10 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, /* Single routine to fetch vertices and emit HW verts. */ - fetch_store_general( feme, - hw_verts, - fetch_elts, - fetch_count ); + feme->translate->run_elts( feme->translate, + fetch_elts, + fetch_count, + hw_verts ); /* XXX: Draw arrays path to avoid re-emitting index list again and * again. @@ -278,7 +232,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, */ draw->render->release_vertices( draw->render, hw_verts, - feme->hw_vertex_size, + feme->translate->key.output_stride, fetch_count ); } diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c index dbbcf05c3c..30dceeb43d 100644 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_vbuf.c @@ -439,8 +439,8 @@ vbuf_alloc_vertices( struct vbuf_stage *vbuf ) /* Allocate a new vertex buffer */ vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, - (ushort) vbuf->vertex_size, - (ushort) vbuf->max_vertices); + (ushort) vbuf->vertex_size, + (ushort) vbuf->max_vertices); vbuf->vertex_ptr = vbuf->vertices; } -- cgit v1.2.3 From 6494946db66b62d280e34a0486b83cca15f5b457 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:36:35 +0100 Subject: draw: remove draw_debug.c --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_debug.c | 113 -------------------------------- 3 files changed, 115 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_debug.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 60bb9dfe88..45def9153c 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -12,7 +12,6 @@ C_SOURCES = \ draw_vs_llvm.c \ draw_context.c\ draw_cull.c \ - draw_debug.c \ draw_flatshade.c \ draw_offset.c \ draw_pt.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 246083a962..bff32d2c8b 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -8,7 +8,6 @@ draw = env.ConvenienceLibrary( 'draw_clip.c', 'draw_context.c', 'draw_cull.c', - 'draw_debug.c', 'draw_flatshade.c', 'draw_offset.c', 'draw_pstipple.c', diff --git a/src/gallium/auxiliary/draw/draw_debug.c b/src/gallium/auxiliary/draw/draw_debug.c deleted file mode 100644 index d6220b5f62..0000000000 --- a/src/gallium/auxiliary/draw/draw_debug.c +++ /dev/null @@ -1,113 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "draw_private.h" -#include "draw_context.h" - - - -static void -draw_prim_info(unsigned prim, unsigned *first, unsigned *incr) -{ - assert(prim >= PIPE_PRIM_POINTS); - assert(prim <= PIPE_PRIM_POLYGON); - - switch (prim) { - case PIPE_PRIM_POINTS: - *first = 1; - *incr = 1; - break; - case PIPE_PRIM_LINES: - *first = 2; - *incr = 2; - break; - case PIPE_PRIM_LINE_STRIP: - *first = 2; - *incr = 1; - break; - case PIPE_PRIM_LINE_LOOP: - *first = 2; - *incr = 1; - break; - case PIPE_PRIM_TRIANGLES: - *first = 3; - *incr = 3; - break; - case PIPE_PRIM_TRIANGLE_STRIP: - *first = 3; - *incr = 1; - break; - case PIPE_PRIM_TRIANGLE_FAN: - case PIPE_PRIM_POLYGON: - *first = 3; - *incr = 1; - break; - case PIPE_PRIM_QUADS: - *first = 4; - *incr = 4; - break; - case PIPE_PRIM_QUAD_STRIP: - *first = 4; - *incr = 2; - break; - default: - assert(0); - *first = 1; - *incr = 1; - break; - } -} - - -unsigned -draw_trim_prim( unsigned mode, unsigned count ) -{ - unsigned length, first, incr; - - draw_prim_info( mode, &first, &incr ); - - if (count < first) - length = 0; - else - length = count - (count - first) % incr; - - return length; -} - - -boolean -draw_validate_prim( unsigned mode, unsigned count ) -{ - return (count > 0 && - count == draw_trim_prim( mode, count )); -} - -- cgit v1.2.3 From 6c38c600ff1212699e2e8e0f2928cd9e69559ac5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:37:51 +0100 Subject: draw: rename draw_vertex_shader.c -> draw_vs.c --- src/gallium/auxiliary/draw/Makefile | 2 +- src/gallium/auxiliary/draw/SConscript | 2 +- src/gallium/auxiliary/draw/draw_vertex_shader.c | 85 ------------------------- src/gallium/auxiliary/draw/draw_vs.c | 85 +++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 87 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_vertex_shader.c create mode 100644 src/gallium/auxiliary/draw/draw_vs.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 45def9153c..9c41649883 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -7,6 +7,7 @@ C_SOURCES = \ draw_aaline.c \ draw_aapoint.c \ draw_clip.c \ + draw_vs.c \ draw_vs_exec.c \ draw_vs_sse.c \ draw_vs_llvm.c \ @@ -30,7 +31,6 @@ C_SOURCES = \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ - draw_vertex_shader.c \ draw_wide_line.c \ draw_wide_point.c diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index bff32d2c8b..388d7879dd 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -26,7 +26,7 @@ draw = env.ConvenienceLibrary( 'draw_validate.c', 'draw_vbuf.c', 'draw_vertex.c', - 'draw_vertex_shader.c', + 'draw_vs.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', diff --git a/src/gallium/auxiliary/draw/draw_vertex_shader.c b/src/gallium/auxiliary/draw/draw_vertex_shader.c deleted file mode 100644 index 03fe00a951..0000000000 --- a/src/gallium/auxiliary/draw/draw_vertex_shader.c +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * 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 - * Brian Paul - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" -#include "draw_context.h" -#include "draw_vs.h" - - - -struct draw_vertex_shader * -draw_create_vertex_shader(struct draw_context *draw, - const struct pipe_shader_state *shader) -{ - struct draw_vertex_shader *vs; - - vs = draw_create_vs_llvm( draw, shader ); - if (!vs) { - vs = draw_create_vs_sse( draw, shader ); - if (!vs) { - vs = draw_create_vs_exec( draw, shader ); - } - } - - assert(vs); - return vs; -} - - -void -draw_bind_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs) -{ - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - - if (dvs) - { - draw->vertex_shader = dvs; - draw->num_vs_outputs = dvs->info.num_outputs; - dvs->prepare( dvs, draw ); - } - else { - draw->vertex_shader = NULL; - draw->num_vs_outputs = 0; - } -} - - -void -draw_delete_vertex_shader(struct draw_context *draw, - struct draw_vertex_shader *dvs) -{ - dvs->delete( dvs ); -} diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c new file mode 100644 index 0000000000..03fe00a951 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * 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 + * Brian Paul + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" +#include "draw_context.h" +#include "draw_vs.h" + + + +struct draw_vertex_shader * +draw_create_vertex_shader(struct draw_context *draw, + const struct pipe_shader_state *shader) +{ + struct draw_vertex_shader *vs; + + vs = draw_create_vs_llvm( draw, shader ); + if (!vs) { + vs = draw_create_vs_sse( draw, shader ); + if (!vs) { + vs = draw_create_vs_exec( draw, shader ); + } + } + + assert(vs); + return vs; +} + + +void +draw_bind_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + if (dvs) + { + draw->vertex_shader = dvs; + draw->num_vs_outputs = dvs->info.num_outputs; + dvs->prepare( dvs, draw ); + } + else { + draw->vertex_shader = NULL; + draw->num_vs_outputs = 0; + } +} + + +void +draw_delete_vertex_shader(struct draw_context *draw, + struct draw_vertex_shader *dvs) +{ + dvs->delete( dvs ); +} -- cgit v1.2.3 From 1b411f894369f6a55c6f11cf650511eaa18a8510 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:39:38 +0100 Subject: draw: sort makefile sources --- src/gallium/auxiliary/draw/Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 9c41649883..0b0578a179 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -7,30 +7,30 @@ C_SOURCES = \ draw_aaline.c \ draw_aapoint.c \ draw_clip.c \ - draw_vs.c \ - draw_vs_exec.c \ - draw_vs_sse.c \ - draw_vs_llvm.c \ draw_context.c\ draw_cull.c \ draw_flatshade.c \ draw_offset.c \ + draw_pstipple.c \ draw_pt.c \ - draw_pt_vcache.c \ + draw_pt_elts.c \ + draw_pt_emit.c \ + draw_pt_fetch.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_shade_pipeline.c \ - draw_pt_fetch.c \ - draw_pt_post_vs.c \ - draw_pt_emit.c \ draw_pt_pipeline.c \ - draw_pt_elts.c \ - draw_pstipple.c \ + draw_pt_post_vs.c \ + draw_pt_vcache.c \ draw_stipple.c \ draw_twoside.c \ draw_unfilled.c \ draw_validate.c \ draw_vbuf.c \ draw_vertex.c \ + draw_vs.c \ + draw_vs_exec.c \ + draw_vs_llvm.c \ + draw_vs_sse.c \ draw_wide_line.c \ draw_wide_point.c -- cgit v1.2.3 From c717f1fbe25f16ce6e607b0f7319ce74f9ae99b4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:43:58 +0100 Subject: softpipe: don't need to trim prims --- src/gallium/drivers/softpipe/sp_draw_arrays.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 421509495a..778291dded 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -118,17 +118,6 @@ softpipe_draw_elements(struct pipe_context *pipe, struct draw_context *draw = sp->draw; unsigned i; - /* first, check that the primitive is not malformed. It is the - * state tracker's responsibility to do send only correctly formed - * primitives down. It currently isn't doing that though... - */ -#if 1 - count = draw_trim_prim( mode, count ); -#else - if (!draw_validate_prim( mode, count )) - assert(0); -#endif - sp->reduced_api_prim = reduced_prim[mode]; if (sp->dirty) -- cgit v1.2.3 From 43452886e2e33e33bdc57abe7e0b4af0abbbd2b1 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:44:09 +0100 Subject: cell: don't need to trim prims --- src/gallium/drivers/cell/ppu/cell_draw_arrays.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 36af5be5f0..6e08cf6fe8 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -101,17 +101,6 @@ cell_draw_elements(struct pipe_context *pipe, struct draw_context *draw = sp->draw; unsigned i; - /* first, check that the primitive is not malformed. It is the - * state tracker's responsibility to do send only correctly formed - * primitives down. It currently isn't doing that though... - */ -#if 1 - count = draw_trim_prim( mode, count ); -#else - if (!draw_validate_prim( mode, count )) - assert(0); -#endif - if (sp->dirty) cell_update_derived( sp ); -- cgit v1.2.3 From 26831bdac594a11e51b6c4b09df78bb11444f5dd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 00:45:05 +0100 Subject: draw: rename pipeline files to draw_pipe_* --- src/gallium/auxiliary/draw/Makefile | 32 +- src/gallium/auxiliary/draw/SConscript | 30 +- src/gallium/auxiliary/draw/draw_aaline.c | 859 ---------------------- src/gallium/auxiliary/draw/draw_aapoint.c | 846 --------------------- src/gallium/auxiliary/draw/draw_clip.c | 503 ------------- src/gallium/auxiliary/draw/draw_cull.c | 150 ---- src/gallium/auxiliary/draw/draw_flatshade.c | 248 ------- src/gallium/auxiliary/draw/draw_offset.c | 186 ----- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 859 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 846 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_clip.c | 503 +++++++++++++ src/gallium/auxiliary/draw/draw_pipe_cull.c | 150 ++++ src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 248 +++++++ src/gallium/auxiliary/draw/draw_pipe_offset.c | 186 +++++ src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 746 +++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_stipple.c | 239 ++++++ src/gallium/auxiliary/draw/draw_pipe_twoside.c | 203 +++++ src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 206 ++++++ src/gallium/auxiliary/draw/draw_pipe_validate.c | 312 ++++++++ src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 529 +++++++++++++ src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 190 +++++ src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 281 +++++++ src/gallium/auxiliary/draw/draw_pipe_wide_prims.c | 366 +++++++++ src/gallium/auxiliary/draw/draw_pstipple.c | 746 ------------------- src/gallium/auxiliary/draw/draw_stipple.c | 239 ------ src/gallium/auxiliary/draw/draw_twoside.c | 203 ----- src/gallium/auxiliary/draw/draw_unfilled.c | 206 ------ src/gallium/auxiliary/draw/draw_validate.c | 312 -------- src/gallium/auxiliary/draw/draw_vbuf.c | 529 ------------- src/gallium/auxiliary/draw/draw_wide_line.c | 190 ----- src/gallium/auxiliary/draw/draw_wide_point.c | 281 ------- src/gallium/auxiliary/draw/draw_wide_prims.c | 366 --------- 32 files changed, 5895 insertions(+), 5895 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_aaline.c delete mode 100644 src/gallium/auxiliary/draw/draw_aapoint.c delete mode 100644 src/gallium/auxiliary/draw/draw_clip.c delete mode 100644 src/gallium/auxiliary/draw/draw_cull.c delete mode 100644 src/gallium/auxiliary/draw/draw_flatshade.c delete mode 100644 src/gallium/auxiliary/draw/draw_offset.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_aaline.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_aapoint.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_clip.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_cull.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_flatshade.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_offset.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_pstipple.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_stipple.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_twoside.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_unfilled.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_validate.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_vbuf.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_line.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_point.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_prims.c delete mode 100644 src/gallium/auxiliary/draw/draw_pstipple.c delete mode 100644 src/gallium/auxiliary/draw/draw_stipple.c delete mode 100644 src/gallium/auxiliary/draw/draw_twoside.c delete mode 100644 src/gallium/auxiliary/draw/draw_unfilled.c delete mode 100644 src/gallium/auxiliary/draw/draw_validate.c delete mode 100644 src/gallium/auxiliary/draw/draw_vbuf.c delete mode 100644 src/gallium/auxiliary/draw/draw_wide_line.c delete mode 100644 src/gallium/auxiliary/draw/draw_wide_point.c delete mode 100644 src/gallium/auxiliary/draw/draw_wide_prims.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 0b0578a179..62f46c6db1 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -4,14 +4,21 @@ include $(TOP)/configs/current LIBNAME = draw C_SOURCES = \ - draw_aaline.c \ - draw_aapoint.c \ - draw_clip.c \ - draw_context.c\ - draw_cull.c \ - draw_flatshade.c \ - draw_offset.c \ - draw_pstipple.c \ + draw_context.c \ + draw_pipe_aaline.c \ + draw_pipe_aapoint.c \ + draw_pipe_clip.c \ + draw_pipe_cull.c \ + draw_pipe_flatshade.c \ + draw_pipe_offset.c \ + draw_pipe_pstipple.c \ + draw_pipe_stipple.c \ + draw_pipe_twoside.c \ + draw_pipe_unfilled.c \ + draw_pipe_validate.c \ + draw_pipe_vbuf.c \ + draw_pipe_wide_line.c \ + draw_pipe_wide_point.c \ draw_pt.c \ draw_pt_elts.c \ draw_pt_emit.c \ @@ -21,18 +28,11 @@ C_SOURCES = \ draw_pt_pipeline.c \ draw_pt_post_vs.c \ draw_pt_vcache.c \ - draw_stipple.c \ - draw_twoside.c \ - draw_unfilled.c \ - draw_validate.c \ - draw_vbuf.c \ draw_vertex.c \ draw_vs.c \ draw_vs_exec.c \ draw_vs_llvm.c \ - draw_vs_sse.c \ - draw_wide_line.c \ - draw_wide_point.c + draw_vs_sse.c include ../../Makefile.template diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 388d7879dd..5fa35d3005 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -3,14 +3,22 @@ Import('*') draw = env.ConvenienceLibrary( target = 'draw', source = [ - 'draw_aaline.c', - 'draw_aapoint.c', - 'draw_clip.c', 'draw_context.c', - 'draw_cull.c', - 'draw_flatshade.c', - 'draw_offset.c', - 'draw_pstipple.c', + 'draw_pipe_aaline.c', + 'draw_pipe_aapoint.c', + 'draw_pipe_clip.c', + 'draw_pipe_cull.c', + 'draw_pipe_flatshade.c', + 'draw_pipe_offset.c', + 'draw_pipe_pstipple.c', + 'draw_pipe_stipple.c', + 'draw_pipe_twoside.c', + 'draw_pipe_unfilled.c', + 'draw_pipe_validate.c', + 'draw_pipe_vbuf.c', + 'draw_pipe_vertex.c', + 'draw_pipe_wide_line.c', + 'draw_pipe_wide_point.c', 'draw_pt.c', 'draw_pt_elts.c', 'draw_pt_emit.c', @@ -20,18 +28,10 @@ draw = env.ConvenienceLibrary( 'draw_pt_pipeline.c', 'draw_pt_post_vs.c', 'draw_pt_vcache.c', - 'draw_stipple.c', - 'draw_twoside.c', - 'draw_unfilled.c', - 'draw_validate.c', - 'draw_vbuf.c', - 'draw_vertex.c', 'draw_vs.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', 'draw_vs_sse.c', - 'draw_wide_line.c', - 'draw_wide_point.c', ]) auxiliaries.insert(0, draw) diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c deleted file mode 100644 index e8d2a45102..0000000000 --- a/src/gallium/auxiliary/draw/draw_aaline.c +++ /dev/null @@ -1,859 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/** - * AA line stage: AA lines are converted to texture mapped triangles. - * - * Authors: Brian Paul - */ - - -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" - -#include "draw_context.h" -#include "draw_private.h" - - -/** - * Max texture level for the alpha texture used for antialiasing - */ -#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */ - - -/** - * Subclass of pipe_shader_state to carry extra fragment shader info. - */ -struct aaline_fragment_shader -{ - struct pipe_shader_state state; - void *driver_fs; - void *aaline_fs; - void *aapoint_fs; /* not yet */ - void *sprite_fs; /* not yet */ - uint sampler_unit; - int generic_attrib; /**< texcoord/generic used for texture */ -}; - - -/** - * Subclass of draw_stage - */ -struct aaline_stage -{ - struct draw_stage stage; - - float half_line_width; - - /** For AA lines, this is the vertex attrib slot for the new texcoords */ - uint tex_slot; - - void *sampler_cso; - struct pipe_texture *texture; - uint num_samplers; - uint num_textures; - - - /* - * Currently bound state - */ - struct aaline_fragment_shader *fs; - struct { - void *sampler[PIPE_MAX_SAMPLERS]; - struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; - } state; - - /* - * Driver interface/override functions - */ - void * (*driver_create_fs_state)(struct pipe_context *, - const struct pipe_shader_state *); - void (*driver_bind_fs_state)(struct pipe_context *, void *); - void (*driver_delete_fs_state)(struct pipe_context *, void *); - - void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, - void **); - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); - - struct pipe_context *pipe; -}; - - - -/** - * Subclass of tgsi_transform_context, used for transforming the - * user's fragment shader to add the special AA instructions. - */ -struct aa_transform_context { - struct tgsi_transform_context base; - uint tempsUsed; /**< bitmask */ - int colorOutput; /**< which output is the primary color */ - uint samplersUsed; /**< bitfield of samplers used */ - int freeSampler; /** an available sampler for the pstipple */ - int maxInput, maxGeneric; /**< max input index found */ - int colorTemp, texTemp; /**< temp registers */ - boolean firstInstruction; -}; - - -/** - * TGSI declaration transform callback. - * Look for a free sampler, a free input attrib, and two free temp regs. - */ -static void -aa_transform_decl(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - - if (decl->Declaration.File == TGSI_FILE_OUTPUT && - decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && - decl->Semantic.SemanticIndex == 0) { - aactx->colorOutput = decl->u.DeclarationRange.First; - } - else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - aactx->samplersUsed |= 1 << i; - } - } - else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) - aactx->maxInput = decl->u.DeclarationRange.Last; - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && - (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { - aactx->maxGeneric = decl->Semantic.SemanticIndex; - } - } - else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - aactx->tempsUsed |= (1 << i); - } - } - - ctx->emit_declaration(ctx, decl); -} - - -/** - * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. - */ -static int -free_bit(uint bitfield) -{ - int i; - for (i = 0; i < 32; i++) { - if ((bitfield & (1 << i)) == 0) - return i; - } - return -1; -} - - -/** - * TGSI instruction transform callback. - * Replace writes to result.color w/ a temp reg. - * Upon END instruction, insert texture sampling code for antialiasing. - */ -static void -aa_transform_inst(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - - if (aactx->firstInstruction) { - /* emit our new declarations before the first instruction */ - - struct tgsi_full_declaration decl; - uint i; - - /* find free sampler */ - aactx->freeSampler = free_bit(aactx->samplersUsed); - if (aactx->freeSampler >= PIPE_MAX_SAMPLERS) - aactx->freeSampler = PIPE_MAX_SAMPLERS - 1; - - /* find two free temp regs */ - for (i = 0; i < 32; i++) { - if ((aactx->tempsUsed & (1 << i)) == 0) { - /* found a free temp */ - if (aactx->colorTemp < 0) - aactx->colorTemp = i; - else if (aactx->texTemp < 0) - aactx->texTemp = i; - else - break; - } - } - assert(aactx->colorTemp >= 0); - assert(aactx->texTemp >= 0); - - /* declare new generic input/texcoord */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; - decl.Declaration.Interpolate = 1; - /* XXX this could be linear... */ - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->maxInput + 1; - ctx->emit_declaration(ctx, &decl); - - /* declare new sampler */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->freeSampler; - ctx->emit_declaration(ctx, &decl); - - /* declare new temp regs */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->texTemp; - ctx->emit_declaration(ctx, &decl); - - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->colorTemp; - ctx->emit_declaration(ctx, &decl); - - aactx->firstInstruction = FALSE; - } - - if (inst->Instruction.Opcode == TGSI_OPCODE_END && - aactx->colorOutput != -1) { - struct tgsi_full_instruction newInst; - - /* TEX */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_TEX; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp; - newInst.Instruction.NumSrcRegs = 2; - newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler; - - ctx->emit_instruction(ctx, &newInst); - - /* MOV rgb */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MOV; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - ctx->emit_instruction(ctx, &newInst); - - /* MUL alpha */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp; - ctx->emit_instruction(ctx, &newInst); - - /* END */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_END; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 0; - ctx->emit_instruction(ctx, &newInst); - } - else { - /* Not an END instruction. - * Look for writes to result.color and replace with colorTemp reg. - */ - uint i; - - for (i = 0; i < inst->Instruction.NumDstRegs; i++) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - if (dst->DstRegister.File == TGSI_FILE_OUTPUT && - dst->DstRegister.Index == aactx->colorOutput) { - dst->DstRegister.File = TGSI_FILE_TEMPORARY; - dst->DstRegister.Index = aactx->colorTemp; - } - } - - ctx->emit_instruction(ctx, inst); - } -} - - -/** - * Generate the frag shader we'll use for drawing AA lines. - * This will be the user's shader plus some texture/modulate instructions. - */ -static void -generate_aaline_fs(struct aaline_stage *aaline) -{ - const struct pipe_shader_state *orig_fs = &aaline->fs->state; - //struct draw_context *draw = aaline->stage.draw; - struct pipe_shader_state aaline_fs; - struct aa_transform_context transform; - -#define MAX 1000 - - aaline_fs = *orig_fs; /* copy to init */ - aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); - - memset(&transform, 0, sizeof(transform)); - transform.colorOutput = -1; - transform.maxInput = -1; - transform.maxGeneric = -1; - transform.colorTemp = -1; - transform.texTemp = -1; - transform.firstInstruction = TRUE; - transform.base.transform_instruction = aa_transform_inst; - transform.base.transform_declaration = aa_transform_decl; - - tgsi_transform_shader(orig_fs->tokens, - (struct tgsi_token *) aaline_fs.tokens, - MAX, &transform.base); - -#if 0 /* DEBUG */ - tgsi_dump(orig_fs->tokens, 0); - tgsi_dump(aaline_fs.tokens, 0); -#endif - - aaline->fs->sampler_unit = transform.freeSampler; - - aaline->fs->aaline_fs - = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); - - aaline->fs->generic_attrib = transform.maxGeneric + 1; -} - - -/** - * Create the texture map we'll use for antialiasing the lines. - */ -static void -aaline_create_texture(struct aaline_stage *aaline) -{ - struct pipe_context *pipe = aaline->pipe; - struct pipe_screen *screen = pipe->screen; - struct pipe_texture texTemp; - uint level; - - memset(&texTemp, 0, sizeof(texTemp)); - texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ - texTemp.last_level = MAX_TEXTURE_LEVEL; - texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; - texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; - texTemp.depth[0] = 1; - texTemp.cpp = 1; - - aaline->texture = screen->texture_create(screen, &texTemp); - - /* Fill in mipmap images. - * Basically each level is solid opaque, except for the outermost - * texels which are zero. Special case the 1x1 and 2x2 levels. - */ - for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { - struct pipe_surface *surface; - const uint size = aaline->texture->width[level]; - ubyte *data; - uint i, j; - - 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); - - for (i = 0; i < size; i++) { - for (j = 0; j < size; j++) { - ubyte d; - if (size == 1) { - d = 255; - } - else if (size == 2) { - d = 200; /* tuneable */ - } - else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { - d = 0; - } - else { - d = 255; - } - data[i * surface->pitch + j] = d; - } - } - - /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); - } -} - - -/** - * Create the sampler CSO that'll be used for antialiasing. - * By using a mipmapped texture, we don't have to generate a different - * texture image for each line size. - */ -static void -aaline_create_sampler(struct aaline_stage *aaline) -{ - struct pipe_sampler_state sampler; - struct pipe_context *pipe = aaline->pipe; - - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.normalized_coords = 1; - sampler.min_lod = 0.0f; - sampler.max_lod = MAX_TEXTURE_LEVEL; - - aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); -} - - -/** - * When we're about to draw our first AA line in a batch, this function is - * called to tell the driver to bind our modified fragment shader. - */ -static void -bind_aaline_fragment_shader(struct aaline_stage *aaline) -{ - if (!aaline->fs->aaline_fs) { - generate_aaline_fs(aaline); - } - aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); -} - - - -static INLINE struct aaline_stage * -aaline_stage( struct draw_stage *stage ) -{ - return (struct aaline_stage *) stage; -} - - -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad, using geometry which will - * fullfill GL's antialiased line requirements. - */ -static void -aaline_line(struct draw_stage *stage, struct prim_header *header) -{ - const struct aaline_stage *aaline = aaline_stage(stage); - const float half_width = aaline->half_line_width; - struct prim_header tri; - struct vertex_header *v[8]; - uint texPos = aaline->tex_slot; - float *pos, *tex; - float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; - float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; - double a = atan2(dy, dx); - float c_a = (float) cos(a), s_a = (float) sin(a); - uint i; - - /* XXX the ends of lines aren't quite perfect yet, but probably passable */ - dx = 0.5F * half_width; - dy = half_width; - - /* allocate/dup new verts */ - for (i = 0; i < 8; i++) { - v[i] = dup_vert(stage, header->v[i/4], i); - } - - /* - * Quad strip for line from v0 to v1 (*=endpoints): - * - * 1 3 5 7 - * +---+---------------------+---+ - * | | - * | *v0 v1* | - * | | - * +---+---------------------+---+ - * 0 2 4 6 - */ - - /* new verts */ - pos = v[0]->data[0]; - pos[0] += (-dx * c_a - dy * s_a); - pos[1] += (-dx * s_a + dy * c_a); - - pos = v[1]->data[0]; - pos[0] += (-dx * c_a - -dy * s_a); - pos[1] += (-dx * s_a + -dy * c_a); - - pos = v[2]->data[0]; - pos[0] += ( dx * c_a - dy * s_a); - pos[1] += ( dx * s_a + dy * c_a); - - pos = v[3]->data[0]; - pos[0] += ( dx * c_a - -dy * s_a); - pos[1] += ( dx * s_a + -dy * c_a); - - pos = v[4]->data[0]; - pos[0] += (-dx * c_a - dy * s_a); - pos[1] += (-dx * s_a + dy * c_a); - - pos = v[5]->data[0]; - pos[0] += (-dx * c_a - -dy * s_a); - pos[1] += (-dx * s_a + -dy * c_a); - - pos = v[6]->data[0]; - pos[0] += ( dx * c_a - dy * s_a); - pos[1] += ( dx * s_a + dy * c_a); - - pos = v[7]->data[0]; - pos[0] += ( dx * c_a - -dy * s_a); - pos[1] += ( dx * s_a + -dy * c_a); - - /* new texcoords */ - tex = v[0]->data[texPos]; - ASSIGN_4V(tex, 0, 0, 0, 1); - - tex = v[1]->data[texPos]; - ASSIGN_4V(tex, 0, 1, 0, 1); - - tex = v[2]->data[texPos]; - ASSIGN_4V(tex, .5, 0, 0, 1); - - tex = v[3]->data[texPos]; - ASSIGN_4V(tex, .5, 1, 0, 1); - - tex = v[4]->data[texPos]; - ASSIGN_4V(tex, .5, 0, 0, 1); - - tex = v[5]->data[texPos]; - ASSIGN_4V(tex, .5, 1, 0, 1); - - tex = v[6]->data[texPos]; - ASSIGN_4V(tex, 1, 0, 0, 1); - - tex = v[7]->data[texPos]; - ASSIGN_4V(tex, 1, 1, 0, 1); - - /* emit 6 tris for the quad strip */ - tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6]; - stage->next->tri( stage->next, &tri ); -} - - -static void -aaline_first_line(struct draw_stage *stage, struct prim_header *header) -{ - auto struct aaline_stage *aaline = aaline_stage(stage); - struct draw_context *draw = stage->draw; - struct pipe_context *pipe = aaline->pipe; - uint num_samplers; - - assert(draw->rasterizer->line_smooth); - - if (draw->rasterizer->line_width <= 3.0) - aaline->half_line_width = 1.5f; - else - aaline->half_line_width = 0.5f * draw->rasterizer->line_width; - - /* - * Bind (generate) our fragprog, sampler and texture - */ - bind_aaline_fragment_shader(aaline); - - /* update vertex attrib info */ - aaline->tex_slot = draw->num_vs_outputs; - assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ - - /* advertise the extra post-transformed vertex attribute */ - draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; - draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib; - draw->extra_vp_outputs.slot = aaline->tex_slot; - - /* how many samplers? */ - /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); - num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); - - aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; - pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], - aaline->texture); - - aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); - - /* now really draw first line */ - stage->line = aaline_line; - stage->line(stage, header); -} - - -static void -aaline_flush(struct draw_stage *stage, unsigned flags) -{ - struct draw_context *draw = stage->draw; - struct aaline_stage *aaline = aaline_stage(stage); - struct pipe_context *pipe = aaline->pipe; - - stage->line = aaline_first_line; - stage->next->flush( stage->next, flags ); - - /* restore original frag shader */ - aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); - - /* XXX restore original texture, sampler state */ - aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, - aaline->state.sampler); - aaline->driver_set_sampler_textures(pipe, aaline->num_textures, - aaline->state.texture); - - draw->extra_vp_outputs.slot = 0; -} - - -static void -aaline_reset_stipple_counter(struct draw_stage *stage) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -aaline_destroy(struct draw_stage *stage) -{ - struct aaline_stage *aaline = aaline_stage(stage); - - aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); - - pipe_texture_release(&aaline->texture); - - draw_free_temp_verts( stage ); - - FREE( stage ); -} - - -static struct aaline_stage * -draw_aaline_stage(struct draw_context *draw) -{ - struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); - - draw_alloc_temp_verts( &aaline->stage, 8 ); - - aaline->stage.draw = draw; - aaline->stage.next = NULL; - aaline->stage.point = passthrough_point; - aaline->stage.line = aaline_first_line; - aaline->stage.tri = passthrough_tri; - aaline->stage.flush = aaline_flush; - aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; - aaline->stage.destroy = aaline_destroy; - - return aaline; -} - - -static struct aaline_stage * -aaline_stage_from_pipe(struct pipe_context *pipe) -{ - struct draw_context *draw = (struct draw_context *) pipe->draw; - return aaline_stage(draw->pipeline.aaline); -} - - -/** - * This function overrides the driver's create_fs_state() function and - * will typically be called by the state tracker. - */ -static void * -aaline_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *fs) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); - - if (aafs) { - aafs->state = *fs; - - /* pass-through */ - aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); - } - - return aafs; -} - - -static void -aaline_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; - /* save current */ - aaline->fs = aafs; - /* pass-through */ - aaline->driver_bind_fs_state(aaline->pipe, - (aafs ? aafs->driver_fs : NULL)); -} - - -static void -aaline_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; - /* pass-through */ - aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs); - FREE(aafs); -} - - -static void -aaline_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - /* save current */ - memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); - aaline->num_samplers = num; - /* pass-through */ - aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); -} - - -static void -aaline_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) -{ - struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); - uint i; - - /* save current */ - for (i = 0; i < num; i++) { - pipe_texture_reference(&aaline->state.texture[i], texture[i]); - } - aaline->num_textures = num; - - /* pass-through */ - aaline->driver_set_sampler_textures(aaline->pipe, num, texture); -} - - -/** - * Called by drivers that want to install this AA line prim stage - * into the draw module's pipeline. This will not be used if the - * hardware has native support for AA lines. - */ -void -draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) -{ - struct aaline_stage *aaline; - - pipe->draw = (void *) draw; - - /* - * Create / install AA line drawing / prim stage - */ - aaline = draw_aaline_stage( draw ); - assert(aaline); - draw->pipeline.aaline = &aaline->stage; - - aaline->pipe = pipe; - - /* create special texture, sampler state */ - aaline_create_texture(aaline); - aaline_create_sampler(aaline); - - /* save original driver functions */ - aaline->driver_create_fs_state = pipe->create_fs_state; - aaline->driver_bind_fs_state = pipe->bind_fs_state; - aaline->driver_delete_fs_state = pipe->delete_fs_state; - - aaline->driver_bind_sampler_states = pipe->bind_sampler_states; - aaline->driver_set_sampler_textures = pipe->set_sampler_textures; - - /* override the driver's functions */ - pipe->create_fs_state = aaline_create_fs_state; - pipe->bind_fs_state = aaline_bind_fs_state; - pipe->delete_fs_state = aaline_delete_fs_state; - - pipe->bind_sampler_states = aaline_bind_sampler_states; - pipe->set_sampler_textures = aaline_set_sampler_textures; -} diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c deleted file mode 100644 index e84d380e50..0000000000 --- a/src/gallium/auxiliary/draw/draw_aapoint.c +++ /dev/null @@ -1,846 +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. - * - **************************************************************************/ - -/** - * AA point stage: AA points are converted to quads and rendered with a - * special fragment shader. Another approach would be to use a texture - * map image of a point, but experiments indicate the quality isn't nearly - * as good as this approach. - * - * Note: this looks a lot like draw_aaline.c but there's actually little - * if any code that can be shared. - * - * Authors: Brian Paul - */ - - -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" - -#include "draw_context.h" -#include "draw_vs.h" - - -/* - * Enabling NORMALIZE might give _slightly_ better results. - * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or - * d=x*x+y*y. Since we're working with a unit circle, the later seems - * close enough and saves some costly instructions. - */ -#define NORMALIZE 0 - - -/** - * Subclass of pipe_shader_state to carry extra fragment shader info. - */ -struct aapoint_fragment_shader -{ - struct pipe_shader_state state; - void *driver_fs; /**< the regular shader */ - void *aapoint_fs; /**< the aa point-augmented shader */ - int generic_attrib; /**< The generic input attrib/texcoord we'll use */ -}; - - -/** - * Subclass of draw_stage - */ -struct aapoint_stage -{ - struct draw_stage stage; - - int psize_slot; - float radius; - - /** this is the vertex attrib slot for the new texcoords */ - uint tex_slot; - - /* - * Currently bound state - */ - struct aapoint_fragment_shader *fs; - - /* - * Driver interface/override functions - */ - void * (*driver_create_fs_state)(struct pipe_context *, - const struct pipe_shader_state *); - void (*driver_bind_fs_state)(struct pipe_context *, void *); - void (*driver_delete_fs_state)(struct pipe_context *, void *); - - struct pipe_context *pipe; -}; - - - -/** - * Subclass of tgsi_transform_context, used for transforming the - * user's fragment shader to add the special AA instructions. - */ -struct aa_transform_context { - struct tgsi_transform_context base; - uint tempsUsed; /**< bitmask */ - int colorOutput; /**< which output is the primary color */ - int maxInput, maxGeneric; /**< max input index found */ - int tmp0, colorTemp; /**< temp registers */ - boolean firstInstruction; -}; - - -/** - * TGSI declaration transform callback. - * Look for two free temp regs and available input reg for new texcoords. - */ -static void -aa_transform_decl(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - - if (decl->Declaration.File == TGSI_FILE_OUTPUT && - decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && - decl->Semantic.SemanticIndex == 0) { - aactx->colorOutput = decl->u.DeclarationRange.First; - } - else if (decl->Declaration.File == TGSI_FILE_INPUT) { - if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) - aactx->maxInput = decl->u.DeclarationRange.Last; - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && - (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { - aactx->maxGeneric = decl->Semantic.SemanticIndex; - } - } - else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - aactx->tempsUsed |= (1 << i); - } - } - - ctx->emit_declaration(ctx, decl); -} - - -/** - * TGSI instruction transform callback. - * Replace writes to result.color w/ a temp reg. - * Upon END instruction, insert texture sampling code for antialiasing. - */ -static void -aa_transform_inst(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst) -{ - struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; - struct tgsi_full_instruction newInst; - - if (aactx->firstInstruction) { - /* emit our new declarations before the first instruction */ - - struct tgsi_full_declaration decl; - const int texInput = aactx->maxInput + 1; - int tmp0; - uint i; - - /* find two free temp regs */ - for (i = 0; i < 32; i++) { - if ((aactx->tempsUsed & (1 << i)) == 0) { - /* found a free temp */ - if (aactx->tmp0 < 0) - aactx->tmp0 = i; - else if (aactx->colorTemp < 0) - aactx->colorTemp = i; - else - break; - } - } - - assert(aactx->colorTemp != aactx->tmp0); - - tmp0 = aactx->tmp0; - - /* declare new generic input/texcoord */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; - decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; - decl.Declaration.Interpolate = 1; - /* XXX this could be linear... */ - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = texInput; - ctx->emit_declaration(ctx, &decl); - - /* declare new temp regs */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = tmp0; - ctx->emit_declaration(ctx, &decl); - - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = aactx->colorTemp; - ctx->emit_declaration(ctx, &decl); - - aactx->firstInstruction = FALSE; - - - /* - * Emit code to compute fragment coverage, kill if outside point radius - * - * Temp reg0 usage: - * t0.x = distance of fragment from center point - * t0.y = boolean, is t0.x > 1.0, also misc temp usage - * t0.z = temporary for computing 1/(1-k) value - * t0.w = final coverage value - */ - - /* MUL t0.xy, tex, tex; # compute x^2, y^2 */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - ctx->emit_instruction(ctx, &newInst); - - /* ADD t0.x, t0.x, t0.y; # x^2 + y^2 */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_ADD; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - ctx->emit_instruction(ctx, &newInst); - -#if NORMALIZE /* OPTIONAL normalization of length */ - /* RSQ t0.x, t0.x; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_RSQ; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - ctx->emit_instruction(ctx, &newInst); - - /* RCP t0.x, t0.x; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_RCP; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - ctx->emit_instruction(ctx, &newInst); -#endif - - /* SGT t0.y, t0.xxxx, t0.wwww; # bool b = d > 1 (NOTE t0.w == 1) */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SGT; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - ctx->emit_instruction(ctx, &newInst); - - /* KILP -t0.yyyy; # if b, KILL */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_KILP; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; - ctx->emit_instruction(ctx, &newInst); - - - /* compute coverage factor = (1-d)/(1-k) */ - - /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SUB; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* RCP t0.z, t0.z; # t0.z = 1 / m */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_RCP; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* SUB t0.y, 1, t0.x; # d = 1 - d */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SUB; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - ctx->emit_instruction(ctx, &newInst); - - /* MUL t0.w, t0.y, t0.z; # coverage = d * m */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* SLE t0.y, t0.x, tex.z; # bool b = distance <= k */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_SLE; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z; - ctx->emit_instruction(ctx, &newInst); - - /* CMP t0.w, -t0.y, tex.w, t0.w; - * # if -t0.y < 0 then - * t0.w = 1 - * else - * t0.w = t0.w - */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_CMP; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = tmp0; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 3; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; - newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; - newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; - ctx->emit_instruction(ctx, &newInst); - - } - - if (inst->Instruction.Opcode == TGSI_OPCODE_END) { - /* add alpha modulation code at tail of program */ - - /* MOV result.color.xyz, colorTemp; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MOV; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - ctx->emit_instruction(ctx, &newInst); - - /* MUL result.color.w, colorTemp, tmp0.w; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; - newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; - newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0; - ctx->emit_instruction(ctx, &newInst); - } - else { - /* Not an END instruction. - * Look for writes to result.color and replace with colorTemp reg. - */ - uint i; - - for (i = 0; i < inst->Instruction.NumDstRegs; i++) { - struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; - if (dst->DstRegister.File == TGSI_FILE_OUTPUT && - dst->DstRegister.Index == aactx->colorOutput) { - dst->DstRegister.File = TGSI_FILE_TEMPORARY; - dst->DstRegister.Index = aactx->colorTemp; - } - } - } - - ctx->emit_instruction(ctx, inst); -} - - -/** - * Generate the frag shader we'll use for drawing AA lines. - * This will be the user's shader plus some texture/modulate instructions. - */ -static void -generate_aapoint_fs(struct aapoint_stage *aapoint) -{ - const struct pipe_shader_state *orig_fs = &aapoint->fs->state; - struct pipe_shader_state aapoint_fs; - struct aa_transform_context transform; - -#define MAX 1000 - - aapoint_fs = *orig_fs; /* copy to init */ - aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); - - memset(&transform, 0, sizeof(transform)); - transform.colorOutput = -1; - transform.maxInput = -1; - transform.maxGeneric = -1; - transform.colorTemp = -1; - transform.tmp0 = -1; - transform.firstInstruction = TRUE; - transform.base.transform_instruction = aa_transform_inst; - transform.base.transform_declaration = aa_transform_decl; - - tgsi_transform_shader(orig_fs->tokens, - (struct tgsi_token *) aapoint_fs.tokens, - MAX, &transform.base); - -#if 0 /* DEBUG */ - printf("draw_aapoint, orig shader:\n"); - tgsi_dump(orig_fs->tokens, 0); - printf("draw_aapoint, new shader:\n"); - tgsi_dump(aapoint_fs.tokens, 0); -#endif - - aapoint->fs->aapoint_fs - = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); - - aapoint->fs->generic_attrib = transform.maxGeneric + 1; -} - - -/** - * When we're about to draw our first AA line in a batch, this function is - * called to tell the driver to bind our modified fragment shader. - */ -static void -bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) -{ - if (!aapoint->fs->aapoint_fs) { - generate_aapoint_fs(aapoint); - } - aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); -} - - - -static INLINE struct aapoint_stage * -aapoint_stage( struct draw_stage *stage ) -{ - return (struct aapoint_stage *) stage; -} - - -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw an AA point by drawing a quad. - */ -static void -aapoint_point(struct draw_stage *stage, struct prim_header *header) -{ - const struct aapoint_stage *aapoint = aapoint_stage(stage); - struct prim_header tri; - struct vertex_header *v[4]; - uint texPos = aapoint->tex_slot; - float radius, *pos, *tex; - uint i; - float k; - - if (aapoint->psize_slot >= 0) { - radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0]; - } - else { - radius = aapoint->radius; - } - - /* - * Note: the texcoords (generic attrib, really) we use are special: - * The S and T components simply vary from -1 to +1. - * The R component is k, below. - * The Q component is 1.0 and will used as a handy constant in the - * fragment shader. - */ - - /* - * k is the threshold distance from the point's center at which - * we begin alpha attenuation (the coverage value). - * Operating within a unit circle, we'll compute the fragment's - * distance 'd' from the center point using the texcoords. - * IF d > 1.0 THEN - * KILL fragment - * ELSE IF d > k THEN - * compute coverage in [0,1] proportional to d in [k, 1]. - * ELSE - * coverage = 1.0; // full coverage - * ENDIF - * - * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to - * avoid using IF/ELSE/ENDIF TGSI opcodes. - */ - -#if !NORMALIZE - k = 1.0f / radius; - k = 1.0f - 2.0f * k + k * k; -#else - k = 1.0f - 1.0f / radius; -#endif - - /* allocate/dup new verts */ - for (i = 0; i < 4; i++) { - v[i] = dup_vert(stage, header->v[0], i); - } - - /* new verts */ - pos = v[0]->data[0]; - pos[0] -= radius; - pos[1] -= radius; - - pos = v[1]->data[0]; - pos[0] += radius; - pos[1] -= radius; - - pos = v[2]->data[0]; - pos[0] += radius; - pos[1] += radius; - - pos = v[3]->data[0]; - pos[0] -= radius; - pos[1] += radius; - - /* new texcoords */ - tex = v[0]->data[texPos]; - ASSIGN_4V(tex, -1, -1, k, 1); - - tex = v[1]->data[texPos]; - ASSIGN_4V(tex, 1, -1, k, 1); - - tex = v[2]->data[texPos]; - ASSIGN_4V(tex, 1, 1, k, 1); - - tex = v[3]->data[texPos]; - ASSIGN_4V(tex, -1, 1, k, 1); - - /* emit 2 tris for the quad strip */ - tri.v[0] = v[0]; - tri.v[1] = v[1]; - tri.v[2] = v[2]; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v[0]; - tri.v[1] = v[2]; - tri.v[2] = v[3]; - stage->next->tri( stage->next, &tri ); -} - - -static void -aapoint_first_point(struct draw_stage *stage, struct prim_header *header) -{ - auto struct aapoint_stage *aapoint = aapoint_stage(stage); - struct draw_context *draw = stage->draw; - - assert(draw->rasterizer->point_smooth); - - if (draw->rasterizer->point_size <= 2.0) - aapoint->radius = 1.0; - else - aapoint->radius = 0.5f * draw->rasterizer->point_size; - - /* - * Bind (generate) our fragprog. - */ - bind_aapoint_fragment_shader(aapoint); - - /* update vertex attrib info */ - aapoint->tex_slot = draw->num_vs_outputs; - assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ - - draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; - draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib; - draw->extra_vp_outputs.slot = aapoint->tex_slot; - - /* find psize slot in post-transform vertex */ - aapoint->psize_slot = -1; - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - aapoint->psize_slot = i; - break; - } - } - } - - /* now really draw first line */ - stage->point = aapoint_point; - stage->point(stage, header); -} - - -static void -aapoint_flush(struct draw_stage *stage, unsigned flags) -{ - struct draw_context *draw = stage->draw; - struct aapoint_stage *aapoint = aapoint_stage(stage); - struct pipe_context *pipe = aapoint->pipe; - - stage->point = aapoint_first_point; - stage->next->flush( stage->next, flags ); - - /* restore original frag shader */ - aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs); - - draw->extra_vp_outputs.slot = 0; -} - - -static void -aapoint_reset_stipple_counter(struct draw_stage *stage) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -aapoint_destroy(struct draw_stage *stage) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -static struct aapoint_stage * -draw_aapoint_stage(struct draw_context *draw) -{ - struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); - - draw_alloc_temp_verts( &aapoint->stage, 4 ); - - aapoint->stage.draw = draw; - aapoint->stage.next = NULL; - aapoint->stage.point = aapoint_first_point; - aapoint->stage.line = passthrough_line; - aapoint->stage.tri = passthrough_tri; - aapoint->stage.flush = aapoint_flush; - aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; - aapoint->stage.destroy = aapoint_destroy; - - return aapoint; -} - - -static struct aapoint_stage * -aapoint_stage_from_pipe(struct pipe_context *pipe) -{ - struct draw_context *draw = (struct draw_context *) pipe->draw; - return aapoint_stage(draw->pipeline.aapoint); -} - - -/** - * This function overrides the driver's create_fs_state() function and - * will typically be called by the state tracker. - */ -static void * -aapoint_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *fs) -{ - struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); - struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); - - if (aafs) { - aafs->state = *fs; - - /* pass-through */ - aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); - } - - return aafs; -} - - -static void -aapoint_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); - struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; - /* save current */ - aapoint->fs = aafs; - /* pass-through */ - aapoint->driver_bind_fs_state(aapoint->pipe, - (aafs ? aafs->driver_fs : NULL)); -} - - -static void -aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); - struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; - /* pass-through */ - aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs); - FREE(aafs); -} - - -/** - * Called by drivers that want to install this AA point prim stage - * into the draw module's pipeline. This will not be used if the - * hardware has native support for AA points. - */ -void -draw_install_aapoint_stage(struct draw_context *draw, - struct pipe_context *pipe) -{ - struct aapoint_stage *aapoint; - - pipe->draw = (void *) draw; - - /* - * Create / install AA point drawing / prim stage - */ - aapoint = draw_aapoint_stage( draw ); - assert(aapoint); - draw->pipeline.aapoint = &aapoint->stage; - - aapoint->pipe = pipe; - - /* save original driver functions */ - aapoint->driver_create_fs_state = pipe->create_fs_state; - aapoint->driver_bind_fs_state = pipe->bind_fs_state; - aapoint->driver_delete_fs_state = pipe->delete_fs_state; - - /* override the driver's functions */ - pipe->create_fs_state = aapoint_create_fs_state; - pipe->bind_fs_state = aapoint_bind_fs_state; - pipe->delete_fs_state = aapoint_delete_fs_state; -} diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c deleted file mode 100644 index 0ac3a240e5..0000000000 --- a/src/gallium/auxiliary/draw/draw_clip.c +++ /dev/null @@ -1,503 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/** - * \brief Clipping stage - * - * \author Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" - -#include "draw_context.h" -#include "draw_vs.h" - - -#ifndef IS_NEGATIVE -#define IS_NEGATIVE(X) ((X) < 0.0) -#endif - -#ifndef DIFFERENT_SIGNS -#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) -#endif - -#ifndef MAX_CLIPPED_VERTICES -#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) -#endif - - - -struct clipper { - struct draw_stage stage; /**< base class */ - - /* Basically duplicate some of the flatshading logic here: - */ - boolean flat; - uint num_color_attribs; - uint color_attribs[4]; /* front/back primary/secondary colors */ - - float (*plane)[4]; -}; - - -/* This is a bit confusing: - */ -static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) -{ - return (struct clipper *)stage; -} - - -#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) - - -/* All attributes are float[4], so this is easy: - */ -static void interp_attr( float *fdst, - float t, - const float *fin, - const float *fout ) -{ - fdst[0] = LINTERP( t, fout[0], fin[0] ); - fdst[1] = LINTERP( t, fout[1], fin[1] ); - fdst[2] = LINTERP( t, fout[2], fin[2] ); - fdst[3] = LINTERP( t, fout[3], fin[3] ); -} - -static void copy_colors( struct draw_stage *stage, - struct vertex_header *dst, - const struct vertex_header *src ) -{ - const struct clipper *clipper = clipper_stage(stage); - uint i; - for (i = 0; i < clipper->num_color_attribs; i++) { - const uint attr = clipper->color_attribs[i]; - COPY_4FV(dst->data[attr], src->data[attr]); - } -} - - - -/* Interpolate between two vertices to produce a third. - */ -static void interp( const struct clipper *clip, - struct vertex_header *dst, - float t, - const struct vertex_header *out, - const struct vertex_header *in ) -{ - const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; - unsigned j; - - /* Vertex header. - */ - { - dst->clipmask = 0; - dst->edgeflag = 0; - dst->pad = 0; - dst->vertex_id = UNDEFINED_VERTEX_ID; - } - - /* Clip coordinates: interpolate normally - */ - { - interp_attr(dst->clip, t, in->clip, out->clip); - } - - /* Do the projective divide and insert window coordinates: - */ - { - const float *pos = dst->clip; - const float *scale = clip->stage.draw->viewport.scale; - const float *trans = clip->stage.draw->viewport.translate; - const float oow = 1.0f / pos[3]; - - dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; - dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; - dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; - dst->data[0][3] = oow; - } - - /* Other attributes - * Note: start at 1 to skip winpos (data[0]) since we just computed - * it above. - */ - for (j = 1; j < nr_attrs; j++) { - interp_attr(dst->data[j], t, in->data[j], out->data[j]); - } -} - - -static void emit_poly( struct draw_stage *stage, - struct vertex_header **inlist, - unsigned n, - const struct prim_header *origPrim) -{ - struct prim_header header; - unsigned i; - - /* later stages may need the determinant, but only the sign matters */ - header.det = origPrim->det; - - for (i = 2; i < n; i++) { - header.v[0] = inlist[i-1]; - header.v[1] = inlist[i]; - header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ - - { - unsigned tmp1 = header.v[1]->edgeflag; - unsigned tmp2 = header.v[2]->edgeflag; - - if (i != n-1) header.v[1]->edgeflag = 0; - if (i != 2) header.v[2]->edgeflag = 0; - - header.edgeflags = ((header.v[0]->edgeflag << 0) | - (header.v[1]->edgeflag << 1) | - (header.v[2]->edgeflag << 2)); - - if (0) { - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint j, k; - debug_printf("Clipped tri:\n"); - for (j = 0; j < 3; j++) { - for (k = 0; k < vs->info.num_outputs; k++) { - debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, - header.v[j]->data[k][0], - header.v[j]->data[k][1], - header.v[j]->data[k][2], - header.v[j]->data[k][3]); - } - } - } - - stage->next->tri( stage->next, &header ); - - header.v[1]->edgeflag = tmp1; - header.v[2]->edgeflag = tmp2; - } - } -} - - - - -/* Clip a triangle against the viewport and user clip planes. - */ -static void -do_clip_tri( struct draw_stage *stage, - struct prim_header *header, - unsigned clipmask ) -{ - struct clipper *clipper = clipper_stage( stage ); - struct vertex_header *a[MAX_CLIPPED_VERTICES]; - struct vertex_header *b[MAX_CLIPPED_VERTICES]; - struct vertex_header **inlist = a; - struct vertex_header **outlist = b; - unsigned tmpnr = 0; - unsigned n = 3; - unsigned i; - - inlist[0] = header->v[0]; - inlist[1] = header->v[1]; - inlist[2] = header->v[2]; - - while (clipmask && n >= 3) { - const unsigned plane_idx = ffs(clipmask)-1; - const float *plane = clipper->plane[plane_idx]; - struct vertex_header *vert_prev = inlist[0]; - float dp_prev = dot4( vert_prev->clip, plane ); - unsigned outcount = 0; - - clipmask &= ~(1<clip, plane ); - - if (!IS_NEGATIVE(dp_prev)) { - outlist[outcount++] = vert_prev; - } - - if (DIFFERENT_SIGNS(dp, dp_prev)) { - struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++]; - outlist[outcount++] = new_vert; - - if (IS_NEGATIVE(dp)) { - /* Going out of bounds. Avoid division by zero as we - * know dp != dp_prev from DIFFERENT_SIGNS, above. - */ - float t = dp / (dp - dp_prev); - interp( clipper, new_vert, t, vert, vert_prev ); - - /* Force edgeflag true in this case: - */ - new_vert->edgeflag = 1; - } else { - /* Coming back in. - */ - float t = dp_prev / (dp_prev - dp); - interp( clipper, new_vert, t, vert_prev, vert ); - - /* Copy starting vert's edgeflag: - */ - new_vert->edgeflag = vert_prev->edgeflag; - } - } - - vert_prev = vert; - dp_prev = dp; - } - - { - struct vertex_header **tmp = inlist; - inlist = outlist; - outlist = tmp; - n = outcount; - } - } - - /* If flat-shading, copy color to new provoking vertex. - */ - if (clipper->flat && inlist[0] != header->v[2]) { - if (1) { - inlist[0] = dup_vert(stage, inlist[0], tmpnr++); - } - - copy_colors(stage, inlist[0], header->v[2]); - } - - - - /* Emit the polygon as triangles to the setup stage: - */ - if (n >= 3) - emit_poly( stage, inlist, n, header ); -} - - -/* Clip a line against the viewport and user clip planes. - */ -static void -do_clip_line( struct draw_stage *stage, - struct prim_header *header, - unsigned clipmask ) -{ - const struct clipper *clipper = clipper_stage( stage ); - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - const float *pos0 = v0->clip; - const float *pos1 = v1->clip; - float t0 = 0.0F; - float t1 = 0.0F; - struct prim_header newprim; - - while (clipmask) { - const unsigned plane_idx = ffs(clipmask)-1; - const float *plane = clipper->plane[plane_idx]; - const float dp0 = dot4( pos0, plane ); - const float dp1 = dot4( pos1, plane ); - - if (dp1 < 0.0F) { - float t = dp1 / (dp1 - dp0); - t1 = MAX2(t1, t); - } - - if (dp0 < 0.0F) { - float t = dp0 / (dp0 - dp1); - t0 = MAX2(t0, t); - } - - if (t0 + t1 >= 1.0F) - return; /* discard */ - - clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ - } - - if (v0->clipmask) { - interp( clipper, stage->tmp[0], t0, v0, v1 ); - - if (clipper->flat) - copy_colors(stage, stage->tmp[0], v0); - - newprim.v[0] = stage->tmp[0]; - } - else { - newprim.v[0] = v0; - } - - if (v1->clipmask) { - interp( clipper, stage->tmp[1], t1, v1, v0 ); - newprim.v[1] = stage->tmp[1]; - } - else { - newprim.v[1] = v1; - } - - stage->next->line( stage->next, &newprim ); -} - - -static void -clip_point( struct draw_stage *stage, - struct prim_header *header ) -{ - if (header->v[0]->clipmask == 0) - stage->next->point( stage->next, header ); -} - - -static void -clip_line( struct draw_stage *stage, - struct prim_header *header ) -{ - unsigned clipmask = (header->v[0]->clipmask | - header->v[1]->clipmask); - - if (clipmask == 0) { - /* no clipping needed */ - stage->next->line( stage->next, header ); - } - else if ((header->v[0]->clipmask & - header->v[1]->clipmask) == 0) { - do_clip_line(stage, header, clipmask); - } - /* else, totally clipped */ -} - - -static void -clip_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - unsigned clipmask = (header->v[0]->clipmask | - header->v[1]->clipmask | - header->v[2]->clipmask); - - if (clipmask == 0) { - /* no clipping needed */ - stage->next->tri( stage->next, header ); - } - else if ((header->v[0]->clipmask & - header->v[1]->clipmask & - header->v[2]->clipmask) == 0) { - do_clip_tri(stage, header, clipmask); - } -} - -/* Update state. Could further delay this until we hit the first - * primitive that really requires clipping. - */ -static void -clip_init_state( struct draw_stage *stage ) -{ - struct clipper *clipper = clipper_stage( stage ); - - clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; - - if (clipper->flat) { - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint i; - - clipper->num_color_attribs = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - clipper->color_attribs[clipper->num_color_attribs++] = i; - } - } - } - - stage->tri = clip_tri; - stage->line = clip_line; -} - - - -static void clip_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - clip_init_state( stage ); - stage->tri( stage, header ); -} - -static void clip_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - clip_init_state( stage ); - stage->line( stage, header ); -} - - -static void clip_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = clip_first_tri; - stage->line = clip_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void clip_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void clip_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Allocate a new clipper stage. - * \return pointer to new stage object - */ -struct draw_stage *draw_clip_stage( struct draw_context *draw ) -{ - struct clipper *clipper = CALLOC_STRUCT(clipper); - - draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); - - clipper->stage.draw = draw; - clipper->stage.point = clip_point; - clipper->stage.line = clip_first_line; - clipper->stage.tri = clip_first_tri; - clipper->stage.flush = clip_flush; - clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; - clipper->stage.destroy = clip_destroy; - - clipper->plane = draw->plane; - - return &clipper->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_cull.c b/src/gallium/auxiliary/draw/draw_cull.c deleted file mode 100644 index 8177b0ac86..0000000000 --- a/src/gallium/auxiliary/draw/draw_cull.c +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/** - * \brief Drawing stage for polygon culling - */ - -/* Authors: Keith Whitwell - */ - - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - - -struct cull_stage { - struct draw_stage stage; - unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ -}; - - -static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) -{ - return (struct cull_stage *)stage; -} - - - - -static void cull_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - /* Window coords: */ - const float *v0 = header->v[0]->data[0]; - const float *v1 = header->v[1]->data[0]; - const float *v2 = header->v[2]->data[0]; - - /* edge vectors e = v0 - v2, f = v1 - v2 */ - const float ex = v0[0] - v2[0]; - const float ey = v0[1] - v2[1]; - const float fx = v1[0] - v2[0]; - const float fy = v1[1] - v2[1]; - - /* det = cross(e,f).z */ - header->det = ex * fy - ey * fx; - - if (header->det != 0) { - /* if (det < 0 then Z points toward camera and triangle is - * counter-clockwise winding. - */ - unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; - - if ((winding & cull_stage(stage)->winding) == 0) { - /* triangle is not culled, pass to next stage */ - stage->next->tri( stage->next, header ); - } - } -} - -static void cull_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct cull_stage *cull = cull_stage(stage); - - cull->winding = stage->draw->rasterizer->cull_mode; - - stage->tri = cull_tri; - stage->tri( stage, header ); -} - - - -static void cull_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void cull_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void cull_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->tri = cull_first_tri; - stage->next->flush( stage->next, flags ); -} - -static void cull_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void cull_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create a new polygon culling stage. - */ -struct draw_stage *draw_cull_stage( struct draw_context *draw ) -{ - struct cull_stage *cull = CALLOC_STRUCT(cull_stage); - - draw_alloc_temp_verts( &cull->stage, 0 ); - - cull->stage.draw = draw; - cull->stage.next = NULL; - cull->stage.point = cull_point; - cull->stage.line = cull_line; - cull->stage.tri = cull_first_tri; - cull->stage.flush = cull_flush; - cull->stage.reset_stipple_counter = cull_reset_stipple_counter; - cull->stage.destroy = cull_destroy; - - return &cull->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c deleted file mode 100644 index 54baa1fbc9..0000000000 --- a/src/gallium/auxiliary/draw/draw_flatshade.c +++ /dev/null @@ -1,248 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" - - -/** subclass of draw_stage */ -struct flat_stage -{ - struct draw_stage stage; - - uint num_color_attribs; - uint color_attribs[4]; /* front/back primary/secondary colors */ -}; - - -static INLINE struct flat_stage * -flat_stage(struct draw_stage *stage) -{ - return (struct flat_stage *) stage; -} - - -/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ -static INLINE void copy_colors( struct draw_stage *stage, - struct vertex_header *dst, - const struct vertex_header *src ) -{ - const struct flat_stage *flat = flat_stage(stage); - uint i; - for (i = 0; i < flat->num_color_attribs; i++) { - const uint attr = flat->color_attribs[i]; - COPY_4FV(dst->data[attr], src->data[attr]); - } -} - - -/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ -static INLINE void copy_colors2( struct draw_stage *stage, - struct vertex_header *dst0, - struct vertex_header *dst1, - const struct vertex_header *src ) -{ - const struct flat_stage *flat = flat_stage(stage); - uint i; - for (i = 0; i < flat->num_color_attribs; i++) { - const uint attr = flat->color_attribs[i]; - COPY_4FV(dst0->data[attr], src->data[attr]); - COPY_4FV(dst1->data[attr], src->data[attr]); - } -} - - -/** - * Flatshade tri. Required for clipping and when unfilled tris are - * active, otherwise handled by hardware. - */ -static void flatshade_tri_0( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = header->v[0]; - tmp.v[1] = dup_vert(stage, header->v[1], 0); - tmp.v[2] = dup_vert(stage, header->v[2], 1); - - copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]); - - stage->next->tri( stage->next, &tmp ); -} - - -static void flatshade_tri_2( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = dup_vert(stage, header->v[1], 1); - tmp.v[2] = header->v[2]; - - copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); - - stage->next->tri( stage->next, &tmp ); -} - - - - - -/** - * Flatshade line. Required for clipping. - */ -static void flatshade_line_0( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.v[0] = header->v[0]; - tmp.v[1] = dup_vert(stage, header->v[1], 0); - - copy_colors(stage, tmp.v[1], tmp.v[0]); - - stage->next->line( stage->next, &tmp ); -} - -static void flatshade_line_1( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = header->v[1]; - - copy_colors(stage, tmp.v[0], tmp.v[1]); - - stage->next->line( stage->next, &tmp ); -} - - -/* Flatshade point -- passthrough. - */ -static void flatshade_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void flatshade_init_state( struct draw_stage *stage ) -{ - struct flat_stage *flat = flat_stage(stage); - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint i; - - /* Find which vertex shader outputs are colors, make a list */ - flat->num_color_attribs = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || - vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - flat->color_attribs[flat->num_color_attribs++] = i; - } - } - - /* Choose flatshade routine according to provoking vertex: - */ - if (stage->draw->rasterizer->flatshade_first) { - stage->line = flatshade_line_0; - stage->tri = flatshade_tri_0; - } - else { - stage->line = flatshade_line_1; - stage->tri = flatshade_tri_2; - } -} - -static void flatshade_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - flatshade_init_state( stage ); - stage->tri( stage, header ); -} - -static void flatshade_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - flatshade_init_state( stage ); - stage->line( stage, header ); -} - - -static void flatshade_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = flatshade_first_tri; - stage->line = flatshade_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void flatshade_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void flatshade_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create flatshading drawing stage. - */ -struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) -{ - struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); - - draw_alloc_temp_verts( &flatshade->stage, 2 ); - - flatshade->stage.draw = draw; - flatshade->stage.next = NULL; - flatshade->stage.point = flatshade_point; - flatshade->stage.line = flatshade_first_line; - flatshade->stage.tri = flatshade_first_tri; - flatshade->stage.flush = flatshade_flush; - flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; - flatshade->stage.destroy = flatshade_destroy; - - return &flatshade->stage; -} - - diff --git a/src/gallium/auxiliary/draw/draw_offset.c b/src/gallium/auxiliary/draw/draw_offset.c deleted file mode 100644 index dbc676deae..0000000000 --- a/src/gallium/auxiliary/draw/draw_offset.c +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/** - * \brief polygon offset state - * - * \author Keith Whitwell - * \author Brian Paul - */ - -#include "pipe/p_util.h" -#include "draw_private.h" - - - -struct offset_stage { - struct draw_stage stage; - - float scale; - float units; -}; - - - -static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) -{ - return (struct offset_stage *) stage; -} - - - - - -/** - * Offset tri Z. Some hardware can handle this, but not usually when - * doing unfilled rendering. - */ -static void do_offset_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct offset_stage *offset = offset_stage(stage); - float inv_det = 1.0f / header->det; - - /* Window coords: - */ - float *v0 = header->v[0]->data[0]; - float *v1 = header->v[1]->data[0]; - float *v2 = header->v[2]->data[0]; - - /* edge vectors e = v0 - v2, f = v1 - v2 */ - float ex = v0[0] - v2[0]; - float ey = v0[1] - v2[1]; - float ez = v0[2] - v2[2]; - float fx = v1[0] - v2[0]; - float fy = v1[1] - v2[1]; - float fz = v1[2] - v2[2]; - - /* (a,b) = cross(e,f).xy */ - float a = ey*fz - ez*fy; - float b = ez*fx - ex*fz; - - float dzdx = FABSF(a * inv_det); - float dzdy = FABSF(b * inv_det); - - float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; - - /* - * Note: we're applying the offset and clamping per-vertex. - * Ideally, the offset is applied per-fragment prior to fragment shading. - */ - v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f); - v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f); - v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f); - - stage->next->tri( stage->next, header ); -} - - -static void offset_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - tmp.v[0] = dup_vert(stage, header->v[0], 0); - tmp.v[1] = dup_vert(stage, header->v[1], 1); - tmp.v[2] = dup_vert(stage, header->v[2], 2); - - do_offset_tri( stage, &tmp ); -} - - -static void offset_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct offset_stage *offset = offset_stage(stage); - float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ - - offset->units = stage->draw->rasterizer->offset_units * mrd; - offset->scale = stage->draw->rasterizer->offset_scale; - - stage->tri = offset_tri; - stage->tri( stage, header ); -} - - -static void offset_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void offset_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void offset_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->tri = offset_first_tri; - stage->next->flush( stage->next, flags ); -} - - -static void offset_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void offset_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create polygon offset drawing stage. - */ -struct draw_stage *draw_offset_stage( struct draw_context *draw ) -{ - struct offset_stage *offset = CALLOC_STRUCT(offset_stage); - - draw_alloc_temp_verts( &offset->stage, 3 ); - - offset->stage.draw = draw; - offset->stage.next = NULL; - offset->stage.point = offset_point; - offset->stage.line = offset_line; - offset->stage.tri = offset_first_tri; - offset->stage.flush = offset_flush; - offset->stage.reset_stipple_counter = offset_reset_stipple_counter; - offset->stage.destroy = offset_destroy; - - return &offset->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c new file mode 100644 index 0000000000..e8d2a45102 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -0,0 +1,859 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * AA line stage: AA lines are converted to texture mapped triangles. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + +/** + * Max texture level for the alpha texture used for antialiasing + */ +#define MAX_TEXTURE_LEVEL 5 /* 32 x 32 */ + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aaline_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *aaline_fs; + void *aapoint_fs; /* not yet */ + void *sprite_fs; /* not yet */ + uint sampler_unit; + int generic_attrib; /**< texcoord/generic used for texture */ +}; + + +/** + * Subclass of draw_stage + */ +struct aaline_stage +{ + struct draw_stage stage; + + float half_line_width; + + /** For AA lines, this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + void *sampler_cso; + struct pipe_texture *texture; + uint num_samplers; + uint num_textures; + + + /* + * Currently bound state + */ + struct aaline_fragment_shader *fs; + struct { + void *sampler[PIPE_MAX_SAMPLERS]; + struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, + void **); + void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, + struct pipe_texture **); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + uint samplersUsed; /**< bitfield of samplers used */ + int freeSampler; /** an available sampler for the pstipple */ + int maxInput, maxGeneric; /**< max input index found */ + int colorTemp, texTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->samplersUsed |= 1 << i; + } + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. + */ +static int +free_bit(uint bitfield) +{ + int i; + for (i = 0; i < 32; i++) { + if ((bitfield & (1 << i)) == 0) + return i; + } + return -1; +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + uint i; + + /* find free sampler */ + aactx->freeSampler = free_bit(aactx->samplersUsed); + if (aactx->freeSampler >= PIPE_MAX_SAMPLERS) + aactx->freeSampler = PIPE_MAX_SAMPLERS - 1; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else if (aactx->texTemp < 0) + aactx->texTemp = i; + else + break; + } + } + assert(aactx->colorTemp >= 0); + assert(aactx->texTemp >= 0); + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->maxInput + 1; + ctx->emit_declaration(ctx, &decl); + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->freeSampler; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->texTemp; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END && + aactx->colorOutput != -1) { + struct tgsi_full_instruction newInst; + + /* TEX */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler; + + ctx->emit_instruction(ctx, &newInst); + + /* MOV rgb */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL alpha */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp; + ctx->emit_instruction(ctx, &newInst); + + /* END */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_END; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + + ctx->emit_instruction(ctx, inst); + } +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aaline_fs(struct aaline_stage *aaline) +{ + const struct pipe_shader_state *orig_fs = &aaline->fs->state; + //struct draw_context *draw = aaline->stage.draw; + struct pipe_shader_state aaline_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aaline_fs = *orig_fs; /* copy to init */ + aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aaline_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(aaline_fs.tokens, 0); +#endif + + aaline->fs->sampler_unit = transform.freeSampler; + + aaline->fs->aaline_fs + = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); + + aaline->fs->generic_attrib = transform.maxGeneric + 1; +} + + +/** + * Create the texture map we'll use for antialiasing the lines. + */ +static void +aaline_create_texture(struct aaline_stage *aaline) +{ + struct pipe_context *pipe = aaline->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_texture texTemp; + uint level; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = MAX_TEXTURE_LEVEL; + texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + aaline->texture = screen->texture_create(screen, &texTemp); + + /* Fill in mipmap images. + * Basically each level is solid opaque, except for the outermost + * texels which are zero. Special case the 1x1 and 2x2 levels. + */ + for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) { + struct pipe_surface *surface; + const uint size = aaline->texture->width[level]; + ubyte *data; + uint i, j; + + 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); + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + ubyte d; + if (size == 1) { + d = 255; + } + else if (size == 2) { + d = 200; /* tuneable */ + } + else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) { + d = 0; + } + else { + d = 255; + } + data[i * surface->pitch + j] = d; + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); + } +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +aaline_create_sampler(struct aaline_stage *aaline) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = aaline->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = MAX_TEXTURE_LEVEL; + + aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aaline_fragment_shader(struct aaline_stage *aaline) +{ + if (!aaline->fs->aaline_fs) { + generate_aaline_fs(aaline); + } + aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); +} + + + +static INLINE struct aaline_stage * +aaline_stage( struct draw_stage *stage ) +{ + return (struct aaline_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad, using geometry which will + * fullfill GL's antialiased line requirements. + */ +static void +aaline_line(struct draw_stage *stage, struct prim_header *header) +{ + const struct aaline_stage *aaline = aaline_stage(stage); + const float half_width = aaline->half_line_width; + struct prim_header tri; + struct vertex_header *v[8]; + uint texPos = aaline->tex_slot; + float *pos, *tex; + float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0]; + float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1]; + double a = atan2(dy, dx); + float c_a = (float) cos(a), s_a = (float) sin(a); + uint i; + + /* XXX the ends of lines aren't quite perfect yet, but probably passable */ + dx = 0.5F * half_width; + dy = half_width; + + /* allocate/dup new verts */ + for (i = 0; i < 8; i++) { + v[i] = dup_vert(stage, header->v[i/4], i); + } + + /* + * Quad strip for line from v0 to v1 (*=endpoints): + * + * 1 3 5 7 + * +---+---------------------+---+ + * | | + * | *v0 v1* | + * | | + * +---+---------------------+---+ + * 0 2 4 6 + */ + + /* new verts */ + pos = v[0]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[1]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[2]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[3]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + pos = v[4]->data[0]; + pos[0] += (-dx * c_a - dy * s_a); + pos[1] += (-dx * s_a + dy * c_a); + + pos = v[5]->data[0]; + pos[0] += (-dx * c_a - -dy * s_a); + pos[1] += (-dx * s_a + -dy * c_a); + + pos = v[6]->data[0]; + pos[0] += ( dx * c_a - dy * s_a); + pos[1] += ( dx * s_a + dy * c_a); + + pos = v[7]->data[0]; + pos[0] += ( dx * c_a - -dy * s_a); + pos[1] += ( dx * s_a + -dy * c_a); + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, 0, 0, 0, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 0, 1, 0, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[4]->data[texPos]; + ASSIGN_4V(tex, .5, 0, 0, 1); + + tex = v[5]->data[texPos]; + ASSIGN_4V(tex, .5, 1, 0, 1); + + tex = v[6]->data[texPos]; + ASSIGN_4V(tex, 1, 0, 0, 1); + + tex = v[7]->data[texPos]; + ASSIGN_4V(tex, 1, 1, 0, 1); + + /* emit 6 tris for the quad strip */ + tri.v[0] = v[2]; tri.v[1] = v[1]; tri.v[2] = v[0]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[3]; tri.v[1] = v[1]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[4]; tri.v[1] = v[3]; tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[5]; tri.v[1] = v[3]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[6]; tri.v[1] = v[5]; tri.v[2] = v[4]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[7]; tri.v[1] = v[5]; tri.v[2] = v[6]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aaline_first_line(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aaline_stage *aaline = aaline_stage(stage); + struct draw_context *draw = stage->draw; + struct pipe_context *pipe = aaline->pipe; + uint num_samplers; + + assert(draw->rasterizer->line_smooth); + + if (draw->rasterizer->line_width <= 3.0) + aaline->half_line_width = 1.5f; + else + aaline->half_line_width = 0.5f * draw->rasterizer->line_width; + + /* + * Bind (generate) our fragprog, sampler and texture + */ + bind_aaline_fragment_shader(aaline); + + /* update vertex attrib info */ + aaline->tex_slot = draw->num_vs_outputs; + assert(aaline->tex_slot > 0); /* output[0] is vertex pos */ + + /* advertise the extra post-transformed vertex attribute */ + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib; + draw->extra_vp_outputs.slot = aaline->tex_slot; + + /* how many samplers? */ + /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ + num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); + num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1); + + aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; + pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], + aaline->texture); + + aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); + + /* now really draw first line */ + stage->line = aaline_line; + stage->line(stage, header); +} + + +static void +aaline_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aaline_stage *aaline = aaline_stage(stage); + struct pipe_context *pipe = aaline->pipe; + + stage->line = aaline_first_line; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + aaline->driver_bind_sampler_states(pipe, aaline->num_samplers, + aaline->state.sampler); + aaline->driver_set_sampler_textures(pipe, aaline->num_textures, + aaline->state.texture); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aaline_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aaline_destroy(struct draw_stage *stage) +{ + struct aaline_stage *aaline = aaline_stage(stage); + + aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); + + pipe_texture_release(&aaline->texture); + + draw_free_temp_verts( stage ); + + FREE( stage ); +} + + +static struct aaline_stage * +draw_aaline_stage(struct draw_context *draw) +{ + struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); + + draw_alloc_temp_verts( &aaline->stage, 8 ); + + aaline->stage.draw = draw; + aaline->stage.next = NULL; + aaline->stage.point = passthrough_point; + aaline->stage.line = aaline_first_line; + aaline->stage.tri = passthrough_tri; + aaline->stage.flush = aaline_flush; + aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; + aaline->stage.destroy = aaline_destroy; + + return aaline; +} + + +static struct aaline_stage * +aaline_stage_from_pipe(struct pipe_context *pipe) +{ + struct draw_context *draw = (struct draw_context *) pipe->draw; + return aaline_stage(draw->pipeline.aaline); +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aaline_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); + } + + return aafs; +} + + +static void +aaline_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* save current */ + aaline->fs = aafs; + /* pass-through */ + aaline->driver_bind_fs_state(aaline->pipe, + (aafs ? aafs->driver_fs : NULL)); +} + + +static void +aaline_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs; + /* pass-through */ + aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +aaline_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + /* save current */ + memcpy(aaline->state.sampler, sampler, num * sizeof(void *)); + aaline->num_samplers = num; + /* pass-through */ + aaline->driver_bind_sampler_states(aaline->pipe, num, sampler); +} + + +static void +aaline_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) +{ + struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); + uint i; + + /* save current */ + for (i = 0; i < num; i++) { + pipe_texture_reference(&aaline->state.texture[i], texture[i]); + } + aaline->num_textures = num; + + /* pass-through */ + aaline->driver_set_sampler_textures(aaline->pipe, num, texture); +} + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) +{ + struct aaline_stage *aaline; + + pipe->draw = (void *) draw; + + /* + * Create / install AA line drawing / prim stage + */ + aaline = draw_aaline_stage( draw ); + assert(aaline); + draw->pipeline.aaline = &aaline->stage; + + aaline->pipe = pipe; + + /* create special texture, sampler state */ + aaline_create_texture(aaline); + aaline_create_sampler(aaline); + + /* save original driver functions */ + aaline->driver_create_fs_state = pipe->create_fs_state; + aaline->driver_bind_fs_state = pipe->bind_fs_state; + aaline->driver_delete_fs_state = pipe->delete_fs_state; + + aaline->driver_bind_sampler_states = pipe->bind_sampler_states; + aaline->driver_set_sampler_textures = pipe->set_sampler_textures; + + /* override the driver's functions */ + pipe->create_fs_state = aaline_create_fs_state; + pipe->bind_fs_state = aaline_bind_fs_state; + pipe->delete_fs_state = aaline_delete_fs_state; + + pipe->bind_sampler_states = aaline_bind_sampler_states; + pipe->set_sampler_textures = aaline_set_sampler_textures; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c new file mode 100644 index 0000000000..e84d380e50 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -0,0 +1,846 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * AA point stage: AA points are converted to quads and rendered with a + * special fragment shader. Another approach would be to use a texture + * map image of a point, but experiments indicate the quality isn't nearly + * as good as this approach. + * + * Note: this looks a lot like draw_aaline.c but there's actually little + * if any code that can be shared. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_vs.h" + + +/* + * Enabling NORMALIZE might give _slightly_ better results. + * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or + * d=x*x+y*y. Since we're working with a unit circle, the later seems + * close enough and saves some costly instructions. + */ +#define NORMALIZE 0 + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct aapoint_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; /**< the regular shader */ + void *aapoint_fs; /**< the aa point-augmented shader */ + int generic_attrib; /**< The generic input attrib/texcoord we'll use */ +}; + + +/** + * Subclass of draw_stage + */ +struct aapoint_stage +{ + struct draw_stage stage; + + int psize_slot; + float radius; + + /** this is the vertex attrib slot for the new texcoords */ + uint tex_slot; + + /* + * Currently bound state + */ + struct aapoint_fragment_shader *fs; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct aa_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int colorOutput; /**< which output is the primary color */ + int maxInput, maxGeneric; /**< max input index found */ + int tmp0, colorTemp; /**< temp registers */ + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for two free temp regs and available input reg for new texcoords. + */ +static void +aa_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_OUTPUT && + decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR && + decl->Semantic.SemanticIndex == 0) { + aactx->colorOutput = decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + if ((int) decl->u.DeclarationRange.Last > aactx->maxInput) + aactx->maxInput = decl->u.DeclarationRange.Last; + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC && + (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) { + aactx->maxGeneric = decl->Semantic.SemanticIndex; + } + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + aactx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +aa_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct aa_transform_context *aactx = (struct aa_transform_context *) ctx; + struct tgsi_full_instruction newInst; + + if (aactx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + const int texInput = aactx->maxInput + 1; + int tmp0; + uint i; + + /* find two free temp regs */ + for (i = 0; i < 32; i++) { + if ((aactx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (aactx->tmp0 < 0) + aactx->tmp0 = i; + else if (aactx->colorTemp < 0) + aactx->colorTemp = i; + else + break; + } + } + + assert(aactx->colorTemp != aactx->tmp0); + + tmp0 = aactx->tmp0; + + /* declare new generic input/texcoord */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC; + decl.Semantic.SemanticIndex = aactx->maxGeneric + 1; + decl.Declaration.Interpolate = 1; + /* XXX this could be linear... */ + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = texInput; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = tmp0; + ctx->emit_declaration(ctx, &decl); + + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = aactx->colorTemp; + ctx->emit_declaration(ctx, &decl); + + aactx->firstInstruction = FALSE; + + + /* + * Emit code to compute fragment coverage, kill if outside point radius + * + * Temp reg0 usage: + * t0.x = distance of fragment from center point + * t0.y = boolean, is t0.x > 1.0, also misc temp usage + * t0.z = temporary for computing 1/(1-k) value + * t0.w = final coverage value + */ + + /* MUL t0.xy, tex, tex; # compute x^2, y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + ctx->emit_instruction(ctx, &newInst); + + /* ADD t0.x, t0.x, t0.y; # x^2 + y^2 */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_ADD; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + ctx->emit_instruction(ctx, &newInst); + +#if NORMALIZE /* OPTIONAL normalization of length */ + /* RSQ t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RSQ; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.x, t0.x; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + ctx->emit_instruction(ctx, &newInst); +#endif + + /* SGT t0.y, t0.xxxx, t0.wwww; # bool b = d > 1 (NOTE t0.w == 1) */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SGT; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + ctx->emit_instruction(ctx, &newInst); + + /* KILP -t0.yyyy; # if b, KILL */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + + + /* compute coverage factor = (1-d)/(1-k) */ + + /* SUB t0.z, tex.w, tex.z; # m = 1 - k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* RCP t0.z, t0.z; # t0.z = 1 / m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_RCP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SUB t0.y, 1, t0.x; # d = 1 - d */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SUB; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + ctx->emit_instruction(ctx, &newInst); + + /* MUL t0.w, t0.y, t0.z; # coverage = d * m */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* SLE t0.y, t0.x, tex.z; # bool b = distance <= k */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_SLE; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z; + ctx->emit_instruction(ctx, &newInst); + + /* CMP t0.w, -t0.y, tex.w, t0.w; + * # if -t0.y < 0 then + * t0.w = 1 + * else + * t0.w = t0.w + */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_CMP; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = tmp0; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 3; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[1].SrcRegister.Index = texInput; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W; + newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W; + ctx->emit_instruction(ctx, &newInst); + + } + + if (inst->Instruction.Opcode == TGSI_OPCODE_END) { + /* add alpha modulation code at tail of program */ + + /* MOV result.color.xyz, colorTemp; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MOV; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + ctx->emit_instruction(ctx, &newInst); + + /* MUL result.color.w, colorTemp, tmp0.w; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT; + newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput; + newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0; + ctx->emit_instruction(ctx, &newInst); + } + else { + /* Not an END instruction. + * Look for writes to result.color and replace with colorTemp reg. + */ + uint i; + + for (i = 0; i < inst->Instruction.NumDstRegs; i++) { + struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i]; + if (dst->DstRegister.File == TGSI_FILE_OUTPUT && + dst->DstRegister.Index == aactx->colorOutput) { + dst->DstRegister.File = TGSI_FILE_TEMPORARY; + dst->DstRegister.Index = aactx->colorTemp; + } + } + } + + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for drawing AA lines. + * This will be the user's shader plus some texture/modulate instructions. + */ +static void +generate_aapoint_fs(struct aapoint_stage *aapoint) +{ + const struct pipe_shader_state *orig_fs = &aapoint->fs->state; + struct pipe_shader_state aapoint_fs; + struct aa_transform_context transform; + +#define MAX 1000 + + aapoint_fs = *orig_fs; /* copy to init */ + aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.colorOutput = -1; + transform.maxInput = -1; + transform.maxGeneric = -1; + transform.colorTemp = -1; + transform.tmp0 = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = aa_transform_inst; + transform.base.transform_declaration = aa_transform_decl; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) aapoint_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + printf("draw_aapoint, orig shader:\n"); + tgsi_dump(orig_fs->tokens, 0); + printf("draw_aapoint, new shader:\n"); + tgsi_dump(aapoint_fs.tokens, 0); +#endif + + aapoint->fs->aapoint_fs + = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); + + aapoint->fs->generic_attrib = transform.maxGeneric + 1; +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) +{ + if (!aapoint->fs->aapoint_fs) { + generate_aapoint_fs(aapoint); + } + aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); +} + + + +static INLINE struct aapoint_stage * +aapoint_stage( struct draw_stage *stage ) +{ + return (struct aapoint_stage *) stage; +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw an AA point by drawing a quad. + */ +static void +aapoint_point(struct draw_stage *stage, struct prim_header *header) +{ + const struct aapoint_stage *aapoint = aapoint_stage(stage); + struct prim_header tri; + struct vertex_header *v[4]; + uint texPos = aapoint->tex_slot; + float radius, *pos, *tex; + uint i; + float k; + + if (aapoint->psize_slot >= 0) { + radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0]; + } + else { + radius = aapoint->radius; + } + + /* + * Note: the texcoords (generic attrib, really) we use are special: + * The S and T components simply vary from -1 to +1. + * The R component is k, below. + * The Q component is 1.0 and will used as a handy constant in the + * fragment shader. + */ + + /* + * k is the threshold distance from the point's center at which + * we begin alpha attenuation (the coverage value). + * Operating within a unit circle, we'll compute the fragment's + * distance 'd' from the center point using the texcoords. + * IF d > 1.0 THEN + * KILL fragment + * ELSE IF d > k THEN + * compute coverage in [0,1] proportional to d in [k, 1]. + * ELSE + * coverage = 1.0; // full coverage + * ENDIF + * + * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to + * avoid using IF/ELSE/ENDIF TGSI opcodes. + */ + +#if !NORMALIZE + k = 1.0f / radius; + k = 1.0f - 2.0f * k + k * k; +#else + k = 1.0f - 1.0f / radius; +#endif + + /* allocate/dup new verts */ + for (i = 0; i < 4; i++) { + v[i] = dup_vert(stage, header->v[0], i); + } + + /* new verts */ + pos = v[0]->data[0]; + pos[0] -= radius; + pos[1] -= radius; + + pos = v[1]->data[0]; + pos[0] += radius; + pos[1] -= radius; + + pos = v[2]->data[0]; + pos[0] += radius; + pos[1] += radius; + + pos = v[3]->data[0]; + pos[0] -= radius; + pos[1] += radius; + + /* new texcoords */ + tex = v[0]->data[texPos]; + ASSIGN_4V(tex, -1, -1, k, 1); + + tex = v[1]->data[texPos]; + ASSIGN_4V(tex, 1, -1, k, 1); + + tex = v[2]->data[texPos]; + ASSIGN_4V(tex, 1, 1, k, 1); + + tex = v[3]->data[texPos]; + ASSIGN_4V(tex, -1, 1, k, 1); + + /* emit 2 tris for the quad strip */ + tri.v[0] = v[0]; + tri.v[1] = v[1]; + tri.v[2] = v[2]; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v[0]; + tri.v[1] = v[2]; + tri.v[2] = v[3]; + stage->next->tri( stage->next, &tri ); +} + + +static void +aapoint_first_point(struct draw_stage *stage, struct prim_header *header) +{ + auto struct aapoint_stage *aapoint = aapoint_stage(stage); + struct draw_context *draw = stage->draw; + + assert(draw->rasterizer->point_smooth); + + if (draw->rasterizer->point_size <= 2.0) + aapoint->radius = 1.0; + else + aapoint->radius = 0.5f * draw->rasterizer->point_size; + + /* + * Bind (generate) our fragprog. + */ + bind_aapoint_fragment_shader(aapoint); + + /* update vertex attrib info */ + aapoint->tex_slot = draw->num_vs_outputs; + assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */ + + draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC; + draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib; + draw->extra_vp_outputs.slot = aapoint->tex_slot; + + /* find psize slot in post-transform vertex */ + aapoint->psize_slot = -1; + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + aapoint->psize_slot = i; + break; + } + } + } + + /* now really draw first line */ + stage->point = aapoint_point; + stage->point(stage, header); +} + + +static void +aapoint_flush(struct draw_stage *stage, unsigned flags) +{ + struct draw_context *draw = stage->draw; + struct aapoint_stage *aapoint = aapoint_stage(stage); + struct pipe_context *pipe = aapoint->pipe; + + stage->point = aapoint_first_point; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs); + + draw->extra_vp_outputs.slot = 0; +} + + +static void +aapoint_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +aapoint_destroy(struct draw_stage *stage) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct aapoint_stage * +draw_aapoint_stage(struct draw_context *draw) +{ + struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); + + draw_alloc_temp_verts( &aapoint->stage, 4 ); + + aapoint->stage.draw = draw; + aapoint->stage.next = NULL; + aapoint->stage.point = aapoint_first_point; + aapoint->stage.line = passthrough_line; + aapoint->stage.tri = passthrough_tri; + aapoint->stage.flush = aapoint_flush; + aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; + aapoint->stage.destroy = aapoint_destroy; + + return aapoint; +} + + +static struct aapoint_stage * +aapoint_stage_from_pipe(struct pipe_context *pipe) +{ + struct draw_context *draw = (struct draw_context *) pipe->draw; + return aapoint_stage(draw->pipeline.aapoint); +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +aapoint_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); + } + + return aafs; +} + + +static void +aapoint_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* save current */ + aapoint->fs = aafs; + /* pass-through */ + aapoint->driver_bind_fs_state(aapoint->pipe, + (aafs ? aafs->driver_fs : NULL)); +} + + +static void +aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); + struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs; + /* pass-through */ + aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs); + FREE(aafs); +} + + +/** + * Called by drivers that want to install this AA point prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA points. + */ +void +draw_install_aapoint_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct aapoint_stage *aapoint; + + pipe->draw = (void *) draw; + + /* + * Create / install AA point drawing / prim stage + */ + aapoint = draw_aapoint_stage( draw ); + assert(aapoint); + draw->pipeline.aapoint = &aapoint->stage; + + aapoint->pipe = pipe; + + /* save original driver functions */ + aapoint->driver_create_fs_state = pipe->create_fs_state; + aapoint->driver_bind_fs_state = pipe->bind_fs_state; + aapoint->driver_delete_fs_state = pipe->delete_fs_state; + + /* override the driver's functions */ + pipe->create_fs_state = aapoint_create_fs_state; + pipe->bind_fs_state = aapoint_bind_fs_state; + pipe->delete_fs_state = aapoint_delete_fs_state; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c new file mode 100644 index 0000000000..0ac3a240e5 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -0,0 +1,503 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * \brief Clipping stage + * + * \author Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw_context.h" +#include "draw_vs.h" + + +#ifndef IS_NEGATIVE +#define IS_NEGATIVE(X) ((X) < 0.0) +#endif + +#ifndef DIFFERENT_SIGNS +#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F) +#endif + +#ifndef MAX_CLIPPED_VERTICES +#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1) +#endif + + + +struct clipper { + struct draw_stage stage; /**< base class */ + + /* Basically duplicate some of the flatshading logic here: + */ + boolean flat; + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ + + float (*plane)[4]; +}; + + +/* This is a bit confusing: + */ +static INLINE struct clipper *clipper_stage( struct draw_stage *stage ) +{ + return (struct clipper *)stage; +} + + +#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) + + +/* All attributes are float[4], so this is easy: + */ +static void interp_attr( float *fdst, + float t, + const float *fin, + const float *fout ) +{ + fdst[0] = LINTERP( t, fout[0], fin[0] ); + fdst[1] = LINTERP( t, fout[1], fin[1] ); + fdst[2] = LINTERP( t, fout[2], fin[2] ); + fdst[3] = LINTERP( t, fout[3], fin[3] ); +} + +static void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct clipper *clipper = clipper_stage(stage); + uint i; + for (i = 0; i < clipper->num_color_attribs; i++) { + const uint attr = clipper->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + + +/* Interpolate between two vertices to produce a third. + */ +static void interp( const struct clipper *clip, + struct vertex_header *dst, + float t, + const struct vertex_header *out, + const struct vertex_header *in ) +{ + const unsigned nr_attrs = clip->stage.draw->num_vs_outputs; + unsigned j; + + /* Vertex header. + */ + { + dst->clipmask = 0; + dst->edgeflag = 0; + dst->pad = 0; + dst->vertex_id = UNDEFINED_VERTEX_ID; + } + + /* Clip coordinates: interpolate normally + */ + { + interp_attr(dst->clip, t, in->clip, out->clip); + } + + /* Do the projective divide and insert window coordinates: + */ + { + const float *pos = dst->clip; + const float *scale = clip->stage.draw->viewport.scale; + const float *trans = clip->stage.draw->viewport.translate; + const float oow = 1.0f / pos[3]; + + dst->data[0][0] = pos[0] * oow * scale[0] + trans[0]; + dst->data[0][1] = pos[1] * oow * scale[1] + trans[1]; + dst->data[0][2] = pos[2] * oow * scale[2] + trans[2]; + dst->data[0][3] = oow; + } + + /* Other attributes + * Note: start at 1 to skip winpos (data[0]) since we just computed + * it above. + */ + for (j = 1; j < nr_attrs; j++) { + interp_attr(dst->data[j], t, in->data[j], out->data[j]); + } +} + + +static void emit_poly( struct draw_stage *stage, + struct vertex_header **inlist, + unsigned n, + const struct prim_header *origPrim) +{ + struct prim_header header; + unsigned i; + + /* later stages may need the determinant, but only the sign matters */ + header.det = origPrim->det; + + for (i = 2; i < n; i++) { + header.v[0] = inlist[i-1]; + header.v[1] = inlist[i]; + header.v[2] = inlist[0]; /* keep in v[2] for flatshading */ + + { + unsigned tmp1 = header.v[1]->edgeflag; + unsigned tmp2 = header.v[2]->edgeflag; + + if (i != n-1) header.v[1]->edgeflag = 0; + if (i != 2) header.v[2]->edgeflag = 0; + + header.edgeflags = ((header.v[0]->edgeflag << 0) | + (header.v[1]->edgeflag << 1) | + (header.v[2]->edgeflag << 2)); + + if (0) { + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint j, k; + debug_printf("Clipped tri:\n"); + for (j = 0; j < 3; j++) { + for (k = 0; k < vs->info.num_outputs; k++) { + debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k, + header.v[j]->data[k][0], + header.v[j]->data[k][1], + header.v[j]->data[k][2], + header.v[j]->data[k][3]); + } + } + } + + stage->next->tri( stage->next, &header ); + + header.v[1]->edgeflag = tmp1; + header.v[2]->edgeflag = tmp2; + } + } +} + + + + +/* Clip a triangle against the viewport and user clip planes. + */ +static void +do_clip_tri( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *a[MAX_CLIPPED_VERTICES]; + struct vertex_header *b[MAX_CLIPPED_VERTICES]; + struct vertex_header **inlist = a; + struct vertex_header **outlist = b; + unsigned tmpnr = 0; + unsigned n = 3; + unsigned i; + + inlist[0] = header->v[0]; + inlist[1] = header->v[1]; + inlist[2] = header->v[2]; + + while (clipmask && n >= 3) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + struct vertex_header *vert_prev = inlist[0]; + float dp_prev = dot4( vert_prev->clip, plane ); + unsigned outcount = 0; + + clipmask &= ~(1<clip, plane ); + + if (!IS_NEGATIVE(dp_prev)) { + outlist[outcount++] = vert_prev; + } + + if (DIFFERENT_SIGNS(dp, dp_prev)) { + struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++]; + outlist[outcount++] = new_vert; + + if (IS_NEGATIVE(dp)) { + /* Going out of bounds. Avoid division by zero as we + * know dp != dp_prev from DIFFERENT_SIGNS, above. + */ + float t = dp / (dp - dp_prev); + interp( clipper, new_vert, t, vert, vert_prev ); + + /* Force edgeflag true in this case: + */ + new_vert->edgeflag = 1; + } else { + /* Coming back in. + */ + float t = dp_prev / (dp_prev - dp); + interp( clipper, new_vert, t, vert_prev, vert ); + + /* Copy starting vert's edgeflag: + */ + new_vert->edgeflag = vert_prev->edgeflag; + } + } + + vert_prev = vert; + dp_prev = dp; + } + + { + struct vertex_header **tmp = inlist; + inlist = outlist; + outlist = tmp; + n = outcount; + } + } + + /* If flat-shading, copy color to new provoking vertex. + */ + if (clipper->flat && inlist[0] != header->v[2]) { + if (1) { + inlist[0] = dup_vert(stage, inlist[0], tmpnr++); + } + + copy_colors(stage, inlist[0], header->v[2]); + } + + + + /* Emit the polygon as triangles to the setup stage: + */ + if (n >= 3) + emit_poly( stage, inlist, n, header ); +} + + +/* Clip a line against the viewport and user clip planes. + */ +static void +do_clip_line( struct draw_stage *stage, + struct prim_header *header, + unsigned clipmask ) +{ + const struct clipper *clipper = clipper_stage( stage ); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->clip; + const float *pos1 = v1->clip; + float t0 = 0.0F; + float t1 = 0.0F; + struct prim_header newprim; + + while (clipmask) { + const unsigned plane_idx = ffs(clipmask)-1; + const float *plane = clipper->plane[plane_idx]; + const float dp0 = dot4( pos0, plane ); + const float dp1 = dot4( pos1, plane ); + + if (dp1 < 0.0F) { + float t = dp1 / (dp1 - dp0); + t1 = MAX2(t1, t); + } + + if (dp0 < 0.0F) { + float t = dp0 / (dp0 - dp1); + t0 = MAX2(t0, t); + } + + if (t0 + t1 >= 1.0F) + return; /* discard */ + + clipmask &= ~(1 << plane_idx); /* turn off this plane's bit */ + } + + if (v0->clipmask) { + interp( clipper, stage->tmp[0], t0, v0, v1 ); + + if (clipper->flat) + copy_colors(stage, stage->tmp[0], v0); + + newprim.v[0] = stage->tmp[0]; + } + else { + newprim.v[0] = v0; + } + + if (v1->clipmask) { + interp( clipper, stage->tmp[1], t1, v1, v0 ); + newprim.v[1] = stage->tmp[1]; + } + else { + newprim.v[1] = v1; + } + + stage->next->line( stage->next, &newprim ); +} + + +static void +clip_point( struct draw_stage *stage, + struct prim_header *header ) +{ + if (header->v[0]->clipmask == 0) + stage->next->point( stage->next, header ); +} + + +static void +clip_line( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->line( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask) == 0) { + do_clip_line(stage, header, clipmask); + } + /* else, totally clipped */ +} + + +static void +clip_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + unsigned clipmask = (header->v[0]->clipmask | + header->v[1]->clipmask | + header->v[2]->clipmask); + + if (clipmask == 0) { + /* no clipping needed */ + stage->next->tri( stage->next, header ); + } + else if ((header->v[0]->clipmask & + header->v[1]->clipmask & + header->v[2]->clipmask) == 0) { + do_clip_tri(stage, header, clipmask); + } +} + +/* Update state. Could further delay this until we hit the first + * primitive that really requires clipping. + */ +static void +clip_init_state( struct draw_stage *stage ) +{ + struct clipper *clipper = clipper_stage( stage ); + + clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE; + + if (clipper->flat) { + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint i; + + clipper->num_color_attribs = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + clipper->color_attribs[clipper->num_color_attribs++] = i; + } + } + } + + stage->tri = clip_tri; + stage->line = clip_line; +} + + + +static void clip_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->tri( stage, header ); +} + +static void clip_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + clip_init_state( stage ); + stage->line( stage, header ); +} + + +static void clip_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = clip_first_tri; + stage->line = clip_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void clip_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void clip_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Allocate a new clipper stage. + * \return pointer to new stage object + */ +struct draw_stage *draw_clip_stage( struct draw_context *draw ) +{ + struct clipper *clipper = CALLOC_STRUCT(clipper); + + draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); + + clipper->stage.draw = draw; + clipper->stage.point = clip_point; + clipper->stage.line = clip_first_line; + clipper->stage.tri = clip_first_tri; + clipper->stage.flush = clip_flush; + clipper->stage.reset_stipple_counter = clip_reset_stipple_counter; + clipper->stage.destroy = clip_destroy; + + clipper->plane = draw->plane; + + return &clipper->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c new file mode 100644 index 0000000000..8177b0ac86 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -0,0 +1,150 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * \brief Drawing stage for polygon culling + */ + +/* Authors: Keith Whitwell + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct cull_stage { + struct draw_stage stage; + unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ +}; + + +static INLINE struct cull_stage *cull_stage( struct draw_stage *stage ) +{ + return (struct cull_stage *)stage; +} + + + + +static void cull_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + /* Window coords: */ + const float *v0 = header->v[0]->data[0]; + const float *v1 = header->v[1]->data[0]; + const float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + const float ex = v0[0] - v2[0]; + const float ey = v0[1] - v2[1]; + const float fx = v1[0] - v2[0]; + const float fy = v1[1] - v2[1]; + + /* det = cross(e,f).z */ + header->det = ex * fy - ey * fx; + + if (header->det != 0) { + /* if (det < 0 then Z points toward camera and triangle is + * counter-clockwise winding. + */ + unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; + + if ((winding & cull_stage(stage)->winding) == 0) { + /* triangle is not culled, pass to next stage */ + stage->next->tri( stage->next, header ); + } + } +} + +static void cull_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct cull_stage *cull = cull_stage(stage); + + cull->winding = stage->draw->rasterizer->cull_mode; + + stage->tri = cull_tri; + stage->tri( stage, header ); +} + + + +static void cull_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void cull_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void cull_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = cull_first_tri; + stage->next->flush( stage->next, flags ); +} + +static void cull_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void cull_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create a new polygon culling stage. + */ +struct draw_stage *draw_cull_stage( struct draw_context *draw ) +{ + struct cull_stage *cull = CALLOC_STRUCT(cull_stage); + + draw_alloc_temp_verts( &cull->stage, 0 ); + + cull->stage.draw = draw; + cull->stage.next = NULL; + cull->stage.point = cull_point; + cull->stage.line = cull_line; + cull->stage.tri = cull_first_tri; + cull->stage.flush = cull_flush; + cull->stage.reset_stipple_counter = cull_reset_stipple_counter; + cull->stage.destroy = cull_destroy; + + return &cull->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c new file mode 100644 index 0000000000..54baa1fbc9 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -0,0 +1,248 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" +#include "draw_vs.h" + + +/** subclass of draw_stage */ +struct flat_stage +{ + struct draw_stage stage; + + uint num_color_attribs; + uint color_attribs[4]; /* front/back primary/secondary colors */ +}; + + +static INLINE struct flat_stage * +flat_stage(struct draw_stage *stage) +{ + return (struct flat_stage *) stage; +} + + +/** Copy all the color attributes from 'src' vertex to 'dst' vertex */ +static INLINE void copy_colors( struct draw_stage *stage, + struct vertex_header *dst, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst->data[attr], src->data[attr]); + } +} + + +/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ +static INLINE void copy_colors2( struct draw_stage *stage, + struct vertex_header *dst0, + struct vertex_header *dst1, + const struct vertex_header *src ) +{ + const struct flat_stage *flat = flat_stage(stage); + uint i; + for (i = 0; i < flat->num_color_attribs; i++) { + const uint attr = flat->color_attribs[i]; + COPY_4FV(dst0->data[attr], src->data[attr]); + COPY_4FV(dst1->data[attr], src->data[attr]); + } +} + + +/** + * Flatshade tri. Required for clipping and when unfilled tris are + * active, otherwise handled by hardware. + */ +static void flatshade_tri_0( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = header->v[0]; + tmp.v[1] = dup_vert(stage, header->v[1], 0); + tmp.v[2] = dup_vert(stage, header->v[2], 1); + + copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]); + + stage->next->tri( stage->next, &tmp ); +} + + +static void flatshade_tri_2( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = header->v[2]; + + copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]); + + stage->next->tri( stage->next, &tmp ); +} + + + + + +/** + * Flatshade line. Required for clipping. + */ +static void flatshade_line_0( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.v[0] = header->v[0]; + tmp.v[1] = dup_vert(stage, header->v[1], 0); + + copy_colors(stage, tmp.v[1], tmp.v[0]); + + stage->next->line( stage->next, &tmp ); +} + +static void flatshade_line_1( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = header->v[1]; + + copy_colors(stage, tmp.v[0], tmp.v[1]); + + stage->next->line( stage->next, &tmp ); +} + + +/* Flatshade point -- passthrough. + */ +static void flatshade_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void flatshade_init_state( struct draw_stage *stage ) +{ + struct flat_stage *flat = flat_stage(stage); + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint i; + + /* Find which vertex shader outputs are colors, make a list */ + flat->num_color_attribs = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR || + vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + flat->color_attribs[flat->num_color_attribs++] = i; + } + } + + /* Choose flatshade routine according to provoking vertex: + */ + if (stage->draw->rasterizer->flatshade_first) { + stage->line = flatshade_line_0; + stage->tri = flatshade_tri_0; + } + else { + stage->line = flatshade_line_1; + stage->tri = flatshade_tri_2; + } +} + +static void flatshade_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->tri( stage, header ); +} + +static void flatshade_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + flatshade_init_state( stage ); + stage->line( stage, header ); +} + + +static void flatshade_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = flatshade_first_tri; + stage->line = flatshade_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void flatshade_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void flatshade_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create flatshading drawing stage. + */ +struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) +{ + struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); + + draw_alloc_temp_verts( &flatshade->stage, 2 ); + + flatshade->stage.draw = draw; + flatshade->stage.next = NULL; + flatshade->stage.point = flatshade_point; + flatshade->stage.line = flatshade_first_line; + flatshade->stage.tri = flatshade_first_tri; + flatshade->stage.flush = flatshade_flush; + flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter; + flatshade->stage.destroy = flatshade_destroy; + + return &flatshade->stage; +} + + diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c new file mode 100644 index 0000000000..dbc676deae --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -0,0 +1,186 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * \brief polygon offset state + * + * \author Keith Whitwell + * \author Brian Paul + */ + +#include "pipe/p_util.h" +#include "draw_private.h" + + + +struct offset_stage { + struct draw_stage stage; + + float scale; + float units; +}; + + + +static INLINE struct offset_stage *offset_stage( struct draw_stage *stage ) +{ + return (struct offset_stage *) stage; +} + + + + + +/** + * Offset tri Z. Some hardware can handle this, but not usually when + * doing unfilled rendering. + */ +static void do_offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float inv_det = 1.0f / header->det; + + /* Window coords: + */ + float *v0 = header->v[0]->data[0]; + float *v1 = header->v[1]->data[0]; + float *v2 = header->v[2]->data[0]; + + /* edge vectors e = v0 - v2, f = v1 - v2 */ + float ex = v0[0] - v2[0]; + float ey = v0[1] - v2[1]; + float ez = v0[2] - v2[2]; + float fx = v1[0] - v2[0]; + float fy = v1[1] - v2[1]; + float fz = v1[2] - v2[2]; + + /* (a,b) = cross(e,f).xy */ + float a = ey*fz - ez*fy; + float b = ez*fx - ex*fz; + + float dzdx = FABSF(a * inv_det); + float dzdy = FABSF(b * inv_det); + + float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale; + + /* + * Note: we're applying the offset and clamping per-vertex. + * Ideally, the offset is applied per-fragment prior to fragment shading. + */ + v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f); + v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f); + v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f); + + stage->next->tri( stage->next, header ); +} + + +static void offset_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + tmp.v[0] = dup_vert(stage, header->v[0], 0); + tmp.v[1] = dup_vert(stage, header->v[1], 1); + tmp.v[2] = dup_vert(stage, header->v[2], 2); + + do_offset_tri( stage, &tmp ); +} + + +static void offset_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct offset_stage *offset = offset_stage(stage); + float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */ + + offset->units = stage->draw->rasterizer->offset_units * mrd; + offset->scale = stage->draw->rasterizer->offset_scale; + + stage->tri = offset_tri; + stage->tri( stage, header ); +} + + +static void offset_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void offset_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void offset_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->tri = offset_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void offset_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void offset_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create polygon offset drawing stage. + */ +struct draw_stage *draw_offset_stage( struct draw_context *draw ) +{ + struct offset_stage *offset = CALLOC_STRUCT(offset_stage); + + draw_alloc_temp_verts( &offset->stage, 3 ); + + offset->stage.draw = draw; + offset->stage.next = NULL; + offset->stage.point = offset_point; + offset->stage.line = offset_line; + offset->stage.tri = offset_first_tri; + offset->stage.flush = offset_flush; + offset->stage.reset_stipple_counter = offset_reset_stipple_counter; + offset->stage.destroy = offset_destroy; + + return &offset->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c new file mode 100644 index 0000000000..4dddb72906 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -0,0 +1,746 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * Polygon stipple stage: implement polygon stipple with texture map and + * fragment program. The fragment program samples the texture and does + * a fragment kill for the stipple-failing fragments. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" + +#include "tgsi/util/tgsi_transform.h" +#include "tgsi/util/tgsi_dump.h" + +#include "draw_context.h" +#include "draw_private.h" + + + +/** + * Subclass of pipe_shader_state to carry extra fragment shader info. + */ +struct pstip_fragment_shader +{ + struct pipe_shader_state state; + void *driver_fs; + void *pstip_fs; + uint sampler_unit; +}; + + +/** + * Subclass of draw_stage + */ +struct pstip_stage +{ + struct draw_stage stage; + + void *sampler_cso; + struct pipe_texture *texture; + uint num_samplers; + uint num_textures; + + /* + * Currently bound state + */ + struct pstip_fragment_shader *fs; + struct { + void *samplers[PIPE_MAX_SAMPLERS]; + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + const struct pipe_poly_stipple *stipple; + } state; + + /* + * Driver interface/override functions + */ + void * (*driver_create_fs_state)(struct pipe_context *, + const struct pipe_shader_state *); + void (*driver_bind_fs_state)(struct pipe_context *, void *); + void (*driver_delete_fs_state)(struct pipe_context *, void *); + + void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); + + void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, + struct pipe_texture **); + + void (*driver_set_polygon_stipple)(struct pipe_context *, + const struct pipe_poly_stipple *); + + struct pipe_context *pipe; +}; + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the special AA instructions. + */ +struct pstip_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int wincoordInput; + int maxInput; + uint samplersUsed; /**< bitfield of samplers used */ + int freeSampler; /** an available sampler for the pstipple */ + int texTemp; /**< temp registers */ + int numImmed; + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +pstip_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + pctx->samplersUsed |= 1 << i; + } + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last); + if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) + pctx->wincoordInput = (int) decl->u.DeclarationRange.First; + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->u.DeclarationRange.First; + i <= decl->u.DeclarationRange.Last; i++) { + pctx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +static void +pstip_transform_immed(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *immed) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + pctx->numImmed++; +} + + +/** + * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. + */ +static int +free_bit(uint bitfield) +{ + int i; + for (i = 0; i < 32; i++) { + if ((bitfield & (1 << i)) == 0) + return i; + } + return -1; +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +pstip_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; + + if (pctx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction newInst; + uint i; + int wincoordInput; + + /* find free sampler */ + pctx->freeSampler = free_bit(pctx->samplersUsed); + if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) + pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; + + if (pctx->wincoordInput < 0) + wincoordInput = pctx->maxInput + 1; + else + wincoordInput = pctx->wincoordInput; + + /* find one free temp reg */ + for (i = 0; i < 32; i++) { + if ((pctx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (pctx->texTemp < 0) + pctx->texTemp = i; + else + break; + } + } + assert(pctx->texTemp >= 0); + + if (pctx->wincoordInput < 0) { + /* declare new position input reg */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Semantic = 1; + decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; + decl.Semantic.SemanticIndex = 0; + decl.Declaration.Interpolate = 1; + decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = wincoordInput; + ctx->emit_declaration(ctx, &decl); + } + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = pctx->freeSampler; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.u.DeclarationRange.First = + decl.u.DeclarationRange.Last = pctx->texTemp; + ctx->emit_declaration(ctx, &decl); + + /* emit immediate = {1/32, 1/32, 1, 1} + * The index/position of this immediate will be pctx->numImmed + */ + { + static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; + struct tgsi_full_immediate immed; + uint size = 4; + immed = tgsi_default_full_immediate(); + immed.Immediate.Size = 1 + size; /* one for the token itself */ + immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value; + ctx->emit_immediate(ctx, &immed); + } + + pctx->firstInstruction = FALSE; + + + /* + * Insert new MUL/TEX/KILP instructions at start of program + * Take gl_FragCoord, divide by 32 (stipple size), sample the + * texture and kill fragment if needed. + * + * We'd like to use non-normalized texcoords to index into a RECT + * texture, but we can only use GL_REPEAT wrap mode with normalized + * texcoords. Darn. + */ + + /* MUL texTemp, INPUT[wincoord], 1/32; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; + newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE; + newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed; + ctx->emit_instruction(ctx, &newInst); + + /* TEX texTemp, texTemp, sampler; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; + newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler; + ctx->emit_instruction(ctx, &newInst); + + /* KILP texTemp; # if texTemp < 0, KILL fragment */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KILP; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; + newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; + newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + } + + /* emit this instruction */ + ctx->emit_instruction(ctx, inst); +} + + +/** + * Generate the frag shader we'll use for doing polygon stipple. + * This will be the user's shader prefixed with a TEX and KIL instruction. + */ +static void +generate_pstip_fs(struct pstip_stage *pstip) +{ + const struct pipe_shader_state *orig_fs = &pstip->fs->state; + /*struct draw_context *draw = pstip->stage.draw;*/ + struct pipe_shader_state pstip_fs; + struct pstip_transform_context transform; + +#define MAX 1000 + + pstip_fs = *orig_fs; /* copy to init */ + pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + + memset(&transform, 0, sizeof(transform)); + transform.wincoordInput = -1; + transform.maxInput = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = pstip_transform_inst; + transform.base.transform_declaration = pstip_transform_decl; + transform.base.transform_immediate = pstip_transform_immed; + + tgsi_transform_shader(orig_fs->tokens, + (struct tgsi_token *) pstip_fs.tokens, + MAX, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(orig_fs->tokens, 0); + tgsi_dump(pstip_fs.tokens, 0); +#endif + + pstip->fs->sampler_unit = transform.freeSampler; + assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); + + pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); +} + + +/** + * Load texture image with current stipple pattern. + */ +static void +pstip_update_texture(struct pstip_stage *pstip) +{ + static const uint bit31 = 1 << 31; + struct pipe_context *pipe = pstip->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_surface *surface; + const uint *stipple = pstip->state.stipple->stipple; + uint i, j; + ubyte *data; + + surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); + data = pipe_surface_map(surface); + + /* + * Load alpha texture. + * Note: 0 means keep the fragment, 255 means kill it. + * We'll negate the texel value and use KILP which kills if value + * is negative. + */ + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + if (stipple[i] & (bit31 >> j)) { + /* fragment "on" */ + data[i * surface->pitch + j] = 0; + } + else { + /* fragment "off" */ + data[i * surface->pitch + j] = 255; + } + } + } + + /* unmap */ + pipe_surface_unmap(surface); + pipe_surface_reference(&surface, NULL); + pipe->texture_update(pipe, pstip->texture, 0, 0x1); +} + + +/** + * Create the texture map we'll use for stippling. + */ +static void +pstip_create_texture(struct pstip_stage *pstip) +{ + struct pipe_context *pipe = pstip->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_texture texTemp; + + memset(&texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ + texTemp.last_level = 0; + texTemp.width[0] = 32; + texTemp.height[0] = 32; + texTemp.depth[0] = 1; + texTemp.cpp = 1; + + pstip->texture = screen->texture_create(screen, &texTemp); + assert(pstip->texture->refcount == 1); +} + + +/** + * Create the sampler CSO that'll be used for antialiasing. + * By using a mipmapped texture, we don't have to generate a different + * texture image for each line size. + */ +static void +pstip_create_sampler(struct pstip_stage *pstip) +{ + struct pipe_sampler_state sampler; + struct pipe_context *pipe = pstip->pipe; + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.normalized_coords = 1; + sampler.min_lod = 0.0f; + sampler.max_lod = 0.0f; + + pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); +} + + +/** + * When we're about to draw our first AA line in a batch, this function is + * called to tell the driver to bind our modified fragment shader. + */ +static void +bind_pstip_fragment_shader(struct pstip_stage *pstip) +{ + if (!pstip->fs->pstip_fs) { + generate_pstip_fs(pstip); + } + pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); +} + + + +static INLINE struct pstip_stage * +pstip_stage( struct draw_stage *stage ) +{ + return (struct pstip_stage *) stage; +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + + +static void +passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + + +static void +pstip_first_tri(struct draw_stage *stage, struct prim_header *header) +{ + struct pstip_stage *pstip = pstip_stage(stage); + struct pipe_context *pipe = pstip->pipe; + uint num_samplers; + + assert(stage->draw->rasterizer->poly_stipple_enable); + + /* bind our fragprog */ + bind_pstip_fragment_shader(pstip); + + /* how many samplers? */ + /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ + num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); + num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); + + /* plug in our sampler, texture */ + pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; + pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], + pstip->texture); + + assert(num_samplers <= PIPE_MAX_SAMPLERS); + + pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); + pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); + + /* now really draw first line */ + stage->tri = passthrough_tri; + stage->tri(stage, header); +} + + +static void +pstip_flush(struct draw_stage *stage, unsigned flags) +{ + /*struct draw_context *draw = stage->draw;*/ + struct pstip_stage *pstip = pstip_stage(stage); + struct pipe_context *pipe = pstip->pipe; + + stage->tri = pstip_first_tri; + stage->next->flush( stage->next, flags ); + + /* restore original frag shader */ + pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); + + /* XXX restore original texture, sampler state */ + pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, + pstip->state.samplers); + pstip->driver_set_sampler_textures(pipe, pstip->num_textures, + pstip->state.textures); +} + + +static void +pstip_reset_stipple_counter(struct draw_stage *stage) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +pstip_destroy(struct draw_stage *stage) +{ + struct pstip_stage *pstip = pstip_stage(stage); + + pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); + + pipe_texture_release(&pstip->texture); + + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +static struct pstip_stage * +draw_pstip_stage(struct draw_context *draw) +{ + struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage); + + draw_alloc_temp_verts( &pstip->stage, 8 ); + + pstip->stage.draw = draw; + pstip->stage.next = NULL; + pstip->stage.point = passthrough_point; + pstip->stage.line = passthrough_line; + pstip->stage.tri = pstip_first_tri; + pstip->stage.flush = pstip_flush; + pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; + pstip->stage.destroy = pstip_destroy; + + return pstip; +} + + +static struct pstip_stage * +pstip_stage_from_pipe(struct pipe_context *pipe) +{ + struct draw_context *draw = (struct draw_context *) pipe->draw; + return pstip_stage(draw->pipeline.pstipple); +} + + +/** + * This function overrides the driver's create_fs_state() function and + * will typically be called by the state tracker. + */ +static void * +pstip_create_fs_state(struct pipe_context *pipe, + const struct pipe_shader_state *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader); + + if (aafs) { + aafs->state = *fs; + + /* pass-through */ + aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs); + } + + return aafs; +} + + +static void +pstip_bind_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* save current */ + pstip->fs = aafs; + /* pass-through */ + pstip->driver_bind_fs_state(pstip->pipe, + (aafs ? aafs->driver_fs : NULL)); +} + + +static void +pstip_delete_fs_state(struct pipe_context *pipe, void *fs) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; + /* pass-through */ + pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs); + FREE(aafs); +} + + +static void +pstip_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + uint i; + + /* save current */ + memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); + for (i = num; i < PIPE_MAX_SAMPLERS; i++) { + pstip->state.samplers[i] = NULL; + } + + pstip->num_samplers = num; + /* pass-through */ + pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); +} + + +static void +pstip_set_sampler_textures(struct pipe_context *pipe, + unsigned num, struct pipe_texture **texture) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + uint i; + + /* save current */ + for (i = 0; i < num; i++) { + pipe_texture_reference(&pstip->state.textures[i], texture[i]); + } + for (; i < PIPE_MAX_SAMPLERS; i++) { + pipe_texture_reference(&pstip->state.textures[i], NULL); + } + + pstip->num_textures = num; + + /* pass-through */ + pstip->driver_set_sampler_textures(pstip->pipe, num, texture); +} + + +static void +pstip_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); + /* save current */ + pstip->state.stipple = stipple; + /* pass-through */ + pstip->driver_set_polygon_stipple(pstip->pipe, stipple); + + pstip_update_texture(pstip); +} + + + +/** + * Called by drivers that want to install this AA line prim stage + * into the draw module's pipeline. This will not be used if the + * hardware has native support for AA lines. + */ +void +draw_install_pstipple_stage(struct draw_context *draw, + struct pipe_context *pipe) +{ + struct pstip_stage *pstip; + + pipe->draw = (void *) draw; + + /* + * Create / install AA line drawing / prim stage + */ + pstip = draw_pstip_stage( draw ); + assert(pstip); + draw->pipeline.pstipple = &pstip->stage; + + pstip->pipe = pipe; + + /* create special texture, sampler state */ + pstip_create_texture(pstip); + pstip_create_sampler(pstip); + + /* save original driver functions */ + pstip->driver_create_fs_state = pipe->create_fs_state; + pstip->driver_bind_fs_state = pipe->bind_fs_state; + pstip->driver_delete_fs_state = pipe->delete_fs_state; + + pstip->driver_bind_sampler_states = pipe->bind_sampler_states; + pstip->driver_set_sampler_textures = pipe->set_sampler_textures; + pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; + + /* override the driver's functions */ + pipe->create_fs_state = pstip_create_fs_state; + pipe->bind_fs_state = pstip_bind_fs_state; + pipe->delete_fs_state = pstip_delete_fs_state; + + pipe->bind_sampler_states = pstip_bind_sampler_states; + pipe->set_sampler_textures = pstip_set_sampler_textures; + pipe->set_polygon_stipple = pstip_set_polygon_stipple; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c new file mode 100644 index 0000000000..506f33512c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -0,0 +1,239 @@ +/************************************************************************** + * + * 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 + */ + +/* Implement line stipple by cutting lines up into smaller lines. + * There are hundreds of ways to implement line stipple, this is one + * choice that should work in all situations, requires no state + * manipulations, but with a penalty in terms of large amounts of + * generated geometry. + */ + + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +/** Subclass of draw_stage */ +struct stipple_stage { + struct draw_stage stage; + float counter; + uint pattern; + uint factor; +}; + + +static INLINE struct stipple_stage * +stipple_stage(struct draw_stage *stage) +{ + return (struct stipple_stage *) stage; +} + + +/** + * Compute interpolated vertex attributes for 'dst' at position 't' + * between 'v0' and 'v1'. + * XXX using linear interpolation for all attribs at this time. + */ +static void +screen_interp( struct draw_context *draw, + struct vertex_header *dst, + float t, + const struct vertex_header *v0, + const struct vertex_header *v1 ) +{ + uint attr; + for (attr = 0; attr < draw->num_vs_outputs; attr++) { + const float *val0 = v0->data[attr]; + const float *val1 = v1->data[attr]; + float *newv = dst->data[attr]; + uint i; + for (i = 0; i < 4; i++) { + newv[i] = val0[i] + t * (val1[i] - val0[i]); + } + } +} + + +static void +emit_segment(struct draw_stage *stage, struct prim_header *header, + float t0, float t1) +{ + struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); + struct prim_header newprim = *header; + + if (t0 > 0.0) { + screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); + newprim.v[0] = v0new; + } + + if (t1 < 1.0) { + screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); + newprim.v[1] = v1new; + } + + stage->next->line( stage->next, &newprim ); +} + + +static INLINE unsigned +stipple_test(int counter, ushort pattern, int factor) +{ + int b = (counter / factor) & 0xf; + return (1 << b) & pattern; +} + + +static void +stipple_line(struct draw_stage *stage, struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + const float *pos0 = v0->data[0]; + const float *pos1 = v1->data[0]; + float start = 0; + int state = 0; + + float x0 = pos0[0]; + float x1 = pos1[0]; + float y0 = pos0[1]; + float y1 = pos1[1]; + + float dx = x0 > x1 ? x0 - x1 : x1 - x0; + float dy = y0 > y1 ? y0 - y1 : y1 - y0; + + float length = MAX2(dx, dy); + int i; + + /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. + */ + for (i = 0; i < length; i++) { + int result = stipple_test( (int) stipple->counter+i, + (ushort) stipple->pattern, stipple->factor ); + if (result != state) { + /* changing from "off" to "on" or vice versa */ + if (state) { + if (start != i) { + /* finishing an "on" segment */ + emit_segment( stage, header, start / length, i / length ); + } + } + else { + /* starting an "on" segment */ + start = (float) i; + } + state = result; + } + } + + if (state && start < length) + emit_segment( stage, header, start / length, 1.0 ); + + stipple->counter += length; +} + + +static void +reset_stipple_counter(struct draw_stage *stage) +{ + struct stipple_stage *stipple = stipple_stage(stage); + stipple->counter = 0; + stage->next->reset_stipple_counter( stage->next ); +} + + +static void +stipple_first_line(struct draw_stage *stage, + struct prim_header *header) +{ + struct stipple_stage *stipple = stipple_stage(stage); + struct draw_context *draw = stage->draw; + + stipple->pattern = draw->rasterizer->line_stipple_pattern; + stipple->factor = draw->rasterizer->line_stipple_factor + 1; + + stage->line = stipple_line; + stage->line( stage, header ); +} + + +static void +stipple_flush(struct draw_stage *stage, unsigned flags) +{ + stage->line = stipple_first_line; + stage->next->flush( stage->next, flags ); +} + + +static void +passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point( stage->next, header ); +} + + +static void +passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + +static void +stipple_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create line stippler stage + */ +struct draw_stage *draw_stipple_stage( struct draw_context *draw ) +{ + struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); + + draw_alloc_temp_verts( &stipple->stage, 2 ); + + stipple->stage.draw = draw; + stipple->stage.next = NULL; + stipple->stage.point = passthrough_point; + stipple->stage.line = stipple_first_line; + stipple->stage.tri = passthrough_tri; + stipple->stage.reset_stipple_counter = reset_stipple_counter; + stipple->stage.flush = stipple_flush; + stipple->stage.destroy = stipple_destroy; + + return &stipple->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c new file mode 100644 index 0000000000..01d905c153 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -0,0 +1,203 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_vs.h" + + +struct twoside_stage { + struct draw_stage stage; + float sign; /**< +1 or -1 */ + uint attrib_front0, attrib_back0; + uint attrib_front1, attrib_back1; +}; + + +static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage ) +{ + return (struct twoside_stage *)stage; +} + + + + +/** + * Copy back color(s) to front color(s). + */ +static INLINE struct vertex_header * +copy_bfc( struct twoside_stage *twoside, + const struct vertex_header *v, + unsigned idx ) +{ + struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); + + if (twoside->attrib_back0) { + COPY_4FV(tmp->data[twoside->attrib_front0], + tmp->data[twoside->attrib_back0]); + } + if (twoside->attrib_back1) { + COPY_4FV(tmp->data[twoside->attrib_front1], + tmp->data[twoside->attrib_back1]); + } + + return tmp; +} + + +/* Twoside tri: + */ +static void twoside_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + + if (header->det * twoside->sign < 0.0) { + /* this is a back-facing triangle */ + struct prim_header tmp; + + tmp.det = header->det; + tmp.edgeflags = header->edgeflags; + /* copy back attribs to front attribs */ + tmp.v[0] = copy_bfc(twoside, header->v[0], 0); + tmp.v[1] = copy_bfc(twoside, header->v[1], 1); + tmp.v[2] = copy_bfc(twoside, header->v[2], 2); + + stage->next->tri( stage->next, &tmp ); + } + else { + stage->next->tri( stage->next, header ); + } +} + + +static void twoside_line( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->line( stage->next, header ); +} + + +static void twoside_point( struct draw_stage *stage, + struct prim_header *header ) +{ + /* pass-through */ + stage->next->point( stage->next, header ); +} + + +static void twoside_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct twoside_stage *twoside = twoside_stage(stage); + const struct draw_vertex_shader *vs = stage->draw->vertex_shader; + uint i; + + twoside->attrib_front0 = 0; + twoside->attrib_front1 = 0; + twoside->attrib_back0 = 0; + twoside->attrib_back1 = 0; + + /* Find which vertex shader outputs are front/back colors */ + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { + if (vs->info.output_semantic_index[i] == 0) + twoside->attrib_front0 = i; + else + twoside->attrib_front1 = i; + } + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { + if (vs->info.output_semantic_index[i] == 0) + twoside->attrib_back0 = i; + else + twoside->attrib_back1 = i; + } + } + + if (!twoside->attrib_back0) + twoside->attrib_front0 = 0; + + if (!twoside->attrib_back1) + twoside->attrib_front1 = 0; + + /* + * We'll multiply the primitive's determinant by this sign to determine + * if the triangle is back-facing (negative). + * sign = -1 for CCW, +1 for CW + */ + twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; + + stage->tri = twoside_tri; + stage->tri( stage, header ); +} + + +static void twoside_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->tri = twoside_first_tri; + stage->next->flush( stage->next, flags ); +} + + +static void twoside_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void twoside_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create twoside pipeline stage. + */ +struct draw_stage *draw_twoside_stage( struct draw_context *draw ) +{ + struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); + + draw_alloc_temp_verts( &twoside->stage, 3 ); + + twoside->stage.draw = draw; + twoside->stage.next = NULL; + twoside->stage.point = twoside_point; + twoside->stage.line = twoside_line; + twoside->stage.tri = twoside_first_tri; + twoside->stage.flush = twoside_flush; + twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; + twoside->stage.destroy = twoside_destroy; + + return &twoside->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c new file mode 100644 index 0000000000..b07860cd9e --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -0,0 +1,206 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * \brief Drawing stage for handling glPolygonMode(line/point). + * Convert triangles to points or lines as needed. + */ + +/* Authors: Keith Whitwell + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + + +struct unfilled_stage { + struct draw_stage stage; + + /** [0] = front face, [1] = back face. + * legal values: PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE, + * and PIPE_POLYGON_MODE_POINT, + */ + unsigned mode[2]; +}; + + +static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) +{ + return (struct unfilled_stage *)stage; +} + + + +static void point( struct draw_stage *stage, + struct vertex_header *v0 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + stage->next->point( stage->next, &tmp ); +} + +static void line( struct draw_stage *stage, + struct vertex_header *v0, + struct vertex_header *v1 ) +{ + struct prim_header tmp; + tmp.v[0] = v0; + tmp.v[1] = v1; + stage->next->line( stage->next, &tmp ); +} + + +static void points( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + + if (header->edgeflags & 0x1) point( stage, v0 ); + if (header->edgeflags & 0x2) point( stage, v1 ); + if (header->edgeflags & 0x4) point( stage, v2 ); +} + + +static void lines( struct draw_stage *stage, + struct prim_header *header ) +{ + struct vertex_header *v0 = header->v[0]; + struct vertex_header *v1 = header->v[1]; + struct vertex_header *v2 = header->v[2]; + +#if 0 + assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); + assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); + assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); +#endif + + if (header->edgeflags & 0x4) line( stage, v2, v0 ); + if (header->edgeflags & 0x1) line( stage, v0, v1 ); + if (header->edgeflags & 0x2) line( stage, v1, v2 ); +} + + +/* Unfilled tri: + * + * Note edgeflags in the vertex struct is not sufficient as we will + * need to manipulate them when decomposing primitives??? + */ +static void unfilled_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + unsigned mode = unfilled->mode[header->det >= 0.0]; + + switch (mode) { + case PIPE_POLYGON_MODE_FILL: + stage->next->tri( stage->next, header ); + break; + case PIPE_POLYGON_MODE_LINE: + lines( stage, header ); + break; + case PIPE_POLYGON_MODE_POINT: + points( stage, header ); + break; + default: + assert(0); + } +} + + +static void unfilled_first_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct unfilled_stage *unfilled = unfilled_stage(stage); + + unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ + unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ + + stage->tri = unfilled_tri; + stage->tri( stage, header ); +} + + +static void unfilled_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line( stage->next, header ); +} + + +static void unfilled_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void unfilled_flush( struct draw_stage *stage, + unsigned flags ) +{ + stage->next->flush( stage->next, flags ); + + stage->tri = unfilled_first_tri; +} + + +static void unfilled_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void unfilled_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +/** + * Create unfilled triangle stage. + */ +struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) +{ + struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); + + draw_alloc_temp_verts( &unfilled->stage, 0 ); + + unfilled->stage.draw = draw; + unfilled->stage.next = NULL; + unfilled->stage.tmp = NULL; + unfilled->stage.point = unfilled_point; + unfilled->stage.line = unfilled_line; + unfilled->stage.tri = unfilled_first_tri; + unfilled->stage.flush = unfilled_flush; + unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; + unfilled->stage.destroy = unfilled_destroy; + + return &unfilled->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c new file mode 100644 index 0000000000..e163e078f0 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -0,0 +1,312 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "draw_private.h" + +static boolean points( unsigned prim ) +{ + return (prim == PIPE_PRIM_POINTS); +} + +static boolean lines( unsigned prim ) +{ + return (prim == PIPE_PRIM_LINES || + prim == PIPE_PRIM_LINE_STRIP || + prim == PIPE_PRIM_LINE_LOOP); +} + +static boolean triangles( unsigned prim ) +{ + return prim >= PIPE_PRIM_TRIANGLES; +} + +/** + * Check if we need any special pipeline stages, or whether + * prims/verts can go through untouched. Don't test for bypass + * clipping or vs modes, this function is just about the primitive + * pipeline stages. + */ +boolean +draw_need_pipeline(const struct draw_context *draw, + unsigned int prim ) +{ + /* Don't have to worry about triangles turning into lines/points + * and triggering the pipeline, because we have to trigger the + * pipeline *anyway* if unfilled mode is active. + */ + if (lines(prim)) + { + /* line stipple */ + if (draw->rasterizer->line_stipple_enable && draw->line_stipple) + return TRUE; + + /* wide lines */ + if (draw->rasterizer->line_width > draw->wide_line_threshold) + return TRUE; + + /* AA lines */ + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) + return TRUE; + } + + if (points(prim)) + { + /* large points */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) + return TRUE; + + /* AA points */ + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + return TRUE; + + /* point sprites */ + if (draw->rasterizer->point_sprite && draw->point_sprite) + return TRUE; + } + + + if (triangles(prim)) + { + /* polygon stipple */ + if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) + return TRUE; + + /* unfilled polygons */ + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) + return TRUE; + + /* polygon offset */ + if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) + return TRUE; + + /* two-side lighting */ + if (draw->rasterizer->light_twoside) + return TRUE; + } + + /* polygon cull - this is difficult - hardware can cull just fine + * most of the time (though sometimes CULL_NEITHER is unsupported. + * + * Generally this isn't a reason to require the pipeline, though. + * + if (draw->rasterizer->cull_mode) + return TRUE; + */ + + return FALSE; +} + + + +/** + * Rebuild the rendering pipeline. + */ +static struct draw_stage *validate_pipeline( struct draw_stage *stage ) +{ + struct draw_context *draw = stage->draw; + struct draw_stage *next = draw->pipeline.rasterize; + int need_det = 0; + int precalc_flat = 0; + boolean wide_lines, wide_points; + + /* Set the validate's next stage to the rasterize stage, so that it + * can be found later if needed for flushing. + */ + stage->next = next; + + /* drawing wide lines? */ + wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold + && !draw->rasterizer->line_smooth); + + /* drawing large points? */ + if (draw->rasterizer->point_sprite && draw->point_sprite) + wide_points = TRUE; + else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + wide_points = FALSE; + else if (draw->rasterizer->point_size > draw->wide_point_threshold) + wide_points = TRUE; + else + wide_points = FALSE; + + /* + * NOTE: we build up the pipeline in end-to-start order. + * + * TODO: make the current primitive part of the state and build + * shorter pipelines for lines & points. + */ + + if (draw->rasterizer->line_smooth && draw->pipeline.aaline) { + draw->pipeline.aaline->next = next; + next = draw->pipeline.aaline; + } + + if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) { + draw->pipeline.aapoint->next = next; + next = draw->pipeline.aapoint; + } + + if (wide_lines) { + draw->pipeline.wide_line->next = next; + next = draw->pipeline.wide_line; + precalc_flat = 1; + } + + if (wide_points || draw->rasterizer->point_sprite) { + draw->pipeline.wide_point->next = next; + next = draw->pipeline.wide_point; + } + + if (draw->rasterizer->line_stipple_enable && draw->line_stipple) { + draw->pipeline.stipple->next = next; + next = draw->pipeline.stipple; + precalc_flat = 1; /* only needed for lines really */ + } + + if (draw->rasterizer->poly_stipple_enable + && draw->pipeline.pstipple) { + draw->pipeline.pstipple->next = next; + next = draw->pipeline.pstipple; + } + + if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { + draw->pipeline.unfilled->next = next; + next = draw->pipeline.unfilled; + precalc_flat = 1; /* only needed for triangles really */ + need_det = 1; + } + + if (draw->rasterizer->flatshade && precalc_flat) { + draw->pipeline.flatshade->next = next; + next = draw->pipeline.flatshade; + } + + if (draw->rasterizer->offset_cw || + draw->rasterizer->offset_ccw) { + draw->pipeline.offset->next = next; + next = draw->pipeline.offset; + need_det = 1; + } + + if (draw->rasterizer->light_twoside) { + draw->pipeline.twoside->next = next; + next = draw->pipeline.twoside; + need_det = 1; + } + + /* Always run the cull stage as we calculate determinant there + * also. + * + * This can actually be a win as culling out the triangles can lead + * to less work emitting vertices, smaller vertex buffers, etc. + * It's difficult to say whether this will be true in general. + */ + if (need_det || draw->rasterizer->cull_mode) { + draw->pipeline.cull->next = next; + next = draw->pipeline.cull; + } + + /* Clip stage + */ + if (!draw->rasterizer->bypass_clipping) + { + draw->pipeline.clip->next = next; + next = draw->pipeline.clip; + } + + + draw->pipeline.first = next; + return next; +} + +static void validate_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->tri( pipeline, header ); +} + +static void validate_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->line( pipeline, header ); +} + +static void validate_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->point( pipeline, header ); +} + +static void validate_reset_stipple_counter( struct draw_stage *stage ) +{ + struct draw_stage *pipeline = validate_pipeline( stage ); + pipeline->reset_stipple_counter( pipeline ); +} + +static void validate_flush( struct draw_stage *stage, + unsigned flags ) +{ + /* May need to pass a backend flush on to the rasterize stage. + */ + if (stage->next) + stage->next->flush( stage->next, flags ); +} + + +static void validate_destroy( struct draw_stage *stage ) +{ + FREE( stage ); +} + + +/** + * Create validate pipeline stage. + */ +struct draw_stage *draw_validate_stage( struct draw_context *draw ) +{ + struct draw_stage *stage = CALLOC_STRUCT(draw_stage); + + stage->draw = draw; + stage->next = NULL; + stage->point = validate_point; + stage->line = validate_line; + stage->tri = validate_tri; + stage->flush = validate_flush; + stage->reset_stipple_counter = validate_reset_stipple_counter; + stage->destroy = validate_destroy; + + return stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c new file mode 100644 index 0000000000..30dceeb43d --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -0,0 +1,529 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * \file + * Vertex buffer drawing stage. + * + * \author José Fonseca + * \author Keith Whitwell + */ + + +#include "pipe/p_debug.h" +#include "pipe/p_util.h" + +#include "draw_vbuf.h" +#include "draw_private.h" +#include "draw_vertex.h" +#include "translate/translate.h" + + +/** + * Vertex buffer emit stage. + */ +struct vbuf_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + struct vbuf_render *render; + + const struct vertex_info *vinfo; + + /** Vertex size in bytes */ + unsigned vertex_size; + + struct translate *translate; + + /* FIXME: we have no guarantee that 'unsigned' is 32bit */ + + /** Vertices in hardware format */ + unsigned *vertices; + unsigned *vertex_ptr; + unsigned max_vertices; + unsigned nr_vertices; + + /** Indices */ + ushort *indices; + unsigned max_indices; + unsigned nr_indices; + + /* Cache point size somewhere it's address won't change: + */ + float point_size; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct vbuf_stage * +vbuf_stage( struct draw_stage *stage ) +{ + assert(stage); + return (struct vbuf_stage *)stage; +} + + +static void vbuf_flush_indices( struct vbuf_stage *vbuf ); +static void vbuf_flush_vertices( struct vbuf_stage *vbuf ); +static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); + + +static INLINE boolean +overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) +{ + unsigned long used = (unsigned long) ((char *)ptr - (char *)map); + return (used + bytes) > bufsz; +} + + +static INLINE void +check_space( struct vbuf_stage *vbuf, unsigned nr ) +{ + if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { + vbuf_flush_vertices(vbuf); + vbuf_alloc_vertices(vbuf); + } + + if (vbuf->nr_indices + nr > vbuf->max_indices ) + vbuf_flush_indices(vbuf); +} + + +static INLINE void +dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) +{ +// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); + unsigned i, j; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + debug_printf("EMIT_OMIT:"); + break; + case EMIT_1F: + debug_printf("EMIT_1F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_1F_PSIZE: + debug_printf("EMIT_1F_PSIZE:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_2F: + debug_printf("EMIT_2F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_3F: + debug_printf("EMIT_3F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + data += sizeof(float); + break; + case EMIT_4F: + debug_printf("EMIT_4F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_4UB: + debug_printf("EMIT_4UB:\t"); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + break; + default: + assert(0); + } + debug_printf("\n"); + } + debug_printf("\n"); +} + + +/** + * Extract the needed fields from post-transformed vertex and emit + * a hardware(driver) vertex. + * Recall that the vertices are constructed by the 'draw' module and + * have a couple of slots at the beginning (1-dword header, 4-dword + * clip pos) that we ignore here. We only use the vertex->data[] fields. + */ +static INLINE ushort +emit_vertex( struct vbuf_stage *vbuf, + struct vertex_header *vertex ) +{ + if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { + /* Hmm - vertices are emitted one at a time - better make sure + * set_buffer is efficient. Consider a special one-shot mode for + * translate. + */ + vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); + vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); + + if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + + vbuf->vertex_ptr += vbuf->vertex_size/4; + vertex->vertex_id = vbuf->nr_vertices++; + } + + return vertex->vertex_id; +} + + +static void +vbuf_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 3 ); + + for (i = 0; i < 3; i++) { + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); + } +} + + +static void +vbuf_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + unsigned i; + + check_space( vbuf, 2 ); + + for (i = 0; i < 2; i++) { + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); + } +} + + +static void +vbuf_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + check_space( vbuf, 1 ); + + vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); +} + + + + +/** + * Set the prim type for subsequent vertices. + * This may result in a new vertex size. The existing vbuffer (if any) + * will be flushed if needed and a new one allocated. + */ +static void +vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) +{ + struct translate_key hw_key; + unsigned dst_offset; + unsigned i; + + vbuf->render->set_primitive(vbuf->render, prim); + + /* Must do this after set_primitive() above: + * + * XXX: need some state managment to track when this needs to be + * recalculated. The driver should tell us whether there was a + * state change. + */ + vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); + + if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { + vbuf_flush_vertices(vbuf); + vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); + } + + /* Translate from pipeline vertices to hw vertices. + */ + dst_offset = 0; + memset(&hw_key, 0, sizeof(hw_key)); + + for (i = 0; i < vbuf->vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) ); + + switch (vbuf->vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; + } + + hw_key.nr_elements = vbuf->vinfo->num_attribs; + hw_key.output_stride = vbuf->vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!vbuf->translate || + memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (vbuf->translate) + vbuf->translate->release(vbuf->translate); + + vbuf->translate = translate_create( &hw_key ); + + vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); + } + + vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; + + /* Allocate new buffer? + */ + if (!vbuf->vertices) + vbuf_alloc_vertices(vbuf); +} + + +static void +vbuf_first_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->tri = vbuf_tri; + vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); + stage->tri( stage, prim ); +} + + +static void +vbuf_first_line( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->line = vbuf_line; + vbuf_set_prim(vbuf, PIPE_PRIM_LINES); + stage->line( stage, prim ); +} + + +static void +vbuf_first_point( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + stage->point = vbuf_point; + vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); + stage->point( stage, prim ); +} + + +static void +vbuf_flush_indices( struct vbuf_stage *vbuf ) +{ + if(!vbuf->nr_indices) + return; + + assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == + vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); + + vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); + + vbuf->nr_indices = 0; +} + + +/** + * Flush existing vertex buffer and allocate a new one. + * + * XXX: We separate flush-on-index-full and flush-on-vb-full, but may + * raise issues uploading vertices if the hardware wants to flush when + * we flush. + */ +static void +vbuf_flush_vertices( struct vbuf_stage *vbuf ) +{ + if(vbuf->vertices) { + vbuf_flush_indices(vbuf); + + /* Reset temporary vertices ids */ + if(vbuf->nr_vertices) + draw_reset_vertex_ids( vbuf->stage.draw ); + + /* Free the vertex buffer */ + vbuf->render->release_vertices(vbuf->render, + vbuf->vertices, + vbuf->vertex_size, + vbuf->nr_vertices); + vbuf->max_vertices = vbuf->nr_vertices = 0; + vbuf->vertex_ptr = vbuf->vertices = NULL; + + } +} + + +static void +vbuf_alloc_vertices( struct vbuf_stage *vbuf ) +{ + assert(!vbuf->nr_indices); + assert(!vbuf->vertices); + + /* Allocate a new vertex buffer */ + vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; + vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, + (ushort) vbuf->vertex_size, + (ushort) vbuf->max_vertices); + vbuf->vertex_ptr = vbuf->vertices; +} + + + +static void +vbuf_flush( struct draw_stage *stage, unsigned flags ) +{ + struct vbuf_stage *vbuf = vbuf_stage( stage ); + + vbuf_flush_indices( vbuf ); + + stage->point = vbuf_first_point; + stage->line = vbuf_first_line; + stage->tri = vbuf_first_tri; + + if (flags & DRAW_FLUSH_BACKEND) + vbuf_flush_vertices( vbuf ); +} + + +static void +vbuf_reset_stipple_counter( struct draw_stage *stage ) +{ + /* XXX: Need to do something here for hardware with linestipple. + */ + (void) stage; +} + + +static void vbuf_destroy( struct draw_stage *stage ) +{ + struct vbuf_stage *vbuf = vbuf_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 ); + + FREE( stage ); +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *draw_vbuf_stage( struct draw_context *draw, + struct vbuf_render *render ) +{ + struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); + + if(!vbuf) + goto fail; + + vbuf->stage.draw = draw; + vbuf->stage.point = vbuf_first_point; + vbuf->stage.line = vbuf_first_line; + vbuf->stage.tri = vbuf_first_tri; + vbuf->stage.flush = vbuf_flush; + vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; + vbuf->stage.destroy = vbuf_destroy; + + vbuf->render = render; + vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1); + + vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * + sizeof(vbuf->indices[0]), + 16 ); + if(!vbuf->indices) + goto fail; + + vbuf->vertices = NULL; + vbuf->vertex_ptr = vbuf->vertices; + + return &vbuf->stage; + + fail: + if (vbuf) + vbuf_destroy(&vbuf->stage); + + return NULL; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c new file mode 100644 index 0000000000..9a168ce8bd --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -0,0 +1,190 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct wideline_stage { + struct draw_stage stage; + + float half_line_width; +}; + + + +static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) +{ + return (struct wideline_stage *)stage; +} + + +static void wideline_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + + +static void wideline_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad (two triangles). + * XXX need to disable polygon stipple. + */ +static void wideline_line( struct draw_stage *stage, + struct prim_header *header ) +{ + /*const struct wideline_stage *wide = wideline_stage(stage);*/ + const float half_width = 0.5f * stage->draw->rasterizer->line_width; + + struct prim_header tri; + + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + const float dx = FABSF(pos0[0] - pos2[0]); + const float dy = FABSF(pos0[1] - pos2[1]); + + /* small tweak to meet GL specification */ + const float bias = 0.125f; + + /* + * Draw wide line as a quad (two tris) by "stretching" the line along + * X or Y. + * We need to tweak coords in several ways to be conformant here. + */ + + if (dx > dy) { + /* x-major line */ + pos0[1] = pos0[1] - half_width - bias; + pos1[1] = pos1[1] + half_width - bias; + pos2[1] = pos2[1] - half_width - bias; + pos3[1] = pos3[1] + half_width - bias; + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } + } + else { + /* y-major line */ + pos0[0] = pos0[0] - half_width + bias; + pos1[0] = pos1[0] + half_width + bias; + pos2[0] = pos2[0] - half_width + bias; + pos3[0] = pos3[0] + half_width + bias; + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void wideline_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->next->flush( stage->next, flags ); +} + + +static void wideline_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void wideline_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) +{ + struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = wideline_point; + wide->stage.line = wideline_line; + wide->stage.tri = wideline_tri; + wide->stage.flush = wideline_flush; + wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; + wide->stage.destroy = wideline_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c new file mode 100644 index 0000000000..3d0add0c1a --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -0,0 +1,281 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_vs.h" + + +struct widepoint_stage { + struct draw_stage stage; + + float half_point_size; + float point_size_min; + float point_size_max; + + float xbias; + float ybias; + + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; + uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; + uint num_texcoords; + + int psize_slot; +}; + + + +static INLINE struct widepoint_stage * +widepoint_stage( struct draw_stage *stage ) +{ + return (struct widepoint_stage *)stage; +} + + +static void passthrough_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + +static void widepoint_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line(stage->next, header); +} + +static void widepoint_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Set the vertex texcoords for sprite mode. + * Coords may be left untouched or set to a right-side-up or upside-down + * orientation. + */ +static void set_texcoords(const struct widepoint_stage *wide, + struct vertex_header *v, const float tc[4]) +{ + uint i; + for (i = 0; i < wide->num_texcoords; i++) { + if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { + uint j = wide->texcoord_slot[i]; + v->data[j][0] = tc[0]; + if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) + v->data[j][1] = 1.0f - tc[1]; + else + v->data[j][1] = tc[1]; + v->data[j][2] = tc[2]; + v->data[j][3] = tc[3]; + } + } +} + + +/* If there are lots of sprite points (and why wouldn't there be?) it + * would probably be more sensible to change hardware setup to + * optimize this rather than doing the whole thing in software like + * this. + */ +static void widepoint_point( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct widepoint_stage *wide = widepoint_stage(stage); + const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; + float half_size; + float left_adj, right_adj, bot_adj, top_adj; + + struct prim_header tri; + + /* four dups of original vertex */ + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + /* point size is either per-vertex or fixed size */ + if (wide->psize_slot >= 0) { + half_size = header->v[0]->data[wide->psize_slot][0]; + + /* XXX: temporary -- do this in the vertex shader?? + */ + half_size = CLAMP(half_size, + wide->point_size_min, + wide->point_size_max); + + half_size *= 0.5f; + } + else { + half_size = wide->half_point_size; + } + + left_adj = -half_size + wide->xbias; + right_adj = half_size + wide->xbias; + bot_adj = half_size + wide->ybias; + top_adj = -half_size + wide->ybias; + + pos0[0] += left_adj; + pos0[1] += top_adj; + + pos1[0] += left_adj; + pos1[1] += bot_adj; + + pos2[0] += right_adj; + pos2[1] += top_adj; + + pos3[0] += right_adj; + pos3[1] += bot_adj; + + if (sprite) { + static const float tex00[4] = { 0, 0, 0, 1 }; + static const float tex01[4] = { 0, 1, 0, 1 }; + static const float tex11[4] = { 1, 1, 0, 1 }; + static const float tex10[4] = { 1, 0, 0, 1 }; + set_texcoords( wide, v0, tex00 ); + set_texcoords( wide, v1, tex01 ); + set_texcoords( wide, v2, tex10 ); + set_texcoords( wide, v3, tex11 ); + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void widepoint_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct widepoint_stage *wide = widepoint_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_point_size = 0.5f * draw->rasterizer->point_size; + wide->point_size_min = draw->rasterizer->point_size_min; + wide->point_size_max = draw->rasterizer->point_size_max; + wide->xbias = 0.0; + wide->ybias = 0.0; + + if (draw->rasterizer->gl_rasterization_rules) { + wide->xbias = 0.125; + } + + /* XXX we won't know the real size if it's computed by the vertex shader! */ + if ((draw->rasterizer->point_size > draw->wide_point_threshold) || + (draw->rasterizer->point_sprite && draw->point_sprite)) { + stage->point = widepoint_point; + } + else { + stage->point = passthrough_point; + } + + if (draw->rasterizer->point_sprite) { + /* find vertex shader texcoord outputs */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i, j = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + wide->texcoord_slot[j] = i; + wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; + j++; + } + } + wide->num_texcoords = j; + } + + wide->psize_slot = -1; + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + wide->psize_slot = i; + break; + } + } + } + + stage->point( stage, header ); +} + + +static void widepoint_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->point = widepoint_first_point; + stage->next->flush( stage->next, flags ); +} + + +static void widepoint_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void widepoint_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) +{ + struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = widepoint_first_point; + wide->stage.line = widepoint_line; + wide->stage.tri = widepoint_tri; + wide->stage.flush = widepoint_flush; + wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter; + wide->stage.destroy = widepoint_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c b/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c new file mode 100644 index 0000000000..d6bff110b4 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c @@ -0,0 +1,366 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "draw_private.h" + + +struct wide_stage { + struct draw_stage stage; + + float half_line_width; + float half_point_size; + + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; + uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; + uint num_texcoords; + + int psize_slot; +}; + + + +static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) +{ + return (struct wide_stage *)stage; +} + + +static void passthrough_point( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->point( stage->next, header ); +} + +static void passthrough_line( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->line(stage->next, header); +} + +static void passthrough_tri( struct draw_stage *stage, + struct prim_header *header ) +{ + stage->next->tri(stage->next, header); +} + + +/** + * Draw a wide line by drawing a quad (two triangles). + * XXX need to disable polygon stipple. + */ +static void wide_line( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const float half_width = wide->half_line_width; + + struct prim_header tri; + + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + const float dx = FABSF(pos0[0] - pos2[0]); + const float dy = FABSF(pos0[1] - pos2[1]); + + /* + * Draw wide line as a quad (two tris) by "stretching" the line along + * X or Y. + * We need to tweak coords in several ways to be conformant here. + */ + + if (dx > dy) { + /* x-major line */ + pos0[1] = pos0[1] - half_width - 0.25f; + pos1[1] = pos1[1] + half_width - 0.25f; + pos2[1] = pos2[1] - half_width - 0.25f; + pos3[1] = pos3[1] + half_width - 0.25f; + if (pos0[0] < pos2[0]) { + /* left to right line */ + pos0[0] -= 0.5f; + pos1[0] -= 0.5f; + pos2[0] -= 0.5f; + pos3[0] -= 0.5f; + } + else { + /* right to left line */ + pos0[0] += 0.5f; + pos1[0] += 0.5f; + pos2[0] += 0.5f; + pos3[0] += 0.5f; + } + } + else { + /* y-major line */ + pos0[0] = pos0[0] - half_width + 0.25f; + pos1[0] = pos1[0] + half_width + 0.25f; + pos2[0] = pos2[0] - half_width + 0.25f; + pos3[0] = pos3[0] + half_width + 0.25f; + if (pos0[1] < pos2[1]) { + /* top to bottom line */ + pos0[1] -= 0.5f; + pos1[1] -= 0.5f; + pos2[1] -= 0.5f; + pos3[1] -= 0.5f; + } + else { + /* bottom to top line */ + pos0[1] += 0.5f; + pos1[1] += 0.5f; + pos2[1] += 0.5f; + pos3[1] += 0.5f; + } + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +/** + * Set the vertex texcoords for sprite mode. + * Coords may be left untouched or set to a right-side-up or upside-down + * orientation. + */ +static void set_texcoords(const struct wide_stage *wide, + struct vertex_header *v, const float tc[4]) +{ + uint i; + for (i = 0; i < wide->num_texcoords; i++) { + if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { + uint j = wide->texcoord_slot[i]; + v->data[j][0] = tc[0]; + if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) + v->data[j][1] = 1.0f - tc[1]; + else + v->data[j][1] = tc[1]; + v->data[j][2] = tc[2]; + v->data[j][3] = tc[3]; + } + } +} + + +/* If there are lots of sprite points (and why wouldn't there be?) it + * would probably be more sensible to change hardware setup to + * optimize this rather than doing the whole thing in software like + * this. + */ +static void wide_point( struct draw_stage *stage, + struct prim_header *header ) +{ + const struct wide_stage *wide = wide_stage(stage); + const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; + float half_size; + float left_adj, right_adj; + + struct prim_header tri; + + /* four dups of original vertex */ + struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); + struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); + struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); + struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); + + float *pos0 = v0->data[0]; + float *pos1 = v1->data[0]; + float *pos2 = v2->data[0]; + float *pos3 = v3->data[0]; + + /* point size is either per-vertex or fixed size */ + if (wide->psize_slot >= 0) { + half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; + } + else { + half_size = wide->half_point_size; + } + + left_adj = -half_size; /* + 0.25f;*/ + right_adj = half_size; /* + 0.25f;*/ + + pos0[0] += left_adj; + pos0[1] -= half_size; + + pos1[0] += left_adj; + pos1[1] += half_size; + + pos2[0] += right_adj; + pos2[1] -= half_size; + + pos3[0] += right_adj; + pos3[1] += half_size; + + if (sprite) { + static const float tex00[4] = { 0, 0, 0, 1 }; + static const float tex01[4] = { 0, 1, 0, 1 }; + static const float tex11[4] = { 1, 1, 0, 1 }; + static const float tex10[4] = { 1, 0, 0, 1 }; + set_texcoords( wide, v0, tex00 ); + set_texcoords( wide, v1, tex01 ); + set_texcoords( wide, v2, tex10 ); + set_texcoords( wide, v3, tex11 ); + } + + tri.det = header->det; /* only the sign matters */ + tri.v[0] = v0; + tri.v[1] = v2; + tri.v[2] = v3; + stage->next->tri( stage->next, &tri ); + + tri.v[0] = v0; + tri.v[1] = v3; + tri.v[2] = v1; + stage->next->tri( stage->next, &tri ); +} + + +static void wide_first_point( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_point_size = 0.5f * draw->rasterizer->point_size; + + /* XXX we won't know the real size if it's computed by the vertex shader! */ + if (draw->rasterizer->point_size > draw->wide_point_threshold) { + stage->point = wide_point; + } + else { + stage->point = passthrough_point; + } + + if (draw->rasterizer->point_sprite) { + /* find vertex shader texcoord outputs */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i, j = 0; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { + wide->texcoord_slot[j] = i; + wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; + j++; + } + } + wide->num_texcoords = j; + } + + wide->psize_slot = -1; + + if (draw->rasterizer->point_size_per_vertex) { + /* find PSIZ vertex output */ + const struct draw_vertex_shader *vs = draw->vertex_shader; + uint i; + for (i = 0; i < vs->info.num_outputs; i++) { + if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { + wide->psize_slot = i; + break; + } + } + } + + stage->point( stage, header ); +} + + + +static void wide_first_line( struct draw_stage *stage, + struct prim_header *header ) +{ + struct wide_stage *wide = wide_stage(stage); + struct draw_context *draw = stage->draw; + + wide->half_line_width = 0.5f * draw->rasterizer->line_width; + + if (draw->rasterizer->line_width != 1.0) { + wide->stage.line = wide_line; + } + else { + wide->stage.line = passthrough_line; + } + + stage->line( stage, header ); +} + + +static void wide_flush( struct draw_stage *stage, unsigned flags ) +{ + stage->line = wide_first_line; + stage->point = wide_first_point; + stage->next->flush( stage->next, flags ); +} + + +static void wide_reset_stipple_counter( struct draw_stage *stage ) +{ + stage->next->reset_stipple_counter( stage->next ); +} + + +static void wide_destroy( struct draw_stage *stage ) +{ + draw_free_temp_verts( stage ); + FREE( stage ); +} + + +struct draw_stage *draw_wide_stage( struct draw_context *draw ) +{ + struct wide_stage *wide = CALLOC_STRUCT(wide_stage); + + draw_alloc_temp_verts( &wide->stage, 4 ); + + wide->stage.draw = draw; + wide->stage.next = NULL; + wide->stage.point = wide_first_point; + wide->stage.line = wide_first_line; + wide->stage.tri = passthrough_tri; + wide->stage.flush = wide_flush; + wide->stage.reset_stipple_counter = wide_reset_stipple_counter; + wide->stage.destroy = wide_destroy; + + return &wide->stage; +} diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c deleted file mode 100644 index 4dddb72906..0000000000 --- a/src/gallium/auxiliary/draw/draw_pstipple.c +++ /dev/null @@ -1,746 +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. - * - **************************************************************************/ - -/** - * Polygon stipple stage: implement polygon stipple with texture map and - * fragment program. The fragment program samples the texture and does - * a fragment kill for the stipple-failing fragments. - * - * Authors: Brian Paul - */ - - -#include "pipe/p_util.h" -#include "pipe/p_inlines.h" -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" - -#include "tgsi/util/tgsi_transform.h" -#include "tgsi/util/tgsi_dump.h" - -#include "draw_context.h" -#include "draw_private.h" - - - -/** - * Subclass of pipe_shader_state to carry extra fragment shader info. - */ -struct pstip_fragment_shader -{ - struct pipe_shader_state state; - void *driver_fs; - void *pstip_fs; - uint sampler_unit; -}; - - -/** - * Subclass of draw_stage - */ -struct pstip_stage -{ - struct draw_stage stage; - - void *sampler_cso; - struct pipe_texture *texture; - uint num_samplers; - uint num_textures; - - /* - * Currently bound state - */ - struct pstip_fragment_shader *fs; - struct { - void *samplers[PIPE_MAX_SAMPLERS]; - struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; - const struct pipe_poly_stipple *stipple; - } state; - - /* - * Driver interface/override functions - */ - void * (*driver_create_fs_state)(struct pipe_context *, - const struct pipe_shader_state *); - void (*driver_bind_fs_state)(struct pipe_context *, void *); - void (*driver_delete_fs_state)(struct pipe_context *, void *); - - void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); - - void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, - struct pipe_texture **); - - void (*driver_set_polygon_stipple)(struct pipe_context *, - const struct pipe_poly_stipple *); - - struct pipe_context *pipe; -}; - - - -/** - * Subclass of tgsi_transform_context, used for transforming the - * user's fragment shader to add the special AA instructions. - */ -struct pstip_transform_context { - struct tgsi_transform_context base; - uint tempsUsed; /**< bitmask */ - int wincoordInput; - int maxInput; - uint samplersUsed; /**< bitfield of samplers used */ - int freeSampler; /** an available sampler for the pstipple */ - int texTemp; /**< temp registers */ - int numImmed; - boolean firstInstruction; -}; - - -/** - * TGSI declaration transform callback. - * Look for a free sampler, a free input attrib, and two free temp regs. - */ -static void -pstip_transform_decl(struct tgsi_transform_context *ctx, - struct tgsi_full_declaration *decl) -{ - struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; - - if (decl->Declaration.File == TGSI_FILE_SAMPLER) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - pctx->samplersUsed |= 1 << i; - } - } - else if (decl->Declaration.File == TGSI_FILE_INPUT) { - pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last); - if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) - pctx->wincoordInput = (int) decl->u.DeclarationRange.First; - } - else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { - uint i; - for (i = decl->u.DeclarationRange.First; - i <= decl->u.DeclarationRange.Last; i++) { - pctx->tempsUsed |= (1 << i); - } - } - - ctx->emit_declaration(ctx, decl); -} - - -static void -pstip_transform_immed(struct tgsi_transform_context *ctx, - struct tgsi_full_immediate *immed) -{ - struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; - pctx->numImmed++; -} - - -/** - * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. - */ -static int -free_bit(uint bitfield) -{ - int i; - for (i = 0; i < 32; i++) { - if ((bitfield & (1 << i)) == 0) - return i; - } - return -1; -} - - -/** - * TGSI instruction transform callback. - * Replace writes to result.color w/ a temp reg. - * Upon END instruction, insert texture sampling code for antialiasing. - */ -static void -pstip_transform_inst(struct tgsi_transform_context *ctx, - struct tgsi_full_instruction *inst) -{ - struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx; - - if (pctx->firstInstruction) { - /* emit our new declarations before the first instruction */ - - struct tgsi_full_declaration decl; - struct tgsi_full_instruction newInst; - uint i; - int wincoordInput; - - /* find free sampler */ - pctx->freeSampler = free_bit(pctx->samplersUsed); - if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) - pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; - - if (pctx->wincoordInput < 0) - wincoordInput = pctx->maxInput + 1; - else - wincoordInput = pctx->wincoordInput; - - /* find one free temp reg */ - for (i = 0; i < 32; i++) { - if ((pctx->tempsUsed & (1 << i)) == 0) { - /* found a free temp */ - if (pctx->texTemp < 0) - pctx->texTemp = i; - else - break; - } - } - assert(pctx->texTemp >= 0); - - if (pctx->wincoordInput < 0) { - /* declare new position input reg */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Semantic = 1; - decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION; - decl.Semantic.SemanticIndex = 0; - decl.Declaration.Interpolate = 1; - decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = wincoordInput; - ctx->emit_declaration(ctx, &decl); - } - - /* declare new sampler */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_SAMPLER; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = pctx->freeSampler; - ctx->emit_declaration(ctx, &decl); - - /* declare new temp regs */ - decl = tgsi_default_full_declaration(); - decl.Declaration.File = TGSI_FILE_TEMPORARY; - decl.u.DeclarationRange.First = - decl.u.DeclarationRange.Last = pctx->texTemp; - ctx->emit_declaration(ctx, &decl); - - /* emit immediate = {1/32, 1/32, 1, 1} - * The index/position of this immediate will be pctx->numImmed - */ - { - static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; - struct tgsi_full_immediate immed; - uint size = 4; - immed = tgsi_default_full_immediate(); - immed.Immediate.Size = 1 + size; /* one for the token itself */ - immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value; - ctx->emit_immediate(ctx, &immed); - } - - pctx->firstInstruction = FALSE; - - - /* - * Insert new MUL/TEX/KILP instructions at start of program - * Take gl_FragCoord, divide by 32 (stipple size), sample the - * texture and kill fragment if needed. - * - * We'd like to use non-normalized texcoords to index into a RECT - * texture, but we can only use GL_REPEAT wrap mode with normalized - * texcoords. Darn. - */ - - /* MUL texTemp, INPUT[wincoord], 1/32; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_MUL; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; - newInst.Instruction.NumSrcRegs = 2; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT; - newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE; - newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed; - ctx->emit_instruction(ctx, &newInst); - - /* TEX texTemp, texTemp, sampler; */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_TEX; - newInst.Instruction.NumDstRegs = 1; - newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp; - newInst.Instruction.NumSrcRegs = 2; - newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; - newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER; - newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler; - ctx->emit_instruction(ctx, &newInst); - - /* KILP texTemp; # if texTemp < 0, KILL fragment */ - newInst = tgsi_default_full_instruction(); - newInst.Instruction.Opcode = TGSI_OPCODE_KILP; - newInst.Instruction.NumDstRegs = 0; - newInst.Instruction.NumSrcRegs = 1; - newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY; - newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp; - newInst.FullSrcRegisters[0].SrcRegister.Negate = 1; - ctx->emit_instruction(ctx, &newInst); - } - - /* emit this instruction */ - ctx->emit_instruction(ctx, inst); -} - - -/** - * Generate the frag shader we'll use for doing polygon stipple. - * This will be the user's shader prefixed with a TEX and KIL instruction. - */ -static void -generate_pstip_fs(struct pstip_stage *pstip) -{ - const struct pipe_shader_state *orig_fs = &pstip->fs->state; - /*struct draw_context *draw = pstip->stage.draw;*/ - struct pipe_shader_state pstip_fs; - struct pstip_transform_context transform; - -#define MAX 1000 - - pstip_fs = *orig_fs; /* copy to init */ - pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); - - memset(&transform, 0, sizeof(transform)); - transform.wincoordInput = -1; - transform.maxInput = -1; - transform.texTemp = -1; - transform.firstInstruction = TRUE; - transform.base.transform_instruction = pstip_transform_inst; - transform.base.transform_declaration = pstip_transform_decl; - transform.base.transform_immediate = pstip_transform_immed; - - tgsi_transform_shader(orig_fs->tokens, - (struct tgsi_token *) pstip_fs.tokens, - MAX, &transform.base); - -#if 0 /* DEBUG */ - tgsi_dump(orig_fs->tokens, 0); - tgsi_dump(pstip_fs.tokens, 0); -#endif - - pstip->fs->sampler_unit = transform.freeSampler; - assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); - - pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); -} - - -/** - * Load texture image with current stipple pattern. - */ -static void -pstip_update_texture(struct pstip_stage *pstip) -{ - static const uint bit31 = 1 << 31; - struct pipe_context *pipe = pstip->pipe; - struct pipe_screen *screen = pipe->screen; - struct pipe_surface *surface; - const uint *stipple = pstip->state.stipple->stipple; - uint i, j; - ubyte *data; - - surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0); - data = pipe_surface_map(surface); - - /* - * Load alpha texture. - * Note: 0 means keep the fragment, 255 means kill it. - * We'll negate the texel value and use KILP which kills if value - * is negative. - */ - for (i = 0; i < 32; i++) { - for (j = 0; j < 32; j++) { - if (stipple[i] & (bit31 >> j)) { - /* fragment "on" */ - data[i * surface->pitch + j] = 0; - } - else { - /* fragment "off" */ - data[i * surface->pitch + j] = 255; - } - } - } - - /* unmap */ - pipe_surface_unmap(surface); - pipe_surface_reference(&surface, NULL); - pipe->texture_update(pipe, pstip->texture, 0, 0x1); -} - - -/** - * Create the texture map we'll use for stippling. - */ -static void -pstip_create_texture(struct pstip_stage *pstip) -{ - struct pipe_context *pipe = pstip->pipe; - struct pipe_screen *screen = pipe->screen; - struct pipe_texture texTemp; - - memset(&texTemp, 0, sizeof(texTemp)); - texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */ - texTemp.last_level = 0; - texTemp.width[0] = 32; - texTemp.height[0] = 32; - texTemp.depth[0] = 1; - texTemp.cpp = 1; - - pstip->texture = screen->texture_create(screen, &texTemp); - assert(pstip->texture->refcount == 1); -} - - -/** - * Create the sampler CSO that'll be used for antialiasing. - * By using a mipmapped texture, we don't have to generate a different - * texture image for each line size. - */ -static void -pstip_create_sampler(struct pstip_stage *pstip) -{ - struct pipe_sampler_state sampler; - struct pipe_context *pipe = pstip->pipe; - - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_REPEAT; - sampler.wrap_t = PIPE_TEX_WRAP_REPEAT; - sampler.wrap_r = PIPE_TEX_WRAP_REPEAT; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.normalized_coords = 1; - sampler.min_lod = 0.0f; - sampler.max_lod = 0.0f; - - pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); -} - - -/** - * When we're about to draw our first AA line in a batch, this function is - * called to tell the driver to bind our modified fragment shader. - */ -static void -bind_pstip_fragment_shader(struct pstip_stage *pstip) -{ - if (!pstip->fs->pstip_fs) { - generate_pstip_fs(pstip); - } - pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); -} - - - -static INLINE struct pstip_stage * -pstip_stage( struct draw_stage *stage ) -{ - return (struct pstip_stage *) stage; -} - - -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - - -static void -pstip_first_tri(struct draw_stage *stage, struct prim_header *header) -{ - struct pstip_stage *pstip = pstip_stage(stage); - struct pipe_context *pipe = pstip->pipe; - uint num_samplers; - - assert(stage->draw->rasterizer->poly_stipple_enable); - - /* bind our fragprog */ - bind_pstip_fragment_shader(pstip); - - /* how many samplers? */ - /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ - num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); - num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1); - - /* plug in our sampler, texture */ - pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; - pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], - pstip->texture); - - assert(num_samplers <= PIPE_MAX_SAMPLERS); - - pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); - - /* now really draw first line */ - stage->tri = passthrough_tri; - stage->tri(stage, header); -} - - -static void -pstip_flush(struct draw_stage *stage, unsigned flags) -{ - /*struct draw_context *draw = stage->draw;*/ - struct pstip_stage *pstip = pstip_stage(stage); - struct pipe_context *pipe = pstip->pipe; - - stage->tri = pstip_first_tri; - stage->next->flush( stage->next, flags ); - - /* restore original frag shader */ - pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs); - - /* XXX restore original texture, sampler state */ - pstip->driver_bind_sampler_states(pipe, pstip->num_samplers, - pstip->state.samplers); - pstip->driver_set_sampler_textures(pipe, pstip->num_textures, - pstip->state.textures); -} - - -static void -pstip_reset_stipple_counter(struct draw_stage *stage) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -pstip_destroy(struct draw_stage *stage) -{ - struct pstip_stage *pstip = pstip_stage(stage); - - pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso); - - pipe_texture_release(&pstip->texture); - - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -static struct pstip_stage * -draw_pstip_stage(struct draw_context *draw) -{ - struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage); - - draw_alloc_temp_verts( &pstip->stage, 8 ); - - pstip->stage.draw = draw; - pstip->stage.next = NULL; - pstip->stage.point = passthrough_point; - pstip->stage.line = passthrough_line; - pstip->stage.tri = pstip_first_tri; - pstip->stage.flush = pstip_flush; - pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; - pstip->stage.destroy = pstip_destroy; - - return pstip; -} - - -static struct pstip_stage * -pstip_stage_from_pipe(struct pipe_context *pipe) -{ - struct draw_context *draw = (struct draw_context *) pipe->draw; - return pstip_stage(draw->pipeline.pstipple); -} - - -/** - * This function overrides the driver's create_fs_state() function and - * will typically be called by the state tracker. - */ -static void * -pstip_create_fs_state(struct pipe_context *pipe, - const struct pipe_shader_state *fs) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader); - - if (aafs) { - aafs->state = *fs; - - /* pass-through */ - aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs); - } - - return aafs; -} - - -static void -pstip_bind_fs_state(struct pipe_context *pipe, void *fs) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; - /* save current */ - pstip->fs = aafs; - /* pass-through */ - pstip->driver_bind_fs_state(pstip->pipe, - (aafs ? aafs->driver_fs : NULL)); -} - - -static void -pstip_delete_fs_state(struct pipe_context *pipe, void *fs) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs; - /* pass-through */ - pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs); - FREE(aafs); -} - - -static void -pstip_bind_sampler_states(struct pipe_context *pipe, - unsigned num, void **sampler) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - uint i; - - /* save current */ - memcpy(pstip->state.samplers, sampler, num * sizeof(void *)); - for (i = num; i < PIPE_MAX_SAMPLERS; i++) { - pstip->state.samplers[i] = NULL; - } - - pstip->num_samplers = num; - /* pass-through */ - pstip->driver_bind_sampler_states(pstip->pipe, num, sampler); -} - - -static void -pstip_set_sampler_textures(struct pipe_context *pipe, - unsigned num, struct pipe_texture **texture) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - uint i; - - /* save current */ - for (i = 0; i < num; i++) { - pipe_texture_reference(&pstip->state.textures[i], texture[i]); - } - for (; i < PIPE_MAX_SAMPLERS; i++) { - pipe_texture_reference(&pstip->state.textures[i], NULL); - } - - pstip->num_textures = num; - - /* pass-through */ - pstip->driver_set_sampler_textures(pstip->pipe, num, texture); -} - - -static void -pstip_set_polygon_stipple(struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple) -{ - struct pstip_stage *pstip = pstip_stage_from_pipe(pipe); - /* save current */ - pstip->state.stipple = stipple; - /* pass-through */ - pstip->driver_set_polygon_stipple(pstip->pipe, stipple); - - pstip_update_texture(pstip); -} - - - -/** - * Called by drivers that want to install this AA line prim stage - * into the draw module's pipeline. This will not be used if the - * hardware has native support for AA lines. - */ -void -draw_install_pstipple_stage(struct draw_context *draw, - struct pipe_context *pipe) -{ - struct pstip_stage *pstip; - - pipe->draw = (void *) draw; - - /* - * Create / install AA line drawing / prim stage - */ - pstip = draw_pstip_stage( draw ); - assert(pstip); - draw->pipeline.pstipple = &pstip->stage; - - pstip->pipe = pipe; - - /* create special texture, sampler state */ - pstip_create_texture(pstip); - pstip_create_sampler(pstip); - - /* save original driver functions */ - pstip->driver_create_fs_state = pipe->create_fs_state; - pstip->driver_bind_fs_state = pipe->bind_fs_state; - pstip->driver_delete_fs_state = pipe->delete_fs_state; - - pstip->driver_bind_sampler_states = pipe->bind_sampler_states; - pstip->driver_set_sampler_textures = pipe->set_sampler_textures; - pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple; - - /* override the driver's functions */ - pipe->create_fs_state = pstip_create_fs_state; - pipe->bind_fs_state = pstip_bind_fs_state; - pipe->delete_fs_state = pstip_delete_fs_state; - - pipe->bind_sampler_states = pstip_bind_sampler_states; - pipe->set_sampler_textures = pstip_set_sampler_textures; - pipe->set_polygon_stipple = pstip_set_polygon_stipple; -} diff --git a/src/gallium/auxiliary/draw/draw_stipple.c b/src/gallium/auxiliary/draw/draw_stipple.c deleted file mode 100644 index 506f33512c..0000000000 --- a/src/gallium/auxiliary/draw/draw_stipple.c +++ /dev/null @@ -1,239 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -/* Implement line stipple by cutting lines up into smaller lines. - * There are hundreds of ways to implement line stipple, this is one - * choice that should work in all situations, requires no state - * manipulations, but with a penalty in terms of large amounts of - * generated geometry. - */ - - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -/** Subclass of draw_stage */ -struct stipple_stage { - struct draw_stage stage; - float counter; - uint pattern; - uint factor; -}; - - -static INLINE struct stipple_stage * -stipple_stage(struct draw_stage *stage) -{ - return (struct stipple_stage *) stage; -} - - -/** - * Compute interpolated vertex attributes for 'dst' at position 't' - * between 'v0' and 'v1'. - * XXX using linear interpolation for all attribs at this time. - */ -static void -screen_interp( struct draw_context *draw, - struct vertex_header *dst, - float t, - const struct vertex_header *v0, - const struct vertex_header *v1 ) -{ - uint attr; - for (attr = 0; attr < draw->num_vs_outputs; attr++) { - const float *val0 = v0->data[attr]; - const float *val1 = v1->data[attr]; - float *newv = dst->data[attr]; - uint i; - for (i = 0; i < 4; i++) { - newv[i] = val0[i] + t * (val1[i] - val0[i]); - } - } -} - - -static void -emit_segment(struct draw_stage *stage, struct prim_header *header, - float t0, float t1) -{ - struct vertex_header *v0new = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1new = dup_vert(stage, header->v[1], 1); - struct prim_header newprim = *header; - - if (t0 > 0.0) { - screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] ); - newprim.v[0] = v0new; - } - - if (t1 < 1.0) { - screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] ); - newprim.v[1] = v1new; - } - - stage->next->line( stage->next, &newprim ); -} - - -static INLINE unsigned -stipple_test(int counter, ushort pattern, int factor) -{ - int b = (counter / factor) & 0xf; - return (1 << b) & pattern; -} - - -static void -stipple_line(struct draw_stage *stage, struct prim_header *header) -{ - struct stipple_stage *stipple = stipple_stage(stage); - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - const float *pos0 = v0->data[0]; - const float *pos1 = v1->data[0]; - float start = 0; - int state = 0; - - float x0 = pos0[0]; - float x1 = pos1[0]; - float y0 = pos0[1]; - float y1 = pos1[1]; - - float dx = x0 > x1 ? x0 - x1 : x1 - x0; - float dy = y0 > y1 ? y0 - y1 : y1 - y0; - - float length = MAX2(dx, dy); - int i; - - /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table. - */ - for (i = 0; i < length; i++) { - int result = stipple_test( (int) stipple->counter+i, - (ushort) stipple->pattern, stipple->factor ); - if (result != state) { - /* changing from "off" to "on" or vice versa */ - if (state) { - if (start != i) { - /* finishing an "on" segment */ - emit_segment( stage, header, start / length, i / length ); - } - } - else { - /* starting an "on" segment */ - start = (float) i; - } - state = result; - } - } - - if (state && start < length) - emit_segment( stage, header, start / length, 1.0 ); - - stipple->counter += length; -} - - -static void -reset_stipple_counter(struct draw_stage *stage) -{ - struct stipple_stage *stipple = stipple_stage(stage); - stipple->counter = 0; - stage->next->reset_stipple_counter( stage->next ); -} - - -static void -stipple_first_line(struct draw_stage *stage, - struct prim_header *header) -{ - struct stipple_stage *stipple = stipple_stage(stage); - struct draw_context *draw = stage->draw; - - stipple->pattern = draw->rasterizer->line_stipple_pattern; - stipple->factor = draw->rasterizer->line_stipple_factor + 1; - - stage->line = stipple_line; - stage->line( stage, header ); -} - - -static void -stipple_flush(struct draw_stage *stage, unsigned flags) -{ - stage->line = stipple_first_line; - stage->next->flush( stage->next, flags ); -} - - -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point( stage->next, header ); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - -static void -stipple_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create line stippler stage - */ -struct draw_stage *draw_stipple_stage( struct draw_context *draw ) -{ - struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage); - - draw_alloc_temp_verts( &stipple->stage, 2 ); - - stipple->stage.draw = draw; - stipple->stage.next = NULL; - stipple->stage.point = passthrough_point; - stipple->stage.line = stipple_first_line; - stipple->stage.tri = passthrough_tri; - stipple->stage.reset_stipple_counter = reset_stipple_counter; - stipple->stage.flush = stipple_flush; - stipple->stage.destroy = stipple_destroy; - - return &stipple->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_twoside.c b/src/gallium/auxiliary/draw/draw_twoside.c deleted file mode 100644 index 01d905c153..0000000000 --- a/src/gallium/auxiliary/draw/draw_twoside.c +++ /dev/null @@ -1,203 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" - - -struct twoside_stage { - struct draw_stage stage; - float sign; /**< +1 or -1 */ - uint attrib_front0, attrib_back0; - uint attrib_front1, attrib_back1; -}; - - -static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage ) -{ - return (struct twoside_stage *)stage; -} - - - - -/** - * Copy back color(s) to front color(s). - */ -static INLINE struct vertex_header * -copy_bfc( struct twoside_stage *twoside, - const struct vertex_header *v, - unsigned idx ) -{ - struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); - - if (twoside->attrib_back0) { - COPY_4FV(tmp->data[twoside->attrib_front0], - tmp->data[twoside->attrib_back0]); - } - if (twoside->attrib_back1) { - COPY_4FV(tmp->data[twoside->attrib_front1], - tmp->data[twoside->attrib_back1]); - } - - return tmp; -} - - -/* Twoside tri: - */ -static void twoside_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct twoside_stage *twoside = twoside_stage(stage); - - if (header->det * twoside->sign < 0.0) { - /* this is a back-facing triangle */ - struct prim_header tmp; - - tmp.det = header->det; - tmp.edgeflags = header->edgeflags; - /* copy back attribs to front attribs */ - tmp.v[0] = copy_bfc(twoside, header->v[0], 0); - tmp.v[1] = copy_bfc(twoside, header->v[1], 1); - tmp.v[2] = copy_bfc(twoside, header->v[2], 2); - - stage->next->tri( stage->next, &tmp ); - } - else { - stage->next->tri( stage->next, header ); - } -} - - -static void twoside_line( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->line( stage->next, header ); -} - - -static void twoside_point( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->point( stage->next, header ); -} - - -static void twoside_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct twoside_stage *twoside = twoside_stage(stage); - const struct draw_vertex_shader *vs = stage->draw->vertex_shader; - uint i; - - twoside->attrib_front0 = 0; - twoside->attrib_front1 = 0; - twoside->attrib_back0 = 0; - twoside->attrib_back1 = 0; - - /* Find which vertex shader outputs are front/back colors */ - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) { - if (vs->info.output_semantic_index[i] == 0) - twoside->attrib_front0 = i; - else - twoside->attrib_front1 = i; - } - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) { - if (vs->info.output_semantic_index[i] == 0) - twoside->attrib_back0 = i; - else - twoside->attrib_back1 = i; - } - } - - if (!twoside->attrib_back0) - twoside->attrib_front0 = 0; - - if (!twoside->attrib_back1) - twoside->attrib_front1 = 0; - - /* - * We'll multiply the primitive's determinant by this sign to determine - * if the triangle is back-facing (negative). - * sign = -1 for CCW, +1 for CW - */ - twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; - - stage->tri = twoside_tri; - stage->tri( stage, header ); -} - - -static void twoside_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->tri = twoside_first_tri; - stage->next->flush( stage->next, flags ); -} - - -static void twoside_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void twoside_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create twoside pipeline stage. - */ -struct draw_stage *draw_twoside_stage( struct draw_context *draw ) -{ - struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); - - draw_alloc_temp_verts( &twoside->stage, 3 ); - - twoside->stage.draw = draw; - twoside->stage.next = NULL; - twoside->stage.point = twoside_point; - twoside->stage.line = twoside_line; - twoside->stage.tri = twoside_first_tri; - twoside->stage.flush = twoside_flush; - twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; - twoside->stage.destroy = twoside_destroy; - - return &twoside->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_unfilled.c b/src/gallium/auxiliary/draw/draw_unfilled.c deleted file mode 100644 index b07860cd9e..0000000000 --- a/src/gallium/auxiliary/draw/draw_unfilled.c +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/** - * \brief Drawing stage for handling glPolygonMode(line/point). - * Convert triangles to points or lines as needed. - */ - -/* Authors: Keith Whitwell - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - - -struct unfilled_stage { - struct draw_stage stage; - - /** [0] = front face, [1] = back face. - * legal values: PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE, - * and PIPE_POLYGON_MODE_POINT, - */ - unsigned mode[2]; -}; - - -static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage ) -{ - return (struct unfilled_stage *)stage; -} - - - -static void point( struct draw_stage *stage, - struct vertex_header *v0 ) -{ - struct prim_header tmp; - tmp.v[0] = v0; - stage->next->point( stage->next, &tmp ); -} - -static void line( struct draw_stage *stage, - struct vertex_header *v0, - struct vertex_header *v1 ) -{ - struct prim_header tmp; - tmp.v[0] = v0; - tmp.v[1] = v1; - stage->next->line( stage->next, &tmp ); -} - - -static void points( struct draw_stage *stage, - struct prim_header *header ) -{ - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - struct vertex_header *v2 = header->v[2]; - - if (header->edgeflags & 0x1) point( stage, v0 ); - if (header->edgeflags & 0x2) point( stage, v1 ); - if (header->edgeflags & 0x4) point( stage, v2 ); -} - - -static void lines( struct draw_stage *stage, - struct prim_header *header ) -{ - struct vertex_header *v0 = header->v[0]; - struct vertex_header *v1 = header->v[1]; - struct vertex_header *v2 = header->v[2]; - -#if 0 - assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag); - assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag); - assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag); -#endif - - if (header->edgeflags & 0x4) line( stage, v2, v0 ); - if (header->edgeflags & 0x1) line( stage, v0, v1 ); - if (header->edgeflags & 0x2) line( stage, v1, v2 ); -} - - -/* Unfilled tri: - * - * Note edgeflags in the vertex struct is not sufficient as we will - * need to manipulate them when decomposing primitives??? - */ -static void unfilled_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct unfilled_stage *unfilled = unfilled_stage(stage); - unsigned mode = unfilled->mode[header->det >= 0.0]; - - switch (mode) { - case PIPE_POLYGON_MODE_FILL: - stage->next->tri( stage->next, header ); - break; - case PIPE_POLYGON_MODE_LINE: - lines( stage, header ); - break; - case PIPE_POLYGON_MODE_POINT: - points( stage, header ); - break; - default: - assert(0); - } -} - - -static void unfilled_first_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct unfilled_stage *unfilled = unfilled_stage(stage); - - unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ - unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ - - stage->tri = unfilled_tri; - stage->tri( stage, header ); -} - - -static void unfilled_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void unfilled_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void unfilled_flush( struct draw_stage *stage, - unsigned flags ) -{ - stage->next->flush( stage->next, flags ); - - stage->tri = unfilled_first_tri; -} - - -static void unfilled_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void unfilled_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -/** - * Create unfilled triangle stage. - */ -struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) -{ - struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); - - draw_alloc_temp_verts( &unfilled->stage, 0 ); - - unfilled->stage.draw = draw; - unfilled->stage.next = NULL; - unfilled->stage.tmp = NULL; - unfilled->stage.point = unfilled_point; - unfilled->stage.line = unfilled_line; - unfilled->stage.tri = unfilled_first_tri; - unfilled->stage.flush = unfilled_flush; - unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; - unfilled->stage.destroy = unfilled_destroy; - - return &unfilled->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c deleted file mode 100644 index e163e078f0..0000000000 --- a/src/gallium/auxiliary/draw/draw_validate.c +++ /dev/null @@ -1,312 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "draw_private.h" - -static boolean points( unsigned prim ) -{ - return (prim == PIPE_PRIM_POINTS); -} - -static boolean lines( unsigned prim ) -{ - return (prim == PIPE_PRIM_LINES || - prim == PIPE_PRIM_LINE_STRIP || - prim == PIPE_PRIM_LINE_LOOP); -} - -static boolean triangles( unsigned prim ) -{ - return prim >= PIPE_PRIM_TRIANGLES; -} - -/** - * Check if we need any special pipeline stages, or whether - * prims/verts can go through untouched. Don't test for bypass - * clipping or vs modes, this function is just about the primitive - * pipeline stages. - */ -boolean -draw_need_pipeline(const struct draw_context *draw, - unsigned int prim ) -{ - /* Don't have to worry about triangles turning into lines/points - * and triggering the pipeline, because we have to trigger the - * pipeline *anyway* if unfilled mode is active. - */ - if (lines(prim)) - { - /* line stipple */ - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) - return TRUE; - - /* wide lines */ - if (draw->rasterizer->line_width > draw->wide_line_threshold) - return TRUE; - - /* AA lines */ - if (draw->rasterizer->line_smooth && draw->pipeline.aaline) - return TRUE; - } - - if (points(prim)) - { - /* large points */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) - return TRUE; - - /* AA points */ - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) - return TRUE; - - /* point sprites */ - if (draw->rasterizer->point_sprite && draw->point_sprite) - return TRUE; - } - - - if (triangles(prim)) - { - /* polygon stipple */ - if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) - return TRUE; - - /* unfilled polygons */ - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) - return TRUE; - - /* polygon offset */ - if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) - return TRUE; - - /* two-side lighting */ - if (draw->rasterizer->light_twoside) - return TRUE; - } - - /* polygon cull - this is difficult - hardware can cull just fine - * most of the time (though sometimes CULL_NEITHER is unsupported. - * - * Generally this isn't a reason to require the pipeline, though. - * - if (draw->rasterizer->cull_mode) - return TRUE; - */ - - return FALSE; -} - - - -/** - * Rebuild the rendering pipeline. - */ -static struct draw_stage *validate_pipeline( struct draw_stage *stage ) -{ - struct draw_context *draw = stage->draw; - struct draw_stage *next = draw->pipeline.rasterize; - int need_det = 0; - int precalc_flat = 0; - boolean wide_lines, wide_points; - - /* Set the validate's next stage to the rasterize stage, so that it - * can be found later if needed for flushing. - */ - stage->next = next; - - /* drawing wide lines? */ - wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold - && !draw->rasterizer->line_smooth); - - /* drawing large points? */ - if (draw->rasterizer->point_sprite && draw->point_sprite) - wide_points = TRUE; - else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) - wide_points = FALSE; - else if (draw->rasterizer->point_size > draw->wide_point_threshold) - wide_points = TRUE; - else - wide_points = FALSE; - - /* - * NOTE: we build up the pipeline in end-to-start order. - * - * TODO: make the current primitive part of the state and build - * shorter pipelines for lines & points. - */ - - if (draw->rasterizer->line_smooth && draw->pipeline.aaline) { - draw->pipeline.aaline->next = next; - next = draw->pipeline.aaline; - } - - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) { - draw->pipeline.aapoint->next = next; - next = draw->pipeline.aapoint; - } - - if (wide_lines) { - draw->pipeline.wide_line->next = next; - next = draw->pipeline.wide_line; - precalc_flat = 1; - } - - if (wide_points || draw->rasterizer->point_sprite) { - draw->pipeline.wide_point->next = next; - next = draw->pipeline.wide_point; - } - - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) { - draw->pipeline.stipple->next = next; - next = draw->pipeline.stipple; - precalc_flat = 1; /* only needed for lines really */ - } - - if (draw->rasterizer->poly_stipple_enable - && draw->pipeline.pstipple) { - draw->pipeline.pstipple->next = next; - next = draw->pipeline.pstipple; - } - - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) { - draw->pipeline.unfilled->next = next; - next = draw->pipeline.unfilled; - precalc_flat = 1; /* only needed for triangles really */ - need_det = 1; - } - - if (draw->rasterizer->flatshade && precalc_flat) { - draw->pipeline.flatshade->next = next; - next = draw->pipeline.flatshade; - } - - if (draw->rasterizer->offset_cw || - draw->rasterizer->offset_ccw) { - draw->pipeline.offset->next = next; - next = draw->pipeline.offset; - need_det = 1; - } - - if (draw->rasterizer->light_twoside) { - draw->pipeline.twoside->next = next; - next = draw->pipeline.twoside; - need_det = 1; - } - - /* Always run the cull stage as we calculate determinant there - * also. - * - * This can actually be a win as culling out the triangles can lead - * to less work emitting vertices, smaller vertex buffers, etc. - * It's difficult to say whether this will be true in general. - */ - if (need_det || draw->rasterizer->cull_mode) { - draw->pipeline.cull->next = next; - next = draw->pipeline.cull; - } - - /* Clip stage - */ - if (!draw->rasterizer->bypass_clipping) - { - draw->pipeline.clip->next = next; - next = draw->pipeline.clip; - } - - - draw->pipeline.first = next; - return next; -} - -static void validate_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->tri( pipeline, header ); -} - -static void validate_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->line( pipeline, header ); -} - -static void validate_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->point( pipeline, header ); -} - -static void validate_reset_stipple_counter( struct draw_stage *stage ) -{ - struct draw_stage *pipeline = validate_pipeline( stage ); - pipeline->reset_stipple_counter( pipeline ); -} - -static void validate_flush( struct draw_stage *stage, - unsigned flags ) -{ - /* May need to pass a backend flush on to the rasterize stage. - */ - if (stage->next) - stage->next->flush( stage->next, flags ); -} - - -static void validate_destroy( struct draw_stage *stage ) -{ - FREE( stage ); -} - - -/** - * Create validate pipeline stage. - */ -struct draw_stage *draw_validate_stage( struct draw_context *draw ) -{ - struct draw_stage *stage = CALLOC_STRUCT(draw_stage); - - stage->draw = draw; - stage->next = NULL; - stage->point = validate_point; - stage->line = validate_line; - stage->tri = validate_tri; - stage->flush = validate_flush; - stage->reset_stipple_counter = validate_reset_stipple_counter; - stage->destroy = validate_destroy; - - return stage; -} diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c deleted file mode 100644 index 30dceeb43d..0000000000 --- a/src/gallium/auxiliary/draw/draw_vbuf.c +++ /dev/null @@ -1,529 +0,0 @@ -/************************************************************************** - * - * 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. - * - **************************************************************************/ - -/** - * \file - * Vertex buffer drawing stage. - * - * \author José Fonseca - * \author Keith Whitwell - */ - - -#include "pipe/p_debug.h" -#include "pipe/p_util.h" - -#include "draw_vbuf.h" -#include "draw_private.h" -#include "draw_vertex.h" -#include "translate/translate.h" - - -/** - * Vertex buffer emit stage. - */ -struct vbuf_stage { - struct draw_stage stage; /**< This must be first (base class) */ - - struct vbuf_render *render; - - const struct vertex_info *vinfo; - - /** Vertex size in bytes */ - unsigned vertex_size; - - struct translate *translate; - - /* FIXME: we have no guarantee that 'unsigned' is 32bit */ - - /** Vertices in hardware format */ - unsigned *vertices; - unsigned *vertex_ptr; - unsigned max_vertices; - unsigned nr_vertices; - - /** Indices */ - ushort *indices; - unsigned max_indices; - unsigned nr_indices; - - /* Cache point size somewhere it's address won't change: - */ - float point_size; -}; - - -/** - * Basically a cast wrapper. - */ -static INLINE struct vbuf_stage * -vbuf_stage( struct draw_stage *stage ) -{ - assert(stage); - return (struct vbuf_stage *)stage; -} - - -static void vbuf_flush_indices( struct vbuf_stage *vbuf ); -static void vbuf_flush_vertices( struct vbuf_stage *vbuf ); -static void vbuf_alloc_vertices( struct vbuf_stage *vbuf ); - - -static INLINE boolean -overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz ) -{ - unsigned long used = (unsigned long) ((char *)ptr - (char *)map); - return (used + bytes) > bufsz; -} - - -static INLINE void -check_space( struct vbuf_stage *vbuf, unsigned nr ) -{ - if (vbuf->nr_vertices + nr > vbuf->max_vertices ) { - vbuf_flush_vertices(vbuf); - vbuf_alloc_vertices(vbuf); - } - - if (vbuf->nr_indices + nr > vbuf->max_indices ) - vbuf_flush_indices(vbuf); -} - - -static INLINE void -dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) -{ -// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - unsigned i, j; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - debug_printf("EMIT_OMIT:"); - break; - case EMIT_1F: - debug_printf("EMIT_1F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_1F_PSIZE: - debug_printf("EMIT_1F_PSIZE:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_2F: - debug_printf("EMIT_2F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_3F: - debug_printf("EMIT_3F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - data += sizeof(float); - break; - case EMIT_4F: - debug_printf("EMIT_4F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_4UB: - debug_printf("EMIT_4UB:\t"); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - break; - default: - assert(0); - } - debug_printf("\n"); - } - debug_printf("\n"); -} - - -/** - * Extract the needed fields from post-transformed vertex and emit - * a hardware(driver) vertex. - * Recall that the vertices are constructed by the 'draw' module and - * have a couple of slots at the beginning (1-dword header, 4-dword - * clip pos) that we ignore here. We only use the vertex->data[] fields. - */ -static INLINE ushort -emit_vertex( struct vbuf_stage *vbuf, - struct vertex_header *vertex ) -{ - if(vertex->vertex_id == UNDEFINED_VERTEX_ID) { - /* Hmm - vertices are emitted one at a time - better make sure - * set_buffer is efficient. Consider a special one-shot mode for - * translate. - */ - vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); - vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); - - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); - - vbuf->vertex_ptr += vbuf->vertex_size/4; - vertex->vertex_id = vbuf->nr_vertices++; - } - - return vertex->vertex_id; -} - - -static void -vbuf_tri( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - check_space( vbuf, 3 ); - - for (i = 0; i < 3; i++) { - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); - } -} - - -static void -vbuf_line( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - unsigned i; - - check_space( vbuf, 2 ); - - for (i = 0; i < 2; i++) { - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] ); - } -} - - -static void -vbuf_point( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - check_space( vbuf, 1 ); - - vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] ); -} - - - - -/** - * Set the prim type for subsequent vertices. - * This may result in a new vertex size. The existing vbuffer (if any) - * will be flushed if needed and a new one allocated. - */ -static void -vbuf_set_prim( struct vbuf_stage *vbuf, uint prim ) -{ - struct translate_key hw_key; - unsigned dst_offset; - unsigned i; - - vbuf->render->set_primitive(vbuf->render, prim); - - /* Must do this after set_primitive() above: - * - * XXX: need some state managment to track when this needs to be - * recalculated. The driver should tell us whether there was a - * state change. - */ - vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render); - - if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) { - vbuf_flush_vertices(vbuf); - vbuf->vertex_size = vbuf->vinfo->size * sizeof(float); - } - - /* Translate from pipeline vertices to hw vertices. - */ - dst_offset = 0; - memset(&hw_key, 0, sizeof(hw_key)); - - for (i = 0; i < vbuf->vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned src_buffer = 0; - unsigned output_format; - unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) ); - - switch (vbuf->vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - src_buffer = 1; - src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; - emit_sz = 4 * sizeof(ubyte); - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; - } - - hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - hw_key.element[i].input_buffer = src_buffer; - hw_key.element[i].input_offset = src_offset; - hw_key.element[i].output_format = output_format; - hw_key.element[i].output_offset = dst_offset; - - dst_offset += emit_sz; - } - - hw_key.nr_elements = vbuf->vinfo->num_attribs; - hw_key.output_stride = vbuf->vinfo->size * 4; - - /* Don't bother with caching at this stage: - */ - if (!vbuf->translate || - memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) - { - if (vbuf->translate) - vbuf->translate->release(vbuf->translate); - - vbuf->translate = translate_create( &hw_key ); - - vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0); - } - - vbuf->point_size = vbuf->stage.draw->rasterizer->point_size; - - /* Allocate new buffer? - */ - if (!vbuf->vertices) - vbuf_alloc_vertices(vbuf); -} - - -static void -vbuf_first_tri( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->tri = vbuf_tri; - vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES); - stage->tri( stage, prim ); -} - - -static void -vbuf_first_line( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->line = vbuf_line; - vbuf_set_prim(vbuf, PIPE_PRIM_LINES); - stage->line( stage, prim ); -} - - -static void -vbuf_first_point( struct draw_stage *stage, - struct prim_header *prim ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - stage->point = vbuf_point; - vbuf_set_prim(vbuf, PIPE_PRIM_POINTS); - stage->point( stage, prim ); -} - - -static void -vbuf_flush_indices( struct vbuf_stage *vbuf ) -{ - if(!vbuf->nr_indices) - return; - - assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == - vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned)); - - vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices); - - vbuf->nr_indices = 0; -} - - -/** - * Flush existing vertex buffer and allocate a new one. - * - * XXX: We separate flush-on-index-full and flush-on-vb-full, but may - * raise issues uploading vertices if the hardware wants to flush when - * we flush. - */ -static void -vbuf_flush_vertices( struct vbuf_stage *vbuf ) -{ - if(vbuf->vertices) { - vbuf_flush_indices(vbuf); - - /* Reset temporary vertices ids */ - if(vbuf->nr_vertices) - draw_reset_vertex_ids( vbuf->stage.draw ); - - /* Free the vertex buffer */ - vbuf->render->release_vertices(vbuf->render, - vbuf->vertices, - vbuf->vertex_size, - vbuf->nr_vertices); - vbuf->max_vertices = vbuf->nr_vertices = 0; - vbuf->vertex_ptr = vbuf->vertices = NULL; - - } -} - - -static void -vbuf_alloc_vertices( struct vbuf_stage *vbuf ) -{ - assert(!vbuf->nr_indices); - assert(!vbuf->vertices); - - /* Allocate a new vertex buffer */ - vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size; - vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render, - (ushort) vbuf->vertex_size, - (ushort) vbuf->max_vertices); - vbuf->vertex_ptr = vbuf->vertices; -} - - - -static void -vbuf_flush( struct draw_stage *stage, unsigned flags ) -{ - struct vbuf_stage *vbuf = vbuf_stage( stage ); - - vbuf_flush_indices( vbuf ); - - stage->point = vbuf_first_point; - stage->line = vbuf_first_line; - stage->tri = vbuf_first_tri; - - if (flags & DRAW_FLUSH_BACKEND) - vbuf_flush_vertices( vbuf ); -} - - -static void -vbuf_reset_stipple_counter( struct draw_stage *stage ) -{ - /* XXX: Need to do something here for hardware with linestipple. - */ - (void) stage; -} - - -static void vbuf_destroy( struct draw_stage *stage ) -{ - struct vbuf_stage *vbuf = vbuf_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 ); - - FREE( stage ); -} - - -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *draw_vbuf_stage( struct draw_context *draw, - struct vbuf_render *render ) -{ - struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); - - if(!vbuf) - goto fail; - - vbuf->stage.draw = draw; - vbuf->stage.point = vbuf_first_point; - vbuf->stage.line = vbuf_first_line; - vbuf->stage.tri = vbuf_first_tri; - vbuf->stage.flush = vbuf_flush; - vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter; - vbuf->stage.destroy = vbuf_destroy; - - vbuf->render = render; - vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1); - - vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * - sizeof(vbuf->indices[0]), - 16 ); - if(!vbuf->indices) - goto fail; - - vbuf->vertices = NULL; - vbuf->vertex_ptr = vbuf->vertices; - - return &vbuf->stage; - - fail: - if (vbuf) - vbuf_destroy(&vbuf->stage); - - return NULL; -} diff --git a/src/gallium/auxiliary/draw/draw_wide_line.c b/src/gallium/auxiliary/draw/draw_wide_line.c deleted file mode 100644 index 9a168ce8bd..0000000000 --- a/src/gallium/auxiliary/draw/draw_wide_line.c +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct wideline_stage { - struct draw_stage stage; - - float half_line_width; -}; - - - -static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) -{ - return (struct wideline_stage *)stage; -} - - -static void wideline_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void wideline_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad (two triangles). - * XXX need to disable polygon stipple. - */ -static void wideline_line( struct draw_stage *stage, - struct prim_header *header ) -{ - /*const struct wideline_stage *wide = wideline_stage(stage);*/ - const float half_width = 0.5f * stage->draw->rasterizer->line_width; - - struct prim_header tri; - - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); - - /* small tweak to meet GL specification */ - const float bias = 0.125f; - - /* - * Draw wide line as a quad (two tris) by "stretching" the line along - * X or Y. - * We need to tweak coords in several ways to be conformant here. - */ - - if (dx > dy) { - /* x-major line */ - pos0[1] = pos0[1] - half_width - bias; - pos1[1] = pos1[1] + half_width - bias; - pos2[1] = pos2[1] - half_width - bias; - pos3[1] = pos3[1] + half_width - bias; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; - } - } - else { - /* y-major line */ - pos0[0] = pos0[0] - half_width + bias; - pos1[0] = pos1[0] + half_width + bias; - pos2[0] = pos2[0] - half_width + bias; - pos3[0] = pos3[0] + half_width + bias; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; - } - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void wideline_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->next->flush( stage->next, flags ); -} - - -static void wideline_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void wideline_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) -{ - struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = wideline_point; - wide->stage.line = wideline_line; - wide->stage.tri = wideline_tri; - wide->stage.flush = wideline_flush; - wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; - wide->stage.destroy = wideline_destroy; - - return &wide->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c deleted file mode 100644 index 3d0add0c1a..0000000000 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ /dev/null @@ -1,281 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_vs.h" - - -struct widepoint_stage { - struct draw_stage stage; - - float half_point_size; - float point_size_min; - float point_size_max; - - float xbias; - float ybias; - - uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; - uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; - uint num_texcoords; - - int psize_slot; -}; - - - -static INLINE struct widepoint_stage * -widepoint_stage( struct draw_stage *stage ) -{ - return (struct widepoint_stage *)stage; -} - - -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void widepoint_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void widepoint_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Set the vertex texcoords for sprite mode. - * Coords may be left untouched or set to a right-side-up or upside-down - * orientation. - */ -static void set_texcoords(const struct widepoint_stage *wide, - struct vertex_header *v, const float tc[4]) -{ - uint i; - for (i = 0; i < wide->num_texcoords; i++) { - if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { - uint j = wide->texcoord_slot[i]; - v->data[j][0] = tc[0]; - if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) - v->data[j][1] = 1.0f - tc[1]; - else - v->data[j][1] = tc[1]; - v->data[j][2] = tc[2]; - v->data[j][3] = tc[3]; - } - } -} - - -/* If there are lots of sprite points (and why wouldn't there be?) it - * would probably be more sensible to change hardware setup to - * optimize this rather than doing the whole thing in software like - * this. - */ -static void widepoint_point( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct widepoint_stage *wide = widepoint_stage(stage); - const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; - float half_size; - float left_adj, right_adj, bot_adj, top_adj; - - struct prim_header tri; - - /* four dups of original vertex */ - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - /* point size is either per-vertex or fixed size */ - if (wide->psize_slot >= 0) { - half_size = header->v[0]->data[wide->psize_slot][0]; - - /* XXX: temporary -- do this in the vertex shader?? - */ - half_size = CLAMP(half_size, - wide->point_size_min, - wide->point_size_max); - - half_size *= 0.5f; - } - else { - half_size = wide->half_point_size; - } - - left_adj = -half_size + wide->xbias; - right_adj = half_size + wide->xbias; - bot_adj = half_size + wide->ybias; - top_adj = -half_size + wide->ybias; - - pos0[0] += left_adj; - pos0[1] += top_adj; - - pos1[0] += left_adj; - pos1[1] += bot_adj; - - pos2[0] += right_adj; - pos2[1] += top_adj; - - pos3[0] += right_adj; - pos3[1] += bot_adj; - - if (sprite) { - static const float tex00[4] = { 0, 0, 0, 1 }; - static const float tex01[4] = { 0, 1, 0, 1 }; - static const float tex11[4] = { 1, 1, 0, 1 }; - static const float tex10[4] = { 1, 0, 0, 1 }; - set_texcoords( wide, v0, tex00 ); - set_texcoords( wide, v1, tex01 ); - set_texcoords( wide, v2, tex10 ); - set_texcoords( wide, v3, tex11 ); - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void widepoint_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct widepoint_stage *wide = widepoint_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_point_size = 0.5f * draw->rasterizer->point_size; - wide->point_size_min = draw->rasterizer->point_size_min; - wide->point_size_max = draw->rasterizer->point_size_max; - wide->xbias = 0.0; - wide->ybias = 0.0; - - if (draw->rasterizer->gl_rasterization_rules) { - wide->xbias = 0.125; - } - - /* XXX we won't know the real size if it's computed by the vertex shader! */ - if ((draw->rasterizer->point_size > draw->wide_point_threshold) || - (draw->rasterizer->point_sprite && draw->point_sprite)) { - stage->point = widepoint_point; - } - else { - stage->point = passthrough_point; - } - - if (draw->rasterizer->point_sprite) { - /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i, j = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { - wide->texcoord_slot[j] = i; - wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; - j++; - } - } - wide->num_texcoords = j; - } - - wide->psize_slot = -1; - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - wide->psize_slot = i; - break; - } - } - } - - stage->point( stage, header ); -} - - -static void widepoint_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->point = widepoint_first_point; - stage->next->flush( stage->next, flags ); -} - - -static void widepoint_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void widepoint_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) -{ - struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = widepoint_first_point; - wide->stage.line = widepoint_line; - wide->stage.tri = widepoint_tri; - wide->stage.flush = widepoint_flush; - wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter; - wide->stage.destroy = widepoint_destroy; - - return &wide->stage; -} diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c deleted file mode 100644 index d6bff110b4..0000000000 --- a/src/gallium/auxiliary/draw/draw_wide_prims.c +++ /dev/null @@ -1,366 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct wide_stage { - struct draw_stage stage; - - float half_line_width; - float half_point_size; - - uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; - uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; - uint num_texcoords; - - int psize_slot; -}; - - - -static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) -{ - return (struct wide_stage *)stage; -} - - -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void passthrough_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void passthrough_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad (two triangles). - * XXX need to disable polygon stipple. - */ -static void wide_line( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - - struct prim_header tri; - - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); - - /* - * Draw wide line as a quad (two tris) by "stretching" the line along - * X or Y. - * We need to tweak coords in several ways to be conformant here. - */ - - if (dx > dy) { - /* x-major line */ - pos0[1] = pos0[1] - half_width - 0.25f; - pos1[1] = pos1[1] + half_width - 0.25f; - pos2[1] = pos2[1] - half_width - 0.25f; - pos3[1] = pos3[1] + half_width - 0.25f; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; - } - } - else { - /* y-major line */ - pos0[0] = pos0[0] - half_width + 0.25f; - pos1[0] = pos1[0] + half_width + 0.25f; - pos2[0] = pos2[0] - half_width + 0.25f; - pos3[0] = pos3[0] + half_width + 0.25f; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; - } - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -/** - * Set the vertex texcoords for sprite mode. - * Coords may be left untouched or set to a right-side-up or upside-down - * orientation. - */ -static void set_texcoords(const struct wide_stage *wide, - struct vertex_header *v, const float tc[4]) -{ - uint i; - for (i = 0; i < wide->num_texcoords; i++) { - if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { - uint j = wide->texcoord_slot[i]; - v->data[j][0] = tc[0]; - if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) - v->data[j][1] = 1.0f - tc[1]; - else - v->data[j][1] = tc[1]; - v->data[j][2] = tc[2]; - v->data[j][3] = tc[3]; - } - } -} - - -/* If there are lots of sprite points (and why wouldn't there be?) it - * would probably be more sensible to change hardware setup to - * optimize this rather than doing the whole thing in software like - * this. - */ -static void wide_point( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; - float half_size; - float left_adj, right_adj; - - struct prim_header tri; - - /* four dups of original vertex */ - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - /* point size is either per-vertex or fixed size */ - if (wide->psize_slot >= 0) { - half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; - } - else { - half_size = wide->half_point_size; - } - - left_adj = -half_size; /* + 0.25f;*/ - right_adj = half_size; /* + 0.25f;*/ - - pos0[0] += left_adj; - pos0[1] -= half_size; - - pos1[0] += left_adj; - pos1[1] += half_size; - - pos2[0] += right_adj; - pos2[1] -= half_size; - - pos3[0] += right_adj; - pos3[1] += half_size; - - if (sprite) { - static const float tex00[4] = { 0, 0, 0, 1 }; - static const float tex01[4] = { 0, 1, 0, 1 }; - static const float tex11[4] = { 1, 1, 0, 1 }; - static const float tex10[4] = { 1, 0, 0, 1 }; - set_texcoords( wide, v0, tex00 ); - set_texcoords( wide, v1, tex01 ); - set_texcoords( wide, v2, tex10 ); - set_texcoords( wide, v3, tex11 ); - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void wide_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_point_size = 0.5f * draw->rasterizer->point_size; - - /* XXX we won't know the real size if it's computed by the vertex shader! */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) { - stage->point = wide_point; - } - else { - stage->point = passthrough_point; - } - - if (draw->rasterizer->point_sprite) { - /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i, j = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { - wide->texcoord_slot[j] = i; - wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; - j++; - } - } - wide->num_texcoords = j; - } - - wide->psize_slot = -1; - - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - wide->psize_slot = i; - break; - } - } - } - - stage->point( stage, header ); -} - - - -static void wide_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_line_width = 0.5f * draw->rasterizer->line_width; - - if (draw->rasterizer->line_width != 1.0) { - wide->stage.line = wide_line; - } - else { - wide->stage.line = passthrough_line; - } - - stage->line( stage, header ); -} - - -static void wide_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->line = wide_first_line; - stage->point = wide_first_point; - stage->next->flush( stage->next, flags ); -} - - -static void wide_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void wide_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_stage( struct draw_context *draw ) -{ - struct wide_stage *wide = CALLOC_STRUCT(wide_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = wide_first_point; - wide->stage.line = wide_first_line; - wide->stage.tri = passthrough_tri; - wide->stage.flush = wide_flush; - wide->stage.reset_stipple_counter = wide_reset_stipple_counter; - wide->stage.destroy = wide_destroy; - - return &wide->stage; -} -- cgit v1.2.3 From 882e5d84dcb19c24b7b56cfe6049810023f3a17e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 13:12:07 +0100 Subject: draw: remove dead code --- src/gallium/auxiliary/draw/draw_vs.h | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index b6f3bbdaea..f9772b83b8 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -81,33 +81,6 @@ draw_create_vs_llvm(struct draw_context *draw, const struct pipe_shader_state *templ); -/* Should be part of the generated shader: - */ -static INLINE unsigned -compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr) -{ - unsigned mask = 0x0; - unsigned i; - - /* Do the hardwired planes first: - */ - if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; - if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; - if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; - if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; - if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; - if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; - - /* Followed by any remaining ones: - */ - for (i = 6; i < nr; i++) { - if (dot4(clip, plane[i]) < 0) - mask |= (1< Date: Sat, 19 Apr 2008 13:20:26 +0100 Subject: draw: remove named clipmask flags, tidy up pt middle ends --- src/gallium/auxiliary/draw/draw_context.h | 37 +++------------------------- src/gallium/auxiliary/draw/draw_private.h | 9 ++----- src/gallium/auxiliary/draw/draw_pt.c | 36 +++++++++++++-------------- src/gallium/auxiliary/draw/draw_pt.h | 6 +++++ src/gallium/auxiliary/draw/draw_pt_post_vs.c | 12 ++++----- 5 files changed, 35 insertions(+), 65 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index c7ac32b452..a0ac980c89 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -42,37 +42,11 @@ struct pipe_context; -struct vertex_buffer; -struct vertex_info; struct draw_context; struct draw_stage; struct draw_vertex_shader; -/** - * Clipmask flags - */ -/*@{*/ -#define CLIP_RIGHT_BIT 0x01 -#define CLIP_LEFT_BIT 0x02 -#define CLIP_TOP_BIT 0x04 -#define CLIP_BOTTOM_BIT 0x08 -#define CLIP_NEAR_BIT 0x10 -#define CLIP_FAR_BIT 0x20 -/*@}*/ - -/** - * Bitshift for each clip flag - */ -/*@{*/ -#define CLIP_RIGHT_SHIFT 0 -#define CLIP_LEFT_SHIFT 1 -#define CLIP_TOP_SHIFT 2 -#define CLIP_BOTTOM_SHIFT 3 -#define CLIP_NEAR_SHIFT 4 -#define CLIP_FAR_SHIFT 5 -/*@}*/ - struct draw_context *draw_create( void ); @@ -168,15 +142,10 @@ void draw_arrays(struct draw_context *draw, unsigned prim, void draw_flush(struct draw_context *draw); -/*********************************************************************** - * draw_debug.c - */ -boolean draw_validate_prim( unsigned prim, unsigned length ); -unsigned draw_trim_prim( unsigned mode, unsigned count ); - - - +/******************************************************************************* + * Driver backend interface + */ struct vbuf_render; void draw_set_render( struct draw_context *draw, struct vbuf_render *render ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 476b1184d4..37ffdbf902 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -44,7 +44,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_exec.h" #include "tgsi/util/tgsi_scan.h" @@ -171,7 +170,8 @@ struct draw_context */ struct { struct { - struct draw_pt_middle_end *opt[PT_MAX_MIDDLE]; + struct draw_pt_middle_end *fetch_emit; + struct draw_pt_middle_end *general; } middle; struct { @@ -289,11 +289,6 @@ extern boolean draw_need_pipeline(const struct draw_context *draw, */ boolean draw_pt_init( struct draw_context *draw ); void draw_pt_destroy( struct draw_context *draw ); -boolean draw_pt_arrays( struct draw_context *draw, - unsigned prim, - unsigned start, - unsigned count ); - void draw_pt_reset_vertex_ids( struct draw_context *draw ); #define DRAW_FLUSH_STATE_CHANGE 0x8 diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index ecaed84070..f153a3ee2c 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -44,7 +44,7 @@ * - pipeline -- the prim pipeline: clipping, wide lines, etc * - backend -- the vbuf_render provided by the driver. */ -boolean +static boolean draw_pt_arrays(struct draw_context *draw, unsigned prim, unsigned start, @@ -70,19 +70,16 @@ draw_pt_arrays(struct draw_context *draw, opt |= PT_SHADE; } + if (opt) + middle = draw->pt.middle.general; + else + middle = draw->pt.middle.fetch_emit; - middle = draw->pt.middle.opt[opt]; - if (middle == NULL) { - middle = draw->pt.middle.opt[PT_PIPELINE | PT_CLIPTEST | PT_SHADE]; - } - - assert(middle); /* May create a short-circuited version of this for small primitives: */ frontend = draw->pt.front.vcache; - frontend->prepare( frontend, prim, middle, opt ); frontend->run( frontend, @@ -102,11 +99,12 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.front.vcache) return FALSE; - draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw ); - draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] = - draw_pt_fetch_pipeline_or_emit( draw ); + draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw ); + if (!draw->pt.middle.fetch_emit) + return FALSE; - if (!draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE]) + draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit( draw ); + if (!draw->pt.middle.general) return FALSE; return TRUE; @@ -115,13 +113,15 @@ boolean draw_pt_init( struct draw_context *draw ) void draw_pt_destroy( struct draw_context *draw ) { - int i; + if (draw->pt.middle.general) { + draw->pt.middle.general->destroy( draw->pt.middle.general ); + draw->pt.middle.general = NULL; + } - for (i = 0; i < PT_MAX_MIDDLE; i++) - if (draw->pt.middle.opt[i]) { - draw->pt.middle.opt[i]->destroy( draw->pt.middle.opt[i] ); - draw->pt.middle.opt[i] = NULL; - } + if (draw->pt.middle.fetch_emit) { + draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit ); + draw->pt.middle.fetch_emit = NULL; + } if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index eb23ee1c1e..1119e9c6b8 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -50,6 +50,12 @@ struct draw_context; #define DRAW_PT_FLAG_MASK (3<<30) +#define PT_SHADE 0x1 +#define PT_CLIPTEST 0x2 +#define PT_PIPELINE 0x4 +#define PT_MAX_MIDDLE 0x8 + + /* The "front end" - prepare sets of fetch, draw elements for the * middle end. * diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index 315b02f4ee..b3ecec6ece 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -52,12 +52,12 @@ compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) /* Do the hardwired planes first: */ - if (-clip[0] + clip[3] < 0) mask |= CLIP_RIGHT_BIT; - if ( clip[0] + clip[3] < 0) mask |= CLIP_LEFT_BIT; - if (-clip[1] + clip[3] < 0) mask |= CLIP_TOP_BIT; - if ( clip[1] + clip[3] < 0) mask |= CLIP_BOTTOM_BIT; - if (-clip[2] + clip[3] < 0) mask |= CLIP_FAR_BIT; - if ( clip[2] + clip[3] < 0) mask |= CLIP_NEAR_BIT; + if (-clip[0] + clip[3] < 0) mask |= (1<<0); + if ( clip[0] + clip[3] < 0) mask |= (1<<1); + if (-clip[1] + clip[3] < 0) mask |= (1<<2); + if ( clip[1] + clip[3] < 0) mask |= (1<<3); + if ( clip[2] + clip[3] < 0) mask |= (1<<4); /* match mesa clipplane numbering - for now */ + if (-clip[2] + clip[3] < 0) mask |= (1<<5); /* match mesa clipplane numbering - for now */ /* Followed by any remaining ones: */ -- cgit v1.2.3 From 0959f909ba585968f0408e78961e1c0ffc69a9f8 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 13:30:19 +0100 Subject: draw: remove dead file pipe_wide_prims.c --- src/gallium/auxiliary/draw/draw_pipe_wide_prims.c | 366 ---------------------- 1 file changed, 366 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pipe_wide_prims.c diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c b/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c deleted file mode 100644 index d6bff110b4..0000000000 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c +++ /dev/null @@ -1,366 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "draw_private.h" - - -struct wide_stage { - struct draw_stage stage; - - float half_line_width; - float half_point_size; - - uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; - uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; - uint num_texcoords; - - int psize_slot; -}; - - - -static INLINE struct wide_stage *wide_stage( struct draw_stage *stage ) -{ - return (struct wide_stage *)stage; -} - - -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void passthrough_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void passthrough_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - - -/** - * Draw a wide line by drawing a quad (two triangles). - * XXX need to disable polygon stipple. - */ -static void wide_line( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const float half_width = wide->half_line_width; - - struct prim_header tri; - - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[1], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[1], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - const float dx = FABSF(pos0[0] - pos2[0]); - const float dy = FABSF(pos0[1] - pos2[1]); - - /* - * Draw wide line as a quad (two tris) by "stretching" the line along - * X or Y. - * We need to tweak coords in several ways to be conformant here. - */ - - if (dx > dy) { - /* x-major line */ - pos0[1] = pos0[1] - half_width - 0.25f; - pos1[1] = pos1[1] + half_width - 0.25f; - pos2[1] = pos2[1] - half_width - 0.25f; - pos3[1] = pos3[1] + half_width - 0.25f; - if (pos0[0] < pos2[0]) { - /* left to right line */ - pos0[0] -= 0.5f; - pos1[0] -= 0.5f; - pos2[0] -= 0.5f; - pos3[0] -= 0.5f; - } - else { - /* right to left line */ - pos0[0] += 0.5f; - pos1[0] += 0.5f; - pos2[0] += 0.5f; - pos3[0] += 0.5f; - } - } - else { - /* y-major line */ - pos0[0] = pos0[0] - half_width + 0.25f; - pos1[0] = pos1[0] + half_width + 0.25f; - pos2[0] = pos2[0] - half_width + 0.25f; - pos3[0] = pos3[0] + half_width + 0.25f; - if (pos0[1] < pos2[1]) { - /* top to bottom line */ - pos0[1] -= 0.5f; - pos1[1] -= 0.5f; - pos2[1] -= 0.5f; - pos3[1] -= 0.5f; - } - else { - /* bottom to top line */ - pos0[1] += 0.5f; - pos1[1] += 0.5f; - pos2[1] += 0.5f; - pos3[1] += 0.5f; - } - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -/** - * Set the vertex texcoords for sprite mode. - * Coords may be left untouched or set to a right-side-up or upside-down - * orientation. - */ -static void set_texcoords(const struct wide_stage *wide, - struct vertex_header *v, const float tc[4]) -{ - uint i; - for (i = 0; i < wide->num_texcoords; i++) { - if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) { - uint j = wide->texcoord_slot[i]; - v->data[j][0] = tc[0]; - if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT) - v->data[j][1] = 1.0f - tc[1]; - else - v->data[j][1] = tc[1]; - v->data[j][2] = tc[2]; - v->data[j][3] = tc[3]; - } - } -} - - -/* If there are lots of sprite points (and why wouldn't there be?) it - * would probably be more sensible to change hardware setup to - * optimize this rather than doing the whole thing in software like - * this. - */ -static void wide_point( struct draw_stage *stage, - struct prim_header *header ) -{ - const struct wide_stage *wide = wide_stage(stage); - const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite; - float half_size; - float left_adj, right_adj; - - struct prim_header tri; - - /* four dups of original vertex */ - struct vertex_header *v0 = dup_vert(stage, header->v[0], 0); - struct vertex_header *v1 = dup_vert(stage, header->v[0], 1); - struct vertex_header *v2 = dup_vert(stage, header->v[0], 2); - struct vertex_header *v3 = dup_vert(stage, header->v[0], 3); - - float *pos0 = v0->data[0]; - float *pos1 = v1->data[0]; - float *pos2 = v2->data[0]; - float *pos3 = v3->data[0]; - - /* point size is either per-vertex or fixed size */ - if (wide->psize_slot >= 0) { - half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; - } - else { - half_size = wide->half_point_size; - } - - left_adj = -half_size; /* + 0.25f;*/ - right_adj = half_size; /* + 0.25f;*/ - - pos0[0] += left_adj; - pos0[1] -= half_size; - - pos1[0] += left_adj; - pos1[1] += half_size; - - pos2[0] += right_adj; - pos2[1] -= half_size; - - pos3[0] += right_adj; - pos3[1] += half_size; - - if (sprite) { - static const float tex00[4] = { 0, 0, 0, 1 }; - static const float tex01[4] = { 0, 1, 0, 1 }; - static const float tex11[4] = { 1, 1, 0, 1 }; - static const float tex10[4] = { 1, 0, 0, 1 }; - set_texcoords( wide, v0, tex00 ); - set_texcoords( wide, v1, tex01 ); - set_texcoords( wide, v2, tex10 ); - set_texcoords( wide, v3, tex11 ); - } - - tri.det = header->det; /* only the sign matters */ - tri.v[0] = v0; - tri.v[1] = v2; - tri.v[2] = v3; - stage->next->tri( stage->next, &tri ); - - tri.v[0] = v0; - tri.v[1] = v3; - tri.v[2] = v1; - stage->next->tri( stage->next, &tri ); -} - - -static void wide_first_point( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_point_size = 0.5f * draw->rasterizer->point_size; - - /* XXX we won't know the real size if it's computed by the vertex shader! */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) { - stage->point = wide_point; - } - else { - stage->point = passthrough_point; - } - - if (draw->rasterizer->point_sprite) { - /* find vertex shader texcoord outputs */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i, j = 0; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) { - wide->texcoord_slot[j] = i; - wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j]; - j++; - } - } - wide->num_texcoords = j; - } - - wide->psize_slot = -1; - - if (draw->rasterizer->point_size_per_vertex) { - /* find PSIZ vertex output */ - const struct draw_vertex_shader *vs = draw->vertex_shader; - uint i; - for (i = 0; i < vs->info.num_outputs; i++) { - if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) { - wide->psize_slot = i; - break; - } - } - } - - stage->point( stage, header ); -} - - - -static void wide_first_line( struct draw_stage *stage, - struct prim_header *header ) -{ - struct wide_stage *wide = wide_stage(stage); - struct draw_context *draw = stage->draw; - - wide->half_line_width = 0.5f * draw->rasterizer->line_width; - - if (draw->rasterizer->line_width != 1.0) { - wide->stage.line = wide_line; - } - else { - wide->stage.line = passthrough_line; - } - - stage->line( stage, header ); -} - - -static void wide_flush( struct draw_stage *stage, unsigned flags ) -{ - stage->line = wide_first_line; - stage->point = wide_first_point; - stage->next->flush( stage->next, flags ); -} - - -static void wide_reset_stipple_counter( struct draw_stage *stage ) -{ - stage->next->reset_stipple_counter( stage->next ); -} - - -static void wide_destroy( struct draw_stage *stage ) -{ - draw_free_temp_verts( stage ); - FREE( stage ); -} - - -struct draw_stage *draw_wide_stage( struct draw_context *draw ) -{ - struct wide_stage *wide = CALLOC_STRUCT(wide_stage); - - draw_alloc_temp_verts( &wide->stage, 4 ); - - wide->stage.draw = draw; - wide->stage.next = NULL; - wide->stage.point = wide_first_point; - wide->stage.line = wide_first_line; - wide->stage.tri = passthrough_tri; - wide->stage.flush = wide_flush; - wide->stage.reset_stipple_counter = wide_reset_stipple_counter; - wide->stage.destroy = wide_destroy; - - return &wide->stage; -} -- cgit v1.2.3 From 507fbe2d327efb8d608ce8e07436b97321560808 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 15:29:27 +0100 Subject: draw: move some pipeline-specific code & state to draw_pipe.[ch] --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_context.c | 141 +++++-------------- src/gallium/auxiliary/draw/draw_pipe.c | 161 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe.h | 110 +++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_aaline.c | 1 + src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 1 + src/gallium/auxiliary/draw/draw_pipe_clip.c | 11 +- src/gallium/auxiliary/draw/draw_pipe_cull.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 1 + src/gallium/auxiliary/draw/draw_pipe_offset.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 1 + src/gallium/auxiliary/draw/draw_pipe_validate.c | 17 +-- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 1 + src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 1 + src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 5 +- src/gallium/auxiliary/draw/draw_private.h | 132 ++++-------------- src/gallium/auxiliary/draw/draw_pt.c | 18 --- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 1 + src/gallium/auxiliary/draw/draw_pt_post_vs.c | 11 ++ src/gallium/auxiliary/draw/draw_vertex.c | 2 - src/gallium/drivers/i915simple/i915_context.c | 2 +- src/gallium/drivers/i915simple/i915_prim_emit.c | 5 +- src/gallium/drivers/softpipe/sp_prim_setup.c | 2 +- src/mesa/state_tracker/st_cb_feedback.c | 2 +- src/mesa/state_tracker/st_cb_rasterpos.c | 2 +- 28 files changed, 377 insertions(+), 262 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pipe.c create mode 100644 src/gallium/auxiliary/draw/draw_pipe.h diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 62f46c6db1..4fffd11b77 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -5,6 +5,7 @@ LIBNAME = draw C_SOURCES = \ draw_context.c \ + draw_pipe.c \ draw_pipe_aaline.c \ draw_pipe_aapoint.c \ draw_pipe_clip.c \ diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 6012bc155e..fa6791fa0b 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -35,6 +35,8 @@ #include "draw_context.h" #include "draw_vbuf.h" #include "draw_vs.h" +#include "draw_pt.h" +#include "draw_pipe.h" struct draw_context *draw_create( void ) @@ -49,32 +51,6 @@ struct draw_context *draw_create( void ) draw->use_sse = FALSE; #endif - /* create pipeline stages */ - draw->pipeline.wide_line = draw_wide_line_stage( draw ); - draw->pipeline.wide_point = draw_wide_point_stage( draw ); - draw->pipeline.stipple = draw_stipple_stage( draw ); - draw->pipeline.unfilled = draw_unfilled_stage( draw ); - draw->pipeline.twoside = draw_twoside_stage( draw ); - draw->pipeline.offset = draw_offset_stage( draw ); - draw->pipeline.clip = draw_clip_stage( draw ); - draw->pipeline.flatshade = draw_flatshade_stage( draw ); - draw->pipeline.cull = draw_cull_stage( draw ); - draw->pipeline.validate = draw_validate_stage( draw ); - draw->pipeline.first = draw->pipeline.validate; - - if (!draw->pipeline.wide_line || - !draw->pipeline.wide_point || - !draw->pipeline.stipple || - !draw->pipeline.unfilled || - !draw->pipeline.twoside || - !draw->pipeline.offset || - !draw->pipeline.clip || - !draw->pipeline.flatshade || - !draw->pipeline.cull || - !draw->pipeline.validate) - goto fail; - - ASSIGN_4V( draw->plane[0], -1, 0, 0, 1 ); ASSIGN_4V( draw->plane[1], 1, 0, 0, 1 ); ASSIGN_4V( draw->plane[2], 0, -1, 0, 1 ); @@ -83,11 +59,6 @@ struct draw_context *draw_create( void ) ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */ draw->nr_planes = 6; - /* these defaults are oriented toward the needs of softpipe */ - draw->wide_point_threshold = 1000000.0; /* infinity */ - draw->wide_line_threshold = 1.0; - draw->line_stipple = TRUE; - draw->point_sprite = TRUE; draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ @@ -100,6 +71,8 @@ struct draw_context *draw_create( void ) draw->machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); draw->machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16); + if (!draw_pipeline_init( draw )) + goto fail; if (!draw_pt_init( draw )) goto fail; @@ -117,39 +90,13 @@ void draw_destroy( struct draw_context *draw ) if (!draw) return; - if (draw->pipeline.wide_line) - draw->pipeline.wide_line->destroy( draw->pipeline.wide_line ); - if (draw->pipeline.wide_point) - draw->pipeline.wide_point->destroy( draw->pipeline.wide_point ); - if (draw->pipeline.stipple) - draw->pipeline.stipple->destroy( draw->pipeline.stipple ); - if (draw->pipeline.unfilled) - draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); - if (draw->pipeline.twoside) - draw->pipeline.twoside->destroy( draw->pipeline.twoside ); - if (draw->pipeline.offset) - draw->pipeline.offset->destroy( draw->pipeline.offset ); - if (draw->pipeline.clip) - draw->pipeline.clip->destroy( draw->pipeline.clip ); - if (draw->pipeline.flatshade) - draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); - if (draw->pipeline.cull) - draw->pipeline.cull->destroy( draw->pipeline.cull ); - if (draw->pipeline.validate) - draw->pipeline.validate->destroy( draw->pipeline.validate ); - if (draw->pipeline.aaline) - draw->pipeline.aaline->destroy( draw->pipeline.aaline ); - if (draw->pipeline.aapoint) - draw->pipeline.aapoint->destroy( draw->pipeline.aapoint ); - if (draw->pipeline.pstipple) - draw->pipeline.pstipple->destroy( draw->pipeline.pstipple ); - if (draw->pipeline.rasterize) - draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); if (draw->machine.Inputs) align_free(draw->machine.Inputs); + if (draw->machine.Outputs) align_free(draw->machine.Outputs); + tgsi_exec_machine_free_data(&draw->machine); /* Not so fast -- we're just borrowing this at the moment. @@ -158,6 +105,7 @@ void draw_destroy( struct draw_context *draw ) draw->render->destroy( draw->render ); */ + draw_pipeline_destroy( draw ); draw_pt_destroy( draw ); FREE( draw ); @@ -284,7 +232,7 @@ void draw_wide_point_threshold(struct draw_context *draw, float threshold) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->wide_point_threshold = threshold; + draw->pipeline.wide_point_threshold = threshold; } @@ -296,7 +244,7 @@ void draw_wide_line_threshold(struct draw_context *draw, float threshold) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->wide_line_threshold = threshold; + draw->pipeline.wide_line_threshold = threshold; } @@ -307,7 +255,7 @@ void draw_enable_line_stipple(struct draw_context *draw, boolean enable) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->line_stipple = enable; + draw->pipeline.line_stipple = enable; } @@ -318,7 +266,7 @@ void draw_enable_point_sprites(struct draw_context *draw, boolean enable) { draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); - draw->point_sprite = enable; + draw->pipeline.point_sprite = enable; } @@ -373,36 +321,6 @@ draw_num_vs_outputs(struct draw_context *draw) } -/** - * Allocate space for temporary post-transform vertices, such as for clipping. - */ -void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) -{ - assert(!stage->tmp); - - stage->nr_tmps = nr; - - if (nr) { - ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); - unsigned i; - - stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); - } -} - - -void draw_free_temp_verts( struct draw_stage *stage ) -{ - if (stage->tmp) { - FREE( stage->tmp[0] ); - FREE( stage->tmp ); - stage->tmp = NULL; - } -} - boolean draw_use_sse(struct draw_context *draw) { @@ -410,23 +328,6 @@ boolean draw_use_sse(struct draw_context *draw) } -void draw_reset_vertex_ids(struct draw_context *draw) -{ - struct draw_stage *stage = draw->pipeline.first; - - while (stage) { - unsigned i; - - for (i = 0; i < stage->nr_tmps; i++) - stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; - - stage = stage->next; - } - - draw_pt_reset_vertex_ids(draw); -} - - void draw_set_render( struct draw_context *draw, struct vbuf_render *render ) { @@ -467,3 +368,23 @@ draw_set_mapped_element_buffer( struct draw_context *draw, draw->user.elts = elements; draw->user.eltSize = eltSize; } + + + +/* Revamp me please: + */ +void draw_do_flush( struct draw_context *draw, unsigned flags ) +{ + if (!draw->flushing) + { + draw->flushing = TRUE; + + if (flags >= DRAW_FLUSH_STATE_CHANGE) { + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; + draw->reduced_prim = ~0; /* is reduced_prim needed any more? */ + } + + draw->flushing = FALSE; + } +} diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c new file mode 100644 index 0000000000..9d62cb2c65 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -0,0 +1,161 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "draw/draw_private.h" +#include "draw/draw_pipe.h" + + +boolean draw_pipeline_init( struct draw_context *draw ) +{ + /* create pipeline stages */ + draw->pipeline.wide_line = draw_wide_line_stage( draw ); + draw->pipeline.wide_point = draw_wide_point_stage( draw ); + draw->pipeline.stipple = draw_stipple_stage( draw ); + draw->pipeline.unfilled = draw_unfilled_stage( draw ); + draw->pipeline.twoside = draw_twoside_stage( draw ); + draw->pipeline.offset = draw_offset_stage( draw ); + draw->pipeline.clip = draw_clip_stage( draw ); + draw->pipeline.flatshade = draw_flatshade_stage( draw ); + draw->pipeline.cull = draw_cull_stage( draw ); + draw->pipeline.validate = draw_validate_stage( draw ); + draw->pipeline.first = draw->pipeline.validate; + + if (!draw->pipeline.wide_line || + !draw->pipeline.wide_point || + !draw->pipeline.stipple || + !draw->pipeline.unfilled || + !draw->pipeline.twoside || + !draw->pipeline.offset || + !draw->pipeline.clip || + !draw->pipeline.flatshade || + !draw->pipeline.cull || + !draw->pipeline.validate) + return FALSE; + + /* these defaults are oriented toward the needs of softpipe */ + draw->pipeline.wide_point_threshold = 1000000.0; /* infinity */ + draw->pipeline.wide_line_threshold = 1.0; + draw->pipeline.line_stipple = TRUE; + draw->pipeline.point_sprite = TRUE; + + return TRUE; +} + + +void draw_pipeline_destroy( struct draw_context *draw ) +{ + if (draw->pipeline.wide_line) + draw->pipeline.wide_line->destroy( draw->pipeline.wide_line ); + if (draw->pipeline.wide_point) + draw->pipeline.wide_point->destroy( draw->pipeline.wide_point ); + if (draw->pipeline.stipple) + draw->pipeline.stipple->destroy( draw->pipeline.stipple ); + if (draw->pipeline.unfilled) + draw->pipeline.unfilled->destroy( draw->pipeline.unfilled ); + if (draw->pipeline.twoside) + draw->pipeline.twoside->destroy( draw->pipeline.twoside ); + if (draw->pipeline.offset) + draw->pipeline.offset->destroy( draw->pipeline.offset ); + if (draw->pipeline.clip) + draw->pipeline.clip->destroy( draw->pipeline.clip ); + if (draw->pipeline.flatshade) + draw->pipeline.flatshade->destroy( draw->pipeline.flatshade ); + if (draw->pipeline.cull) + draw->pipeline.cull->destroy( draw->pipeline.cull ); + if (draw->pipeline.validate) + draw->pipeline.validate->destroy( draw->pipeline.validate ); + if (draw->pipeline.aaline) + draw->pipeline.aaline->destroy( draw->pipeline.aaline ); + if (draw->pipeline.aapoint) + draw->pipeline.aapoint->destroy( draw->pipeline.aapoint ); + if (draw->pipeline.pstipple) + draw->pipeline.pstipple->destroy( draw->pipeline.pstipple ); + if (draw->pipeline.rasterize) + draw->pipeline.rasterize->destroy( draw->pipeline.rasterize ); +} + + + + +/* This is only used for temporary verts. + */ +#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) + + +/** + * Allocate space for temporary post-transform vertices, such as for clipping. + */ +void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) +{ + assert(!stage->tmp); + + stage->nr_tmps = nr; + + if (nr) { + ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + unsigned i; + + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + } +} + + +void draw_free_temp_verts( struct draw_stage *stage ) +{ + if (stage->tmp) { + FREE( stage->tmp[0] ); + FREE( stage->tmp ); + stage->tmp = NULL; + } +} + +void draw_reset_vertex_ids(struct draw_context *draw) +{ + struct draw_stage *stage = draw->pipeline.first; + + while (stage) { + unsigned i; + + for (i = 0; i < stage->nr_tmps; i++) + stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; + + stage = stage->next; + } + + draw_pt_reset_vertex_ids(draw); +} + + diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h new file mode 100644 index 0000000000..5b97ca5c8c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -0,0 +1,110 @@ +/************************************************************************** + * + * 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 + */ + +#ifndef DRAW_PIPE_H +#define DRAW_PIPE_H + +#include "pipe/p_compiler.h" +#include "draw_private.h" /* for sizeof(vertex_header) */ + + + +/** + * Base class for all primitive drawing stages. + */ +struct draw_stage +{ + struct draw_context *draw; /**< parent context */ + + struct draw_stage *next; /**< next stage in pipeline */ + + struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ + unsigned nr_tmps; + + void (*point)( struct draw_stage *, + struct prim_header * ); + + void (*line)( struct draw_stage *, + struct prim_header * ); + + void (*tri)( struct draw_stage *, + struct prim_header * ); + + void (*flush)( struct draw_stage *, + unsigned flags ); + + void (*reset_stipple_counter)( struct draw_stage * ); + + void (*destroy)( struct draw_stage * ); +}; + + +extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); +extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); +extern struct draw_stage *draw_offset_stage( struct draw_context *context ); +extern struct draw_stage *draw_clip_stage( struct draw_context *context ); +extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); +extern struct draw_stage *draw_cull_stage( struct draw_context *context ); +extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_line_stage( struct draw_context *context ); +extern struct draw_stage *draw_wide_point_stage( struct draw_context *context ); +extern struct draw_stage *draw_validate_stage( struct draw_context *context ); + + +extern void draw_free_temp_verts( struct draw_stage *stage ); + +extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); + + + + +/** + * Get a writeable copy of a vertex. + * \param stage drawing stage info + * \param vert the vertex to copy (source) + * \param idx index into stage's tmp[] array to put the copy (dest) + * \return pointer to the copied vertex + */ +static INLINE struct vertex_header * +dup_vert( struct draw_stage *stage, + const struct vertex_header *vert, + unsigned idx ) +{ + struct vertex_header *tmp = stage->tmp[idx]; + const uint vsize = sizeof(struct vertex_header) + + stage->draw->num_vs_outputs * 4 * sizeof(float); + memcpy(tmp, vert, vsize); + tmp->vertex_id = UNDEFINED_VERTEX_ID; + return tmp; +} + +#endif diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index e8d2a45102..24bc87d4f8 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -43,6 +43,7 @@ #include "draw_context.h" #include "draw_private.h" +#include "draw_pipe.h" /** diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index e84d380e50..9f878f6c02 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -49,6 +49,7 @@ #include "draw_context.h" #include "draw_vs.h" +#include "draw_pipe.h" /* diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 0ac3a240e5..6780f275d9 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -35,8 +35,8 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" -#include "draw_context.h" #include "draw_vs.h" +#include "draw_pipe.h" #ifndef IS_NEGATIVE @@ -204,7 +204,14 @@ static void emit_poly( struct draw_stage *stage, } } - +static INLINE float +dot4(const float *a, const float *b) +{ + return (a[0]*b[0] + + a[1]*b[1] + + a[2]*b[2] + + a[3]*b[3]); +} /* Clip a triangle against the viewport and user clip planes. diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index 8177b0ac86..c406f89d05 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -35,7 +35,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" -#include "draw_private.h" +#include "draw_pipe.h" struct cull_stage { diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 54baa1fbc9..bdb8b49dc4 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -31,6 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" +#include "draw_pipe.h" /** subclass of draw_stage */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index dbc676deae..dbdece45bb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -33,7 +33,7 @@ */ #include "pipe/p_util.h" -#include "draw_private.h" +#include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 4dddb72906..4903ba2133 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -44,7 +44,7 @@ #include "tgsi/util/tgsi_dump.h" #include "draw_context.h" -#include "draw_private.h" +#include "draw_pipe.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 506f33512c..49429ee9e1 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -39,7 +39,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" -#include "draw_private.h" +#include "draw_pipe.h" /** Subclass of draw_stage */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 01d905c153..09a9d23d57 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -32,7 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" - +#include "draw_pipe.h" struct twoside_stage { struct draw_stage stage; diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index b07860cd9e..31e24f6a14 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -36,6 +36,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "draw_private.h" +#include "draw_pipe.h" struct unfilled_stage { diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index e163e078f0..ffddc2f62c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -31,6 +31,7 @@ #include "pipe/p_util.h" #include "pipe/p_defines.h" #include "draw_private.h" +#include "draw_pipe.h" static boolean points( unsigned prim ) { @@ -66,11 +67,11 @@ draw_need_pipeline(const struct draw_context *draw, if (lines(prim)) { /* line stipple */ - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) + if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) return TRUE; /* wide lines */ - if (draw->rasterizer->line_width > draw->wide_line_threshold) + if (draw->rasterizer->line_width > draw->pipeline.wide_line_threshold) return TRUE; /* AA lines */ @@ -81,7 +82,7 @@ draw_need_pipeline(const struct draw_context *draw, if (points(prim)) { /* large points */ - if (draw->rasterizer->point_size > draw->wide_point_threshold) + if (draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) return TRUE; /* AA points */ @@ -89,7 +90,7 @@ draw_need_pipeline(const struct draw_context *draw, return TRUE; /* point sprites */ - if (draw->rasterizer->point_sprite && draw->point_sprite) + if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite) return TRUE; } @@ -145,15 +146,15 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) stage->next = next; /* drawing wide lines? */ - wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold + wide_lines = (draw->rasterizer->line_width > draw->pipeline.wide_line_threshold && !draw->rasterizer->line_smooth); /* drawing large points? */ - if (draw->rasterizer->point_sprite && draw->point_sprite) + if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite) wide_points = TRUE; else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) wide_points = FALSE; - else if (draw->rasterizer->point_size > draw->wide_point_threshold) + else if (draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) wide_points = TRUE; else wide_points = FALSE; @@ -186,7 +187,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) next = draw->pipeline.wide_point; } - if (draw->rasterizer->line_stipple_enable && draw->line_stipple) { + if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) { draw->pipeline.stipple->next = next; next = draw->pipeline.stipple; precalc_flat = 1; /* only needed for lines really */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index 30dceeb43d..c835727e32 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -40,6 +40,7 @@ #include "draw_vbuf.h" #include "draw_private.h" #include "draw_vertex.h" +#include "draw_pipe.h" #include "translate/translate.h" diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 9a168ce8bd..329b5d0fb0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_private.h" +#include "draw_pipe.h" struct wideline_stage { diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 3d0add0c1a..7a439178a0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "pipe/p_shader_tokens.h" #include "draw_vs.h" +#include "draw_pipe.h" struct widepoint_stage { @@ -203,8 +204,8 @@ static void widepoint_first_point( struct draw_stage *stage, } /* XXX we won't know the real size if it's computed by the vertex shader! */ - if ((draw->rasterizer->point_size > draw->wide_point_threshold) || - (draw->rasterizer->point_sprite && draw->point_sprite)) { + if ((draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) || + (draw->rasterizer->point_sprite && draw->pipeline.point_sprite)) { stage->point = widepoint_point; } else { diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 37ffdbf902..b2b2f82b8f 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -51,12 +51,11 @@ struct pipe_context; struct gallivm_prog; struct gallivm_cpu_engine; - -struct draw_pt_middle_end; -struct draw_pt_front_end; struct draw_vertex_shader; +struct draw_context; +struct draw_stage; +struct vbuf_render; -#define MAX_SHADER_VERTICES 128 /** * Basic vertex info. @@ -70,17 +69,14 @@ struct vertex_header { float clip[4]; - float data[][4]; /* Note variable size */ + /* This will probably become float (*data)[4] soon: + */ + float data[][4]; }; /* NOTE: It should match vertex_id size above */ #define UNDEFINED_VERTEX_ID 0xffff -/* XXX This is too large */ -#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) -#define MAX_VERTEX_ALLOCATION ((MAX_VERTEX_SIZE + 0x0f) & ~0x0f) - - /** * Basic info for a point/line/triangle primitive. @@ -95,41 +91,6 @@ struct prim_header { -struct draw_context; - -/** - * Base class for all primitive drawing stages. - */ -struct draw_stage -{ - struct draw_context *draw; /**< parent context */ - - struct draw_stage *next; /**< next stage in pipeline */ - - struct vertex_header **tmp; /**< temp vert storage, such as for clipping */ - unsigned nr_tmps; - - void (*point)( struct draw_stage *, - struct prim_header * ); - - void (*line)( struct draw_stage *, - struct prim_header * ); - - void (*tri)( struct draw_stage *, - struct prim_header * ); - - void (*flush)( struct draw_stage *, - unsigned flags ); - - void (*reset_stipple_counter)( struct draw_stage * ); - - void (*destroy)( struct draw_stage * ); -}; - - - -struct vbuf_render; - #define PT_SHADE 0x1 #define PT_CLIPTEST 0x2 @@ -161,6 +122,12 @@ struct draw_context struct draw_stage *wide_line; struct draw_stage *wide_point; struct draw_stage *rasterize; + + float wide_point_threshold; /**< convert pnts to tris if larger than this */ + float wide_line_threshold; /**< convert lines to tris if wider than this */ + boolean line_stipple; /**< do line stipple? */ + boolean point_sprite; /**< convert points to quads for sprites? */ + } pipeline; @@ -225,10 +192,6 @@ struct draw_context float plane[12][4]; unsigned nr_planes; - float wide_point_threshold; /**< convert pnts to tris if larger than this */ - float wide_line_threshold; /**< convert lines to tris if wider than this */ - boolean line_stipple; /**< do line stipple? */ - boolean point_sprite; /**< convert points to quads for sprites? */ boolean use_sse; /* If a prim stage introduces new vertex attributes, they'll be stored here @@ -252,44 +215,29 @@ struct draw_context -extern struct draw_stage *draw_unfilled_stage( struct draw_context *context ); -extern struct draw_stage *draw_twoside_stage( struct draw_context *context ); -extern struct draw_stage *draw_offset_stage( struct draw_context *context ); -extern struct draw_stage *draw_clip_stage( struct draw_context *context ); -extern struct draw_stage *draw_flatshade_stage( struct draw_context *context ); -extern struct draw_stage *draw_cull_stage( struct draw_context *context ); -extern struct draw_stage *draw_stipple_stage( struct draw_context *context ); -extern struct draw_stage *draw_wide_line_stage( struct draw_context *context ); -extern struct draw_stage *draw_wide_point_stage( struct draw_context *context ); -extern struct draw_stage *draw_validate_stage( struct draw_context *context ); - - -extern void draw_free_temp_verts( struct draw_stage *stage ); - -extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); extern void draw_reset_vertex_ids( struct draw_context *draw ); -extern int draw_vertex_cache_check_space( struct draw_context *draw, - unsigned nr_verts ); -extern void draw_vertex_cache_invalidate( struct draw_context *draw ); -extern void draw_vertex_cache_unreference( struct draw_context *draw ); -extern void draw_vertex_cache_reset_vertex_ids( struct draw_context *draw ); +/******************************************************************************* + * Vertex processing (was passthrough) code: + */ +boolean draw_pt_init( struct draw_context *draw ); +void draw_pt_destroy( struct draw_context *draw ); +void draw_pt_reset_vertex_ids( struct draw_context *draw ); -extern void draw_update_vertex_fetch( struct draw_context *draw ); +/******************************************************************************* + * Primitive processing (pipelnie) code: + */ -extern boolean draw_need_pipeline(const struct draw_context *draw, - unsigned prim ); +boolean draw_pipeline_init( struct draw_context *draw ); +void draw_pipeline_destroy( struct draw_context *draw ); +boolean draw_need_pipeline(const struct draw_context *draw, + unsigned prim ); -/* Passthrough mode (second attempt): - */ -boolean draw_pt_init( struct draw_context *draw ); -void draw_pt_destroy( struct draw_context *draw ); -void draw_pt_reset_vertex_ids( struct draw_context *draw ); #define DRAW_FLUSH_STATE_CHANGE 0x8 #define DRAW_FLUSH_BACKEND 0x10 @@ -301,36 +249,6 @@ boolean draw_get_edgeflag( struct draw_context *draw, unsigned idx ); -/** - * Get a writeable copy of a vertex. - * \param stage drawing stage info - * \param vert the vertex to copy (source) - * \param idx index into stage's tmp[] array to put the copy (dest) - * \return pointer to the copied vertex - */ -static INLINE struct vertex_header * -dup_vert( struct draw_stage *stage, - const struct vertex_header *vert, - unsigned idx ) -{ - struct vertex_header *tmp = stage->tmp[idx]; - const uint vsize = sizeof(struct vertex_header) - + stage->draw->num_vs_outputs * 4 * sizeof(float); - memcpy(tmp, vert, vsize); - tmp->vertex_id = UNDEFINED_VERTEX_ID; - return tmp; -} - -static INLINE float -dot4(const float *a, const float *b) -{ - float result = (a[0]*b[0] + - a[1]*b[1] + - a[2]*b[2] + - a[3]*b[3]); - - return result; -} #endif /* DRAW_PRIVATE_H */ diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index f153a3ee2c..965269251f 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -165,21 +165,3 @@ draw_arrays(struct draw_context *draw, unsigned prim, draw_pt_arrays(draw, prim, start, count); } - -/* Revamp me please: - */ -void draw_do_flush( struct draw_context *draw, unsigned flags ) -{ - if (!draw->flushing) - { - draw->flushing = TRUE; - - if (flags >= DRAW_FLUSH_STATE_CHANGE) { - draw->pipeline.first->flush( draw->pipeline.first, flags ); - draw->pipeline.first = draw->pipeline.validate; - draw->reduced_prim = ~0; - } - - draw->flushing = FALSE; - } -} diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c index 1a9a3adb03..922344e448 100644 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c @@ -35,6 +35,7 @@ #include "draw/draw_private.h" #include "draw/draw_vertex.h" #include "draw/draw_pt.h" +#include "draw/draw_pipe.h" static void do_point( struct draw_context *draw, const char *v0 ) diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index b3ecec6ece..581f044dae 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -44,6 +44,17 @@ struct pt_post_vs { +static INLINE float +dot4(const float *a, const float *b) +{ + return (a[0]*b[0] + + a[1]*b[1] + + a[2]*b[2] + + a[3]*b[3]); +} + + + static INLINE unsigned compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr) { diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index 168036eee8..a42adaafb1 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -72,6 +72,4 @@ draw_compute_vertex_size(struct vertex_info *vinfo) assert(0); } } - - assert(vinfo->size * 4 <= MAX_VERTEX_SIZE); } diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c index 58a5854f0d..4bef21619c 100644 --- a/src/gallium/drivers/i915simple/i915_context.c +++ b/src/gallium/drivers/i915simple/i915_context.c @@ -142,7 +142,7 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen, */ i915->draw = draw_create(); assert(i915->draw); - if (GETENV("I915_VBUF")) { + if (!GETENV("I915_NO_VBUF")) { draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915)); } else { diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c index b6fb0a6d88..9ffa460138 100644 --- a/src/gallium/drivers/i915simple/i915_prim_emit.c +++ b/src/gallium/drivers/i915simple/i915_prim_emit.c @@ -26,7 +26,7 @@ **************************************************************************/ -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "pipe/p_util.h" #include "i915_context.h" @@ -78,9 +78,6 @@ emit_hw_vertex( struct i915_context *i915, const uint j = vinfo->src_index[i]; const float *attrib = vertex->data[j]; switch (vinfo->emit[i]) { - case EMIT_OMIT: - /* no-op */ - break; case EMIT_1F: OUT_BATCH( fui(attrib[0]) ); count++; diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c index 0ddb06764a..feb35d492a 100644 --- a/src/gallium/drivers/softpipe/sp_prim_setup.c +++ b/src/gallium/drivers/softpipe/sp_prim_setup.c @@ -39,7 +39,7 @@ #include "sp_setup.h" #include "sp_state.h" #include "sp_prim_setup.h" -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "draw/draw_vertex.h" #include "pipe/p_util.h" diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c index 605bfee743..1b50792bd1 100644 --- a/src/mesa/state_tracker/st_cb_feedback.c +++ b/src/mesa/state_tracker/st_cb_feedback.c @@ -56,7 +56,7 @@ #include "cso_cache/cso_cache.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" /** diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index 2ed228778e..3cb7b68bea 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -46,7 +46,7 @@ #include "st_cb_rasterpos.h" #include "st_draw.h" #include "draw/draw_context.h" -#include "draw/draw_private.h" +#include "draw/draw_pipe.h" #include "shader/prog_instruction.h" #include "vbo/vbo.h" -- cgit v1.2.3 From c898eae27221bd23b11327553c215a94369eeb99 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 15:35:22 +0100 Subject: draw: always emit header in draw_pt_fetch.c --- src/gallium/auxiliary/draw/draw_pt.h | 1 - src/gallium/auxiliary/draw/draw_pt_fetch.c | 8 ++------ src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 1 - 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 1119e9c6b8..eaf8e0374a 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -176,7 +176,6 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); struct pt_fetch; void draw_pt_fetch_prepare( struct pt_fetch *fetch, - boolean emit_header, unsigned vertex_size ); void draw_pt_fetch_run( struct pt_fetch *fetch, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 1aed251c85..037e3765da 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -54,7 +54,6 @@ struct pt_fetch { * */ void draw_pt_fetch_prepare( struct pt_fetch *fetch, - boolean emit_header, unsigned vertex_size ) { struct draw_context *draw = fetch->draw; @@ -66,16 +65,13 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, memset(&key, 0, sizeof(key)); - /* If PT_SHADE is not set, then we are creating post-shader - * vertices, meaning that we need to emit/leave space for a vertex - * header. + /* Always emit/leave space for a vertex header. * * It's worth considering whether the vertex headers should contain * a pointer to the 'data', rather than having it inline. * Something to look at after we've fully switched over to the pt * paths. */ - if (emit_header) { /* Need to set header->vertex_id = 0xffff somehow. */ @@ -121,7 +117,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, fetch->translate = translate_create( &key ); - if (emit_header) { + { static struct vertex_header vh = { 0, 0, 0, 0xffff }; fetch->translate->set_buffer(fetch->translate, draw->nr_vertex_buffers, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 0b9e8d15ba..560f1bcd92 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -71,7 +71,6 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, draw_pt_fetch_prepare( fpme->fetch, - (opt & (PT_CLIPTEST | PT_PIPELINE)) != 0, fpme->vertex_size ); /* XXX: it's not really gl rasterization rules we care about here, -- cgit v1.2.3 From bee1d31641674c67676de86fbb4b35ca5bf7f33f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 16:39:24 +0100 Subject: draw: move pt_pipeline code to draw_pipe.c This is now the drawing interface to the pipeline. No more calling into pipeline.first->tri(), etc. --- src/gallium/auxiliary/draw/Makefile | 1 - src/gallium/auxiliary/draw/SConscript | 1 - src/gallium/auxiliary/draw/draw_pipe.c | 117 ++++++++++++++- src/gallium/auxiliary/draw/draw_private.h | 24 +++- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 14 +- src/gallium/auxiliary/draw/draw_pt_pipeline.c | 158 --------------------- 6 files changed, 140 insertions(+), 175 deletions(-) delete mode 100644 src/gallium/auxiliary/draw/draw_pt_pipeline.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 4fffd11b77..5289f2660a 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -26,7 +26,6 @@ C_SOURCES = \ draw_pt_fetch.c \ draw_pt_fetch_emit.c \ draw_pt_fetch_shade_pipeline.c \ - draw_pt_pipeline.c \ draw_pt_post_vs.c \ draw_pt_vcache.c \ draw_vertex.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 5fa35d3005..6f3ca4fa49 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -25,7 +25,6 @@ draw = env.ConvenienceLibrary( 'draw_pt_fetch.c', 'draw_pt_fetch_emit.c', 'draw_pt_fetch_shade_pipeline.c', - 'draw_pt_pipeline.c', 'draw_pt_post_vs.c', 'draw_pt_vcache.c', 'draw_vs.c', diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 9d62cb2c65..b18b747d9c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -35,6 +35,7 @@ #include "draw/draw_pipe.h" + boolean draw_pipeline_init( struct draw_context *draw ) { /* create pipeline stages */ @@ -142,6 +143,60 @@ void draw_free_temp_verts( struct draw_stage *stage ) } } + + +static void do_point( struct draw_context *draw, + const char *v0 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 0; + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + + draw->pipeline.first->point( draw->pipeline.first, &prim ); +} + + +static void do_line( struct draw_context *draw, + const char *v0, + const char *v1 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 1; /* fixme */ + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + + draw->pipeline.first->line( draw->pipeline.first, &prim ); +} + + +static void do_triangle( struct draw_context *draw, + char *v0, + char *v1, + char *v2 ) +{ + struct prim_header prim; + + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + prim.v[2] = (struct vertex_header *)v2; + prim.reset_line_stipple = 1; + prim.edgeflags = ((prim.v[0]->edgeflag) | + (prim.v[1]->edgeflag << 1) | + (prim.v[2]->edgeflag << 2)); + prim.pad = 0; + + draw->pipeline.first->tri( draw->pipeline.first, &prim ); +} + + +/* Reset vertex ids. This is basically a type of flush. + */ void draw_reset_vertex_ids(struct draw_context *draw) { struct draw_stage *stage = draw->pipeline.first; @@ -155,7 +210,67 @@ void draw_reset_vertex_ids(struct draw_context *draw) stage = stage->next; } - draw_pt_reset_vertex_ids(draw); + if (draw->pipeline.verts) + { + unsigned i; + char *verts = draw->pipeline.verts; + unsigned stride = draw->pipeline.vertex_stride; + + for (i = 0; i < draw->pipeline.vertex_count; i++) { + ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; + verts += stride; + } + } } +/* Code to run the pipeline on a fairly arbitary collection of vertices. + * + * Vertex headers must be pre-initialized with the + * UNDEFINED_VERTEX_ID, this code will cause that id to become + * overwritten, so it may have to be reset if there is the intention + * to reuse the vertices. + * + * This code provides a callback to reset the vertex id's which the + * draw_vbuf.c code uses when it has to perform a flush. + */ +void draw_pipeline_run( struct draw_context *draw, + unsigned prim, + struct vertex_header *vertices, + unsigned vertex_count, + unsigned stride, + const ushort *elts, + unsigned count ) +{ + char *verts = (char *)vertices; + unsigned i; + + draw->pipeline.verts = verts; + draw->pipeline.vertex_stride = stride; + draw->pipeline.vertex_count = vertex_count; + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) + do_point( draw, + verts + stride * elts[i] ); + break; + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) + do_line( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1]); + break; + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) + do_triangle( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1], + verts + stride * elts[i+2]); + break; + } + + draw->pipeline.verts = NULL; + draw->pipeline.vertex_count = 0; +} + diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index b2b2f82b8f..4d123cf8d9 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -128,6 +128,11 @@ struct draw_context boolean line_stipple; /**< do line stipple? */ boolean point_sprite; /**< convert points to quads for sprites? */ + /* Temporary storage while the pipeline is being run: + */ + char *verts; + unsigned vertex_stride; + unsigned vertex_count; } pipeline; @@ -144,13 +149,6 @@ struct draw_context struct { struct draw_pt_front_end *vcache; } front; - - struct { - char *verts; - unsigned vertex_stride; - unsigned vertex_count; - } pipeline; - } pt; boolean flushing; @@ -235,10 +233,22 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw ); boolean draw_pipeline_init( struct draw_context *draw ); void draw_pipeline_destroy( struct draw_context *draw ); +void draw_pipeline_run( struct draw_context *draw, + unsigned prim, + struct vertex_header *vertices, + unsigned vertex_count, + unsigned stride, + const ushort *elts, + unsigned count ); + boolean draw_need_pipeline(const struct draw_context *draw, unsigned prim ); +/******************************************************************************* + * Flushing + */ + #define DRAW_FLUSH_STATE_CHANGE 0x8 #define DRAW_FLUSH_BACKEND 0x10 diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 560f1bcd92..a47693ba20 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -148,13 +148,13 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, /* Do we need to run the pipeline? */ if (opt & PT_PIPELINE) { - draw_pt_run_pipeline( fpme->draw, - fpme->prim, - pipeline_verts, - fetch_count, - fpme->vertex_size, - draw_elts, - draw_count ); + draw_pipeline_run( fpme->draw, + fpme->prim, + pipeline_verts, + fetch_count, + fpme->vertex_size, + draw_elts, + draw_count ); } else { draw_pt_emit( fpme->emit, diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c deleted file mode 100644 index 922344e448..0000000000 --- a/src/gallium/auxiliary/draw/draw_pt_pipeline.c +++ /dev/null @@ -1,158 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "pipe/p_util.h" -#include "draw/draw_context.h" -#include "draw/draw_private.h" -#include "draw/draw_vertex.h" -#include "draw/draw_pt.h" -#include "draw/draw_pipe.h" - -static void do_point( struct draw_context *draw, - const char *v0 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 0; - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - - draw->pipeline.first->point( draw->pipeline.first, &prim ); -} - - -static void do_line( struct draw_context *draw, - const char *v0, - const char *v1 ) -{ - struct prim_header prim; - - prim.reset_line_stipple = 1; /* fixme */ - prim.edgeflags = 1; - prim.pad = 0; - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - - draw->pipeline.first->line( draw->pipeline.first, &prim ); -} - - -static void do_triangle( struct draw_context *draw, - char *v0, - char *v1, - char *v2 ) -{ - struct prim_header prim; - - prim.v[0] = (struct vertex_header *)v0; - prim.v[1] = (struct vertex_header *)v1; - prim.v[2] = (struct vertex_header *)v2; - prim.reset_line_stipple = 1; - prim.edgeflags = ((prim.v[0]->edgeflag) | - (prim.v[1]->edgeflag << 1) | - (prim.v[2]->edgeflag << 2)); - prim.pad = 0; - - if (0) debug_printf("tri ef: %d %d %d\n", - prim.v[0]->edgeflag, - prim.v[1]->edgeflag, - prim.v[2]->edgeflag); - - draw->pipeline.first->tri( draw->pipeline.first, &prim ); -} - - - -void draw_pt_reset_vertex_ids( struct draw_context *draw ) -{ - unsigned i; - char *verts = draw->pt.pipeline.verts; - unsigned stride = draw->pt.pipeline.vertex_stride; - - for (i = 0; i < draw->pt.pipeline.vertex_count; i++) { - ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; - verts += stride; - } -} - - -/* Code to run the pipeline on a fairly arbitary collection of vertices. - * - * Vertex headers must be pre-initialized with the - * UNDEFINED_VERTEX_ID, this code will cause that id to become - * overwritten, so it may have to be reset if there is the intention - * to reuse the vertices. - * - * This code provides a callback to reset the vertex id's which the - * draw_vbuf.c code uses when it has to perform a flush. - */ -void draw_pt_run_pipeline( struct draw_context *draw, - unsigned prim, - struct vertex_header *pipeline_verts, - unsigned vertex_count, - unsigned stride, - const ushort *elts, - unsigned count ) -{ - char *verts = (char *)pipeline_verts; - unsigned i; - - draw->pt.pipeline.verts = verts; - draw->pt.pipeline.vertex_stride = stride; - draw->pt.pipeline.vertex_count = vertex_count; - - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) - do_point( draw, - verts + stride * elts[i] ); - break; - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) - do_line( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1]); - break; - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) - do_triangle( draw, - verts + stride * elts[i+0], - verts + stride * elts[i+1], - verts + stride * elts[i+2]); - break; - } - - draw->pt.pipeline.verts = NULL; - draw->pt.pipeline.vertex_count = 0; -} - -- cgit v1.2.3 From e7bac4276634ea1ee81ac71f6f6869f87e689872 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 16:43:15 +0100 Subject: draw: put pipeline flushing behind a new interface --- src/gallium/auxiliary/draw/draw_context.c | 8 +++----- src/gallium/auxiliary/draw/draw_pipe.c | 8 ++++++++ src/gallium/auxiliary/draw/draw_private.h | 5 ++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index fa6791fa0b..3e69867d11 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -379,11 +379,9 @@ void draw_do_flush( struct draw_context *draw, unsigned flags ) { draw->flushing = TRUE; - if (flags >= DRAW_FLUSH_STATE_CHANGE) { - draw->pipeline.first->flush( draw->pipeline.first, flags ); - draw->pipeline.first = draw->pipeline.validate; - draw->reduced_prim = ~0; /* is reduced_prim needed any more? */ - } + draw_pipeline_flush( draw, flags ); + + draw->reduced_prim = ~0; /* is reduced_prim needed any more? */ draw->flushing = FALSE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index b18b747d9c..3fae908514 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -274,3 +274,11 @@ void draw_pipeline_run( struct draw_context *draw, draw->pipeline.vertex_count = 0; } + + +void draw_pipeline_flush( struct draw_context *draw, + unsigned flags ) +{ + draw->pipeline.first->flush( draw->pipeline.first, flags ); + draw->pipeline.first = draw->pipeline.validate; +} diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 4d123cf8d9..59635d643b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -227,7 +227,7 @@ void draw_pt_reset_vertex_ids( struct draw_context *draw ); /******************************************************************************* - * Primitive processing (pipelnie) code: + * Primitive processing (pipeline) code: */ boolean draw_pipeline_init( struct draw_context *draw ); @@ -241,6 +241,9 @@ void draw_pipeline_run( struct draw_context *draw, const ushort *elts, unsigned count ); +void draw_pipeline_flush( struct draw_context *draw, + unsigned flags ); + boolean draw_need_pipeline(const struct draw_context *draw, unsigned prim ); -- cgit v1.2.3 From 2dae208fb19e79c7446a29ee5dee53e50283b57c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 17:16:23 +0100 Subject: draw: make room for extra_vs_outputs --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index a47693ba20..e1df594035 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -56,8 +56,12 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; struct draw_context *draw = fpme->draw; struct draw_vertex_shader *vs = draw->vertex_shader; + + /* Add one to num_outputs because the pipeline occasionally tags on + * an additional texcoord, eg for AA lines. + */ unsigned nr = MAX2( vs->info.num_inputs, - vs->info.num_outputs ); + vs->info.num_outputs + 1 ); fpme->prim = prim; fpme->opt = opt; -- cgit v1.2.3 From dcf6f776ce32b89b7ff784bb38030bd29698e005 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 17:16:41 +0100 Subject: draw: make draw_reset_vertex_ids private to the draw_pipe_* code --- src/gallium/auxiliary/draw/draw_pipe.c | 2 ++ src/gallium/auxiliary/draw/draw_pipe.h | 2 +- src/gallium/auxiliary/draw/draw_private.h | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 3fae908514..0c0840af0c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -196,6 +196,8 @@ static void do_triangle( struct draw_context *draw, /* Reset vertex ids. This is basically a type of flush. + * + * Called only from draw_pipe_vbuf.c */ void draw_reset_vertex_ids(struct draw_context *draw) { diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h index 5b97ca5c8c..f2749b34bb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.h +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -81,9 +81,9 @@ extern struct draw_stage *draw_validate_stage( struct draw_context *context ); extern void draw_free_temp_verts( struct draw_stage *stage ); - extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); +extern void draw_reset_vertex_ids( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 59635d643b..6cf3e54e28 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -214,7 +214,6 @@ struct draw_context -extern void draw_reset_vertex_ids( struct draw_context *draw ); -- cgit v1.2.3 From 7d72607e142c0412b88183b849fd701e698b8f79 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 17:27:52 +0100 Subject: draw: move incoming vertex state into draw->pt This state is effectively private to the vertex processing part of the draw module. --- src/gallium/auxiliary/draw/draw_context.c | 28 +++++-------- src/gallium/auxiliary/draw/draw_private.h | 47 +++++++++++----------- src/gallium/auxiliary/draw/draw_pt.c | 8 ++++ src/gallium/auxiliary/draw/draw_pt.h | 9 +---- src/gallium/auxiliary/draw/draw_pt_elts.c | 6 +-- src/gallium/auxiliary/draw/draw_pt_fetch.c | 20 ++++----- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 6 +-- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 +- src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 +- src/mesa/state_tracker/st_draw.c | 6 +-- 10 files changed, 63 insertions(+), 71 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 3e69867d11..4988d67faa 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -62,8 +62,6 @@ struct draw_context *draw_create( void ) draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */ - draw_set_mapped_element_buffer( draw, 0, NULL ); - tgsi_exec_machine_init(&draw->machine); /* FIXME: give this machine thing a proper constructor: @@ -188,8 +186,8 @@ draw_set_vertex_buffers(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - memcpy(draw->vertex_buffer, buffers, count * sizeof(buffers[0])); - draw->nr_vertex_buffers = count; + memcpy(draw->pt.vertex_buffer, buffers, count * sizeof(buffers[0])); + draw->pt.nr_vertex_buffers = count; } @@ -200,8 +198,8 @@ draw_set_vertex_elements(struct draw_context *draw, { assert(count <= PIPE_MAX_ATTRIBS); - memcpy(draw->vertex_element, elements, count * sizeof(elements[0])); - draw->nr_vertex_elements = count; + memcpy(draw->pt.vertex_element, elements, count * sizeof(elements[0])); + draw->pt.nr_vertex_elements = count; } @@ -212,7 +210,7 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw, unsigned attr, const void *buffer) { - draw->user.vbuffer[attr] = buffer; + draw->pt.user.vbuffer[attr] = buffer; } @@ -220,7 +218,7 @@ void draw_set_mapped_constant_buffer(struct draw_context *draw, const void *buffer) { - draw->user.constants = buffer; + draw->pt.user.constants = buffer; } @@ -337,18 +335,10 @@ void draw_set_render( struct draw_context *draw, void draw_set_edgeflags( struct draw_context *draw, const unsigned *edgeflag ) { - draw->user.edgeflag = edgeflag; + draw->pt.user.edgeflag = edgeflag; } -boolean draw_get_edgeflag( struct draw_context *draw, - unsigned idx ) -{ - if (draw->user.edgeflag) - return (draw->user.edgeflag[idx/32] & (1 << (idx%32))) != 0; - else - return 1; -} /** @@ -365,8 +355,8 @@ void draw_set_mapped_element_buffer( struct draw_context *draw, unsigned eltSize, void *elements ) { - draw->user.elts = elements; - draw->user.eltSize = eltSize; + draw->pt.user.elts = elements; + draw->pt.user.eltSize = eltSize; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 6cf3e54e28..27f61c2f40 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -149,6 +149,29 @@ struct draw_context struct { struct draw_pt_front_end *vcache; } front; + + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_buffers; + + struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_elements; + + /* user-space vertex data, buffers */ + struct { + const unsigned *edgeflag; + + /** vertex element/index buffer (ex: glDrawElements) */ + const void *elts; + /** bytes per index (0, 1, 2 or 4) */ + unsigned eltSize; + + /** vertex arrays */ + const void *vbuffer[PIPE_MAX_ATTRIBS]; + + /** constant buffer (for vertex shader) */ + const void *constants; + } user; + } pt; boolean flushing; @@ -157,33 +180,12 @@ struct draw_context const struct pipe_rasterizer_state *rasterizer; struct pipe_viewport_state viewport; - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - unsigned nr_vertex_buffers; - - struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; - unsigned nr_vertex_elements; - struct draw_vertex_shader *vertex_shader; boolean identity_viewport; uint num_vs_outputs; /**< convenience, from vertex_shader */ - /* user-space vertex data, buffers */ - struct { - const unsigned *edgeflag; - - /** vertex element/index buffer (ex: glDrawElements) */ - const void *elts; - /** bytes per index (0, 1, 2 or 4) */ - unsigned eltSize; - - /** vertex arrays */ - const void *vbuffer[PIPE_MAX_ATTRIBS]; - - /** constant buffer (for vertex shader) */ - const void *constants; - } user; /* Clip derived state: */ @@ -257,9 +259,6 @@ boolean draw_need_pipeline(const struct draw_context *draw, void draw_do_flush( struct draw_context *draw, unsigned flags ); -boolean draw_get_edgeflag( struct draw_context *draw, - unsigned idx ); - diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 965269251f..9f8e8d3d62 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -165,3 +165,11 @@ draw_arrays(struct draw_context *draw, unsigned prim, draw_pt_arrays(draw, prim, start, count); } +boolean draw_pt_get_edgeflag( struct draw_context *draw, + unsigned idx ) +{ + if (draw->pt.user.edgeflag) + return (draw->pt.user.edgeflag[idx/32] & (1 << (idx%32))) != 0; + else + return 1; +} diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index eaf8e0374a..fd0d158fcf 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -141,13 +141,8 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *d /* More helpers: */ -void draw_pt_run_pipeline( struct draw_context *draw, - unsigned prim, - struct vertex_header *verts, - unsigned vertex_count, - unsigned vertex_stride, - const ushort *elts, - unsigned count ); +boolean draw_pt_get_edgeflag( struct draw_context *draw, + unsigned idx ); /******************************************************************************* diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c index d49770e7b2..2094c081ed 100644 --- a/src/gallium/auxiliary/draw/draw_pt_elts.c +++ b/src/gallium/auxiliary/draw/draw_pt_elts.c @@ -59,7 +59,7 @@ static unsigned elt_vert( const void *elts, unsigned idx ) pt_elt_func draw_pt_elt_func( struct draw_context *draw ) { - switch (draw->user.eltSize) { + switch (draw->pt.user.eltSize) { case 0: return elt_vert; case 1: return elt_ubyte; case 2: return elt_ushort; @@ -71,9 +71,9 @@ pt_elt_func draw_pt_elt_func( struct draw_context *draw ) const void *draw_pt_elt_ptr( struct draw_context *draw, unsigned start ) { - const char *elts = draw->user.elts; + const char *elts = draw->pt.user.elts; - switch (draw->user.eltSize) { + switch (draw->pt.user.eltSize) { case 0: return (const void *)(((const ubyte *)NULL) + start); case 1: diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index 037e3765da..c588710b75 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -76,7 +76,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, /* Need to set header->vertex_id = 0xffff somehow. */ key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT; - key.element[nr].input_buffer = draw->nr_vertex_buffers; + key.element[nr].input_buffer = draw->pt.nr_vertex_buffers; key.element[nr].input_offset = 0; key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT; key.element[nr].output_offset = dst_offset; @@ -90,10 +90,10 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, } - for (i = 0; i < draw->nr_vertex_elements; i++) { - key.element[nr].input_format = draw->vertex_element[i].src_format; - key.element[nr].input_buffer = draw->vertex_element[i].vertex_buffer_index; - key.element[nr].input_offset = draw->vertex_element[i].src_offset; + for (i = 0; i < draw->pt.nr_vertex_elements; i++) { + key.element[nr].input_format = draw->pt.vertex_element[i].src_format; + key.element[nr].input_buffer = draw->pt.vertex_element[i].vertex_buffer_index; + key.element[nr].input_offset = draw->pt.vertex_element[i].src_offset; key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; key.element[nr].output_offset = dst_offset; @@ -120,7 +120,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, { static struct vertex_header vh = { 0, 0, 0, 0xffff }; fetch->translate->set_buffer(fetch->translate, - draw->nr_vertex_buffers, + draw->pt.nr_vertex_buffers, &vh, 0); } @@ -139,12 +139,12 @@ void draw_pt_fetch_run( struct pt_fetch *fetch, struct translate *translate = fetch->translate; unsigned i; - for (i = 0; i < draw->nr_vertex_buffers; i++) { + for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { translate->set_buffer(translate, i, - ((char *)draw->user.vbuffer[i] + - draw->vertex_buffer[i].buffer_offset), - draw->vertex_buffer[i].pitch ); + ((char *)draw->pt.user.vbuffer[i] + + draw->pt.vertex_buffer[i].buffer_offset), + draw->pt.vertex_buffer[i].pitch ); } translate->run_elts( translate, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 6e4fea460b..1b9b3bfaa6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -117,7 +117,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, memset(&key, 0, sizeof(key)); for (i = 0; i < vinfo->num_attribs; i++) { - const struct pipe_vertex_element *src = &draw->vertex_element[vinfo->src_index[i]]; + const struct pipe_vertex_element *src = &draw->pt.vertex_element[vinfo->src_index[i]]; unsigned emit_sz = 0; unsigned input_format = src->src_format; @@ -144,7 +144,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, break; case EMIT_1F_PSIZE: input_format = PIPE_FORMAT_R32_FLOAT; - input_buffer = draw->nr_vertex_buffers; + input_buffer = draw->pt.nr_vertex_buffers; input_offset = 0; output_format = PIPE_FORMAT_R32_FLOAT; emit_sz = 1 * sizeof(float); @@ -179,7 +179,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, feme->translate = translate_create( &key ); feme->translate->set_buffer(feme->translate, - draw->nr_vertex_buffers, + draw->pt.nr_vertex_buffers, &feme->point_size, 0); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index e1df594035..881e47d59d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -135,7 +135,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, shader->run_linear(shader, (const float (*)[4])pipeline_verts->data, ( float (*)[4])pipeline_verts->data, - (const float (*)[4])draw->user.constants, + (const float (*)[4])draw->pt.user.constants, fetch_count, fpme->vertex_size, fpme->vertex_size); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 5561f2b6fb..b61bb50664 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -106,7 +106,7 @@ static unsigned add_edgeflag( struct vcache_frontend *vcache, unsigned idx, unsigned mask ) { - if (mask && draw_get_edgeflag(vcache->draw, idx)) + if (mask && draw_pt_get_edgeflag(vcache->draw, idx)) return idx | DRAW_PT_EDGEFLAG; else return idx; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index f0f62246dd..befcb96bd8 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -611,10 +611,10 @@ st_feedback_draw_vbo(GLcontext *ctx, * unmap vertex/index buffers */ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (draw->vertex_buffer[i].buffer) { + if (draw->pt.vertex_buffer[i].buffer) { pipe->winsys->buffer_unmap(pipe->winsys, - draw->vertex_buffer[i].buffer); - pipe_buffer_reference(winsys, &draw->vertex_buffer[i].buffer, NULL); + draw->pt.vertex_buffer[i].buffer); + pipe_buffer_reference(winsys, &draw->pt.vertex_buffer[i].buffer, NULL); draw_set_mapped_vertex_buffer(draw, i, NULL); } } -- cgit v1.2.3 From d3cb62b8b3ea03bfb9800bf4b738d9814ef3c516 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:02:42 +0100 Subject: draw: fix scons build --- src/gallium/auxiliary/draw/SConscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 6f3ca4fa49..91e6a35c5e 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -4,6 +4,7 @@ draw = env.ConvenienceLibrary( target = 'draw', source = [ 'draw_context.c', + 'draw_pipe.c', 'draw_pipe_aaline.c', 'draw_pipe_aapoint.c', 'draw_pipe_clip.c', @@ -16,7 +17,6 @@ draw = env.ConvenienceLibrary( 'draw_pipe_unfilled.c', 'draw_pipe_validate.c', 'draw_pipe_vbuf.c', - 'draw_pipe_vertex.c', 'draw_pipe_wide_line.c', 'draw_pipe_wide_point.c', 'draw_pt.c', @@ -27,6 +27,7 @@ draw = env.ConvenienceLibrary( 'draw_pt_fetch_shade_pipeline.c', 'draw_pt_post_vs.c', 'draw_pt_vcache.c', + 'draw_vertex.c', 'draw_vs.c', 'draw_vs_exec.c', 'draw_vs_llvm.c', -- cgit v1.2.3 From af523a5bd7828fd554669cf83f18992af967a075 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:25:33 +0100 Subject: rtasm: include yet another i386 define varient --- src/gallium/auxiliary/rtasm/rtasm_cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c index eb3359750b..d577ff5b42 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -32,7 +32,7 @@ int rtasm_cpu_has_sse(void) { /* FIXME: actually detect this at run-time */ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) return 1; #else return 0; @@ -42,7 +42,7 @@ int rtasm_cpu_has_sse(void) int rtasm_cpu_has_sse2(void) { /* FIXME: actually detect this at run-time */ -#if defined(__i386__) || defined(__386__) +#if defined(__i386__) || defined(__386__) || defined(i386) return 1; #else return 0; -- cgit v1.2.3 From b1158a5e0031aa33a71baa7bc14ca2c0fe0dabc4 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:26:39 +0100 Subject: translate: don't crash on failure to create sse version --- src/gallium/auxiliary/translate/translate_generic.c | 11 +++++++++++ src/gallium/auxiliary/translate/translate_sse.c | 13 ++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index e7fb1dcb2d..9de007c767 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -567,8 +567,14 @@ static void generic_run_elts( struct translate *translate, tg->attrib[attr].output_offset); tg->attrib[attr].fetch( src, data ); + + debug_printf("vert %d/%d attr %d: %f %f %f %f\n", + i, elt, attr, data[0], data[1], data[2], data[3]); + + tg->attrib[attr].emit( data, dst ); } + debug_printf("\n"); vert += tg->translate.key.output_stride; } @@ -602,8 +608,13 @@ static void generic_run( struct translate *translate, tg->attrib[attr].output_offset); tg->attrib[attr].fetch( src, data ); + + debug_printf("vert %d attr %d: %f %f %f %f\n", + i, attr, data[0], data[1], data[2], data[3]); + tg->attrib[attr].emit( data, dst ); } + debug_printf("\n"); vert += tg->translate.key.output_stride; } diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index cb8815c173..575852d222 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -145,7 +145,7 @@ static struct x86_reg get_inv_255( struct translate_sse *p ) p->inv_255[0] = p->inv_255[1] = p->inv_255[2] = - p->inv_255[3] = 1.0 / 255.0f; + p->inv_255[3] = 1.0f / 255.0f; sse_movups(p->func, reg, x86_make_disp(translateESI, @@ -575,22 +575,21 @@ struct translate *translate_sse2_create( const struct translate_key *key ) if (p == NULL) goto fail; - if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) - goto fail; - - - p->translate.key = *key; p->translate.release = translate_sse_release; p->translate.set_buffer = translate_sse_set_buffer; p->translate.run_elts = translate_sse_run_elts; p->translate.run = translate_sse_run; + if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) + goto fail; + if (!build_vertex_emit(p, &p->linear_func, TRUE)) goto fail; if (!build_vertex_emit(p, &p->elt_func, FALSE)) goto fail; + p->translate.key = *key; p->gen_run = (run_func)x86_get_func(&p->linear_func); p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); @@ -598,7 +597,7 @@ struct translate *translate_sse2_create( const struct translate_key *key ) fail: if (p) - p->translate.release( &p->translate ); + translate_sse_release( &p->translate ); return NULL; } -- cgit v1.2.3 From bfd179776f5ded75c2134a54f0a57a1579118cd0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 18:41:53 +0100 Subject: draw: add missing translate->set_buffer for fetch emit path --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 1b9b3bfaa6..70d136dce6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -185,6 +185,14 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, } feme->point_size = draw->rasterizer->point_size; + + for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { + feme->translate->set_buffer(feme->translate, + i, + ((char *)draw->pt.user.vbuffer[i] + + draw->pt.vertex_buffer[i].buffer_offset), + draw->pt.vertex_buffer[i].pitch ); + } } -- cgit v1.2.3 From d0a4bf08b1a80d62f81301c5b37723dfca436b62 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 20:18:40 +0100 Subject: translate: fix several bugs - specify cdecl calling convention on WIN32 - fix load bgra8 function - fix previous don't crash fix. --- .../auxiliary/translate/translate_generic.c | 11 +++--- src/gallium/auxiliary/translate/translate_sse.c | 42 ++++++++++++---------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 9de007c767..402780ee53 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -568,13 +568,11 @@ static void generic_run_elts( struct translate *translate, tg->attrib[attr].fetch( src, data ); - debug_printf("vert %d/%d attr %d: %f %f %f %f\n", - i, elt, attr, data[0], data[1], data[2], data[3]); - + if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n", + i, elt, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } - debug_printf("\n"); vert += tg->translate.key.output_stride; } @@ -609,12 +607,11 @@ static void generic_run( struct translate *translate, tg->attrib[attr].fetch( src, data ); - debug_printf("vert %d attr %d: %f %f %f %f\n", - i, attr, data[0], data[1], data[2], data[3]); + if (0) debug_printf("vert %d attr %d: %f %f %f %f\n", + i, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } - debug_printf("\n"); vert += tg->translate.key.output_stride; } diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index 575852d222..e587e5afec 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -45,15 +45,21 @@ #define W 3 -typedef void (*run_func)( struct translate *translate, - unsigned start, - unsigned count, - void *output_buffer ); +#ifdef WIN32 +#define RTASM __cdecl +#else +#define RTASM +#endif + +typedef void (RTASM *run_func)( struct translate *translate, + unsigned start, + unsigned count, + void *output_buffer ); -typedef void (*run_elts_func)( struct translate *translate, - const unsigned *elts, - unsigned count, - void *output_buffer ); +typedef void (RTASM *run_elts_func)( struct translate *translate, + const unsigned *elts, + unsigned count, + void *output_buffer ); @@ -212,17 +218,17 @@ static void emit_load_R8G8B8A8_UNORM( struct translate_sse *p, /* Load and unpack twice: */ sse_movss(p->func, data, src); - sse2_punpcklbw(p->func, src, get_identity(p)); - sse2_punpcklbw(p->func, src, get_identity(p)); + sse2_punpcklbw(p->func, data, get_identity(p)); + sse2_punpcklbw(p->func, data, get_identity(p)); /* Convert to float: */ - sse2_cvtdq2ps(p->func, src, src); + sse2_cvtdq2ps(p->func, data, data); /* Scale by 1/255.0 */ - sse_mulps(p->func, src, get_inv_255(p)); + sse_mulps(p->func, data, get_inv_255(p)); } @@ -551,7 +557,6 @@ static void translate_sse_run_elts( struct translate *translate, elts, count, output_buffer ); - } static void translate_sse_run( struct translate *translate, @@ -570,26 +575,27 @@ static void translate_sse_run( struct translate *translate, struct translate *translate_sse2_create( const struct translate_key *key ) { - struct translate_sse *p = CALLOC_STRUCT( translate_sse ); + struct translate_sse *p = NULL; + + if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) + goto fail; + p = CALLOC_STRUCT( translate_sse ); if (p == NULL) goto fail; + p->translate.key = *key; p->translate.release = translate_sse_release; p->translate.set_buffer = translate_sse_set_buffer; p->translate.run_elts = translate_sse_run_elts; p->translate.run = translate_sse_run; - if (!rtasm_cpu_has_sse() || !rtasm_cpu_has_sse2()) - goto fail; - if (!build_vertex_emit(p, &p->linear_func, TRUE)) goto fail; if (!build_vertex_emit(p, &p->elt_func, FALSE)) goto fail; - p->translate.key = *key; p->gen_run = (run_func)x86_get_func(&p->linear_func); p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); -- cgit v1.2.3 From 68a7cb21fa14eac9e38bf398623739a892cc0d52 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 19 Apr 2008 20:20:40 +0100 Subject: draw: rearrange debug code --- src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 55 +------------------------ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 16 +++++-- src/gallium/auxiliary/draw/draw_vertex.c | 54 ++++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vertex.h | 2 + 4 files changed, 70 insertions(+), 57 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index c835727e32..c5810febe0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -115,59 +115,6 @@ check_space( struct vbuf_stage *vbuf, unsigned nr ) } -static INLINE void -dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) -{ -// assert(vinfo == vbuf->render->get_vertex_info(vbuf->render)); - unsigned i, j; - - for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->src_index[i]; - switch (vinfo->emit[i]) { - case EMIT_OMIT: - debug_printf("EMIT_OMIT:"); - break; - case EMIT_1F: - debug_printf("EMIT_1F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_1F_PSIZE: - debug_printf("EMIT_1F_PSIZE:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_2F: - debug_printf("EMIT_2F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_3F: - debug_printf("EMIT_3F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - data += sizeof(float); - break; - case EMIT_4F: - debug_printf("EMIT_4F:\t"); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - debug_printf("%f ", *(float *)data); data += sizeof(float); - break; - case EMIT_4UB: - debug_printf("EMIT_4UB:\t"); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - debug_printf("%u ", *data++); - break; - default: - assert(0); - } - debug_printf("\n"); - } - debug_printf("\n"); -} /** @@ -189,7 +136,7 @@ emit_vertex( struct vbuf_stage *vbuf, vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0); vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr); - if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); + if (0) draw_dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr); vbuf->vertex_ptr += vbuf->vertex_size/4; vertex->vertex_id = vbuf->nr_vertices++; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 70d136dce6..002ced2186 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -75,6 +75,7 @@ struct fetch_emit_middle_end { struct draw_context *draw; struct translate *translate; + const struct vertex_info *vinfo; /* Cache point size somewhere it's address won't change: */ @@ -106,9 +107,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, /* Must do this after set_primitive() above: */ - vinfo = draw->render->get_vertex_info(draw->render); - - + vinfo = feme->vinfo = draw->render->get_vertex_info(draw->render); + + /* Transform from API vertices to HW vertices, skipping the * pipeline_vertex intermediate step. @@ -229,6 +230,15 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, fetch_count, hw_verts ); + if (0) { + unsigned i; + for (i = 0; i < fetch_count; i++) { + debug_printf("\n\nvertex %d:\n", i); + draw_dump_emitted_vertex( feme->vinfo, + (const uint8_t *)hw_verts + feme->vinfo->size * 4 * i ); + } + } + /* XXX: Draw arrays path to avoid re-emitting index list again and * again. */ diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index a42adaafb1..1446f785c5 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -73,3 +73,57 @@ draw_compute_vertex_size(struct vertex_info *vinfo) } } } + + +void +draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) +{ + unsigned i, j; + + for (i = 0; i < vinfo->num_attribs; i++) { + j = vinfo->src_index[i]; + switch (vinfo->emit[i]) { + case EMIT_OMIT: + debug_printf("EMIT_OMIT:"); + break; + case EMIT_1F: + debug_printf("EMIT_1F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_1F_PSIZE: + debug_printf("EMIT_1F_PSIZE:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_2F: + debug_printf("EMIT_2F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_3F: + debug_printf("EMIT_3F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + data += sizeof(float); + break; + case EMIT_4F: + debug_printf("EMIT_4F:\t"); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + debug_printf("%f ", *(float *)data); data += sizeof(float); + break; + case EMIT_4UB: + debug_printf("EMIT_4UB:\t"); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + debug_printf("%u ", *data++); + break; + default: + assert(0); + } + debug_printf("\n"); + } + debug_printf("\n"); +} diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 65818463ca..6d8bac5138 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -106,5 +106,7 @@ draw_emit_vertex_attr(struct vertex_info *vinfo, extern void draw_compute_vertex_size(struct vertex_info *vinfo); +void draw_dump_emitted_vertex(const struct vertex_info *vinfo, + const uint8_t *data); #endif /* DRAW_VERTEX_H */ -- cgit v1.2.3 From 29858e1b553cee1fd7e3380ea62c69d2a6b91b95 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 20 Apr 2008 14:41:02 +0900 Subject: gallium: Refcount textures. Pipe driver does refcount textures. If cso_context does not, dangling pointers appear. --- src/gallium/auxiliary/cso_cache/cso_context.c | 37 ++++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 4a1a6cb79c..746b176185 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -25,16 +25,19 @@ * **************************************************************************/ - /* Wrap the cso cache & hash mechanisms in a simplified + /** + * @file + * + * Wrap the cso cache & hash mechanisms in a simplified * pipe-driver-specific interface. * - * Authors: - * Zack Rusin - * Keith Whitwell + * @author Zack Rusin + * @author Keith Whitwell */ #include "pipe/p_state.h" #include "pipe/p_util.h" +#include "pipe/p_inlines.h" #include "cso_cache/cso_context.h" #include "cso_cache/cso_cache.h" @@ -277,23 +280,39 @@ void cso_set_sampler_textures( struct cso_context *ctx, ctx->nr_textures = count; for (i = 0; i < count; i++) - ctx->textures[i] = textures[i]; + pipe_texture_reference(&ctx->textures[i], textures[i]); for ( ; i < PIPE_MAX_SAMPLERS; i++) - ctx->textures[i] = NULL; + pipe_texture_reference(&ctx->textures[i], NULL); ctx->pipe->set_sampler_textures(ctx->pipe, count, textures); } void cso_save_sampler_textures( struct cso_context *ctx ) { + uint i; + ctx->nr_textures_saved = ctx->nr_textures; - memcpy(ctx->textures_saved, ctx->textures, sizeof(ctx->textures)); + for (i = 0; i < ctx->nr_textures; i++) { + assert(!ctx->textures_saved[i]); + pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]); + } } void cso_restore_sampler_textures( struct cso_context *ctx ) { - cso_set_sampler_textures(ctx, ctx->nr_textures_saved, ctx->textures_saved); - ctx->nr_textures_saved = 0; + uint i; + + ctx->nr_textures = ctx->nr_textures_saved; + + for (i = 0; i < ctx->nr_textures; i++) { + pipe_texture_reference(&ctx->textures[i], NULL); + ctx->textures[i] = ctx->textures_saved[i]; + ctx->textures_saved[i] = NULL; + } + for ( ; i < PIPE_MAX_SAMPLERS; i++) + pipe_texture_reference(&ctx->textures[i], NULL); + + ctx->pipe->set_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); } -- cgit v1.2.3 From 40e0439db448a7d93ddb18faac7f14b47b1343c0 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 21 Apr 2008 13:02:59 +0900 Subject: gallium: Centralize SSE usage logic. --- src/gallium/auxiliary/draw/draw_context.c | 12 ------------ src/gallium/auxiliary/draw/draw_context.h | 2 -- src/gallium/auxiliary/draw/draw_private.h | 2 -- src/gallium/auxiliary/draw/draw_vs_sse.c | 3 ++- src/gallium/auxiliary/rtasm/rtasm_cpu.c | 10 ++++++++-- 5 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 4988d67faa..b4dbdccd61 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -45,12 +45,6 @@ struct draw_context *draw_create( void ) if (draw == NULL) goto fail; -#if defined(__i386__) || defined(__386__) - draw->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL; -#else - draw->use_sse = FALSE; -#endif - ASSIGN_4V( draw->plane[0], -1, 0, 0, 1 ); ASSIGN_4V( draw->plane[1], 1, 0, 0, 1 ); ASSIGN_4V( draw->plane[2], 0, -1, 0, 1 ); @@ -320,12 +314,6 @@ draw_num_vs_outputs(struct draw_context *draw) -boolean draw_use_sse(struct draw_context *draw) -{ - return (boolean) draw->use_sse; -} - - void draw_set_render( struct draw_context *draw, struct vbuf_render *render ) { diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index a0ac980c89..68e2efb865 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -73,8 +73,6 @@ void draw_enable_line_stipple(struct draw_context *draw, boolean enable); void draw_enable_point_sprites(struct draw_context *draw, boolean enable); -boolean draw_use_sse(struct draw_context *draw); - void draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 27f61c2f40..da973e868b 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -192,8 +192,6 @@ struct draw_context float plane[12][4]; unsigned nr_planes; - boolean use_sse; - /* If a prim stage introduces new vertex attributes, they'll be stored here */ struct { diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 8e2d381f14..b1e9f67114 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -41,6 +41,7 @@ #include "draw_private.h" #include "draw_context.h" +#include "rtasm/rtasm_cpu.h" #include "rtasm/rtasm_x86sse.h" #include "tgsi/exec/tgsi_sse2.h" #include "tgsi/util/tgsi_parse.h" @@ -155,7 +156,7 @@ draw_create_vs_sse(struct draw_context *draw, struct draw_sse_vertex_shader *vs; uint nt = tgsi_num_tokens(templ->tokens); - if (!draw->use_sse) + if (!rtasm_cpu_has_sse2()) return NULL; vs = CALLOC_STRUCT( draw_sse_vertex_shader ); diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c index d577ff5b42..175245a9f6 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -26,14 +26,20 @@ **************************************************************************/ +#include "pipe/p_debug.h" #include "rtasm_cpu.h" +static boolean rtasm_sse_enabled(void) +{ + return !debug_get_bool_option("GALLIUM_NOSSE", FALSE); +} + int rtasm_cpu_has_sse(void) { /* FIXME: actually detect this at run-time */ #if defined(__i386__) || defined(__386__) || defined(i386) - return 1; + return rtasm_sse_enabled(); #else return 0; #endif @@ -43,7 +49,7 @@ int rtasm_cpu_has_sse2(void) { /* FIXME: actually detect this at run-time */ #if defined(__i386__) || defined(__386__) || defined(i386) - return 1; + return rtasm_sse_enabled(); #else return 0; #endif -- cgit v1.2.3 From 201ac414d4df00745e487a6ffbc9979a2e70f0c6 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 00:10:39 -0400 Subject: make llvm draw paths compile with the latest changes switch the method of distribution of builtins (to get rid of the llvm2cpp dependency) --- src/gallium/auxiliary/draw/draw_vs_llvm.c | 13 +- src/gallium/auxiliary/gallivm/Makefile | 8 +- src/gallium/auxiliary/gallivm/gallivm_builtins.cpp | 708 ++++----------------- src/gallium/auxiliary/gallivm/instructions.cpp | 11 +- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 37 +- src/gallium/auxiliary/gallivm/llvm_builtins.c | 2 +- src/gallium/auxiliary/gallivm/soabuiltins.c | 2 +- 7 files changed, 199 insertions(+), 582 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index c219a91156..2ebf05526a 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -73,16 +73,17 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, (struct draw_llvm_vertex_shader *)base; struct tgsi_exec_machine *machine = shader->machine; - unsigned int j; + unsigned int i, j; + unsigned slot; for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); - /* Swizzle inputs. + /* Swizzle inputs. */ for (j = 0; j < max_vertices; j++) { - for (slot = 0; slot < draw->num_vs_inputs; slot++) { + for (slot = 0; slot < base->info.num_inputs; slot++) { machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; @@ -102,7 +103,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, /* Unswizzle all output results */ - for (slot = 1; slot < draw->num_vs_outputs; slot++) { + for (slot = 1; slot < base->info.num_inputs; slot++) { output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; @@ -145,7 +146,7 @@ draw_create_vs_llvm(struct draw_context *draw, /* we make a private copy of the tokens */ vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0])); - tgsi_scan_shader(shader->tokens, &vs->base.info); + tgsi_scan_shader(vs->base.state.tokens, &vs->base.info); vs->base.prepare = vs_llvm_prepare; vs->base.run_linear = vs_llvm_run_linear; @@ -156,7 +157,7 @@ draw_create_vs_llvm(struct draw_context *draw, struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS); gallivm_ir_set_layout(ir, GALLIVM_SOA); gallivm_ir_set_components(ir, 4); - gallivm_ir_fill_from_tgsi(ir, vs->base.state->tokens); + gallivm_ir_fill_from_tgsi(ir, vs->base.state.tokens); vs->llvm_prog = gallivm_ir_compile(ir); gallivm_ir_delete(ir); } diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile index c24e19e062..6bfd187fb3 100644 --- a/src/gallium/auxiliary/gallivm/Makefile +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -65,10 +65,14 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-contents -o=$@ -f -for=shader -funcname=createGallivmBuiltins + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin + (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp.bin gallivmsoabuiltins.cpp: soabuiltins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts|llvm2cpp -gen-module -o=$@ -f -for=shader -funcname=createSoaBuiltins + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin + (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp.bin # Emacs tags tags: diff --git a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp index 1796f0a177..a6f8cd043b 100644 --- a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp +++ b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp @@ -1,567 +1,141 @@ -// Generated by llvm2cpp - DO NOT MODIFY! - - -Module* createGallivmBuiltins(Module *mod) { - -mod->setModuleIdentifier("shader"); - -// Type Definitions -ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 25); - -PointerType* PointerTy_1 = PointerType::get(ArrayTy_0, 0); - -std::vectorFuncTy_2_args; -FuncTy_2_args.push_back(Type::FloatTy); -FuncTy_2_args.push_back(Type::FloatTy); -FunctionType* FuncTy_2 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_2_args, - /*isVarArg=*/false); - -PointerType* PointerTy_3 = PointerType::get(FuncTy_2, 0); - -VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4); - -std::vectorFuncTy_5_args; -FuncTy_5_args.push_back(VectorTy_4); -FunctionType* FuncTy_5 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_5_args, - /*isVarArg=*/false); - -std::vectorFuncTy_6_args; -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FuncTy_6_args.push_back(VectorTy_4); -FunctionType* FuncTy_6 = FunctionType::get( - /*Result=*/VectorTy_4, - /*Params=*/FuncTy_6_args, - /*isVarArg=*/false); - -VectorType* VectorTy_7 = VectorType::get(IntegerType::get(32), 4); - -std::vectorFuncTy_9_args; -FunctionType* FuncTy_9 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_9_args, - /*isVarArg=*/true); - -PointerType* PointerTy_8 = PointerType::get(FuncTy_9, 0); - -PointerType* PointerTy_10 = PointerType::get(IntegerType::get(8), 0); - -std::vectorFuncTy_12_args; -FuncTy_12_args.push_back(Type::FloatTy); -FunctionType* FuncTy_12 = FunctionType::get( - /*Result=*/Type::FloatTy, - /*Params=*/FuncTy_12_args, - /*isVarArg=*/false); - -PointerType* PointerTy_11 = PointerType::get(FuncTy_12, 0); - -std::vectorFuncTy_13_args; -FuncTy_13_args.push_back(VectorTy_4); -FunctionType* FuncTy_13 = FunctionType::get( - /*Result=*/IntegerType::get(32), - /*Params=*/FuncTy_13_args, - /*isVarArg=*/false); - - -// Function Declarations - -Function* func_approx = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"approx", mod); -func_approx->setCallingConv(CallingConv::C); -const ParamAttrsList *func_approx_PAL = 0; -func_approx->setParamAttrs(func_approx_PAL); - -Function* func_powf = new Function( - /*Type=*/FuncTy_2, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"powf", mod); // (external, no body) -func_powf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_powf_PAL = 0; -func_powf->setParamAttrs(func_powf_PAL); - -Function* func_lit = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"lit", mod); -func_lit->setCallingConv(CallingConv::C); -const ParamAttrsList *func_lit_PAL = 0; -func_lit->setParamAttrs(func_lit_PAL); - -Function* func_cmp = new Function( - /*Type=*/FuncTy_6, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"cmp", mod); -func_cmp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cmp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_cmp_PAL = ParamAttrsList::get(Attrs); - -} -func_cmp->setParamAttrs(func_cmp_PAL); - -Function* func_vcos = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vcos", mod); -func_vcos->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vcos_PAL = 0; -func_vcos->setParamAttrs(func_vcos_PAL); - -Function* func_printf = new Function( - /*Type=*/FuncTy_9, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"printf", mod); // (external, no body) -func_printf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_printf_PAL = 0; -func_printf->setParamAttrs(func_printf_PAL); - -Function* func_cosf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"cosf", mod); // (external, no body) -func_cosf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_cosf_PAL = 0; -func_cosf->setParamAttrs(func_cosf_PAL); - -Function* func_scs = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"scs", mod); -func_scs->setCallingConv(CallingConv::C); -const ParamAttrsList *func_scs_PAL = 0; -func_scs->setParamAttrs(func_scs_PAL); - -Function* func_sinf = new Function( - /*Type=*/FuncTy_12, - /*Linkage=*/GlobalValue::ExternalLinkage, - /*Name=*/"sinf", mod); // (external, no body) -func_sinf->setCallingConv(CallingConv::C); -const ParamAttrsList *func_sinf_PAL = 0; -func_sinf->setParamAttrs(func_sinf_PAL); - -Function* func_vsin = new Function( - /*Type=*/FuncTy_5, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"vsin", mod); -func_vsin->setCallingConv(CallingConv::C); -const ParamAttrsList *func_vsin_PAL = 0; -func_vsin->setParamAttrs(func_vsin_PAL); - -Function* func_kilp = new Function( - /*Type=*/FuncTy_13, - /*Linkage=*/GlobalValue::WeakLinkage, - /*Name=*/"kilp", mod); -func_kilp->setCallingConv(CallingConv::C); -const ParamAttrsList *func_kilp_PAL = 0; -{ - ParamAttrsVector Attrs; - ParamAttrsWithIndex PAWI; - PAWI.index = 0; PAWI.attrs = 0 | ParamAttr::NoUnwind; - Attrs.push_back(PAWI); - func_kilp_PAL = ParamAttrsList::get(Attrs); - -} -func_kilp->setParamAttrs(func_kilp_PAL); - -// Global Variable Declarations - - -GlobalVariable* gvar_array__str = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str", -mod); - -GlobalVariable* gvar_array__str1 = new GlobalVariable( -/*Type=*/ArrayTy_0, -/*isConstant=*/true, -/*Linkage=*/GlobalValue::InternalLinkage, -/*Initializer=*/0, // has initializer, specified below -/*Name=*/".str1", -mod); - -// Constant Definitions -Constant* const_array_14 = ConstantArray::get("VEC IN is %f %f %f %f\x0A", true); -Constant* const_array_15 = ConstantArray::get("VEC OUT is %f %f %f %f\x0A", true); -ConstantFP* const_float_16 = ConstantFP::get(Type::FloatTy, APFloat(-1.280000e+02f)); -ConstantFP* const_float_17 = ConstantFP::get(Type::FloatTy, APFloat(1.280000e+02f)); -Constant* const_float_18 = Constant::getNullValue(Type::FloatTy); -Constant* const_int32_19 = Constant::getNullValue(IntegerType::get(32)); -std::vector const_packed_20_elems; -ConstantFP* const_float_21 = ConstantFP::get(Type::FloatTy, APFloat(1.000000e+00f)); -const_packed_20_elems.push_back(const_float_21); -UndefValue* const_float_22 = UndefValue::get(Type::FloatTy); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_22); -const_packed_20_elems.push_back(const_float_21); -Constant* const_packed_20 = ConstantVector::get(VectorTy_4, const_packed_20_elems); -ConstantInt* const_int32_23 = ConstantInt::get(APInt(32, "1", 10)); -ConstantInt* const_int32_24 = ConstantInt::get(APInt(32, "3", 10)); -ConstantInt* const_int32_25 = ConstantInt::get(APInt(32, "2", 10)); -std::vector const_packed_26_elems; -const_packed_26_elems.push_back(const_float_21); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_18); -const_packed_26_elems.push_back(const_float_21); -Constant* const_packed_26 = ConstantVector::get(VectorTy_4, const_packed_26_elems); -Constant* const_double_27 = Constant::getNullValue(Type::DoubleTy); -std::vector const_packed_28_elems; -const_packed_28_elems.push_back(const_int32_19); -ConstantInt* const_int32_29 = ConstantInt::get(APInt(32, "5", 10)); -const_packed_28_elems.push_back(const_int32_29); -const_packed_28_elems.push_back(const_int32_25); -const_packed_28_elems.push_back(const_int32_24); -Constant* const_packed_28 = ConstantVector::get(VectorTy_7, const_packed_28_elems); -std::vector const_packed_30_elems; -const_packed_30_elems.push_back(const_int32_19); -const_packed_30_elems.push_back(const_int32_23); -ConstantInt* const_int32_31 = ConstantInt::get(APInt(32, "6", 10)); -const_packed_30_elems.push_back(const_int32_31); -const_packed_30_elems.push_back(const_int32_24); -Constant* const_packed_30 = ConstantVector::get(VectorTy_7, const_packed_30_elems); -std::vector const_packed_32_elems; -const_packed_32_elems.push_back(const_int32_19); -const_packed_32_elems.push_back(const_int32_23); -const_packed_32_elems.push_back(const_int32_25); -ConstantInt* const_int32_33 = ConstantInt::get(APInt(32, "7", 10)); -const_packed_32_elems.push_back(const_int32_33); -Constant* const_packed_32 = ConstantVector::get(VectorTy_7, const_packed_32_elems); -std::vector const_ptr_34_indices; -const_ptr_34_indices.push_back(const_int32_19); -const_ptr_34_indices.push_back(const_int32_19); -Constant* const_ptr_34 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_34_indices[0], const_ptr_34_indices.size() ); -UndefValue* const_packed_35 = UndefValue::get(VectorTy_4); -std::vector const_ptr_36_indices; -const_ptr_36_indices.push_back(const_int32_19); -const_ptr_36_indices.push_back(const_int32_19); -Constant* const_ptr_36 = ConstantExpr::getGetElementPtr(gvar_array__str1, &const_ptr_36_indices[0], const_ptr_36_indices.size() ); - -// Global Variable Definitions -gvar_array__str->setInitializer(const_array_14); -gvar_array__str1->setInitializer(const_array_15); - -// Function Definitions - -// Function: approx (func_approx) -{ - Function::arg_iterator args = func_approx->arg_begin(); - Value* float_a = args++; - float_a->setName("a"); - Value* float_b = args++; - float_b->setName("b"); - - BasicBlock* label_entry = new BasicBlock("entry",func_approx,0); - - // Block entry (label_entry) - FCmpInst* int1_cmp = new FCmpInst(FCmpInst::FCMP_OLT, float_b, const_float_16, "cmp", label_entry); - SelectInst* float_b_addr_0 = new SelectInst(int1_cmp, const_float_16, float_b, "b.addr.0", label_entry); - FCmpInst* int1_cmp3 = new FCmpInst(FCmpInst::FCMP_OGT, float_b_addr_0, const_float_17, "cmp3", label_entry); - SelectInst* float_b_addr_1 = new SelectInst(int1_cmp3, const_float_17, float_b_addr_0, "b.addr.1", label_entry); - FCmpInst* int1_cmp7 = new FCmpInst(FCmpInst::FCMP_OLT, float_a, const_float_18, "cmp7", label_entry); - SelectInst* float_a_addr_0 = new SelectInst(int1_cmp7, const_float_18, float_a, "a.addr.0", label_entry); - std::vector float_call_params; - float_call_params.push_back(float_a_addr_0); - float_call_params.push_back(float_b_addr_1); - CallInst* float_call = new CallInst(func_powf, float_call_params.begin(), float_call_params.end(), "call", label_entry); - float_call->setCallingConv(CallingConv::C); - float_call->setTailCall(true);const ParamAttrsList *float_call_PAL = 0; - float_call->setParamAttrs(float_call_PAL); - - new ReturnInst(float_call, label_entry); - -} - -// Function: lit (func_lit) -{ - Function::arg_iterator args = func_lit->arg_begin(); - Value* packed_tmp = args++; - packed_tmp->setName("tmp"); - - BasicBlock* label_entry_38 = new BasicBlock("entry",func_lit,0); - BasicBlock* label_ifthen = new BasicBlock("ifthen",func_lit,0); - BasicBlock* label_UnifiedReturnBlock = new BasicBlock("UnifiedReturnBlock",func_lit,0); - - // Block entry (label_entry_38) - ExtractElementInst* float_tmp6 = new ExtractElementInst(packed_tmp, const_int32_19, "tmp6", label_entry_38); - FCmpInst* int1_cmp_39 = new FCmpInst(FCmpInst::FCMP_OGT, float_tmp6, const_float_18, "cmp", label_entry_38); - new BranchInst(label_ifthen, label_UnifiedReturnBlock, int1_cmp_39, label_entry_38); - - // Block ifthen (label_ifthen) - InsertElementInst* packed_tmp10 = new InsertElementInst(const_packed_20, float_tmp6, const_int32_23, "tmp10", label_ifthen); - ExtractElementInst* float_tmp12 = new ExtractElementInst(packed_tmp, const_int32_23, "tmp12", label_ifthen); - ExtractElementInst* float_tmp14 = new ExtractElementInst(packed_tmp, const_int32_24, "tmp14", label_ifthen); - std::vector float_call_41_params; - float_call_41_params.push_back(float_tmp12); - float_call_41_params.push_back(float_tmp14); - CallInst* float_call_41 = new CallInst(func_approx, float_call_41_params.begin(), float_call_41_params.end(), "call", label_ifthen); - float_call_41->setCallingConv(CallingConv::C); - float_call_41->setTailCall(true);const ParamAttrsList *float_call_41_PAL = 0; - float_call_41->setParamAttrs(float_call_41_PAL); - - InsertElementInst* packed_tmp16 = new InsertElementInst(packed_tmp10, float_call_41, const_int32_25, "tmp16", label_ifthen); - new ReturnInst(packed_tmp16, label_ifthen); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock) - new ReturnInst(const_packed_26, label_UnifiedReturnBlock); - -} - -// Function: cmp (func_cmp) -{ - Function::arg_iterator args = func_cmp->arg_begin(); - Value* packed_tmp0 = args++; - packed_tmp0->setName("tmp0"); - Value* packed_tmp1 = args++; - packed_tmp1->setName("tmp1"); - Value* packed_tmp2 = args++; - packed_tmp2->setName("tmp2"); - - BasicBlock* label_entry_44 = new BasicBlock("entry",func_cmp,0); - BasicBlock* label_cond__14 = new BasicBlock("cond.?14",func_cmp,0); - BasicBlock* label_cond_cont20 = new BasicBlock("cond.cont20",func_cmp,0); - BasicBlock* label_cond__28 = new BasicBlock("cond.?28",func_cmp,0); - BasicBlock* label_cond_cont34 = new BasicBlock("cond.cont34",func_cmp,0); - BasicBlock* label_cond__42 = new BasicBlock("cond.?42",func_cmp,0); - BasicBlock* label_cond_cont48 = new BasicBlock("cond.cont48",func_cmp,0); - - // Block entry (label_entry_44) - ExtractElementInst* float_tmp3 = new ExtractElementInst(packed_tmp0, const_int32_19, "tmp3", label_entry_44); - CastInst* double_conv = new FPExtInst(float_tmp3, Type::DoubleTy, "conv", label_entry_44); - FCmpInst* int1_cmp_45 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv, const_double_27, "cmp", label_entry_44); - ExtractElementInst* float_tmp11 = new ExtractElementInst(packed_tmp0, const_int32_23, "tmp11", label_entry_44); - CastInst* double_conv12 = new FPExtInst(float_tmp11, Type::DoubleTy, "conv12", label_entry_44); - FCmpInst* int1_cmp13 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv12, const_double_27, "cmp13", label_entry_44); - SelectInst* packed_tmp1_tmp2 = new SelectInst(int1_cmp_45, packed_tmp1, packed_tmp2, "tmp1.tmp2", label_entry_44); - new BranchInst(label_cond__14, label_cond_cont20, int1_cmp13, label_entry_44); - - // Block cond.?14 (label_cond__14) - ShuffleVectorInst* packed_tmp233 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp1, const_packed_28, "tmp233", label_cond__14); - ExtractElementInst* float_tmp254 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp254", label_cond__14); - CastInst* double_conv265 = new FPExtInst(float_tmp254, Type::DoubleTy, "conv265", label_cond__14); - FCmpInst* int1_cmp276 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv265, const_double_27, "cmp276", label_cond__14); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp276, label_cond__14); - - // Block cond.cont20 (label_cond_cont20) - ShuffleVectorInst* packed_tmp23 = new ShuffleVectorInst(packed_tmp1_tmp2, packed_tmp2, const_packed_28, "tmp23", label_cond_cont20); - ExtractElementInst* float_tmp25 = new ExtractElementInst(packed_tmp0, const_int32_25, "tmp25", label_cond_cont20); - CastInst* double_conv26 = new FPExtInst(float_tmp25, Type::DoubleTy, "conv26", label_cond_cont20); - FCmpInst* int1_cmp27 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv26, const_double_27, "cmp27", label_cond_cont20); - new BranchInst(label_cond__28, label_cond_cont34, int1_cmp27, label_cond_cont20); - - // Block cond.?28 (label_cond__28) - PHINode* packed_tmp23_reg2mem_0 = new PHINode(VectorTy_4, "tmp23.reg2mem.0", label_cond__28); - packed_tmp23_reg2mem_0->reserveOperandSpace(2); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_0->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp378 = new ShuffleVectorInst(packed_tmp23_reg2mem_0, packed_tmp1, const_packed_30, "tmp378", label_cond__28); - ExtractElementInst* float_tmp399 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp399", label_cond__28); - CastInst* double_conv4010 = new FPExtInst(float_tmp399, Type::DoubleTy, "conv4010", label_cond__28); - FCmpInst* int1_cmp4111 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv4010, const_double_27, "cmp4111", label_cond__28); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp4111, label_cond__28); - - // Block cond.cont34 (label_cond_cont34) - PHINode* packed_tmp23_reg2mem_1 = new PHINode(VectorTy_4, "tmp23.reg2mem.1", label_cond_cont34); - packed_tmp23_reg2mem_1->reserveOperandSpace(2); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp233, label_cond__14); - packed_tmp23_reg2mem_1->addIncoming(packed_tmp23, label_cond_cont20); - - ShuffleVectorInst* packed_tmp37 = new ShuffleVectorInst(packed_tmp23_reg2mem_1, packed_tmp2, const_packed_30, "tmp37", label_cond_cont34); - ExtractElementInst* float_tmp39 = new ExtractElementInst(packed_tmp0, const_int32_24, "tmp39", label_cond_cont34); - CastInst* double_conv40 = new FPExtInst(float_tmp39, Type::DoubleTy, "conv40", label_cond_cont34); - FCmpInst* int1_cmp41 = new FCmpInst(FCmpInst::FCMP_OLT, double_conv40, const_double_27, "cmp41", label_cond_cont34); - new BranchInst(label_cond__42, label_cond_cont48, int1_cmp41, label_cond_cont34); - - // Block cond.?42 (label_cond__42) - PHINode* packed_tmp37_reg2mem_0 = new PHINode(VectorTy_4, "tmp37.reg2mem.0", label_cond__42); - packed_tmp37_reg2mem_0->reserveOperandSpace(2); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_0->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp5113 = new ShuffleVectorInst(packed_tmp37_reg2mem_0, packed_tmp1, const_packed_32, "tmp5113", label_cond__42); - new ReturnInst(packed_tmp5113, label_cond__42); - - // Block cond.cont48 (label_cond_cont48) - PHINode* packed_tmp37_reg2mem_1 = new PHINode(VectorTy_4, "tmp37.reg2mem.1", label_cond_cont48); - packed_tmp37_reg2mem_1->reserveOperandSpace(2); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp378, label_cond__28); - packed_tmp37_reg2mem_1->addIncoming(packed_tmp37, label_cond_cont34); - - ShuffleVectorInst* packed_tmp51 = new ShuffleVectorInst(packed_tmp37_reg2mem_1, packed_tmp2, const_packed_32, "tmp51", label_cond_cont48); - new ReturnInst(packed_tmp51, label_cond_cont48); - -} - -// Function: vcos (func_vcos) -{ - Function::arg_iterator args = func_vcos->arg_begin(); - Value* packed_val = args++; - packed_val->setName("val"); - - BasicBlock* label_entry_53 = new BasicBlock("entry",func_vcos,0); - - // Block entry (label_entry_53) - ExtractElementInst* float_tmp1 = new ExtractElementInst(packed_val, const_int32_19, "tmp1", label_entry_53); - CastInst* double_conv_54 = new FPExtInst(float_tmp1, Type::DoubleTy, "conv", label_entry_53); - ExtractElementInst* float_tmp3_55 = new ExtractElementInst(packed_val, const_int32_23, "tmp3", label_entry_53); - CastInst* double_conv4 = new FPExtInst(float_tmp3_55, Type::DoubleTy, "conv4", label_entry_53); - ExtractElementInst* float_tmp6_56 = new ExtractElementInst(packed_val, const_int32_25, "tmp6", label_entry_53); - CastInst* double_conv7 = new FPExtInst(float_tmp6_56, Type::DoubleTy, "conv7", label_entry_53); - ExtractElementInst* float_tmp9 = new ExtractElementInst(packed_val, const_int32_24, "tmp9", label_entry_53); - CastInst* double_conv10 = new FPExtInst(float_tmp9, Type::DoubleTy, "conv10", label_entry_53); - std::vector int32_call_params; - int32_call_params.push_back(const_ptr_34); - int32_call_params.push_back(double_conv_54); - int32_call_params.push_back(double_conv4); - int32_call_params.push_back(double_conv7); - int32_call_params.push_back(double_conv10); - CallInst* int32_call = new CallInst(func_printf, int32_call_params.begin(), int32_call_params.end(), "call", label_entry_53); - int32_call->setCallingConv(CallingConv::C); - int32_call->setTailCall(true);const ParamAttrsList *int32_call_PAL = 0; - int32_call->setParamAttrs(int32_call_PAL); - - CallInst* float_call13 = new CallInst(func_cosf, float_tmp1, "call13", label_entry_53); - float_call13->setCallingConv(CallingConv::C); - float_call13->setTailCall(true);const ParamAttrsList *float_call13_PAL = 0; - float_call13->setParamAttrs(float_call13_PAL); - - InsertElementInst* packed_tmp15 = new InsertElementInst(const_packed_35, float_call13, const_int32_19, "tmp15", label_entry_53); - CallInst* float_call18 = new CallInst(func_cosf, float_tmp1, "call18", label_entry_53); - float_call18->setCallingConv(CallingConv::C); - float_call18->setTailCall(true);const ParamAttrsList *float_call18_PAL = 0; - float_call18->setParamAttrs(float_call18_PAL); - - InsertElementInst* packed_tmp20 = new InsertElementInst(packed_tmp15, float_call18, const_int32_23, "tmp20", label_entry_53); - CallInst* float_call23 = new CallInst(func_cosf, float_tmp1, "call23", label_entry_53); - float_call23->setCallingConv(CallingConv::C); - float_call23->setTailCall(true);const ParamAttrsList *float_call23_PAL = 0; - float_call23->setParamAttrs(float_call23_PAL); - - InsertElementInst* packed_tmp25 = new InsertElementInst(packed_tmp20, float_call23, const_int32_25, "tmp25", label_entry_53); - CallInst* float_call28 = new CallInst(func_cosf, float_tmp1, "call28", label_entry_53); - float_call28->setCallingConv(CallingConv::C); - float_call28->setTailCall(true);const ParamAttrsList *float_call28_PAL = 0; - float_call28->setParamAttrs(float_call28_PAL); - - InsertElementInst* packed_tmp30 = new InsertElementInst(packed_tmp25, float_call28, const_int32_24, "tmp30", label_entry_53); - CastInst* double_conv33 = new FPExtInst(float_call13, Type::DoubleTy, "conv33", label_entry_53); - CastInst* double_conv36 = new FPExtInst(float_call18, Type::DoubleTy, "conv36", label_entry_53); - CastInst* double_conv39 = new FPExtInst(float_call23, Type::DoubleTy, "conv39", label_entry_53); - CastInst* double_conv42 = new FPExtInst(float_call28, Type::DoubleTy, "conv42", label_entry_53); - std::vector int32_call43_params; - int32_call43_params.push_back(const_ptr_36); - int32_call43_params.push_back(double_conv33); - int32_call43_params.push_back(double_conv36); - int32_call43_params.push_back(double_conv39); - int32_call43_params.push_back(double_conv42); - CallInst* int32_call43 = new CallInst(func_printf, int32_call43_params.begin(), int32_call43_params.end(), "call43", label_entry_53); - int32_call43->setCallingConv(CallingConv::C); - int32_call43->setTailCall(true);const ParamAttrsList *int32_call43_PAL = 0; - int32_call43->setParamAttrs(int32_call43_PAL); - - new ReturnInst(packed_tmp30, label_entry_53); - -} - -// Function: scs (func_scs) -{ - Function::arg_iterator args = func_scs->arg_begin(); - Value* packed_val_58 = args++; - packed_val_58->setName("val"); - - BasicBlock* label_entry_59 = new BasicBlock("entry",func_scs,0); - - // Block entry (label_entry_59) - ExtractElementInst* float_tmp2 = new ExtractElementInst(packed_val_58, const_int32_19, "tmp2", label_entry_59); - CallInst* float_call_60 = new CallInst(func_cosf, float_tmp2, "call", label_entry_59); - float_call_60->setCallingConv(CallingConv::C); - float_call_60->setTailCall(true);const ParamAttrsList *float_call_60_PAL = 0; - float_call_60->setParamAttrs(float_call_60_PAL); - - InsertElementInst* packed_tmp5 = new InsertElementInst(const_packed_35, float_call_60, const_int32_19, "tmp5", label_entry_59); - CallInst* float_call7 = new CallInst(func_sinf, float_tmp2, "call7", label_entry_59); - float_call7->setCallingConv(CallingConv::C); - float_call7->setTailCall(true);const ParamAttrsList *float_call7_PAL = 0; - float_call7->setParamAttrs(float_call7_PAL); - - InsertElementInst* packed_tmp9 = new InsertElementInst(packed_tmp5, float_call7, const_int32_23, "tmp9", label_entry_59); - new ReturnInst(packed_tmp9, label_entry_59); - -} - -// Function: vsin (func_vsin) -{ - Function::arg_iterator args = func_vsin->arg_begin(); - Value* packed_val_62 = args++; - packed_val_62->setName("val"); - - BasicBlock* label_entry_63 = new BasicBlock("entry",func_vsin,0); - - // Block entry (label_entry_63) - ExtractElementInst* float_tmp2_64 = new ExtractElementInst(packed_val_62, const_int32_19, "tmp2", label_entry_63); - CallInst* float_call_65 = new CallInst(func_sinf, float_tmp2_64, "call", label_entry_63); - float_call_65->setCallingConv(CallingConv::C); - float_call_65->setTailCall(true);const ParamAttrsList *float_call_65_PAL = 0; - float_call_65->setParamAttrs(float_call_65_PAL); - - InsertElementInst* packed_tmp6 = new InsertElementInst(const_packed_35, float_call_65, const_int32_19, "tmp6", label_entry_63); - InsertElementInst* packed_tmp9_66 = new InsertElementInst(packed_tmp6, float_call_65, const_int32_23, "tmp9", label_entry_63); - InsertElementInst* packed_tmp12 = new InsertElementInst(packed_tmp9_66, float_call_65, const_int32_25, "tmp12", label_entry_63); - InsertElementInst* packed_tmp15_67 = new InsertElementInst(packed_tmp12, float_call_65, const_int32_24, "tmp15", label_entry_63); - new ReturnInst(packed_tmp15_67, label_entry_63); - -} - -// Function: kilp (func_kilp) -{ - Function::arg_iterator args = func_kilp->arg_begin(); - Value* packed_val_69 = args++; - packed_val_69->setName("val"); - - BasicBlock* label_entry_70 = new BasicBlock("entry",func_kilp,0); - BasicBlock* label_lor_rhs = new BasicBlock("lor_rhs",func_kilp,0); - BasicBlock* label_lor_rhs5 = new BasicBlock("lor_rhs5",func_kilp,0); - BasicBlock* label_lor_rhs11 = new BasicBlock("lor_rhs11",func_kilp,0); - BasicBlock* label_UnifiedReturnBlock_71 = new BasicBlock("UnifiedReturnBlock",func_kilp,0); - - // Block entry (label_entry_70) - ExtractElementInst* float_tmp1_72 = new ExtractElementInst(packed_val_69, const_int32_19, "tmp1", label_entry_70); - FCmpInst* int1_cmp_73 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp1_72, const_float_18, "cmp", label_entry_70); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs, int1_cmp_73, label_entry_70); - - // Block lor_rhs (label_lor_rhs) - ExtractElementInst* float_tmp3_75 = new ExtractElementInst(packed_val_69, const_int32_23, "tmp3", label_lor_rhs); - FCmpInst* int1_cmp4 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp3_75, const_float_18, "cmp4", label_lor_rhs); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs5, int1_cmp4, label_lor_rhs); - - // Block lor_rhs5 (label_lor_rhs5) - ExtractElementInst* float_tmp7 = new ExtractElementInst(packed_val_69, const_int32_25, "tmp7", label_lor_rhs5); - FCmpInst* int1_cmp8 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp7, const_float_18, "cmp8", label_lor_rhs5); - new BranchInst(label_UnifiedReturnBlock_71, label_lor_rhs11, int1_cmp8, label_lor_rhs5); - - // Block lor_rhs11 (label_lor_rhs11) - ExtractElementInst* float_tmp13 = new ExtractElementInst(packed_val_69, const_int32_24, "tmp13", label_lor_rhs11); - FCmpInst* int1_cmp14 = new FCmpInst(FCmpInst::FCMP_OLT, float_tmp13, const_float_18, "cmp14", label_lor_rhs11); - CastInst* int32_retval = new ZExtInst(int1_cmp14, IntegerType::get(32), "retval", label_lor_rhs11); - new ReturnInst(int32_retval, label_lor_rhs11); - - // Block UnifiedReturnBlock (label_UnifiedReturnBlock_71) - new ReturnInst(const_int32_23, label_UnifiedReturnBlock_71); - -} - -return mod; - -} +static const unsigned char llvm_builtins_data[] = { +0x42,0x43,0xc0,0xde,0x21,0x0c,0x00,0x00,0x2b,0x02,0x00,0x00,0x01,0x10,0x00,0x00, +0x10,0x00,0x00,0x00,0x07,0x81,0x23,0x91,0x41,0xc8,0x04,0x49,0x06,0x10,0x32,0x39, +0x92,0x01,0x84,0x0c,0x25,0x05,0x08,0x19,0x1e,0x04,0x8b,0x62,0x80,0x14,0x45,0x02, +0x42,0x92,0x0b,0x42,0xa4,0x10,0x32,0x14,0x38,0x08,0x18,0x49,0x0a,0x32,0x44,0x24, +0x48,0x0a,0x90,0x21,0x23,0x44,0x72,0x80,0x8c,0x14,0x21,0x86,0x0a,0x8a,0x0a,0x64, +0x0c,0x1f,0x00,0x00,0x49,0x18,0x00,0x00,0x02,0x00,0x00,0x00,0x0b,0x04,0x00,0x0c, +0x00,0x00,0x00,0x00,0x51,0x20,0x00,0x00,0x13,0x00,0x00,0x00,0x32,0x22,0x48,0x09, +0x20,0x65,0x82,0x84,0x00,0x26,0x45,0x48,0x05,0x09,0x26,0x45,0xc6,0x05,0x42,0x52, +0x26,0x08,0xb0,0x19,0x80,0x61,0x04,0x02,0x98,0x23,0x00,0x83,0x21,0x80,0x39,0x82, +0x60,0x0a,0x80,0x2e,0xd5,0x61,0x04,0x42,0x20,0x49,0x90,0x22,0x4d,0xa2,0x73,0x04, +0x08,0xb9,0x32,0x00,0x00,0x8a,0x10,0xc2,0x65,0xb8,0x42,0x84,0x10,0x42,0x0d,0x44, +0x11,0x00,0x18,0x01,0x28,0x82,0x08,0x00,0x13,0xa2,0x74,0xb0,0x03,0x3c,0xb0,0x83, +0x36,0x80,0x87,0x71,0x68,0x03,0x76,0x48,0x07,0x77,0xa8,0x07,0x7c,0x68,0x83,0x73, +0x70,0x87,0x7a,0xd8,0x70,0x0f,0xe5,0xd0,0x06,0xf0,0xa0,0x07,0x73,0x20,0x07,0x7a, +0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x71,0xa0,0x07,0x78,0xa0, +0x07,0x78,0xd0,0x06,0xe9,0x80,0x07,0x7a,0x80,0x07,0x7a,0x80,0x07,0x6d,0x90,0x0e, +0x71,0x60,0x07,0x7a,0x10,0x07,0x76,0xa0,0x07,0x71,0x60,0x07,0x6d,0x90,0x0e,0x73, +0x20,0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x90,0x0e,0x76,0x40, +0x07,0x7a,0x30,0x07,0x72,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0e,0x73,0x20,0x07, +0x7a,0x30,0x07,0x72,0xa0,0x07,0x73,0x20,0x07,0x6d,0x60,0x0e,0x76,0x40,0x07,0x7a, +0x30,0x07,0x72,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x76,0x40,0x07,0x7a,0x60, +0x07,0x74,0xa0,0x07,0x76,0x40,0x07,0x6d,0x60,0x0f,0x71,0x20,0x07,0x78,0xa0,0x07, +0x71,0x20,0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xd0,0x06,0xe1,0x00,0x07,0x7a, +0x00,0x07,0x7a,0x60,0x07,0x74,0xd0,0x06,0xe6,0x80,0x07,0x70,0xa0,0x07,0x71,0x20, +0x07,0x78,0xa0,0x07,0x71,0x20,0x07,0x78,0xa0,0xf3,0x40,0x88,0x04,0x32,0x32,0x02, +0x04,0x60,0x76,0xc6,0xfc,0x6c,0x48,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0x0c,0x49, +0x14,0x20,0x00,0x00,0x00,0x00,0x80,0x21,0xc9,0x02,0x00,0x01,0x00,0x00,0x00,0x30, +0x24,0x61,0x00,0x20,0x08,0x00,0x00,0x00,0x86,0x24,0x0b,0x00,0x04,0x00,0x00,0x00, +0xc0,0x90,0xa4,0x01,0x02,0x00,0x00,0x00,0x00,0x18,0x92,0x1c,0x40,0x00,0x00,0x00, +0x00,0x00,0x43,0x92,0x05,0x00,0x02,0x00,0x00,0x00,0x60,0x48,0x72,0x00,0x01,0x00, +0x00,0x00,0x00,0x0c,0x49,0x16,0x00,0x08,0x00,0x00,0x00,0x80,0x21,0x89,0x01,0x00, +0x41,0x00,0x00,0x00,0x90,0x05,0x02,0x00,0x10,0x00,0x00,0x00,0x32,0x1e,0x98,0x10, +0x19,0x11,0x4c,0x90,0x8c,0x09,0x26,0x47,0xc6,0x04,0x43,0x92,0x8a,0x59,0x8b,0x43, +0x50,0xd2,0x09,0x02,0x81,0xd2,0x73,0x50,0xc9,0x0c,0x2a,0x99,0x41,0x25,0x33,0xa8, +0x64,0x56,0x28,0x66,0x2d,0x0e,0x41,0xcf,0x2a,0x15,0x04,0x4a,0xcf,0x41,0x25,0x33, +0xa8,0x64,0x06,0x95,0xcc,0xa0,0x92,0x59,0x01,0x00,0x00,0x00,0x53,0x82,0x26,0x0c, +0x04,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, +0x05,0x00,0x00,0x00,0x04,0xc6,0x08,0x40,0x10,0x04,0xe1,0x70,0x18,0x23,0x00,0x41, +0x10,0x84,0xc3,0x60,0x04,0x00,0x00,0x00,0x93,0x0c,0xce,0x43,0x4c,0x31,0x3c,0x8e, +0x34,0xc9,0x30,0x41,0xc2,0x14,0x03,0x34,0x51,0x93,0x0c,0x4d,0x44,0x4c,0x31,0x44, +0x8d,0x35,0x56,0x01,0x04,0xc3,0x55,0x21,0x16,0x0e,0x04,0x00,0x0f,0x00,0x00,0x00, +0x46,0x41,0x08,0xcc,0x73,0x9b,0x05,0x21,0x30,0xcf,0x6e,0x18,0x84,0x00,0x2c,0x8b, +0x35,0x04,0x80,0x39,0x04,0x81,0x5d,0x20,0x80,0x0f,0x0c,0x43,0xe4,0xd3,0x36,0x81, +0x04,0x3e,0x30,0x0c,0x91,0x4f,0x5b,0x05,0x12,0xf8,0xc0,0x30,0x44,0x7e,0x7d,0x00, +0x05,0xd1,0x4c,0x11,0x66,0x12,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x2a,0x00,0x00,0x00,0x13,0x04,0x43,0x2c,0x10,0x00,0x00,0x00, +0x08,0x00,0x00,0x00,0x24,0x8a,0xa0,0x0c,0x46,0x00,0x4a,0x80,0xc2,0x1c,0x84,0x55, +0x55,0xd6,0x1c,0x84,0x45,0x51,0x16,0x81,0x19,0x80,0x11,0x80,0x31,0x02,0x10,0x04, +0x41,0xfc,0x03,0x00,0x63,0x08,0x0d,0x34,0xc9,0x70,0x55,0xc2,0x2c,0x43,0x20,0x60, +0x73,0x0c,0xd3,0x15,0x8d,0x21,0x34,0xd1,0x18,0x42,0xf3,0x8c,0x55,0x00,0x81,0xa0, +0x6d,0x73,0x0c,0x19,0xe7,0x60,0x87,0x52,0x38,0x10,0x00,0x00,0x13,0x00,0x00,0x00, +0x17,0x60,0x20,0xc5,0x74,0x10,0x8d,0x65,0x14,0x13,0xf3,0xd4,0xb4,0x6d,0x14,0x13, +0xf3,0xd4,0xb8,0x69,0x14,0x13,0xf3,0xd4,0xb6,0x75,0x14,0x13,0xf3,0xd4,0xba,0x35, +0x0c,0x13,0xf3,0x9c,0x80,0xe4,0x36,0x48,0x81,0x10,0xc3,0x4a,0x4c,0x54,0xd4,0x6c, +0x8b,0x23,0x28,0x76,0x41,0x4c,0xcc,0xa3,0x1b,0x07,0x21,0x00,0xcb,0x72,0x00,0x05, +0xd1,0x4c,0x11,0x66,0x18,0x83,0xc0,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x82,0x00,0x00,0x00,0x13,0x04,0x47,0x2c,0x10,0x00,0x00,0x00, +0x08,0x00,0x00,0x00,0x24,0x46,0x00,0x8a,0xa0,0x0c,0x4a,0xa0,0x14,0x8a,0xa1,0x1c, +0x68,0x8c,0x00,0x10,0x9a,0x83,0x80,0xa8,0x48,0x9a,0x83,0x80,0xa6,0x4a,0x9a,0x83, +0x80,0xa6,0xc8,0x02,0x63,0x08,0x0d,0x64,0xdb,0xc0,0x49,0x06,0xee,0x22,0xc6,0x10, +0x9a,0xc9,0xbc,0x81,0x93,0x0c,0xdf,0x45,0x4c,0x31,0x38,0x4f,0x37,0xcb,0x10,0x08, +0x60,0x30,0xc8,0x10,0x06,0x0e,0x36,0x86,0xd0,0x44,0x36,0x06,0x03,0x27,0x19,0xc8, +0xe0,0x22,0x66,0x19,0x06,0xa2,0x0c,0x06,0x19,0xc2,0xe0,0xc1,0xc6,0x10,0x9a,0xc8, +0xce,0x60,0xe0,0x24,0x03,0x1a,0x5c,0xc4,0x2c,0xc3,0x40,0xa4,0xc1,0x40,0x45,0x20, +0x06,0x81,0x19,0x08,0x83,0x0c,0x6a,0xe0,0x64,0x63,0x08,0x8d,0x64,0x6c,0x30,0x70, +0x92,0xa1,0x0d,0x2e,0x62,0x96,0xa1,0x30,0xdc,0x60,0xa0,0x22,0x10,0x83,0xc0,0x0c, +0x84,0x41,0x86,0x37,0x78,0xb2,0x31,0x84,0x46,0xb2,0x38,0x18,0x38,0xc9,0x20,0x07, +0x17,0x31,0xcb,0x50,0x18,0x73,0x30,0x50,0x11,0xac,0xc1,0x00,0x07,0xc4,0x20,0x03, +0x1d,0x38,0x1a,0xd6,0xc1,0x40,0x45,0xb0,0x06,0x03,0x1c,0x10,0x83,0x0c,0x76,0xf0, +0x68,0x78,0x07,0xe1,0x40,0x00,0x00,0x00,0x4c,0x00,0x00,0x00,0x56,0x62,0x08,0xcc, +0x63,0xef,0x3a,0xa9,0x00,0x19,0x7b,0x73,0x23,0x73,0xf9,0xa1,0x91,0x31,0x98,0x62, +0x62,0x9e,0x7b,0xb7,0x06,0x62,0x62,0x1e,0xda,0x1c,0x88,0x89,0x79,0x6a,0x7b,0x20, +0x26,0xe6,0xb1,0x6d,0x83,0x98,0x98,0xe7,0x36,0x92,0x43,0x70,0x9a,0xca,0xd6,0x73, +0xa3,0x79,0x26,0xe6,0xb9,0x77,0x3f,0x22,0x0c,0x9b,0x21,0x18,0x9f,0xb6,0x90,0x64, +0x62,0x9e,0xda,0x9f,0x98,0xc7,0x36,0x9b,0x67,0x62,0x9e,0x7b,0xf7,0x23,0xc2,0xb0, +0x19,0x82,0xf1,0x6b,0x53,0x79,0x26,0xe6,0xb1,0x6f,0x3f,0x22,0x0c,0x9b,0x21,0x18, +0x9f,0xb6,0x98,0x62,0x62,0x9e,0xbb,0xb7,0x97,0x67,0x62,0x1e,0xfb,0xf6,0x23,0xc2, +0xb0,0x19,0x82,0xf1,0x6b,0x43,0x31,0x04,0xa7,0xa9,0x6c,0xdd,0x66,0x0a,0x81,0x79, +0xf0,0xfa,0x08,0x16,0xc1,0x69,0x06,0x5f,0x70,0x9a,0xe9,0xc6,0x49,0x01,0xc8,0xd8, +0x9b,0x1b,0x99,0xcb,0x4f,0x0c,0x8d,0xad,0x18,0x13,0xf3,0xdc,0x3b,0x6f,0x35,0xc7, +0xc4,0x3c,0x79,0x5d,0xdf,0x06,0x52,0x08,0xcc,0x53,0xdf,0x26,0x62,0x4c,0xcc,0x63, +0xdf,0xb7,0xb9,0x1c,0x02,0xf3,0xe0,0x75,0x5d,0x5b,0xc7,0x20,0x30,0x8f,0x79,0x14, +0x13,0xf3,0xd4,0xf5,0x19,0x2c,0x82,0xd3,0x0c,0xbe,0xe0,0x34,0x13,0xce,0x5b,0x0b, +0x22,0x38,0x4d,0x85,0xd3,0x35,0x6d,0x37,0xc5,0xc4,0x3c,0x79,0x4d,0x1a,0x40,0xc6, +0xde,0xdc,0xc8,0x5c,0x7e,0x64,0x70,0x8c,0x83,0x10,0x9c,0xa6,0xb2,0x94,0x42,0x60, +0x1e,0x7b,0x37,0x19,0x43,0x70,0x9a,0x0a,0xa7,0xcd,0xa4,0x98,0x98,0xc7,0xbe,0x8d, +0xc5,0x98,0x98,0xe7,0xee,0x7b,0x3b,0x29,0x26,0xe6,0xb1,0xf3,0x13,0x58,0x04,0xa7, +0x19,0x7c,0xc1,0x69,0x26,0x9b,0xb6,0x0f,0x43,0x70,0x9a,0xaa,0xb6,0x6d,0xc4,0x98, +0x98,0xc7,0xce,0xf1,0x03,0x28,0x88,0x66,0x8a,0x30,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x4a,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, +0x07,0x00,0x00,0x00,0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0xbd, +0x61,0x8c,0x04,0x10,0x1e,0xe1,0x19,0xc6,0x48,0x02,0xe1,0x11,0x1e,0x00,0x00,0x00, +0x63,0x08,0xcd,0x63,0xd5,0xc0,0x31,0x84,0x06,0xb2,0x6b,0xe0,0x18,0x42,0x13,0x59, +0x36,0x70,0x0c,0xa1,0x71,0x6c,0x1b,0x38,0x16,0x02,0x04,0xc7,0x64,0x61,0x1a,0x37, +0x16,0x01,0x04,0x48,0x35,0xc7,0x20,0x79,0xcf,0x58,0x04,0x10,0x20,0xd5,0x1c,0xc3, +0x07,0x06,0xd0,0x58,0x04,0x10,0x20,0xd5,0x1c,0x43,0x18,0x88,0x41,0x34,0x16,0x01, +0x04,0x48,0x35,0xc7,0x30,0x06,0x64,0xe0,0x98,0x37,0xd0,0xc0,0x60,0xa0,0x89,0xc1, +0x40,0x23,0x83,0x81,0x63,0x21,0x40,0x70,0x50,0x66,0x70,0x06,0x68,0x90,0x06,0x58, +0x06,0xe1,0x40,0x00,0x25,0x00,0x00,0x00,0x56,0x52,0x4c,0xcc,0x73,0xd3,0x56,0x41, +0x4c,0xcc,0x53,0xdb,0x05,0x31,0x31,0xcf,0x6d,0x19,0xc4,0xc4,0x3c,0xba,0x6d,0x10, +0x13,0xf3,0xf4,0xd6,0x41,0x08,0xc0,0xb2,0x18,0x46,0x21,0x38,0x4d,0x85,0x9b,0x46, +0x21,0x38,0x4d,0xb5,0x9b,0x8a,0x21,0x00,0xcb,0x82,0xdf,0x66,0x62,0x08,0x4e,0x53, +0xdd,0xb7,0x9d,0x18,0x82,0xd3,0x54,0xb7,0x6e,0x28,0x86,0xe0,0x34,0xd5,0xdd,0xdb, +0x47,0x31,0x31,0x4f,0x9d,0x9b,0x87,0x21,0x00,0xcb,0x52,0xdf,0x06,0x62,0x08,0xc0, +0xb2,0xd4,0xbc,0x59,0x10,0x82,0xd3,0x54,0x96,0x62,0x08,0x4e,0x53,0xe1,0xb6,0x85, +0x14,0x13,0xf3,0xd8,0xb4,0x8d,0x14,0x13,0xf3,0xd8,0xb9,0x89,0x18,0x02,0xb0,0x2c, +0xf6,0x6d,0x24,0x86,0x00,0x2c,0x8b,0xcd,0x1b,0x87,0x21,0x38,0x4d,0x55,0xd3,0xd6, +0x30,0x54,0xc0,0x72,0x00,0x05,0xd1,0x4c,0x11,0x06,0x00,0x00,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x19,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00, +0x03,0x00,0x00,0x00,0x24,0x4a,0x60,0x04,0x80,0xc2,0x0c,0x00,0x00,0x00,0x00,0x00, +0x63,0x08,0xcd,0x33,0x16,0x01,0x04,0x48,0x34,0xc7,0x00,0x49,0xcf,0x58,0x04,0x10, +0x28,0xd1,0x1c,0xc3,0x44,0x39,0x58,0x85,0x03,0x01,0x00,0x00,0x0a,0x00,0x00,0x00, +0x16,0x41,0x4c,0xcc,0x63,0xdb,0x04,0x31,0x31,0x4f,0x6e,0x0d,0x43,0x05,0x2c,0x07, +0x50,0x10,0xcd,0x14,0x61,0x56,0x41,0x4c,0xcc,0xd3,0x1b,0x45,0x21,0x00,0xcb,0xb2, +0x9b,0x04,0x21,0x00,0xcb,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x20,0x00,0x00, +0x1b,0x00,0x00,0x00,0x13,0x04,0x41,0x2c,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00, +0x24,0xca,0x60,0x04,0xa0,0x04,0x8a,0x80,0xc2,0x0c,0x00,0x00,0x63,0x08,0xcd,0x33, +0x16,0x01,0x04,0xca,0x34,0xc7,0x20,0x51,0xcf,0x1c,0x43,0x45,0x41,0x73,0x0c,0x16, +0x15,0xcd,0x31,0x5c,0x94,0x83,0x58,0x38,0x10,0x00,0x00,0x00,0x0b,0x00,0x00,0x00, +0x86,0x51,0x4c,0xcc,0x53,0xe7,0x76,0x51,0x4c,0xcc,0x53,0xdb,0x36,0x41,0x4c,0xcc, +0x63,0x5b,0x05,0x31,0x31,0x8f,0x6e,0x0d,0x43,0x05,0x2c,0x66,0x41,0x4c,0xcc,0xd3, +0x1f,0x40,0x41,0x34,0x53,0x84,0x19,0x05,0x21,0x00,0xcb,0x02,0x00,0x00,0x00,0x00, +0x61,0x20,0x00,0x00,0x2f,0x00,0x00,0x00,0x13,0x04,0x45,0x2c,0x10,0x00,0x00,0x00, +0x03,0x00,0x00,0x00,0x24,0xca,0xa0,0x04,0x46,0x00,0x8a,0x80,0xc0,0x08,0x00,0x00, +0x63,0x08,0x0d,0x34,0xc9,0x30,0x49,0xc4,0x2c,0x03,0x11,0x50,0x63,0x08,0xcd,0x33, +0xc9,0x50,0x49,0xc4,0x2c,0x03,0x21,0x58,0x63,0x08,0x4d,0x34,0xc9,0x70,0x49,0xc4, +0x2c,0x03,0x31,0x60,0x63,0x08,0x8d,0x33,0xc9,0x90,0x49,0x84,0x69,0x22,0x70,0xc3, +0x27,0x1c,0x08,0x00,0x1a,0x00,0x00,0x00,0x96,0x51,0x4c,0xcc,0x53,0xdf,0x66,0x41, +0x08,0xcc,0x83,0xdb,0x04,0x31,0x31,0x4f,0x6d,0x15,0xc4,0xc4,0x3c,0xb7,0x61,0x10, +0x02,0xf3,0xf0,0x47,0x20,0xb9,0x0d,0x52,0x20,0xc4,0xb0,0x12,0x13,0x15,0x35,0xdb, +0xe2,0x08,0x8a,0x5d,0x10,0x13,0xf3,0xec,0x37,0x90,0x2c,0x4e,0xf4,0x47,0x87,0x54, +0xd7,0x17,0x70,0x2c,0x4e,0xf4,0x47,0x87,0x74,0x02,0xc8,0xe2,0x44,0x7f,0x74,0x48, +0xb9,0x69,0x14,0x02,0xf3,0xd4,0xb8,0x6d,0x18,0x11,0x31,0x55,0xc0,0x62,0x0d,0x43, +0x05,0x2c,0x07,0x50,0x10,0xcd,0x14,0x61,0x46,0x31,0x08,0xcc,0x03,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x71,0x20,0x00,0x00,0x12,0x00,0x00,0x00,0x66,0x40,0x54,0x82, +0x23,0x59,0xc2,0x20,0x09,0x92,0x1d,0x18,0x4f,0x84,0x34,0x53,0x61,0x03,0xc4,0xe3, +0x58,0x85,0x05,0x14,0xbe,0x34,0x45,0xb5,0x21,0x10,0x82,0x23,0x15,0x46,0x30,0x2c, +0xc8,0x64,0x02,0x06,0xf0,0x3c,0x91,0x73,0x19,0x00,0xe1,0x4b,0x53,0x64,0x0a,0x84, +0x84,0x34,0x85,0x31,0x10,0x0a,0xb2,0x3c,0x56,0x30,0x08,0xcc,0x63,0x0b,0x44,0x25, +0x21,0x0d,0x00,0x00,0x00,0x00,0x00,0x00}; diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index 8919491792..b35d6790f7 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -35,6 +35,8 @@ #include "storage.h" +#include "pipe/p_util.h" + #include #include #include @@ -42,7 +44,8 @@ #include #include #include -#include +#include +#include #include #include @@ -53,7 +56,6 @@ using namespace llvm; #include "gallivm_builtins.cpp" #if 0 - llvm::Value *arrayFromChannels(std::vector &vals) { VectorType *vectorType = VectorType::get(Type::FloatTy, 4); @@ -84,7 +86,10 @@ Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicB m_llvmLit = 0; m_fmtPtr = 0; - createGallivmBuiltins(m_mod); + MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( + (const char*)&llvm_builtins_data[0], + (const char*)&llvm_builtins_data[Elements(llvm_builtins_data)-1]); + m_mod = ParseBitcodeFile(buffer); } llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2) diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 6f83b56a72..3c16a3692d 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -1,8 +1,35 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ #include "instructionssoa.h" #include "storagesoa.h" #include "pipe/p_shader_tokens.h" +#include "pipe/p_util.h" #include #include @@ -10,7 +37,10 @@ #include #include #include -#include +#include +#include +#include + #include @@ -183,7 +213,10 @@ llvm::Module * InstructionsSoa::currentModule() const void InstructionsSoa::createBuiltins() { - m_builtins = createSoaBuiltins(); + MemoryBuffer *buffer = MemoryBuffer::getMemBuffer( + (const char*)&soabuiltins_data[0], + (const char*)&soabuiltins_data[Elements(soabuiltins_data)-1]); + m_builtins = ParseBitcodeFile(buffer); createDependencies(); } diff --git a/src/gallium/auxiliary/gallivm/llvm_builtins.c b/src/gallium/auxiliary/gallivm/llvm_builtins.c index 4f98d754ba..64b5d499a8 100644 --- a/src/gallium/auxiliary/gallivm/llvm_builtins.c +++ b/src/gallium/auxiliary/gallivm/llvm_builtins.c @@ -30,7 +30,7 @@ * Authors: * Zack Rusin zack@tungstengraphics.com */ -typedef __attribute__(( ocu_vector_type(4) )) float float4; +typedef __attribute__(( ext_vector_type(4) )) float float4; extern float powf(float a, float b); diff --git a/src/gallium/auxiliary/gallivm/soabuiltins.c b/src/gallium/auxiliary/gallivm/soabuiltins.c index 4d658be520..40addebd8c 100644 --- a/src/gallium/auxiliary/gallivm/soabuiltins.c +++ b/src/gallium/auxiliary/gallivm/soabuiltins.c @@ -31,7 +31,7 @@ * Authors: * Zack Rusin zack@tungstengraphics.com */ -typedef __attribute__(( ocu_vector_type(4) )) float float4; +typedef __attribute__(( ext_vector_type(4) )) float float4; void dp3(float4 *res, float4 tmp0x, float4 tmp0y, float4 tmp0z, float4 tmp0w, -- cgit v1.2.3 From b6c9d2ef2cfadbbe3e7aa94f21fd0da36d089952 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 12:37:41 +0100 Subject: rtasm: add dump facility for x86 (from tgsi_sse2.c) --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 267 ++++++++++++++++++++++++++--- 1 file changed, 243 insertions(+), 24 deletions(-) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 7f8cc23d15..f2c08c96a6 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -34,6 +34,116 @@ #define X86_TWOB 0x0f +#define DUMP_SSE 0 + +#if DUMP_SSE + +static void +_print_reg( + struct x86_reg reg ) +{ + if (reg.mod != mod_REG) + debug_printf( "[" ); + + switch( reg.file ) { + case file_REG32: + switch( reg.idx ) { + case reg_AX: debug_printf( "EAX" ); break; + case reg_CX: debug_printf( "ECX" ); break; + case reg_DX: debug_printf( "EDX" ); break; + case reg_BX: debug_printf( "EBX" ); break; + case reg_SP: debug_printf( "ESP" ); break; + case reg_BP: debug_printf( "EBP" ); break; + case reg_SI: debug_printf( "ESI" ); break; + case reg_DI: debug_printf( "EDI" ); break; + } + break; + case file_MMX: + debug_printf( "MMX%u", reg.idx ); + break; + case file_XMM: + debug_printf( "XMM%u", reg.idx ); + break; + case file_x87: + debug_printf( "fp%u", reg.idx ); + break; + } + + if (reg.mod == mod_DISP8 || + reg.mod == mod_DISP32) + debug_printf("+%d", reg.disp); + + if (reg.mod != mod_REG) + debug_printf( "]" ); +} + +static void +_fill( + const char *op ) +{ + unsigned count = 10 - strlen( op ); + + while( count-- ) { + debug_printf( " " ); + } +} + +#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) +#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) +#define DUMP( OP ) debug_printf( "\n%s", OP ) + +#define DUMP_I( OP, I ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + debug_printf( "%u", I ); \ +} while( 0 ) + +#define DUMP_R( OP, R0 ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ +} while( 0 ) + +#define DUMP_RR( OP, R0, R1 ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ + debug_printf( ", " ); \ + _print_reg( R1 ); \ +} while( 0 ) + +#define DUMP_RI( OP, R0, I ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ + debug_printf( ", " ); \ + debug_printf( "%u", I ); \ +} while( 0 ) + +#define DUMP_RRI( OP, R0, R1, I ) do { \ + debug_printf( "\n%s", OP ); \ + _fill( OP ); \ + _print_reg( R0 ); \ + debug_printf( ", " ); \ + _print_reg( R1 ); \ + debug_printf( ", " ); \ + debug_printf( "%u", I ); \ +} while( 0 ) + +#else + +#define DUMP_START() +#define DUMP_END() +#define DUMP( OP ) +#define DUMP_I( OP, I ) +#define DUMP_R( OP, R0 ) +#define DUMP_RR( OP, R0, R1 ) +#define DUMP_RI( OP, R0, I ) +#define DUMP_RRI( OP, R0, R1, I ) + +#endif + + static void do_realloc( struct x86_function *p ) { if (p->size == 0) { @@ -272,6 +382,7 @@ unsigned char *x86_jcc_forward( struct x86_function *p, unsigned char *x86_jmp_forward( struct x86_function *p) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0xe9); emit_1i(p, 0); return x86_get_label(p); @@ -279,6 +390,8 @@ unsigned char *x86_jmp_forward( struct x86_function *p) unsigned char *x86_call_forward( struct x86_function *p) { + DUMP( __FUNCTION__ ); + emit_1ub(p, 0xe8); emit_1i(p, 0); return x86_get_label(p); @@ -294,6 +407,7 @@ void x86_fixup_fwd_jump( struct x86_function *p, void x86_jmp( struct x86_function *p, unsigned char *label) { + DUMP_I( __FUNCTION__, label ); emit_1ub(p, 0xe9); emit_1i(p, pointer_to_intptr( label ) - pointer_to_intptr( x86_get_label(p) ) - 4); } @@ -310,12 +424,14 @@ static unsigned char *cptr( void (*label)() ) */ void x86_call( struct x86_function *p, void (*label)()) { + DUMP_I( __FUNCTION__, label ); emit_1ub(p, 0xe8); emit_1i(p, cptr(label) - x86_get_label(p) - 4); } #else void x86_call( struct x86_function *p, struct x86_reg reg) { + DUMP_R( __FUNCTION__, reg ); emit_1ub(p, 0xff); emit_modrm_noreg(p, 2, reg); } @@ -328,6 +444,7 @@ void x86_call( struct x86_function *p, struct x86_reg reg) */ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) { + DUMP_RI( __FUNCTION__, dst, imm ); assert(dst.mod == mod_REG); emit_1ub(p, 0xb8 + dst.idx); emit_1i(p, imm); @@ -336,6 +453,7 @@ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) void x86_push( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x50 + reg.idx); p->stack_offset += 4; @@ -344,6 +462,7 @@ void x86_push( struct x86_function *p, void x86_pop( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x58 + reg.idx); p->stack_offset -= 4; @@ -352,6 +471,7 @@ void x86_pop( struct x86_function *p, void x86_inc( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x40 + reg.idx); } @@ -359,17 +479,20 @@ void x86_inc( struct x86_function *p, void x86_dec( struct x86_function *p, struct x86_reg reg ) { + DUMP_R( __FUNCTION__, reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x48 + reg.idx); } void x86_ret( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0xc3); } void x86_sahf( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0x9e); } @@ -377,6 +500,7 @@ void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x8b, 0x89, dst, src ); } @@ -384,6 +508,7 @@ void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x33, 0x31, dst, src ); } @@ -391,6 +516,7 @@ void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x3b, 0x39, dst, src ); } @@ -398,6 +524,7 @@ void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, 0x8d); emit_modrm( p, dst, src ); } @@ -406,6 +533,7 @@ void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, 0x85); emit_modrm( p, dst, src ); } @@ -414,6 +542,7 @@ void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm(p, 0x03, 0x01, dst, src ); } @@ -422,6 +551,7 @@ void x86_add( struct x86_function *p, void x86_mul( struct x86_function *p, struct x86_reg src ) { + DUMP_R( __FUNCTION__, src ); emit_1ub(p, 0xf7); emit_modrm_noreg(p, 4, src ); } @@ -431,6 +561,7 @@ void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0xAF); emit_modrm(p, dst, src); } @@ -440,6 +571,7 @@ void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm(p, 0x2b, 0x29, dst, src ); } @@ -447,6 +579,7 @@ void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x0b, 0x09, dst, src ); } @@ -454,6 +587,7 @@ void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_op_modrm( p, 0x23, 0x21, dst, src ); } @@ -468,6 +602,7 @@ void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, 0xF3, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -476,6 +611,7 @@ void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x28, 0x29, dst, src ); } @@ -484,6 +620,7 @@ void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -492,6 +629,7 @@ void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ @@ -501,6 +639,7 @@ void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ @@ -510,6 +649,7 @@ void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -518,6 +658,7 @@ void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -526,6 +667,7 @@ void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5E); emit_modrm( p, dst, src ); } @@ -534,6 +676,7 @@ void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5D); emit_modrm( p, dst, src ); } @@ -542,6 +685,7 @@ void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5C); emit_modrm( p, dst, src ); } @@ -550,6 +694,7 @@ void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -558,6 +703,7 @@ void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -566,6 +712,7 @@ void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -574,6 +721,7 @@ void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -582,6 +730,7 @@ void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x55); emit_modrm( p, dst, src ); } @@ -590,6 +739,7 @@ void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x54); emit_modrm( p, dst, src ); } @@ -598,6 +748,7 @@ void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x52); emit_modrm( p, dst, src ); } @@ -606,6 +757,7 @@ void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x52); emit_modrm( p, dst, src ); @@ -615,6 +767,7 @@ void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x12); emit_modrm( p, dst, src ); @@ -624,6 +777,7 @@ void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x16); emit_modrm( p, dst, src ); @@ -633,6 +787,7 @@ void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x56); emit_modrm( p, dst, src ); } @@ -641,6 +796,7 @@ void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x57); emit_modrm( p, dst, src ); } @@ -649,6 +805,7 @@ void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.file == file_MMX && (src.file == file_XMM || src.mod != mod_REG)); @@ -662,6 +819,7 @@ void sse2_cvtdq2ps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x5b); emit_modrm( p, dst, src ); } @@ -671,31 +829,34 @@ void sse2_cvtdq2ps( struct x86_function *p, * arg0. */ void sse_shufps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, + struct x86_reg dst, + struct x86_reg src, unsigned char shuf) { + DUMP_RRI( __FUNCTION__, dst, src, shuf ); emit_2ub(p, X86_TWOB, 0xC6); - emit_modrm(p, dest, arg0); + emit_modrm(p, dst, src); emit_1ub(p, shuf); } void sse_cmpps( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, + struct x86_reg dst, + struct x86_reg src, unsigned char cc) { + DUMP_RRI( "CMPPS", dst, src, cc ); emit_2ub(p, X86_TWOB, 0xC2); - emit_modrm(p, dest, arg0); + emit_modrm(p, dst, src); emit_1ub(p, cc); } void sse_pmovmskb( struct x86_function *p, - struct x86_reg dest, + struct x86_reg dst, struct x86_reg src) { - emit_3ub(p, 0x66, X86_TWOB, 0xD7); - emit_modrm(p, dest, src); + DUMP_RR( __FUNCTION__, dst, src ); + emit_3ub(p, 0x66, X86_TWOB, 0xD7); + emit_modrm(p, dst, src); } /*********************************************************************** @@ -706,12 +867,13 @@ void sse_pmovmskb( struct x86_function *p, * Perform a reduced swizzle: */ void sse2_pshufd( struct x86_function *p, - struct x86_reg dest, - struct x86_reg arg0, + struct x86_reg dst, + struct x86_reg src, unsigned char shuf) { + DUMP_RRI( __FUNCTION__, dst, src, shuf ); emit_3ub(p, 0x66, X86_TWOB, 0x70); - emit_modrm(p, dest, arg0); + emit_modrm(p, dst, src); emit_1ub(p, shuf); } @@ -719,6 +881,7 @@ void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); emit_modrm( p, dst, src ); } @@ -727,6 +890,7 @@ void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x5B); emit_modrm( p, dst, src ); } @@ -735,6 +899,7 @@ void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x6B); emit_modrm( p, dst, src ); } @@ -743,6 +908,7 @@ void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x63); emit_modrm( p, dst, src ); } @@ -751,6 +917,7 @@ void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x67); emit_modrm( p, dst, src ); } @@ -759,6 +926,7 @@ void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x60); emit_modrm( p, dst, src ); } @@ -768,6 +936,7 @@ void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -776,6 +945,7 @@ void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -784,6 +954,7 @@ void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); emit_2ub(p, 0x66, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); } @@ -796,30 +967,35 @@ void sse2_movd( struct x86_function *p, */ void x87_fist( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 2, dst); } void x87_fistp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 3, dst); } void x87_fild( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); emit_1ub(p, 0xdf); emit_modrm_noreg(p, 0, arg); } void x87_fldz( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xee); } void x87_fldcw( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_REG32); assert(arg.mod != mod_REG); emit_1ub(p, 0xd9); @@ -828,26 +1004,31 @@ void x87_fldcw( struct x86_function *p, struct x86_reg arg ) void x87_fld1( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xe8); } void x87_fldl2e( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xea); } void x87_fldln2( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xed); } void x87_fwait( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_1ub(p, 0x9b); } void x87_fnclex( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xdb, 0xe2); } @@ -884,49 +1065,55 @@ static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86 assert(0); } -void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xc8, 0xdc, 0xc8, 4); } -void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xe0, 0xdc, 0xe8, 4); } -void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xe8, 0xdc, 0xe0, 5); } -void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xc0, 0xdc, 0xc0, 0); } -void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xf0, 0xdc, 0xf8, 6); } -void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) +void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - x87_arith_op(p, dst, arg, + DUMP_RR( __FUNCTION__, dst, src ); + x87_arith_op(p, dst, src, 0xd8, 0xf8, 0xdc, 0xf0, 7); @@ -934,6 +1121,7 @@ void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg ) void x87_fmulp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc8+dst.idx); @@ -941,6 +1129,7 @@ void x87_fmulp( struct x86_function *p, struct x86_reg dst ) void x87_fsubp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe8+dst.idx); @@ -948,6 +1137,7 @@ void x87_fsubp( struct x86_function *p, struct x86_reg dst ) void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe0+dst.idx); @@ -955,6 +1145,7 @@ void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) void x87_faddp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc0+dst.idx); @@ -962,6 +1153,7 @@ void x87_faddp( struct x86_function *p, struct x86_reg dst ) void x87_fdivp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf8+dst.idx); @@ -969,6 +1161,7 @@ void x87_fdivp( struct x86_function *p, struct x86_reg dst ) void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf0+dst.idx); @@ -976,70 +1169,83 @@ void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) void x87_fucom( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe0+arg.idx); } void x87_fucomp( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe8+arg.idx); } void x87_fucompp( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xda, 0xe9); } void x87_fxch( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); assert(arg.file == file_x87); emit_2ub(p, 0xd9, 0xc8+arg.idx); } void x87_fabs( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xe1); } void x87_fchs( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xe0); } void x87_fcos( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xff); } void x87_fprndint( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfc); } void x87_fscale( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfd); } void x87_fsin( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfe); } void x87_fsincos( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfb); } void x87_fsqrt( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xfa); } void x87_fxtract( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf4); } @@ -1049,6 +1255,7 @@ void x87_fxtract( struct x86_function *p ) */ void x87_f2xm1( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf0); } @@ -1057,6 +1264,7 @@ void x87_f2xm1( struct x86_function *p ) */ void x87_fyl2x( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf1); } @@ -1067,12 +1275,14 @@ void x87_fyl2x( struct x86_function *p ) */ void x87_fyl2xp1( struct x86_function *p ) { + DUMP( __FUNCTION__ ); emit_2ub(p, 0xd9, 0xf9); } void x87_fld( struct x86_function *p, struct x86_reg arg ) { + DUMP_R( __FUNCTION__, arg ); if (arg.file == file_x87) emit_2ub(p, 0xd9, 0xc0 + arg.idx); else { @@ -1083,6 +1293,7 @@ void x87_fld( struct x86_function *p, struct x86_reg arg ) void x87_fst( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd0 + dst.idx); else { @@ -1093,6 +1304,7 @@ void x87_fst( struct x86_function *p, struct x86_reg dst ) void x87_fstp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd8 + dst.idx); else { @@ -1103,6 +1315,7 @@ void x87_fstp( struct x86_function *p, struct x86_reg dst ) void x87_fcom( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd0 + dst.idx); else { @@ -1113,6 +1326,7 @@ void x87_fcom( struct x86_function *p, struct x86_reg dst ) void x87_fcomp( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd8 + dst.idx); else { @@ -1124,6 +1338,7 @@ void x87_fcomp( struct x86_function *p, struct x86_reg dst ) void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) { + DUMP_R( __FUNCTION__, dst ); assert(dst.file == file_REG32); if (dst.idx == reg_AX && @@ -1153,6 +1368,7 @@ void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1166,6 +1382,7 @@ void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1179,6 +1396,7 @@ void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); @@ -1188,6 +1406,7 @@ void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { + DUMP_RR( __FUNCTION__, dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6f, 0x7f, dst, src ); -- cgit v1.2.3 From f30f3206121c56e5c50ccafb1467a8301044d411 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 12:38:14 +0100 Subject: util: add wrappers for float math functions on windows --- src/gallium/include/pipe/p_util.h | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index dbca080a4b..77783b11a8 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -402,6 +402,52 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, int src_pitch, unsigned src_x, int src_y); + +#ifdef WIN32 + +static INLINE float cosf( float f ) +{ + return (float) cos( (double) f ); +} + +static INLINE float sinf( float f ) +{ + return (float) sin( (double) f ); +} + +static INLINE float ceilf( float f ) +{ + return (float) ceil( (double) f ); +} + +static INLINE float floorf( float f ) +{ + return (float) floor( (double) f ); +} + +static INLINE float powf( float f, float g ) +{ + return (float) pow( (double) f, (double) g ); +} + +static INLINE float sqrtf( float f ) +{ + return (float) sqrt( (double) f ); +} + +static INLINE float fabsf( float f ) +{ + return (float) fabs( (double) f ); +} + +static INLINE float logf( float f ) +{ + return (float) cos( (double) f ); +} + +#endif + + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 615cdd3a535bb71754baa8b37e79b85af01854dd Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 12:39:59 +0100 Subject: tgsi: use new float math funcs, drop local disassembly code --- src/gallium/auxiliary/tgsi/exec/tgsi_exec.c | 88 ++--- src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 591 +++++++--------------------- 2 files changed, 178 insertions(+), 501 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c index 78e7dec569..29e104bbd1 100644 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c @@ -287,10 +287,10 @@ micro_abs( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) fabs( (double) src->f[0] ); - dst->f[1] = (float) fabs( (double) src->f[1] ); - dst->f[2] = (float) fabs( (double) src->f[2] ); - dst->f[3] = (float) fabs( (double) src->f[3] ); + dst->f[0] = fabsf( src->f[0] ); + dst->f[1] = fabsf( src->f[1] ); + dst->f[2] = fabsf( src->f[2] ); + dst->f[3] = fabsf( src->f[3] ); } static void @@ -334,10 +334,10 @@ micro_ceil( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) ceil( (double) src->f[0] ); - dst->f[1] = (float) ceil( (double) src->f[1] ); - dst->f[2] = (float) ceil( (double) src->f[2] ); - dst->f[3] = (float) ceil( (double) src->f[3] ); + dst->f[0] = ceilf( src->f[0] ); + dst->f[1] = ceilf( src->f[1] ); + dst->f[2] = ceilf( src->f[2] ); + dst->f[3] = ceilf( src->f[3] ); } static void @@ -345,10 +345,10 @@ micro_cos( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) cos( (double) src->f[0] ); - dst->f[1] = (float) cos( (double) src->f[1] ); - dst->f[2] = (float) cos( (double) src->f[2] ); - dst->f[3] = (float) cos( (double) src->f[3] ); + dst->f[0] = cosf( src->f[0] ); + dst->f[1] = cosf( src->f[1] ); + dst->f[2] = cosf( src->f[2] ); + dst->f[3] = cosf( src->f[3] ); } static void @@ -430,10 +430,10 @@ micro_exp2( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src) { - dst->f[0] = (float) pow( 2.0, (double) src->f[0] ); - dst->f[1] = (float) pow( 2.0, (double) src->f[1] ); - dst->f[2] = (float) pow( 2.0, (double) src->f[2] ); - dst->f[3] = (float) pow( 2.0, (double) src->f[3] ); + dst->f[0] = powf( 2.0f, src->f[0] ); + dst->f[1] = powf( 2.0f, src->f[1] ); + dst->f[2] = powf( 2.0f, src->f[2] ); + dst->f[3] = powf( 2.0f, src->f[3] ); } static void @@ -463,10 +463,10 @@ micro_flr( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) floor( (double) src->f[0] ); - dst->f[1] = (float) floor( (double) src->f[1] ); - dst->f[2] = (float) floor( (double) src->f[2] ); - dst->f[3] = (float) floor( (double) src->f[3] ); + dst->f[0] = floorf( src->f[0] ); + dst->f[1] = floorf( src->f[1] ); + dst->f[2] = floorf( src->f[2] ); + dst->f[3] = floorf( src->f[3] ); } static void @@ -474,10 +474,10 @@ micro_frc( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = src->f[0] - (float) floor( (double) src->f[0] ); - dst->f[1] = src->f[1] - (float) floor( (double) src->f[1] ); - dst->f[2] = src->f[2] - (float) floor( (double) src->f[2] ); - dst->f[3] = src->f[3] - (float) floor( (double) src->f[3] ); + dst->f[0] = src->f[0] - floorf( src->f[0] ); + dst->f[1] = src->f[1] - floorf( src->f[1] ); + dst->f[2] = src->f[2] - floorf( src->f[2] ); + dst->f[3] = src->f[3] - floorf( src->f[3] ); } static void @@ -510,10 +510,10 @@ micro_lg2( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) log( (double) src->f[0] ) * 1.442695f; - dst->f[1] = (float) log( (double) src->f[1] ) * 1.442695f; - dst->f[2] = (float) log( (double) src->f[2] ) * 1.442695f; - dst->f[3] = (float) log( (double) src->f[3] ) * 1.442695f; + dst->f[0] = logf( src->f[0] ) * 1.442695f; + dst->f[1] = logf( src->f[1] ) * 1.442695f; + dst->f[2] = logf( src->f[2] ) * 1.442695f; + dst->f[3] = logf( src->f[3] ) * 1.442695f; } static void @@ -764,10 +764,10 @@ micro_pow( const union tgsi_exec_channel *src0, const union tgsi_exec_channel *src1 ) { - dst->f[0] = (float) pow( (double) src0->f[0], (double) src1->f[0] ); - dst->f[1] = (float) pow( (double) src0->f[1], (double) src1->f[1] ); - dst->f[2] = (float) pow( (double) src0->f[2], (double) src1->f[2] ); - dst->f[3] = (float) pow( (double) src0->f[3], (double) src1->f[3] ); + dst->f[0] = powf( src0->f[0], src1->f[0] ); + dst->f[1] = powf( src0->f[1], src1->f[1] ); + dst->f[2] = powf( src0->f[2], src1->f[2] ); + dst->f[3] = powf( src0->f[3], src1->f[3] ); } static void @@ -775,10 +775,10 @@ micro_rnd( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) floor( (double) (src->f[0] + 0.5f) ); - dst->f[1] = (float) floor( (double) (src->f[1] + 0.5f) ); - dst->f[2] = (float) floor( (double) (src->f[2] + 0.5f) ); - dst->f[3] = (float) floor( (double) (src->f[3] + 0.5f) ); + dst->f[0] = floorf( src->f[0] + 0.5f ); + dst->f[1] = floorf( src->f[1] + 0.5f ); + dst->f[2] = floorf( src->f[2] + 0.5f ); + dst->f[3] = floorf( src->f[3] + 0.5f ); } static void @@ -833,20 +833,20 @@ micro_sin( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) sin( (double) src->f[0] ); - dst->f[1] = (float) sin( (double) src->f[1] ); - dst->f[2] = (float) sin( (double) src->f[2] ); - dst->f[3] = (float) sin( (double) src->f[3] ); + dst->f[0] = sinf( src->f[0] ); + dst->f[1] = sinf( src->f[1] ); + dst->f[2] = sinf( src->f[2] ); + dst->f[3] = sinf( src->f[3] ); } static void micro_sqrt( union tgsi_exec_channel *dst, const union tgsi_exec_channel *src ) { - dst->f[0] = (float) sqrt( (double) src->f[0] ); - dst->f[1] = (float) sqrt( (double) src->f[1] ); - dst->f[2] = (float) sqrt( (double) src->f[2] ); - dst->f[3] = (float) sqrt( (double) src->f[3] ); + dst->f[0] = sqrtf( src->f[0] ); + dst->f[1] = sqrtf( src->f[1] ); + dst->f[2] = sqrtf( src->f[2] ); + dst->f[3] = sqrtf( src->f[3] ); } static void diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index d47935e982..c3295a27ff 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -38,113 +38,6 @@ #define HIGH_PRECISION 1 /* for 1/sqrt() */ -#define DUMP_SSE 0 - -#if DUMP_SSE - -static void -_print_reg( - struct x86_reg reg ) -{ - if (reg.mod != mod_REG) - debug_printf( "[" ); - - switch( reg.file ) { - case file_REG32: - switch( reg.idx ) { - case reg_AX: - debug_printf( "EAX" ); - break; - case reg_CX: - debug_printf( "ECX" ); - break; - case reg_DX: - debug_printf( "EDX" ); - break; - case reg_BX: - debug_printf( "EBX" ); - break; - case reg_SP: - debug_printf( "ESP" ); - break; - case reg_BP: - debug_printf( "EBP" ); - break; - case reg_SI: - debug_printf( "ESI" ); - break; - case reg_DI: - debug_printf( "EDI" ); - break; - } - break; - case file_MMX: - assert( 0 ); - break; - case file_XMM: - debug_printf( "XMM%u", reg.idx ); - break; - case file_x87: - assert( 0 ); - break; - } - - if (reg.mod == mod_DISP8 || - reg.mod == mod_DISP32) - debug_printf("+%d", reg.disp); - - if (reg.mod != mod_REG) - debug_printf( "]" ); -} - -static void -_fill( - const char *op ) -{ - unsigned count = 10 - strlen( op ); - - while( count-- ) { - debug_printf( " " ); - } -} - -#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) -#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) -#define DUMP( OP ) debug_printf( "\n%s", OP ) -#define DUMP_I( OP, I ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - debug_printf( "%u", I ); } while( 0 ) -#define DUMP_R( OP, R0 ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 ); } while( 0 ) -#define DUMP_RR( OP, R0, R1 ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 );\ - debug_printf( ", " );\ - _print_reg( R1 ); } while( 0 ) -#define DUMP_RRI( OP, R0, R1, I ) do {\ - debug_printf( "\n%s", OP );\ - _fill( OP );\ - _print_reg( R0 );\ - debug_printf( ", " );\ - _print_reg( R1 );\ - debug_printf( ", " );\ - debug_printf( "%u", I ); } while( 0 ) - -#else - -#define DUMP_START() -#define DUMP_END() -#define DUMP( OP ) -#define DUMP_I( OP, I ) -#define DUMP_R( OP, R0 ) -#define DUMP_RR( OP, R0, R1 ) -#define DUMP_RRI( OP, R0, R1, I ) - -#endif #define FOR_EACH_CHANNEL( CHAN )\ for( CHAN = 0; CHAN < 4; CHAN++ ) @@ -310,200 +203,6 @@ get_coef( ((vec * 3 + member) * 4 + chan) * 4 ); } -/** - * X86 rtasm wrappers. - */ - -static void -emit_addps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ADDPS", dst, src ); - sse_addps( func, dst, src ); -} - -static void -emit_andnps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ANDNPS", dst, src ); - sse_andnps( func, dst, src ); -} - -static void -emit_andps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ANDPS", dst, src ); - sse_andps( func, dst, src ); -} - -static void -emit_call( - struct x86_function *func, - void (* addr)() ) -{ - struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); - - DUMP_I( "CALL", addr ); - x86_mov_reg_imm( func, ecx, (unsigned long) addr ); - x86_call( func, ecx ); -} - -static void -emit_cmpps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src, - enum sse_cc cc ) -{ - DUMP_RRI( "CMPPS", dst, src, cc ); - sse_cmpps( func, dst, src, cc ); -} - -static void -emit_cvttps2dq( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "CVTTPS2DQ", dst, src ); - sse2_cvttps2dq( func, dst, src ); -} - -static void -emit_maxps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MAXPS", dst, src ); - sse_maxps( func, dst, src ); -} - -static void -emit_minps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MINPS", dst, src ); - sse_minps( func, dst, src ); -} - -static void -emit_mov( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOV", dst, src ); - x86_mov( func, dst, src ); -} - -static void -emit_movaps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVAPS", dst, src ); - sse_movaps( func, dst, src ); -} - -static void -emit_movss( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVSS", dst, src ); - sse_movss( func, dst, src ); -} - -static void -emit_movups( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MOVUPS", dst, src ); - sse_movups( func, dst, src ); -} - -static void -emit_mulps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "MULPS", dst, src ); - sse_mulps( func, dst, src ); -} - -static void -emit_or( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "OR", dst, src ); - x86_or( func, dst, src ); -} - -static void -emit_orps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "ORPS", dst, src ); - sse_orps( func, dst, src ); -} - -static void -emit_pmovmskb( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "PMOVMSKB", dst, src ); - sse_pmovmskb( func, dst, src ); -} - -static void -emit_pop( - struct x86_function *func, - struct x86_reg dst ) -{ - DUMP_R( "POP", dst ); - x86_pop( func, dst ); -} - -static void -emit_push( - struct x86_function *func, - struct x86_reg dst ) -{ - DUMP_R( "PUSH", dst ); - x86_push( func, dst ); -} - -static void -emit_rcpps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "RCPPS", dst, src ); - sse2_rcpps( func, dst, src ); -} #ifdef WIN32 static void @@ -511,7 +210,6 @@ emit_retw( struct x86_function *func, unsigned size ) { - DUMP_I( "RET", size ); x86_retw( func, size ); } #else @@ -519,51 +217,10 @@ static void emit_ret( struct x86_function *func ) { - DUMP( "RET" ); x86_ret( func ); } #endif -static void -emit_rsqrtps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "RSQRTPS", dst, src ); - sse_rsqrtps( func, dst, src ); -} - -static void -emit_shufps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src, - unsigned char shuf ) -{ - DUMP_RRI( "SHUFPS", dst, src, shuf ); - sse_shufps( func, dst, src, shuf ); -} - -static void -emit_subps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "SUBPS", dst, src ); - sse_subps( func, dst, src ); -} - -static void -emit_xorps( - struct x86_function *func, - struct x86_reg dst, - struct x86_reg src ) -{ - DUMP_RR( "XORPS", dst, src ); - sse_xorps( func, dst, src ); -} /** * Data fetch helpers. @@ -582,11 +239,11 @@ emit_const( unsigned vec, unsigned chan ) { - emit_movss( + sse_movss( func, make_xmm( xmm ), get_const( vec, chan ) ); - emit_shufps( + sse_shufps( func, make_xmm( xmm ), make_xmm( xmm ), @@ -600,11 +257,11 @@ emit_immediate( unsigned vec, unsigned chan ) { - emit_movss( + sse_movss( func, make_xmm( xmm ), get_immediate( vec, chan ) ); - emit_shufps( + sse_shufps( func, make_xmm( xmm ), make_xmm( xmm ), @@ -625,7 +282,7 @@ emit_inputf( unsigned vec, unsigned chan ) { - emit_movups( + sse_movups( func, make_xmm( xmm ), get_input( vec, chan ) ); @@ -644,7 +301,7 @@ emit_output( unsigned vec, unsigned chan ) { - emit_movups( + sse_movups( func, get_output( vec, chan ), make_xmm( xmm ) ); @@ -663,7 +320,7 @@ emit_tempf( unsigned vec, unsigned chan ) { - emit_movaps( + sse_movaps( func, make_xmm( xmm ), get_temp( vec, chan ) ); @@ -684,11 +341,11 @@ emit_coef( unsigned chan, unsigned member ) { - emit_movss( + sse_movss( func, make_xmm( xmm ), get_coef( vec, chan, member ) ); - emit_shufps( + sse_shufps( func, make_xmm( xmm ), make_xmm( xmm ), @@ -706,7 +363,7 @@ emit_inputs( unsigned vec, unsigned chan ) { - emit_movups( + sse_movups( func, get_input( vec, chan ), make_xmm( xmm ) ); @@ -719,7 +376,7 @@ emit_temps( unsigned vec, unsigned chan ) { - emit_movaps( + sse_movaps( func, get_temp( vec, chan ), make_xmm( xmm ) ); @@ -796,39 +453,39 @@ static void emit_push_gp( struct x86_function *func ) { - emit_push( + x86_push( func, get_const_base() ); - emit_push( + x86_push( func, get_input_base() ); - emit_push( + x86_push( func, get_output_base() ); /* It is important on non-win32 platforms that temp base is pushed last. */ - emit_push( + x86_push( func, get_temp_base() ); } static void -emit_pop_gp( +x86_pop_gp( struct x86_function *func ) { /* Restore GP registers in a reverse order. */ - emit_pop( + x86_pop( func, get_temp_base() ); - emit_pop( + x86_pop( func, get_output_base() ); - emit_pop( + x86_pop( func, get_input_base() ); - emit_pop( + x86_pop( func, get_const_base() ); } @@ -839,7 +496,7 @@ emit_func_call_dst( unsigned xmm_dst, void (*code)() ) { - emit_movaps( + sse_movaps( func, get_temp( TEMP_R0, 0 ), make_xmm( xmm_dst ) ); @@ -848,19 +505,22 @@ emit_func_call_dst( func ); #ifdef WIN32 - emit_push( + x86_push( func, get_temp( TEMP_R0, 0 ) ); #endif - emit_call( - func, - code ); + { + struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); + + x86_mov_reg_imm( func, ecx, (unsigned long) code ); + x86_call( func, ecx ); + } - emit_pop_gp( + x86_pop_gp( func ); - emit_movaps( + sse_movaps( func, make_xmm( xmm_dst ), get_temp( TEMP_R0, 0 ) ); @@ -873,7 +533,7 @@ emit_func_call_dst_src( unsigned xmm_src, void (*code)() ) { - emit_movaps( + sse_movaps( func, get_temp( TEMP_R0, 1 ), make_xmm( xmm_src ) ); @@ -893,7 +553,7 @@ emit_abs( struct x86_function *func, unsigned xmm ) { - emit_andps( + sse_andps( func, make_xmm( xmm ), get_temp( @@ -907,7 +567,7 @@ emit_add( unsigned xmm_dst, unsigned xmm_src ) { - emit_addps( + sse_addps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -918,17 +578,15 @@ cos4f( float *store ) { #ifdef WIN32 - store[0] = (float) cos( (double) store[0] ); - store[1] = (float) cos( (double) store[1] ); - store[2] = (float) cos( (double) store[2] ); - store[3] = (float) cos( (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif + store[X + 0] = cosf( store[X + 0] ); store[X + 1] = cosf( store[X + 1] ); store[X + 2] = cosf( store[X + 2] ); store[X + 3] = cosf( store[X + 3] ); -#endif } static void @@ -947,17 +605,14 @@ ex24f( float *store ) { #ifdef WIN32 - store[0] = (float) pow( 2.0, (double) store[0] ); - store[1] = (float) pow( 2.0, (double) store[1] ); - store[2] = (float) pow( 2.0, (double) store[2] ); - store[3] = (float) pow( 2.0, (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif store[X + 0] = powf( 2.0f, store[X + 0] ); store[X + 1] = powf( 2.0f, store[X + 1] ); store[X + 2] = powf( 2.0f, store[X + 2] ); store[X + 3] = powf( 2.0f, store[X + 3] ); -#endif } static void @@ -976,7 +631,7 @@ emit_f2it( struct x86_function *func, unsigned xmm ) { - emit_cvttps2dq( + sse2_cvttps2dq( func, make_xmm( xmm ), make_xmm( xmm ) ); @@ -991,10 +646,10 @@ flr4f( #else const unsigned X = TEMP_R0 * 16; #endif - store[X + 0] = (float) floor( (double) store[X + 0] ); - store[X + 1] = (float) floor( (double) store[X + 1] ); - store[X + 2] = (float) floor( (double) store[X + 2] ); - store[X + 3] = (float) floor( (double) store[X + 3] ); + store[X + 0] = floorf( store[X + 0] ); + store[X + 1] = floorf( store[X + 1] ); + store[X + 2] = floorf( store[X + 2] ); + store[X + 3] = floorf( store[X + 3] ); } static void @@ -1017,10 +672,10 @@ frc4f( #else const unsigned X = TEMP_R0 * 16; #endif - store[X + 0] -= (float) floor( (double) store[X + 0] ); - store[X + 1] -= (float) floor( (double) store[X + 1] ); - store[X + 2] -= (float) floor( (double) store[X + 2] ); - store[X + 3] -= (float) floor( (double) store[X + 3] ); + store[X + 0] -= floorf( store[X + 0] ); + store[X + 1] -= floorf( store[X + 1] ); + store[X + 2] -= floorf( store[X + 2] ); + store[X + 3] -= floorf( store[X + 3] ); } static void @@ -1066,7 +721,7 @@ emit_MOV( unsigned xmm_dst, unsigned xmm_src ) { - emit_movups( + sse_movups( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1077,7 +732,7 @@ emit_mul (struct x86_function *func, unsigned xmm_dst, unsigned xmm_src) { - emit_mulps( + sse_mulps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1088,7 +743,7 @@ emit_neg( struct x86_function *func, unsigned xmm ) { - emit_xorps( + sse_xorps( func, make_xmm( xmm ), get_temp( @@ -1101,17 +756,14 @@ pow4f( float *store ) { #ifdef WIN32 - store[0] = (float) pow( (double) store[0], (double) store[4] ); - store[1] = (float) pow( (double) store[1], (double) store[5] ); - store[2] = (float) pow( (double) store[2], (double) store[6] ); - store[3] = (float) pow( (double) store[3], (double) store[7] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif store[X + 0] = powf( store[X + 0], store[X + 4] ); store[X + 1] = powf( store[X + 1], store[X + 5] ); store[X + 2] = powf( store[X + 2], store[X + 6] ); store[X + 3] = powf( store[X + 3], store[X + 7] ); -#endif } static void @@ -1133,7 +785,11 @@ emit_rcp ( unsigned xmm_dst, unsigned xmm_src ) { - emit_rcpps( + /* On Intel CPUs at least, this is only accurate to 12 bits -- not + * good enough. Need to either emit a proper divide or use the + * iterative technique described below in emit_rsqrt(). + */ + sse2_rcpps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1145,17 +801,14 @@ rsqrt4f( float *store ) { #ifdef WIN32 - store[0] = 1.0F / (float) sqrt( (double) store[0] ); - store[1] = 1.0F / (float) sqrt( (double) store[1] ); - store[2] = 1.0F / (float) sqrt( (double) store[2] ); - store[3] = 1.0F / (float) sqrt( (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; - store[X + 0] = 1.0F / sqrt( store[X + 0] ); - store[X + 1] = 1.0F / sqrt( store[X + 1] ); - store[X + 2] = 1.0F / sqrt( store[X + 2] ); - store[X + 3] = 1.0F / sqrt( store[X + 3] ); #endif + store[X + 0] = 1.0F / sqrtf( store[X + 0] ); + store[X + 1] = 1.0F / sqrtf( store[X + 1] ); + store[X + 2] = 1.0F / sqrtf( store[X + 2] ); + store[X + 3] = 1.0F / sqrtf( store[X + 3] ); } #endif @@ -1166,12 +819,41 @@ emit_rsqrt( unsigned xmm_src ) { #if HIGH_PRECISION +#if 1 emit_func_call_dst_src( func, xmm_dst, xmm_src, rsqrt4f ); #else + /* Although rsqrtps() and rcpps() are low precision on some/all SSE + * implementations, it is possible to improve its precision at + * fairly low cost, using a newton/raphson step, as below: + * + * x1 = 2 * rcpps(a) - a * rcpps(a) * rcpps(a) + * x1 = 0.5 * rsqrtps(a) * [3.0 - (a * rsqrtps(a))* rsqrtps(a)] + * + * See: http://softwarecommunity.intel.com/articles/eng/1818.htm + */ + /* This is some code that woudl do the above for a scalar 'a'. We + * obviously are interested in a vector version: + * + * movss xmm3, a; + * movss xmm1, half; + * movss xmm2, three; + * rsqrtss xmm0, xmm3; + * mulss xmm3, xmm0; + * mulss xmm1, xmm0; + * mulss xmm3, xmm0; + * subss xmm2, xmm3; + * mulss xmm1, xmm2; + * movss x, xmm1; + */ +#endif +#else + /* On Intel CPUs at least, this is only accurate to 12 bits -- not + * good enough. + */ emit_rsqrtps( func, make_xmm( xmm_dst ), @@ -1184,7 +866,7 @@ emit_setsign( struct x86_function *func, unsigned xmm ) { - emit_orps( + sse_orps( func, make_xmm( xmm ), get_temp( @@ -1197,17 +879,14 @@ sin4f( float *store ) { #ifdef WIN32 - store[0] = (float) sin( (double) store[0] ); - store[1] = (float) sin( (double) store[1] ); - store[2] = (float) sin( (double) store[2] ); - store[3] = (float) sin( (double) store[3] ); + const unsigned X = 0; #else const unsigned X = TEMP_R0 * 16; +#endif store[X + 0] = sinf( store[X + 0] ); store[X + 1] = sinf( store[X + 1] ); store[X + 2] = sinf( store[X + 2] ); store[X + 3] = sinf( store[X + 3] ); -#endif } static void @@ -1226,7 +905,7 @@ emit_sub( unsigned xmm_dst, unsigned xmm_src ) { - emit_subps( + sse_subps( func, make_xmm( xmm_dst ), make_xmm( xmm_src ) ); @@ -1435,16 +1114,16 @@ emit_kil( } } - emit_push( + x86_push( func, x86_make_reg( file_REG32, reg_AX ) ); - emit_push( + x86_push( func, x86_make_reg( file_REG32, reg_DX ) ); FOR_EACH_CHANNEL( chan_index ) { if( uniquemask & (1 << chan_index) ) { - emit_cmpps( + sse_cmpps( func, make_xmm( registers[chan_index] ), get_temp( @@ -1453,17 +1132,17 @@ emit_kil( cc_LessThan ); if( chan_index == firstchan ) { - emit_pmovmskb( + sse_pmovmskb( func, x86_make_reg( file_REG32, reg_AX ), make_xmm( registers[chan_index] ) ); } else { - emit_pmovmskb( + sse_pmovmskb( func, x86_make_reg( file_REG32, reg_DX ), make_xmm( registers[chan_index] ) ); - emit_or( + x86_or( func, x86_make_reg( file_REG32, reg_AX ), x86_make_reg( file_REG32, reg_DX ) ); @@ -1471,17 +1150,17 @@ emit_kil( } } - emit_or( + x86_or( func, get_temp( TGSI_EXEC_TEMP_KILMASK_I, TGSI_EXEC_TEMP_KILMASK_C ), x86_make_reg( file_REG32, reg_AX ) ); - emit_pop( + x86_pop( func, x86_make_reg( file_REG32, reg_DX ) ); - emit_pop( + x86_pop( func, x86_make_reg( file_REG32, reg_AX ) ); } @@ -1497,12 +1176,12 @@ emit_setcc( FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); - emit_cmpps( + sse_cmpps( func, make_xmm( 0 ), make_xmm( 1 ), cc ); - emit_andps( + sse_andps( func, make_xmm( 0 ), get_temp( @@ -1523,22 +1202,22 @@ emit_cmp( FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); FETCH( func, *inst, 2, 2, chan_index ); - emit_cmpps( + sse_cmpps( func, make_xmm( 0 ), get_temp( TGSI_EXEC_TEMP_00000000_I, TGSI_EXEC_TEMP_00000000_C ), cc_LessThan ); - emit_andps( + sse_andps( func, make_xmm( 1 ), make_xmm( 0 ) ); - emit_andnps( + sse_andnps( func, make_xmm( 0 ), make_xmm( 2 ) ); - emit_orps( + sse_orps( func, make_xmm( 0 ), make_xmm( 1 ) ); @@ -1589,7 +1268,7 @@ emit_instruction( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { FETCH( func, *inst, 0, 0, CHAN_X ); - emit_maxps( + sse_maxps( func, make_xmm( 0 ), get_temp( @@ -1601,7 +1280,7 @@ emit_instruction( /* XMM[1] = SrcReg[0].yyyy */ FETCH( func, *inst, 1, 0, CHAN_Y ); /* XMM[1] = max(XMM[1], 0) */ - emit_maxps( + sse_maxps( func, make_xmm( 1 ), get_temp( @@ -1610,14 +1289,14 @@ emit_instruction( /* XMM[2] = SrcReg[0].wwww */ FETCH( func, *inst, 2, 0, CHAN_W ); /* XMM[2] = min(XMM[2], 128.0) */ - emit_minps( + sse_minps( func, make_xmm( 2 ), get_temp( TGSI_EXEC_TEMP_128_I, TGSI_EXEC_TEMP_128_C ) ); /* XMM[2] = max(XMM[2], -128.0) */ - emit_maxps( + sse_maxps( func, make_xmm( 2 ), get_temp( @@ -1625,16 +1304,16 @@ emit_instruction( TGSI_EXEC_TEMP_MINUS_128_C ) ); emit_pow( func, 1, 2 ); FETCH( func, *inst, 0, 0, CHAN_X ); - emit_xorps( + sse_xorps( func, make_xmm( 2 ), make_xmm( 2 ) ); - emit_cmpps( + sse_cmpps( func, make_xmm( 2 ), make_xmm( 0 ), cc_LessThanEqual ); - emit_andps( + sse_andps( func, make_xmm( 2 ), make_xmm( 1 ) ); @@ -1756,7 +1435,7 @@ emit_instruction( FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); - emit_minps( + sse_minps( func, make_xmm( 0 ), make_xmm( 1 ) ); @@ -1768,7 +1447,7 @@ emit_instruction( FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { FETCH( func, *inst, 0, 0, chan_index ); FETCH( func, *inst, 1, 1, chan_index ); - emit_maxps( + sse_maxps( func, make_xmm( 0 ), make_xmm( 1 ) ); @@ -2376,8 +2055,6 @@ tgsi_emit_sse2( unsigned ok = 1; uint num_immediates = 0; - DUMP_START(); - func->csr = func->store; tgsi_parse_init( &parse, tokens ); @@ -2387,24 +2064,24 @@ tgsi_emit_sse2( */ if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) { /* DECLARATION phase, do not load output argument. */ - emit_mov( + x86_mov( func, get_input_base(), get_argument( 0 ) ); /* skipping outputs argument here */ - emit_mov( + x86_mov( func, get_const_base(), get_argument( 2 ) ); - emit_mov( + x86_mov( func, get_temp_base(), get_argument( 3 ) ); - emit_mov( + x86_mov( func, get_coef_base(), get_argument( 4 ) ); - emit_mov( + x86_mov( func, get_immediate_base(), get_argument( 5 ) ); @@ -2412,23 +2089,23 @@ tgsi_emit_sse2( else { assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX); - emit_mov( + x86_mov( func, get_input_base(), get_argument( 0 ) ); - emit_mov( + x86_mov( func, get_output_base(), get_argument( 1 ) ); - emit_mov( + x86_mov( func, get_const_base(), get_argument( 2 ) ); - emit_mov( + x86_mov( func, get_temp_base(), get_argument( 3 ) ); - emit_mov( + x86_mov( func, get_immediate_base(), get_argument( 4 ) ); @@ -2451,7 +2128,7 @@ tgsi_emit_sse2( if( !instruction_phase ) { /* INSTRUCTION phase, overwrite coeff with output. */ instruction_phase = TRUE; - emit_mov( + x86_mov( func, get_output_base(), get_argument( 1 ) ); @@ -2463,8 +2140,10 @@ tgsi_emit_sse2( &parse.FullToken.FullInstruction ); if (!ok) { - debug_printf("failed to translate tgsi opcode %d to SSE\n", - parse.FullToken.FullInstruction.Instruction.Opcode ); + debug_printf("failed to translate tgsi opcode %d to SSE (%s)\n", + parse.FullToken.FullInstruction.Instruction.Opcode, + parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ? + "vertex shader" : "fragment shader"); } break; @@ -2499,8 +2178,6 @@ tgsi_emit_sse2( tgsi_parse_free( &parse ); - DUMP_END(); - return ok; } -- cgit v1.2.3 From 76a3590046d74c923d9837f82ece1587224b9a41 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 14:19:15 +0100 Subject: util: work around freaky win32 math.h --- src/gallium/include/pipe/p_util.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index 77783b11a8..43d94ec4ba 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -405,6 +405,8 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch, #ifdef WIN32 +#if !defined(_INC_MATH) || !defined(__cplusplus) + static INLINE float cosf( float f ) { return (float) cos( (double) f ); @@ -444,7 +446,7 @@ static INLINE float logf( float f ) { return (float) cos( (double) f ); } - +#endif /* _INC_MATH */ #endif -- cgit v1.2.3 From 08717d94619802f7816420be155c0c92fa727109 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 21 Apr 2008 20:44:45 +0900 Subject: gallium: Do not mistake pipe state objects for state tracker state objects. --- src/gallium/auxiliary/cso_cache/cso_context.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 746b176185..4541be8a5c 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -266,8 +266,9 @@ void cso_save_samplers(struct cso_context *ctx) void cso_restore_samplers(struct cso_context *ctx) { - cso_set_samplers(ctx, ctx->nr_samplers_saved, - (const struct pipe_sampler_state **) ctx->samplers_saved); + ctx->nr_samplers = ctx->nr_samplers_saved; + memcpy(ctx->samplers, ctx->samplers_saved, sizeof(ctx->samplers)); + cso_single_sampler_done( ctx ); } @@ -313,6 +314,8 @@ void cso_restore_sampler_textures( struct cso_context *ctx ) pipe_texture_reference(&ctx->textures[i], NULL); ctx->pipe->set_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); + + ctx->nr_textures_saved = 0; } -- cgit v1.2.3 From 13d8b1b211a803f44ffe325e7eed887cce4abaca Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 21 Apr 2008 22:26:33 +0900 Subject: gallium: Set all state via cso_context in blit/gen_mipmap utils. cso_restore_* functions are implemented on top of cso_set_*, therefore they require full knowledge of the current pipe state to work correctly. Directly calling pipe's set_*_state functions will lead to undefined state. Also save and restore shaders. --- src/gallium/auxiliary/util/u_blit.c | 10 +++++++--- src/gallium/auxiliary/util/u_gen_mipmap.c | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index eec5e600c9..be5e83e834 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -300,6 +300,8 @@ util_blit_pixels(struct blit_state *ctx, cso_save_samplers(ctx->cso); cso_save_sampler_textures(ctx->cso); cso_save_framebuffer(ctx->cso); + cso_save_fragment_shader(ctx->cso); + cso_save_vertex_shader(ctx->cso); /* set misc state we care about */ cso_set_blend(ctx->cso, &ctx->blend); @@ -313,11 +315,11 @@ util_blit_pixels(struct blit_state *ctx, cso_single_sampler_done(ctx->cso); /* texture */ - pipe->set_sampler_textures(pipe, 1, &tex); + cso_set_sampler_textures(ctx->cso, 1, &tex); /* shaders */ - pipe->bind_fs_state(pipe, ctx->fs); - pipe->bind_vs_state(pipe, ctx->vs); + cso_set_fragment_shader(ctx->cso, ctx->fs); + cso_set_vertex_shader(ctx->cso, ctx->vs); /* drawing dest */ memset(&fb, 0, sizeof(fb)); @@ -344,6 +346,8 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_samplers(ctx->cso); cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); + cso_restore_fragment_shader(ctx->cso); + cso_restore_vertex_shader(ctx->cso); /* free the texture */ pipe_surface_reference(&texSurf, NULL); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 2fd214d22e..f0c4063b28 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -880,16 +880,18 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_samplers(ctx->cso); cso_save_sampler_textures(ctx->cso); cso_save_framebuffer(ctx->cso); + cso_save_fragment_shader(ctx->cso); + cso_save_vertex_shader(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - pipe->bind_vs_state(pipe, ctx->vs); - pipe->bind_fs_state(pipe, ctx->fs); + cso_set_fragment_shader(ctx->cso, ctx->fs); + cso_set_vertex_shader(ctx->cso, ctx->vs); #if 0 - pipe->set_viewport_state(pipe, &ctx->viewport); + cso_set_viewport(ctx->cso, &ctx->viewport); #endif /* init framebuffer state */ @@ -930,7 +932,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); #endif - pipe->set_sampler_textures(pipe, 1, &pt); + cso_set_sampler_textures(ctx->cso, 1, &pt); /* quad coords in window coords (bypassing clipping, viewport mapping) */ set_vertex_data(ctx, @@ -954,4 +956,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_samplers(ctx->cso); cso_restore_sampler_textures(ctx->cso); cso_restore_framebuffer(ctx->cso); + cso_restore_fragment_shader(ctx->cso); + cso_restore_vertex_shader(ctx->cso); } -- cgit v1.2.3 From e29583afcb238cf7a70089cfdf50a69ca277c53a Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 22 Apr 2008 00:14:08 +0900 Subject: gallium: Include dependent header. --- src/gallium/auxiliary/tgsi/util/tgsi_parse.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h index a98e88e343..da0121c482 100644 --- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h @@ -1,6 +1,8 @@ #if !defined TGSI_PARSE_H #define TGSI_PARSE_H +#include "pipe/p_shader_tokens.h" + #if defined __cplusplus extern "C" { #endif -- cgit v1.2.3 From d3045ebb0642b09b4d353be6d4a258e6766061e6 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 22 Apr 2008 00:16:04 +0900 Subject: gallium: Hash the fragment shader tokens, instead of pipe_shader_state. PS: pipe_shader_state should probably go away now that it is reduced to a single pointer. --- src/gallium/auxiliary/cso_cache/cso_context.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 4541be8a5c..87995c80c3 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -38,6 +38,7 @@ #include "pipe/p_state.h" #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "tgsi/util/tgsi_parse.h" #include "cso_cache/cso_context.h" #include "cso_cache/cso_cache.h" @@ -148,6 +149,7 @@ void cso_set_blend(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); cso->state = *templ; @@ -198,6 +200,7 @@ void cso_single_sampler(struct cso_context *ctx, (void*)templ); if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); cso->state = *templ; @@ -333,6 +336,7 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha)); cso->state = *templ; @@ -381,6 +385,7 @@ void cso_set_rasterizer(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); cso->state = *templ; @@ -420,17 +425,23 @@ void cso_restore_rasterizer(struct cso_context *ctx) void cso_set_fragment_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_shader_state)); + const struct tgsi_token *tokens = templ->tokens; + unsigned num_tokens = tgsi_num_tokens(tokens); + size_t tokens_size = num_tokens*sizeof(struct tgsi_token); + unsigned hash_key = cso_construct_key((void*)tokens, tokens_size); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, - hash_key, CSO_FRAGMENT_SHADER, - (void*)templ); + hash_key, + CSO_FRAGMENT_SHADER, + (void*)tokens); void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader)); + /* FIXME: handle OOM */ + struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader) + tokens_size); + struct tgsi_token *cso_tokens = (struct tgsi_token *)((char *)cso + sizeof(*cso)); - cso->state = *templ; + memcpy(cso_tokens, tokens, tokens_size); + cso->state.tokens = cso_tokens; cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_fs_state; cso->context = ctx->pipe; @@ -477,6 +488,7 @@ void cso_set_vertex_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { + /* FIXME: handle OOM */ struct cso_vertex_shader *cso = MALLOC(sizeof(struct cso_vertex_shader)); cso->state = *templ; -- cgit v1.2.3 From a918a9c744f656c8bf2e3fd2841732e01a5ccefc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 16:10:13 +0100 Subject: draw: consolidate all the passthrough line/tri/point funcs --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_pipe.c | 63 ---------- src/gallium/auxiliary/draw/draw_pipe.h | 6 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 38 +++---- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 16 +-- src/gallium/auxiliary/draw/draw_pipe_cull.c | 18 +-- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 9 +- src/gallium/auxiliary/draw/draw_pipe_offset.c | 16 +-- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 25 +--- src/gallium/auxiliary/draw/draw_pipe_stipple.c | 16 +-- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 19 +--- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 17 +-- src/gallium/auxiliary/draw/draw_pipe_util.c | 133 ++++++++++++++++++++++ src/gallium/auxiliary/draw/draw_pipe_wide_line.c | 17 +-- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 23 +--- 16 files changed, 177 insertions(+), 241 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pipe_util.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 5289f2660a..bc6acfe458 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -16,6 +16,7 @@ C_SOURCES = \ draw_pipe_stipple.c \ draw_pipe_twoside.c \ draw_pipe_unfilled.c \ + draw_pipe_util.c \ draw_pipe_validate.c \ draw_pipe_vbuf.c \ draw_pipe_wide_line.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 91e6a35c5e..0b9852f633 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -15,6 +15,7 @@ draw = env.ConvenienceLibrary( 'draw_pipe_stipple.c', 'draw_pipe_twoside.c', 'draw_pipe_unfilled.c', + 'draw_pipe_util.c', 'draw_pipe_validate.c', 'draw_pipe_vbuf.c', 'draw_pipe_wide_line.c', diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 0c0840af0c..d0890203a5 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -108,40 +108,6 @@ void draw_pipeline_destroy( struct draw_context *draw ) -/* This is only used for temporary verts. - */ -#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) - - -/** - * Allocate space for temporary post-transform vertices, such as for clipping. - */ -void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) -{ - assert(!stage->tmp); - - stage->nr_tmps = nr; - - if (nr) { - ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); - unsigned i; - - stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); - } -} - - -void draw_free_temp_verts( struct draw_stage *stage ) -{ - if (stage->tmp) { - FREE( stage->tmp[0] ); - FREE( stage->tmp ); - stage->tmp = NULL; - } -} @@ -195,35 +161,6 @@ static void do_triangle( struct draw_context *draw, } -/* Reset vertex ids. This is basically a type of flush. - * - * Called only from draw_pipe_vbuf.c - */ -void draw_reset_vertex_ids(struct draw_context *draw) -{ - struct draw_stage *stage = draw->pipeline.first; - - while (stage) { - unsigned i; - - for (i = 0; i < stage->nr_tmps; i++) - stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; - - stage = stage->next; - } - - if (draw->pipeline.verts) - { - unsigned i; - char *verts = draw->pipeline.verts; - unsigned stride = draw->pipeline.vertex_stride; - - for (i = 0; i < draw->pipeline.vertex_count; i++) { - ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; - verts += stride; - } - } -} /* Code to run the pipeline on a fairly arbitary collection of vertices. diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h index f2749b34bb..2476abb2b2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.h +++ b/src/gallium/auxiliary/draw/draw_pipe.h @@ -81,10 +81,14 @@ extern struct draw_stage *draw_validate_stage( struct draw_context *context ); extern void draw_free_temp_verts( struct draw_stage *stage ); -extern void draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); +extern boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ); extern void draw_reset_vertex_ids( struct draw_context *draw ); +void draw_pipe_passthrough_tri(struct draw_stage *stage, struct prim_header *header); +void draw_pipe_passthrough_line(struct draw_stage *stage, struct prim_header *header); +void draw_pipe_passthrough_point(struct draw_stage *stage, struct prim_header *header); + /** diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 24bc87d4f8..b27360170a 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -334,7 +334,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, * Generate the frag shader we'll use for drawing AA lines. * This will be the user's shader plus some texture/modulate instructions. */ -static void +static boolean generate_aaline_fs(struct aaline_stage *aaline) { const struct pipe_shader_state *orig_fs = &aaline->fs->state; @@ -346,6 +346,8 @@ generate_aaline_fs(struct aaline_stage *aaline) aaline_fs = *orig_fs; /* copy to init */ aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + if (aaline_fs.tokens == NULL) + return FALSE; memset(&transform, 0, sizeof(transform)); transform.colorOutput = -1; @@ -372,6 +374,7 @@ generate_aaline_fs(struct aaline_stage *aaline) = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); aaline->fs->generic_attrib = transform.maxGeneric + 1; + return TRUE; } @@ -469,13 +472,15 @@ aaline_create_sampler(struct aaline_stage *aaline) * When we're about to draw our first AA line in a batch, this function is * called to tell the driver to bind our modified fragment shader. */ -static void +static boolean bind_aaline_fragment_shader(struct aaline_stage *aaline) { - if (!aaline->fs->aaline_fs) { - generate_aaline_fs(aaline); - } + if (!aaline->fs->aaline_fs && + !generate_aaline_fs(aaline)) + return FALSE; + aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs); + return TRUE; } @@ -487,20 +492,6 @@ aaline_stage( struct draw_stage *stage ) } -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} - - /** * Draw a wide line by drawing a quad, using geometry which will * fullfill GL's antialiased line requirements. @@ -638,7 +629,10 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) /* * Bind (generate) our fragprog, sampler and texture */ - bind_aaline_fragment_shader(aaline); + if (!bind_aaline_fragment_shader(aaline)) { + stage->line = draw_pipe_passthrough_line; + return; + } /* update vertex attrib info */ aaline->tex_slot = draw->num_vs_outputs; @@ -721,9 +715,9 @@ draw_aaline_stage(struct draw_context *draw) aaline->stage.draw = draw; aaline->stage.next = NULL; - aaline->stage.point = passthrough_point; + aaline->stage.point = draw_pipe_passthrough_point; aaline->stage.line = aaline_first_line; - aaline->stage.tri = passthrough_tri; + aaline->stage.tri = draw_pipe_passthrough_tri; aaline->stage.flush = aaline_flush; aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter; aaline->stage.destroy = aaline_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 9f878f6c02..6d22d7ac48 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -546,18 +546,6 @@ aapoint_stage( struct draw_stage *stage ) } -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} /** @@ -749,8 +737,8 @@ draw_aapoint_stage(struct draw_context *draw) aapoint->stage.draw = draw; aapoint->stage.next = NULL; aapoint->stage.point = aapoint_first_point; - aapoint->stage.line = passthrough_line; - aapoint->stage.tri = passthrough_tri; + aapoint->stage.line = draw_pipe_passthrough_line; + aapoint->stage.tri = draw_pipe_passthrough_tri; aapoint->stage.flush = aapoint_flush; aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter; aapoint->stage.destroy = aapoint_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index c406f89d05..8c13f40b55 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -95,20 +95,6 @@ static void cull_first_tri( struct draw_stage *stage, -static void cull_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void cull_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - static void cull_flush( struct draw_stage *stage, unsigned flags ) { stage->tri = cull_first_tri; @@ -139,8 +125,8 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw ) cull->stage.draw = draw; cull->stage.next = NULL; - cull->stage.point = cull_point; - cull->stage.line = cull_line; + cull->stage.point = draw_pipe_passthrough_point; + cull->stage.line = draw_pipe_passthrough_line; cull->stage.tri = cull_first_tri; cull->stage.flush = cull_flush; cull->stage.reset_stipple_counter = cull_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index bdb8b49dc4..2aeb309554 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -152,13 +152,6 @@ static void flatshade_line_1( struct draw_stage *stage, } -/* Flatshade point -- passthrough. - */ -static void flatshade_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} static void flatshade_init_state( struct draw_stage *stage ) @@ -236,7 +229,7 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) flatshade->stage.draw = draw; flatshade->stage.next = NULL; - flatshade->stage.point = flatshade_point; + flatshade->stage.point = draw_pipe_passthrough_point; flatshade->stage.line = flatshade_first_line; flatshade->stage.tri = flatshade_first_tri; flatshade->stage.flush = flatshade_flush; diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index dbdece45bb..c1dc21cd32 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -129,18 +129,6 @@ static void offset_first_tri( struct draw_stage *stage, } -static void offset_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void offset_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} static void offset_flush( struct draw_stage *stage, @@ -175,8 +163,8 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw ) offset->stage.draw = draw; offset->stage.next = NULL; - offset->stage.point = offset_point; - offset->stage.line = offset_line; + offset->stage.point = draw_pipe_passthrough_point; + offset->stage.line = draw_pipe_passthrough_line; offset->stage.tri = offset_first_tri; offset->stage.flush = offset_flush; offset->stage.reset_stipple_counter = offset_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 4903ba2133..5686729cd3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -473,25 +473,6 @@ pstip_stage( struct draw_stage *stage ) } -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point(stage->next, header); -} - - -static void -passthrough_line(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->line(stage->next, header); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} @@ -523,7 +504,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); /* now really draw first line */ - stage->tri = passthrough_tri; + stage->tri = draw_pipe_passthrough_tri; stage->tri(stage, header); } @@ -579,8 +560,8 @@ draw_pstip_stage(struct draw_context *draw) pstip->stage.draw = draw; pstip->stage.next = NULL; - pstip->stage.point = passthrough_point; - pstip->stage.line = passthrough_line; + pstip->stage.point = draw_pipe_passthrough_point; + pstip->stage.line = draw_pipe_passthrough_line; pstip->stage.tri = pstip_first_tri; pstip->stage.flush = pstip_flush; pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c index 49429ee9e1..9cf5840cce 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c @@ -195,18 +195,6 @@ stipple_flush(struct draw_stage *stage, unsigned flags) } -static void -passthrough_point(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->point( stage->next, header ); -} - - -static void -passthrough_tri(struct draw_stage *stage, struct prim_header *header) -{ - stage->next->tri(stage->next, header); -} static void @@ -228,9 +216,9 @@ struct draw_stage *draw_stipple_stage( struct draw_context *draw ) stipple->stage.draw = draw; stipple->stage.next = NULL; - stipple->stage.point = passthrough_point; + stipple->stage.point = draw_pipe_passthrough_point; stipple->stage.line = stipple_first_line; - stipple->stage.tri = passthrough_tri; + stipple->stage.tri = draw_pipe_passthrough_tri; stipple->stage.reset_stipple_counter = reset_stipple_counter; stipple->stage.flush = stipple_flush; stipple->stage.destroy = stipple_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 09a9d23d57..453fd3ac71 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -99,21 +99,6 @@ static void twoside_tri( struct draw_stage *stage, } -static void twoside_line( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->line( stage->next, header ); -} - - -static void twoside_point( struct draw_stage *stage, - struct prim_header *header ) -{ - /* pass-through */ - stage->next->point( stage->next, header ); -} - static void twoside_first_tri( struct draw_stage *stage, struct prim_header *header ) @@ -192,8 +177,8 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw ) twoside->stage.draw = draw; twoside->stage.next = NULL; - twoside->stage.point = twoside_point; - twoside->stage.line = twoside_line; + twoside->stage.point = draw_pipe_passthrough_point; + twoside->stage.line = draw_pipe_passthrough_line; twoside->stage.tri = twoside_first_tri; twoside->stage.flush = twoside_flush; twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index 31e24f6a14..d4ddfec1b3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -148,19 +148,6 @@ static void unfilled_first_tri( struct draw_stage *stage, } -static void unfilled_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line( stage->next, header ); -} - - -static void unfilled_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - static void unfilled_flush( struct draw_stage *stage, unsigned flags ) @@ -196,8 +183,8 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) unfilled->stage.draw = draw; unfilled->stage.next = NULL; unfilled->stage.tmp = NULL; - unfilled->stage.point = unfilled_point; - unfilled->stage.line = unfilled_line; + unfilled->stage.point = draw_pipe_passthrough_point; + unfilled->stage.line = draw_pipe_passthrough_line; unfilled->stage.tri = unfilled_first_tri; unfilled->stage.flush = unfilled_flush; unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter; diff --git a/src/gallium/auxiliary/draw/draw_pipe_util.c b/src/gallium/auxiliary/draw/draw_pipe_util.c new file mode 100644 index 0000000000..e9821de976 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pipe_util.c @@ -0,0 +1,133 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "draw/draw_private.h" +#include "draw/draw_pipe.h" + + + +void +draw_pipe_passthrough_point(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->point(stage->next, header); +} + +void +draw_pipe_passthrough_line(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->line(stage->next, header); +} + +void +draw_pipe_passthrough_tri(struct draw_stage *stage, struct prim_header *header) +{ + stage->next->tri(stage->next, header); +} + + + + + +/* This is only used for temporary verts. + */ +#define MAX_VERTEX_SIZE ((2 + PIPE_MAX_SHADER_OUTPUTS) * 4 * sizeof(float)) + + +/** + * Allocate space for temporary post-transform vertices, such as for clipping. + */ +boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) +{ + unsigned i; + ubyte *store; + + assert(!stage->tmp); + + stage->tmp = NULL; + stage->nr_tmps = nr; + if (nr == 0) + return FALSE; + + store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + if (store == NULL) + return FALSE; + + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + + return TRUE; +} + + +void draw_free_temp_verts( struct draw_stage *stage ) +{ + if (stage->tmp) { + FREE( stage->tmp[0] ); + FREE( stage->tmp ); + stage->tmp = NULL; + } +} + + +/* Reset vertex ids. This is basically a type of flush. + * + * Called only from draw_pipe_vbuf.c + */ +void draw_reset_vertex_ids(struct draw_context *draw) +{ + struct draw_stage *stage = draw->pipeline.first; + + while (stage) { + unsigned i; + + for (i = 0; i < stage->nr_tmps; i++) + stage->tmp[i]->vertex_id = UNDEFINED_VERTEX_ID; + + stage = stage->next; + } + + if (draw->pipeline.verts) + { + unsigned i; + char *verts = draw->pipeline.verts; + unsigned stride = draw->pipeline.vertex_stride; + + for (i = 0; i < draw->pipeline.vertex_count; i++) { + ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID; + verts += stride; + } + } +} + diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c index 329b5d0fb0..452732e662 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c @@ -49,19 +49,6 @@ static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage ) } -static void wideline_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - - -static void wideline_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} - /** * Draw a wide line by drawing a quad (two triangles). @@ -180,9 +167,9 @@ struct draw_stage *draw_wide_line_stage( struct draw_context *draw ) wide->stage.draw = draw; wide->stage.next = NULL; - wide->stage.point = wideline_point; + wide->stage.point = draw_pipe_passthrough_point; wide->stage.line = wideline_line; - wide->stage.tri = wideline_tri; + wide->stage.tri = draw_pipe_passthrough_point; wide->stage.flush = wideline_flush; wide->stage.reset_stipple_counter = wideline_reset_stipple_counter; wide->stage.destroy = wideline_destroy; diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 7a439178a0..8101340680 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -61,23 +61,6 @@ widepoint_stage( struct draw_stage *stage ) } -static void passthrough_point( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->point( stage->next, header ); -} - -static void widepoint_line( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->line(stage->next, header); -} - -static void widepoint_tri( struct draw_stage *stage, - struct prim_header *header ) -{ - stage->next->tri(stage->next, header); -} /** @@ -209,7 +192,7 @@ static void widepoint_first_point( struct draw_stage *stage, stage->point = widepoint_point; } else { - stage->point = passthrough_point; + stage->point = draw_pipe_passthrough_point; } if (draw->rasterizer->point_sprite) { @@ -272,8 +255,8 @@ struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) wide->stage.draw = draw; wide->stage.next = NULL; wide->stage.point = widepoint_first_point; - wide->stage.line = widepoint_line; - wide->stage.tri = widepoint_tri; + wide->stage.line = draw_pipe_passthrough_line; + wide->stage.tri = draw_pipe_passthrough_tri; wide->stage.flush = widepoint_flush; wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter; wide->stage.destroy = widepoint_destroy; -- cgit v1.2.3 From 69ecc2a577dc45451d56cee3e41cb6e7e542b097 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 16:38:09 +0100 Subject: draw: propogate errors out of aaline stage --- src/gallium/auxiliary/draw/draw_context.h | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 58 ++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 68e2efb865..6171c75cb4 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -73,7 +73,7 @@ void draw_enable_line_stipple(struct draw_context *draw, boolean enable); void draw_enable_point_sprites(struct draw_context *draw, boolean enable); -void +boolean draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); void diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index b27360170a..ae1abf91c2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -338,7 +338,6 @@ static boolean generate_aaline_fs(struct aaline_stage *aaline) { const struct pipe_shader_state *orig_fs = &aaline->fs->state; - //struct draw_context *draw = aaline->stage.draw; struct pipe_shader_state aaline_fs; struct aa_transform_context transform; @@ -372,6 +371,8 @@ generate_aaline_fs(struct aaline_stage *aaline) aaline->fs->aaline_fs = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs); + if (aaline->fs->aaline_fs == NULL) + return FALSE; aaline->fs->generic_attrib = transform.maxGeneric + 1; return TRUE; @@ -381,7 +382,7 @@ generate_aaline_fs(struct aaline_stage *aaline) /** * Create the texture map we'll use for antialiasing the lines. */ -static void +static boolean aaline_create_texture(struct aaline_stage *aaline) { struct pipe_context *pipe = aaline->pipe; @@ -399,6 +400,8 @@ aaline_create_texture(struct aaline_stage *aaline) texTemp.cpp = 1; aaline->texture = screen->texture_create(screen, &texTemp); + if (!aaline->texture) + return FALSE; /* Fill in mipmap images. * Basically each level is solid opaque, except for the outermost @@ -414,6 +417,8 @@ aaline_create_texture(struct aaline_stage *aaline) surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0); data = pipe_surface_map(surface); + if (data == NULL) + return FALSE; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { @@ -439,6 +444,7 @@ aaline_create_texture(struct aaline_stage *aaline) pipe_surface_reference(&surface, NULL); pipe->texture_update(pipe, aaline->texture, 0, (1 << level)); } + return TRUE; } @@ -447,7 +453,7 @@ aaline_create_texture(struct aaline_stage *aaline) * By using a mipmapped texture, we don't have to generate a different * texture image for each line size. */ -static void +static boolean aaline_create_sampler(struct aaline_stage *aaline) { struct pipe_sampler_state sampler; @@ -465,6 +471,10 @@ aaline_create_sampler(struct aaline_stage *aaline) sampler.max_lod = MAX_TEXTURE_LEVEL; aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler); + if (aaline->sampler_cso == NULL) + return FALSE; + + return TRUE; } @@ -696,9 +706,11 @@ aaline_destroy(struct draw_stage *stage) { struct aaline_stage *aaline = aaline_stage(stage); - aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); + if (aaline->sampler_cso) + aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso); - pipe_texture_release(&aaline->texture); + if (aaline->texture) + pipe_texture_release(&aaline->texture); draw_free_temp_verts( stage ); @@ -710,8 +722,11 @@ static struct aaline_stage * draw_aaline_stage(struct draw_context *draw) { struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage); + if (aaline == NULL) + return NULL; - draw_alloc_temp_verts( &aaline->stage, 8 ); + if (draw_alloc_temp_verts( &aaline->stage, 8 )) + goto fail; aaline->stage.draw = draw; aaline->stage.next = NULL; @@ -723,6 +738,12 @@ draw_aaline_stage(struct draw_context *draw) aaline->stage.destroy = aaline_destroy; return aaline; + + fail: + if (aaline) + aaline_destroy(&aaline->stage); + + return NULL; } @@ -816,7 +837,7 @@ aaline_set_sampler_textures(struct pipe_context *pipe, * into the draw module's pipeline. This will not be used if the * hardware has native support for AA lines. */ -void +boolean draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) { struct aaline_stage *aaline; @@ -827,14 +848,17 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) * Create / install AA line drawing / prim stage */ aaline = draw_aaline_stage( draw ); - assert(aaline); - draw->pipeline.aaline = &aaline->stage; + if (!aaline) + goto fail; aaline->pipe = pipe; /* create special texture, sampler state */ - aaline_create_texture(aaline); - aaline_create_sampler(aaline); + if (!aaline_create_texture(aaline)) + goto fail; + + if (!aaline_create_sampler(aaline)) + goto fail; /* save original driver functions */ aaline->driver_create_fs_state = pipe->create_fs_state; @@ -851,4 +875,16 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe) pipe->bind_sampler_states = aaline_bind_sampler_states; pipe->set_sampler_textures = aaline_set_sampler_textures; + + /* Install once everything is known to be OK: + */ + draw->pipeline.aaline = &aaline->stage; + + return TRUE; + + fail: + if (aaline) + aaline->stage.destroy( &aaline->stage ); + + return FALSE; } -- cgit v1.2.3 From 0cd90a917d289363a3edb5cfa40c391eb07aa97c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 16:45:41 +0100 Subject: draw: propogate errors out of aapoint stage --- src/gallium/auxiliary/draw/draw_context.h | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 2 +- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 46 ++++++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 6171c75cb4..197235b2d8 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -76,7 +76,7 @@ void draw_enable_point_sprites(struct draw_context *draw, boolean enable); boolean draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); -void +boolean draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); void diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index ae1abf91c2..bc514d40f0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -725,7 +725,7 @@ draw_aaline_stage(struct draw_context *draw) if (aaline == NULL) return NULL; - if (draw_alloc_temp_verts( &aaline->stage, 8 )) + if (!draw_alloc_temp_verts( &aaline->stage, 8 )) goto fail; aaline->stage.draw = draw; diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 6d22d7ac48..6d689c36de 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -484,7 +484,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx, * Generate the frag shader we'll use for drawing AA lines. * This will be the user's shader plus some texture/modulate instructions. */ -static void +static boolean generate_aapoint_fs(struct aapoint_stage *aapoint) { const struct pipe_shader_state *orig_fs = &aapoint->fs->state; @@ -495,6 +495,8 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) aapoint_fs = *orig_fs; /* copy to init */ aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + if (aapoint_fs.tokens == NULL) + return FALSE; memset(&transform, 0, sizeof(transform)); transform.colorOutput = -1; @@ -519,8 +521,12 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) aapoint->fs->aapoint_fs = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs); + if (aapoint->fs->aapoint_fs == NULL) + return FALSE; aapoint->fs->generic_attrib = transform.maxGeneric + 1; + + return TRUE; } @@ -528,13 +534,15 @@ generate_aapoint_fs(struct aapoint_stage *aapoint) * When we're about to draw our first AA line in a batch, this function is * called to tell the driver to bind our modified fragment shader. */ -static void +static boolean bind_aapoint_fragment_shader(struct aapoint_stage *aapoint) { - if (!aapoint->fs->aapoint_fs) { - generate_aapoint_fs(aapoint); - } + if (!aapoint->fs->aapoint_fs && + !generate_aapoint_fs(aapoint)) + return FALSE; + aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs); + return TRUE; } @@ -731,8 +739,11 @@ static struct aapoint_stage * draw_aapoint_stage(struct draw_context *draw) { struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage); + if (aapoint == NULL) + goto fail; - draw_alloc_temp_verts( &aapoint->stage, 4 ); + if (!draw_alloc_temp_verts( &aapoint->stage, 4 )) + goto fail; aapoint->stage.draw = draw; aapoint->stage.next = NULL; @@ -744,6 +755,13 @@ draw_aapoint_stage(struct draw_context *draw) aapoint->stage.destroy = aapoint_destroy; return aapoint; + + fail: + if (aapoint) + aapoint_destroy(&aapoint->stage); + + return NULL; + } @@ -806,20 +824,19 @@ aapoint_delete_fs_state(struct pipe_context *pipe, void *fs) * into the draw module's pipeline. This will not be used if the * hardware has native support for AA points. */ -void +boolean draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe) { struct aapoint_stage *aapoint; - pipe->draw = (void *) draw; /* * Create / install AA point drawing / prim stage */ aapoint = draw_aapoint_stage( draw ); - assert(aapoint); - draw->pipeline.aapoint = &aapoint->stage; + if (aapoint == NULL) + goto fail; aapoint->pipe = pipe; @@ -832,4 +849,13 @@ draw_install_aapoint_stage(struct draw_context *draw, pipe->create_fs_state = aapoint_create_fs_state; pipe->bind_fs_state = aapoint_bind_fs_state; pipe->delete_fs_state = aapoint_delete_fs_state; + + pipe->draw = (void *) draw; + draw->pipeline.aapoint = &aapoint->stage; + + fail: + if (aapoint) + aapoint->stage.destroy( &aapoint->stage ); + + return FALSE; } -- cgit v1.2.3 From 0d4ece4c5a243dc4b684331bad49f220311e5520 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 17:03:37 +0100 Subject: draw: propogate lots of errors --- src/gallium/auxiliary/draw/draw_context.h | 2 +- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 10 ++++---- src/gallium/auxiliary/draw/draw_pipe_aapoint.c | 14 ++++++----- src/gallium/auxiliary/draw/draw_pipe_clip.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_cull.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_flatshade.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_offset.c | 8 +++++++ src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 14 +++++++++-- src/gallium/auxiliary/draw/draw_pipe_twoside.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_unfilled.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pipe_util.c | 28 ++++++++++++---------- src/gallium/auxiliary/draw/draw_pipe_validate.c | 2 ++ src/gallium/auxiliary/draw/draw_pipe_vbuf.c | 5 ++-- src/gallium/auxiliary/draw/draw_pipe_wide_point.c | 11 ++++++++- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 2 ++ .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 ++ src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 ++ 17 files changed, 120 insertions(+), 35 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 197235b2d8..2742001698 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -79,7 +79,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe); boolean draw_install_aapoint_stage(struct draw_context *draw, struct pipe_context *pipe); -void +boolean draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe); diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index bc514d40f0..fbb5b45b40 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -765,13 +765,13 @@ aaline_create_fs_state(struct pipe_context *pipe, { struct aaline_stage *aaline = aaline_stage_from_pipe(pipe); struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader); + if (aafs == NULL) + return NULL; - if (aafs) { - aafs->state = *fs; + aafs->state = *fs; - /* pass-through */ - aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); - } + /* pass-through */ + aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs); return aafs; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index 6d689c36de..ac0aa4cd7c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -783,13 +783,13 @@ aapoint_create_fs_state(struct pipe_context *pipe, { struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe); struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader); + if (aafs == NULL) + return NULL; - if (aafs) { - aafs->state = *fs; + aafs->state = *fs; - /* pass-through */ - aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); - } + /* pass-through */ + aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs); return aafs; } @@ -830,6 +830,7 @@ draw_install_aapoint_stage(struct draw_context *draw, { struct aapoint_stage *aapoint; + pipe->draw = (void *) draw; /* * Create / install AA point drawing / prim stage @@ -850,9 +851,10 @@ draw_install_aapoint_stage(struct draw_context *draw, pipe->bind_fs_state = aapoint_bind_fs_state; pipe->delete_fs_state = aapoint_delete_fs_state; - pipe->draw = (void *) draw; draw->pipeline.aapoint = &aapoint->stage; + return TRUE; + fail: if (aapoint) aapoint->stage.destroy( &aapoint->stage ); diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 6780f275d9..21216addea 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -493,8 +493,11 @@ static void clip_destroy( struct draw_stage *stage ) struct draw_stage *draw_clip_stage( struct draw_context *draw ) { struct clipper *clipper = CALLOC_STRUCT(clipper); + if (clipper == NULL) + goto fail; - draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ); + if (!draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 )) + goto fail; clipper->stage.draw = draw; clipper->stage.point = clip_point; @@ -507,4 +510,10 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw ) clipper->plane = draw->plane; return &clipper->stage; + + fail: + if (clipper) + clipper->stage.destroy( &clipper->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c index 8c13f40b55..87aaf1f85b 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_cull.c +++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c @@ -120,8 +120,11 @@ static void cull_destroy( struct draw_stage *stage ) struct draw_stage *draw_cull_stage( struct draw_context *draw ) { struct cull_stage *cull = CALLOC_STRUCT(cull_stage); + if (cull == NULL) + goto fail; - draw_alloc_temp_verts( &cull->stage, 0 ); + if (!draw_alloc_temp_verts( &cull->stage, 0 )) + goto fail; cull->stage.draw = draw; cull->stage.next = NULL; @@ -133,4 +136,10 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw ) cull->stage.destroy = cull_destroy; return &cull->stage; + + fail: + if (cull) + cull->stage.destroy( &cull->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c index 2aeb309554..205000cbea 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c +++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c @@ -224,8 +224,11 @@ static void flatshade_destroy( struct draw_stage *stage ) struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) { struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage); + if (flatshade == NULL) + goto fail; - draw_alloc_temp_verts( &flatshade->stage, 2 ); + if (!draw_alloc_temp_verts( &flatshade->stage, 2 )) + goto fail; flatshade->stage.draw = draw; flatshade->stage.next = NULL; @@ -237,6 +240,12 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw ) flatshade->stage.destroy = flatshade_destroy; return &flatshade->stage; + + fail: + if (flatshade) + flatshade->stage.destroy( &flatshade->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c index c1dc21cd32..ffec85ccdd 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_offset.c +++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c @@ -158,6 +158,8 @@ static void offset_destroy( struct draw_stage *stage ) struct draw_stage *draw_offset_stage( struct draw_context *draw ) { struct offset_stage *offset = CALLOC_STRUCT(offset_stage); + if (offset == NULL) + goto fail; draw_alloc_temp_verts( &offset->stage, 3 ); @@ -171,4 +173,10 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw ) offset->stage.destroy = offset_destroy; return &offset->stage; + + fail: + if (offset) + offset->stage.destroy( &offset->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 5686729cd3..ac08aa10ce 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -686,7 +686,7 @@ pstip_set_polygon_stipple(struct pipe_context *pipe, * into the draw module's pipeline. This will not be used if the * hardware has native support for AA lines. */ -void +boolean draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe) { @@ -698,7 +698,9 @@ draw_install_pstipple_stage(struct draw_context *draw, * Create / install AA line drawing / prim stage */ pstip = draw_pstip_stage( draw ); - assert(pstip); + if (pstip == NULL) + goto fail; + draw->pipeline.pstipple = &pstip->stage; pstip->pipe = pipe; @@ -724,4 +726,12 @@ draw_install_pstipple_stage(struct draw_context *draw, pipe->bind_sampler_states = pstip_bind_sampler_states; pipe->set_sampler_textures = pstip_set_sampler_textures; pipe->set_polygon_stipple = pstip_set_polygon_stipple; + + return TRUE; + + fail: + if (pstip) + pstip->stage.destroy( &pstip->stage ); + + return FALSE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c index 453fd3ac71..5910dccc43 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c +++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c @@ -172,8 +172,11 @@ static void twoside_destroy( struct draw_stage *stage ) struct draw_stage *draw_twoside_stage( struct draw_context *draw ) { struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage); + if (twoside == NULL) + goto fail; - draw_alloc_temp_verts( &twoside->stage, 3 ); + if (!draw_alloc_temp_verts( &twoside->stage, 3 )) + goto fail; twoside->stage.draw = draw; twoside->stage.next = NULL; @@ -185,4 +188,10 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw ) twoside->stage.destroy = twoside_destroy; return &twoside->stage; + + fail: + if (twoside) + twoside->stage.destroy( &twoside->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c index d4ddfec1b3..eeb2bc43f9 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c +++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c @@ -177,8 +177,11 @@ static void unfilled_destroy( struct draw_stage *stage ) struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) { struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage); + if (unfilled == NULL) + goto fail; - draw_alloc_temp_verts( &unfilled->stage, 0 ); + if (!draw_alloc_temp_verts( &unfilled->stage, 0 )) + goto fail; unfilled->stage.draw = draw; unfilled->stage.next = NULL; @@ -191,4 +194,10 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw ) unfilled->stage.destroy = unfilled_destroy; return &unfilled->stage; + + fail: + if (unfilled) + unfilled->stage.destroy( &unfilled->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_util.c b/src/gallium/auxiliary/draw/draw_pipe_util.c index e9821de976..04438f4dd0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_util.c +++ b/src/gallium/auxiliary/draw/draw_pipe_util.c @@ -68,24 +68,28 @@ draw_pipe_passthrough_tri(struct draw_stage *stage, struct prim_header *header) */ boolean draw_alloc_temp_verts( struct draw_stage *stage, unsigned nr ) { - unsigned i; - ubyte *store; - assert(!stage->tmp); stage->tmp = NULL; stage->nr_tmps = nr; - if (nr == 0) - return FALSE; - store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); - if (store == NULL) - return FALSE; + if (nr != 0) + { + unsigned i; + ubyte *store = (ubyte *) MALLOC( MAX_VERTEX_SIZE * nr ); + + if (store == NULL) + return FALSE; - stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); - - for (i = 0; i < nr; i++) - stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + stage->tmp = (struct vertex_header **) MALLOC( sizeof(struct vertex_header *) * nr ); + if (stage->tmp == NULL) { + FREE(store); + return FALSE; + } + + for (i = 0; i < nr; i++) + stage->tmp[i] = (struct vertex_header *)(store + i * MAX_VERTEX_SIZE); + } return TRUE; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index ffddc2f62c..a2e0812c89 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -299,6 +299,8 @@ static void validate_destroy( struct draw_stage *stage ) struct draw_stage *draw_validate_stage( struct draw_context *draw ) { struct draw_stage *stage = CALLOC_STRUCT(draw_stage); + if (stage == NULL) + return NULL; stage->draw = draw; stage->next = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c index c5810febe0..afd5f5544d 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c +++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c @@ -443,8 +443,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, struct vbuf_render *render ) { struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage); - - if(!vbuf) + if (vbuf == NULL) goto fail; vbuf->stage.draw = draw; @@ -461,7 +460,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw, vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * sizeof(vbuf->indices[0]), 16 ); - if(!vbuf->indices) + if (!vbuf->indices) goto fail; vbuf->vertices = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c index 8101340680..ed08573382 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c @@ -249,8 +249,11 @@ static void widepoint_destroy( struct draw_stage *stage ) struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) { struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage); + if (wide == NULL) + goto fail; - draw_alloc_temp_verts( &wide->stage, 4 ); + if (!draw_alloc_temp_verts( &wide->stage, 4 )) + goto fail; wide->stage.draw = draw; wide->stage.next = NULL; @@ -262,4 +265,10 @@ struct draw_stage *draw_wide_point_stage( struct draw_context *draw ) wide->stage.destroy = widepoint_destroy; return &wide->stage; + + fail: + if (wide) + wide->stage.destroy( &wide->stage ); + + return NULL; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 002ced2186..7735173042 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -271,6 +271,8 @@ static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ) { struct fetch_emit_middle_end *fetch_emit = CALLOC_STRUCT( fetch_emit_middle_end ); + if (fetch_emit == NULL) + return NULL; fetch_emit->base.prepare = fetch_emit_prepare; fetch_emit->base.run = fetch_emit_run; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 881e47d59d..98a2cb45e4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -114,6 +114,8 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, (struct vertex_header *)MALLOC(fpme->vertex_size * fetch_count); if (!pipeline_verts) { + /* Not much we can do here - just skip the rendering. + */ assert(0); return; } diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index b61bb50664..3cc2941f96 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -487,6 +487,8 @@ static void vcache_destroy( struct draw_pt_front_end *frontend ) struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ) { struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend ); + if (vcache == NULL) + return NULL; vcache->base.prepare = vcache_prepare; vcache->base.run = NULL; -- cgit v1.2.3 From 30b4dc29091347252bc61d3be9370db0a45c16c3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 17:17:27 +0100 Subject: draw: more propogation -- pstipple stage. --- src/gallium/auxiliary/draw/draw_pipe_aaline.c | 1 + src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 43 ++++++++++++++++++------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index fbb5b45b40..7e5f8bd281 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -641,6 +641,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header) */ if (!bind_aaline_fragment_shader(aaline)) { stage->line = draw_pipe_passthrough_line; + stage->line(stage, header); return; } diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index ac08aa10ce..61bdd29aa0 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -320,7 +320,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, * Generate the frag shader we'll use for doing polygon stipple. * This will be the user's shader prefixed with a TEX and KIL instruction. */ -static void +static boolean generate_pstip_fs(struct pstip_stage *pstip) { const struct pipe_shader_state *orig_fs = &pstip->fs->state; @@ -332,6 +332,8 @@ generate_pstip_fs(struct pstip_stage *pstip) pstip_fs = *orig_fs; /* copy to init */ pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX); + if (pstip_fs.tokens == NULL) + return FALSE; memset(&transform, 0, sizeof(transform)); transform.wincoordInput = -1; @@ -355,6 +357,8 @@ generate_pstip_fs(struct pstip_stage *pstip) assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS); pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs); + + return TRUE; } @@ -404,7 +408,7 @@ pstip_update_texture(struct pstip_stage *pstip) /** * Create the texture map we'll use for stippling. */ -static void +static boolean pstip_create_texture(struct pstip_stage *pstip) { struct pipe_context *pipe = pstip->pipe; @@ -421,7 +425,10 @@ pstip_create_texture(struct pstip_stage *pstip) texTemp.cpp = 1; pstip->texture = screen->texture_create(screen, &texTemp); - assert(pstip->texture->refcount == 1); + if (pstip->texture == NULL) + return FALSE; + + return TRUE; } @@ -430,7 +437,7 @@ pstip_create_texture(struct pstip_stage *pstip) * By using a mipmapped texture, we don't have to generate a different * texture image for each line size. */ -static void +static boolean pstip_create_sampler(struct pstip_stage *pstip) { struct pipe_sampler_state sampler; @@ -448,6 +455,10 @@ pstip_create_sampler(struct pstip_stage *pstip) sampler.max_lod = 0.0f; pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler); + if (pstip->sampler_cso == NULL) + return FALSE; + + return TRUE; } @@ -455,13 +466,15 @@ pstip_create_sampler(struct pstip_stage *pstip) * When we're about to draw our first AA line in a batch, this function is * called to tell the driver to bind our modified fragment shader. */ -static void +static boolean bind_pstip_fragment_shader(struct pstip_stage *pstip) { - if (!pstip->fs->pstip_fs) { - generate_pstip_fs(pstip); - } + if (!pstip->fs->pstip_fs || + !generate_pstip_fs(pstip)) + return FALSE; + pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs); + return TRUE; } @@ -486,7 +499,12 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header) assert(stage->draw->rasterizer->poly_stipple_enable); /* bind our fragprog */ - bind_pstip_fragment_shader(pstip); + if (!bind_pstip_fragment_shader(pstip)) { + stage->tri = draw_pipe_passthrough_tri; + stage->tri(stage, header); + return; + } + /* how many samplers? */ /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ @@ -706,8 +724,11 @@ draw_install_pstipple_stage(struct draw_context *draw, pstip->pipe = pipe; /* create special texture, sampler state */ - pstip_create_texture(pstip); - pstip_create_sampler(pstip); + if (!pstip_create_texture(pstip)) + goto fail; + + if (!pstip_create_sampler(pstip)) + goto fail; /* save original driver functions */ pstip->driver_create_fs_state = pipe->create_fs_state; -- cgit v1.2.3 From 0824fb1d6afc651c0ab814e96f08326c706de216 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 12:42:37 -0400 Subject: actually write the results --- src/gallium/auxiliary/draw/draw_vs_llvm.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 2ebf05526a..dcada66514 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -103,15 +103,16 @@ vs_llvm_run_linear( struct draw_vertex_shader *base, /* Unswizzle all output results */ - for (slot = 1; slot < base->info.num_inputs; slot++) { - output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; - output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; - output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; - output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; - - output = (float (*)[4])((char *)output + output_stride); + for (j = 0; j < max_vertices; j++) { + for (slot = 0; slot < base->info.num_outputs; slot++) { + output[slot][0] = machine->Outputs[slot].xyzw[0].f[j]; + output[slot][1] = machine->Outputs[slot].xyzw[1].f[j]; + output[slot][2] = machine->Outputs[slot].xyzw[2].f[j]; + output[slot][3] = machine->Outputs[slot].xyzw[3].f[j]; + } + output = (float (*)[4])((char *)output + output_stride); } - } + } } -- cgit v1.2.3 From 65efe807b9067aa07b382e3c4d9cea6222c5fc6b Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 21 Apr 2008 17:51:39 +0100 Subject: gallium: Use CSO cache for shaders. --- src/mesa/state_tracker/st_atom_shader.c | 4 ++-- src/mesa/state_tracker/st_cb_bitmap.c | 11 ++++++----- src/mesa/state_tracker/st_cb_blit.c | 5 ----- src/mesa/state_tracker/st_cb_clear.c | 12 ++++++------ src/mesa/state_tracker/st_cb_drawpixels.c | 12 ++++++------ src/mesa/state_tracker/st_gen_mipmap.c | 6 ------ 6 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index ec39026eb3..4a641a4a73 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -273,8 +273,8 @@ update_linkage( struct st_context *st ) st->vp = stvp; st->fp = stfp; - st->pipe->bind_vs_state(st->pipe, stvp->driver_shader); - st->pipe->bind_fs_state(st->pipe, stfp->driver_shader); + cso_set_vertex_shader(st->cso_context, stvp->driver_shader); + cso_set_fragment_shader(st->cso_context, stfp->driver_shader); st->vertex_result_to_slot = xvp->output_to_slot; } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 505a13cc2b..1b863143e0 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -438,16 +438,18 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_samplers(cso); cso_save_sampler_textures(cso); cso_save_viewport(cso); + cso_save_fragment_shader(cso); + cso_save_vertex_shader(cso); /* rasterizer state: just scissor */ st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled; cso_set_rasterizer(cso, &st->bitmap.rasterizer); /* fragment shader state: TEX lookup program */ - pipe->bind_fs_state(pipe, stfp->driver_shader); + cso_set_fragment_shader(cso, stfp->driver_shader); /* vertex shader state: position + texcoord pass-through */ - pipe->bind_vs_state(pipe, st->bitmap.vs); + cso_set_vertex_shader(cso, st->bitmap.vs); /* sampler / texture state */ cso_single_sampler(cso, 0, &st->bitmap.sampler); @@ -488,9 +490,8 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_restore_samplers(cso); cso_restore_sampler_textures(cso); cso_restore_viewport(cso); - /* shaders don't go through cso yet */ - pipe->bind_fs_state(pipe, st->fp->driver_shader); - pipe->bind_vs_state(pipe, st->vp->driver_shader); + cso_save_fragment_shader(cso); + cso_save_vertex_shader(cso); } diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 63211d8b66..0533d9460f 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -71,7 +71,6 @@ st_BlitFramebuffer(GLcontext *ctx, GLbitfield mask, GLenum filter) { struct st_context *st = ctx->st; - struct pipe_context *pipe = st->pipe; const uint pFilter = ((filter == GL_NEAREST) ? PIPE_TEX_MIPFILTER_NEAREST @@ -100,10 +99,6 @@ st_BlitFramebuffer(GLcontext *ctx, 0.0, pFilter); } - - /* shaders don't go through CSO yet */ - pipe->bind_fs_state(pipe, st->fp->driver_shader); - pipe->bind_vs_state(pipe, st->vp->driver_shader); } diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 6469511c6f..bb27faad21 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -195,7 +195,6 @@ clear_with_quad(GLcontext *ctx, GLboolean color, GLboolean depth, GLboolean stencil) { struct st_context *st = ctx->st; - struct pipe_context *pipe = st->pipe; const GLfloat x0 = ctx->DrawBuffer->_Xmin; const GLfloat x1 = ctx->DrawBuffer->_Xmax; GLfloat y0, y1; @@ -222,6 +221,8 @@ clear_with_quad(GLcontext *ctx, cso_save_depth_stencil_alpha(st->cso_context); cso_save_rasterizer(st->cso_context); cso_save_viewport(st->cso_context); + cso_save_fragment_shader(st->cso_context); + cso_save_vertex_shader(st->cso_context); /* blend state: RGBA masking */ { @@ -273,8 +274,8 @@ clear_with_quad(GLcontext *ctx, cso_set_rasterizer(st->cso_context, &st->clear.raster); cso_set_viewport(st->cso_context, &st->clear.viewport); - pipe->bind_fs_state(pipe, st->clear.fs); - pipe->bind_vs_state(pipe, st->clear.vs); + cso_set_fragment_shader(st->cso_context, st->clear.fs); + cso_set_vertex_shader(st->cso_context, st->clear.vs); /* draw quad matching scissor rect (XXX verify coord round-off) */ draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor); @@ -284,9 +285,8 @@ clear_with_quad(GLcontext *ctx, cso_restore_depth_stencil_alpha(st->cso_context); cso_restore_rasterizer(st->cso_context); cso_restore_viewport(st->cso_context); - /* these don't go through cso yet */ - pipe->bind_fs_state(pipe, st->fp->driver_shader); - pipe->bind_vs_state(pipe, st->vp->driver_shader); + cso_restore_fragment_shader(st->cso_context); + cso_restore_vertex_shader(st->cso_context); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 5fb27857a7..75261c3350 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -532,6 +532,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_viewport(cso); cso_save_samplers(cso); cso_save_sampler_textures(cso); + cso_save_fragment_shader(cso); + cso_save_vertex_shader(cso); /* rasterizer state: just scissor */ { @@ -543,10 +545,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* fragment shader state: TEX lookup program */ - pipe->bind_fs_state(pipe, stfp->driver_shader); + cso_set_fragment_shader(cso, stfp->driver_shader); /* vertex shader state: position + texcoord pass-through */ - pipe->bind_vs_state(pipe, stvp->driver_shader); + cso_set_vertex_shader(cso, stvp->driver_shader); /* texture sampling state: */ @@ -615,10 +617,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_restore_viewport(cso); cso_restore_samplers(cso); cso_restore_sampler_textures(cso); - - /* shaders don't go through cso yet */ - pipe->bind_fs_state(pipe, st->fp->driver_shader); - pipe->bind_vs_state(pipe, st->vp->driver_shader); + cso_restore_fragment_shader(cso); + cso_restore_vertex_shader(cso); } diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index a931911227..da9ec12a4d 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -95,12 +95,6 @@ st_render_mipmap(struct st_context *st, util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel, PIPE_TEX_FILTER_LINEAR); - /* shaders don't go through CSO yet */ - if (st->fp) - pipe->bind_fs_state(pipe, st->fp->driver_shader); - if (st->vp) - pipe->bind_vs_state(pipe, st->vp->driver_shader); - return TRUE; } -- cgit v1.2.3 From b17e123a8f20239e8e1fc6816ccf115d9ec57471 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:09:38 +0100 Subject: rtasm: propogate errors in x86 emit --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 34 +++++++++++++++++++++++++----- src/gallium/auxiliary/rtasm/rtasm_x86sse.h | 1 + 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index f2c08c96a6..c2fe0e40f5 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -146,7 +146,10 @@ _fill( static void do_realloc( struct x86_function *p ) { - if (p->size == 0) { + if (p->store == p->error_overflow) { + p->csr = p->store; + } + else if (p->size == 0) { p->size = 1024; p->store = rtasm_exec_malloc(p->size); p->csr = p->store; @@ -156,10 +159,22 @@ static void do_realloc( struct x86_function *p ) unsigned char *tmp = p->store; p->size *= 2; p->store = rtasm_exec_malloc(p->size); - memcpy(p->store, tmp, used); - p->csr = p->store + used; + + if (p->store) { + memcpy(p->store, tmp, used); + p->csr = p->store + used; + } + else { + p->csr = p->store; + } + rtasm_exec_free(tmp); } + + if (p->store == NULL) { + p->store = p->csr = p->error_overflow; + p->size = 4; + } } /* Emit bytes to the instruction stream: @@ -1440,12 +1455,17 @@ void x86_init_func_size( struct x86_function *p, unsigned code_size ) { p->size = code_size; p->store = rtasm_exec_malloc(code_size); + if (p->store == NULL) { + p->store = p->error_overflow; + } p->csr = p->store; } void x86_release_func( struct x86_function *p ) { - rtasm_exec_free(p->store); + if (p->store && p->store != p->error_overflow) + rtasm_exec_free(p->store); + p->store = NULL; p->csr = NULL; p->size = 0; @@ -1456,7 +1476,11 @@ void (*x86_get_func( struct x86_function *p ))(void) { if (DISASSEM && p->store) debug_printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)(void)) p->store; + + if (p->store == p->error_overflow) + return (void (*)(void)) NULL; + else + return (void (*)(void)) p->store; } #else diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h index 5e99ceea70..695a1cef4e 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h @@ -43,6 +43,7 @@ struct x86_function { unsigned char *csr; unsigned stack_offset; int need_emms; + unsigned char error_overflow[4]; const char *fn; }; -- cgit v1.2.3 From d3db46eb8257c1b0cf823f1805ca00457be9aff3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:09:54 +0100 Subject: translate: fail on x86 rtasm fail --- src/gallium/auxiliary/translate/translate_sse.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c index e587e5afec..f590d48b78 100644 --- a/src/gallium/auxiliary/translate/translate_sse.c +++ b/src/gallium/auxiliary/translate/translate_sse.c @@ -597,7 +597,12 @@ struct translate *translate_sse2_create( const struct translate_key *key ) goto fail; p->gen_run = (run_func)x86_get_func(&p->linear_func); + if (p->gen_run == NULL) + goto fail; + p->gen_run_elts = (run_elts_func)x86_get_func(&p->elt_func); + if (p->gen_run_elts == NULL) + goto fail; return &p->translate; -- cgit v1.2.3 From 785831fc6fc56815d9637c7dd2acbcee6dfbbb0a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:11:58 +0100 Subject: cso: propogate one easy error - many more --- src/gallium/auxiliary/cso_cache/cso_cache.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index 18acab0967..f607528fdc 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -290,6 +290,8 @@ void * cso_take_state(struct cso_cache *sc, struct cso_cache *cso_cache_create(void) { struct cso_cache *sc = MALLOC_STRUCT(cso_cache); + if (sc == NULL) + return NULL; sc->max_size = 4096; sc->blend_hash = cso_hash_create(); -- cgit v1.2.3 From 73c2711bb186692b866720058a09f5eb05950213 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:43:53 +0100 Subject: rtasm: clean up debug dumping a little --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 286 ++++++++++++++--------------- 1 file changed, 140 insertions(+), 146 deletions(-) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index c2fe0e40f5..10796c540d 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -77,69 +77,60 @@ _print_reg( debug_printf( "]" ); } -static void -_fill( - const char *op ) -{ - unsigned count = 10 - strlen( op ); - while( count-- ) { - debug_printf( " " ); - } -} +#define DUMP_START() debug_printf( "\n" ) +#define DUMP_END() debug_printf( "\n" ) -#define DUMP_START() debug_printf( "\nsse-dump start ----------------" ) -#define DUMP_END() debug_printf( "\nsse-dump end ----------------\n" ) -#define DUMP( OP ) debug_printf( "\n%s", OP ) +#define DUMP() do { \ + const char *foo = __FUNCTION__; \ + while (*foo && *foo != '_') \ + foo++; \ + if (*foo) \ + foo++; \ + debug_printf( "\n% 15s ", foo ); \ +} while (0) -#define DUMP_I( OP, I ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_I( I ) do { \ + DUMP(); \ debug_printf( "%u", I ); \ } while( 0 ) -#define DUMP_R( OP, R0 ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_R( R0 ) do { \ + DUMP(); \ _print_reg( R0 ); \ } while( 0 ) -#define DUMP_RR( OP, R0, R1 ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_RR( R0, R1 ) do { \ + DUMP(); \ _print_reg( R0 ); \ debug_printf( ", " ); \ _print_reg( R1 ); \ } while( 0 ) -#define DUMP_RI( OP, R0, I ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_RI( R0, I ) do { \ + DUMP(); \ _print_reg( R0 ); \ - debug_printf( ", " ); \ - debug_printf( "%u", I ); \ + debug_printf( ", %u", I ); \ } while( 0 ) -#define DUMP_RRI( OP, R0, R1, I ) do { \ - debug_printf( "\n%s", OP ); \ - _fill( OP ); \ +#define DUMP_RRI( R0, R1, I ) do { \ + DUMP(); \ _print_reg( R0 ); \ debug_printf( ", " ); \ _print_reg( R1 ); \ - debug_printf( ", " ); \ - debug_printf( "%u", I ); \ + debug_printf( ", %u", I ); \ } while( 0 ) #else #define DUMP_START() #define DUMP_END() -#define DUMP( OP ) -#define DUMP_I( OP, I ) -#define DUMP_R( OP, R0 ) -#define DUMP_RR( OP, R0, R1 ) -#define DUMP_RI( OP, R0, I ) -#define DUMP_RRI( OP, R0, R1, I ) +#define DUMP( ) +#define DUMP_I( I ) +#define DUMP_R( R0 ) +#define DUMP_RR( R0, R1 ) +#define DUMP_RI( R0, I ) +#define DUMP_RRI( R0, R1, I ) #endif @@ -173,7 +164,7 @@ static void do_realloc( struct x86_function *p ) if (p->store == NULL) { p->store = p->csr = p->error_overflow; - p->size = 4; + p->size = sizeof(p->error_overflow); } } @@ -397,7 +388,7 @@ unsigned char *x86_jcc_forward( struct x86_function *p, unsigned char *x86_jmp_forward( struct x86_function *p) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0xe9); emit_1i(p, 0); return x86_get_label(p); @@ -405,7 +396,7 @@ unsigned char *x86_jmp_forward( struct x86_function *p) unsigned char *x86_call_forward( struct x86_function *p) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0xe8); emit_1i(p, 0); @@ -422,7 +413,7 @@ void x86_fixup_fwd_jump( struct x86_function *p, void x86_jmp( struct x86_function *p, unsigned char *label) { - DUMP_I( __FUNCTION__, label ); + DUMP_I( label ); emit_1ub(p, 0xe9); emit_1i(p, pointer_to_intptr( label ) - pointer_to_intptr( x86_get_label(p) ) - 4); } @@ -439,14 +430,14 @@ static unsigned char *cptr( void (*label)() ) */ void x86_call( struct x86_function *p, void (*label)()) { - DUMP_I( __FUNCTION__, label ); + DUMP_I( label ); emit_1ub(p, 0xe8); emit_1i(p, cptr(label) - x86_get_label(p) - 4); } #else void x86_call( struct x86_function *p, struct x86_reg reg) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); emit_1ub(p, 0xff); emit_modrm_noreg(p, 2, reg); } @@ -459,7 +450,7 @@ void x86_call( struct x86_function *p, struct x86_reg reg) */ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) { - DUMP_RI( __FUNCTION__, dst, imm ); + DUMP_RI( dst, imm ); assert(dst.mod == mod_REG); emit_1ub(p, 0xb8 + dst.idx); emit_1i(p, imm); @@ -468,7 +459,7 @@ void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm ) void x86_push( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x50 + reg.idx); p->stack_offset += 4; @@ -477,7 +468,7 @@ void x86_push( struct x86_function *p, void x86_pop( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x58 + reg.idx); p->stack_offset -= 4; @@ -486,7 +477,7 @@ void x86_pop( struct x86_function *p, void x86_inc( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x40 + reg.idx); } @@ -494,20 +485,20 @@ void x86_inc( struct x86_function *p, void x86_dec( struct x86_function *p, struct x86_reg reg ) { - DUMP_R( __FUNCTION__, reg ); + DUMP_R( reg ); assert(reg.mod == mod_REG); emit_1ub(p, 0x48 + reg.idx); } void x86_ret( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0xc3); } void x86_sahf( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0x9e); } @@ -515,7 +506,7 @@ void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x8b, 0x89, dst, src ); } @@ -523,7 +514,7 @@ void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x33, 0x31, dst, src ); } @@ -531,7 +522,7 @@ void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x3b, 0x39, dst, src ); } @@ -539,7 +530,7 @@ void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, 0x8d); emit_modrm( p, dst, src ); } @@ -548,7 +539,7 @@ void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, 0x85); emit_modrm( p, dst, src ); } @@ -557,7 +548,7 @@ void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm(p, 0x03, 0x01, dst, src ); } @@ -566,7 +557,7 @@ void x86_add( struct x86_function *p, void x86_mul( struct x86_function *p, struct x86_reg src ) { - DUMP_R( __FUNCTION__, src ); + DUMP_R( src ); emit_1ub(p, 0xf7); emit_modrm_noreg(p, 4, src ); } @@ -576,7 +567,7 @@ void x86_imul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0xAF); emit_modrm(p, dst, src); } @@ -586,7 +577,7 @@ void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm(p, 0x2b, 0x29, dst, src ); } @@ -594,7 +585,7 @@ void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x0b, 0x09, dst, src ); } @@ -602,7 +593,7 @@ void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_op_modrm( p, 0x23, 0x21, dst, src ); } @@ -617,7 +608,7 @@ void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, 0xF3, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -626,7 +617,7 @@ void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x28, 0x29, dst, src ); } @@ -635,7 +626,7 @@ void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x10, 0x11, dst, src ); } @@ -644,7 +635,7 @@ void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */ @@ -654,7 +645,7 @@ void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod != mod_REG || src.mod != mod_REG); emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */ @@ -664,7 +655,7 @@ void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -673,7 +664,7 @@ void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5F); emit_modrm( p, dst, src ); } @@ -682,7 +673,7 @@ void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x5E); emit_modrm( p, dst, src ); } @@ -691,7 +682,7 @@ void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5D); emit_modrm( p, dst, src ); } @@ -700,7 +691,7 @@ void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5C); emit_modrm( p, dst, src ); } @@ -709,7 +700,7 @@ void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -718,7 +709,7 @@ void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x59); emit_modrm( p, dst, src ); } @@ -727,7 +718,7 @@ void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -736,7 +727,7 @@ void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x58); emit_modrm( p, dst, src ); } @@ -745,7 +736,7 @@ void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x55); emit_modrm( p, dst, src ); } @@ -754,7 +745,7 @@ void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x54); emit_modrm( p, dst, src ); } @@ -763,7 +754,7 @@ void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x52); emit_modrm( p, dst, src ); } @@ -772,7 +763,7 @@ void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x52); emit_modrm( p, dst, src ); @@ -782,7 +773,7 @@ void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x12); emit_modrm( p, dst, src ); @@ -792,7 +783,7 @@ void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.mod == mod_REG && src.mod == mod_REG); emit_2ub(p, X86_TWOB, 0x16); emit_modrm( p, dst, src ); @@ -802,7 +793,7 @@ void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x56); emit_modrm( p, dst, src ); } @@ -811,7 +802,7 @@ void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x57); emit_modrm( p, dst, src ); } @@ -820,7 +811,7 @@ void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.file == file_MMX && (src.file == file_XMM || src.mod != mod_REG)); @@ -834,7 +825,7 @@ void sse2_cvtdq2ps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x5b); emit_modrm( p, dst, src ); } @@ -848,7 +839,7 @@ void sse_shufps( struct x86_function *p, struct x86_reg src, unsigned char shuf) { - DUMP_RRI( __FUNCTION__, dst, src, shuf ); + DUMP_RRI( dst, src, shuf ); emit_2ub(p, X86_TWOB, 0xC6); emit_modrm(p, dst, src); emit_1ub(p, shuf); @@ -859,7 +850,7 @@ void sse_cmpps( struct x86_function *p, struct x86_reg src, unsigned char cc) { - DUMP_RRI( "CMPPS", dst, src, cc ); + DUMP_RRI( dst, src, cc ); emit_2ub(p, X86_TWOB, 0xC2); emit_modrm(p, dst, src); emit_1ub(p, cc); @@ -869,7 +860,7 @@ void sse_pmovmskb( struct x86_function *p, struct x86_reg dst, struct x86_reg src) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0xD7); emit_modrm(p, dst, src); } @@ -886,7 +877,7 @@ void sse2_pshufd( struct x86_function *p, struct x86_reg src, unsigned char shuf) { - DUMP_RRI( __FUNCTION__, dst, src, shuf ); + DUMP_RRI( dst, src, shuf ); emit_3ub(p, 0x66, X86_TWOB, 0x70); emit_modrm(p, dst, src); emit_1ub(p, shuf); @@ -896,7 +887,7 @@ void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub( p, 0xF3, X86_TWOB, 0x5B ); emit_modrm( p, dst, src ); } @@ -905,7 +896,7 @@ void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x5B); emit_modrm( p, dst, src ); } @@ -914,7 +905,7 @@ void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x6B); emit_modrm( p, dst, src ); } @@ -923,7 +914,7 @@ void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x63); emit_modrm( p, dst, src ); } @@ -932,7 +923,7 @@ void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x67); emit_modrm( p, dst, src ); } @@ -941,7 +932,7 @@ void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0x66, X86_TWOB, 0x60); emit_modrm( p, dst, src ); } @@ -951,7 +942,7 @@ void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -960,7 +951,7 @@ void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_3ub(p, 0xF3, X86_TWOB, 0x53); emit_modrm( p, dst, src ); } @@ -969,7 +960,7 @@ void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); emit_2ub(p, 0x66, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); } @@ -982,35 +973,35 @@ void sse2_movd( struct x86_function *p, */ void x87_fist( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 2, dst); } void x87_fistp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); emit_1ub(p, 0xdb); emit_modrm_noreg(p, 3, dst); } void x87_fild( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); emit_1ub(p, 0xdf); emit_modrm_noreg(p, 0, arg); } void x87_fldz( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xee); } void x87_fldcw( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_REG32); assert(arg.mod != mod_REG); emit_1ub(p, 0xd9); @@ -1019,31 +1010,31 @@ void x87_fldcw( struct x86_function *p, struct x86_reg arg ) void x87_fld1( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xe8); } void x87_fldl2e( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xea); } void x87_fldln2( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xed); } void x87_fwait( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_1ub(p, 0x9b); } void x87_fnclex( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xdb, 0xe2); } @@ -1082,7 +1073,7 @@ static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86 void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xc8, 0xdc, 0xc8, @@ -1091,7 +1082,7 @@ void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xe0, 0xdc, 0xe8, @@ -1100,7 +1091,7 @@ void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xe8, 0xdc, 0xe0, @@ -1109,7 +1100,7 @@ void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xc0, 0xdc, 0xc0, @@ -1118,7 +1109,7 @@ void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xf0, 0xdc, 0xf8, @@ -1127,7 +1118,7 @@ void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); x87_arith_op(p, dst, src, 0xd8, 0xf8, 0xdc, 0xf0, @@ -1136,7 +1127,7 @@ void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void x87_fmulp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc8+dst.idx); @@ -1144,7 +1135,7 @@ void x87_fmulp( struct x86_function *p, struct x86_reg dst ) void x87_fsubp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe8+dst.idx); @@ -1152,7 +1143,7 @@ void x87_fsubp( struct x86_function *p, struct x86_reg dst ) void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xe0+dst.idx); @@ -1160,7 +1151,7 @@ void x87_fsubrp( struct x86_function *p, struct x86_reg dst ) void x87_faddp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xc0+dst.idx); @@ -1168,7 +1159,7 @@ void x87_faddp( struct x86_function *p, struct x86_reg dst ) void x87_fdivp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf8+dst.idx); @@ -1176,7 +1167,7 @@ void x87_fdivp( struct x86_function *p, struct x86_reg dst ) void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_x87); assert(dst.idx >= 1); emit_2ub(p, 0xde, 0xf0+dst.idx); @@ -1184,83 +1175,83 @@ void x87_fdivrp( struct x86_function *p, struct x86_reg dst ) void x87_fucom( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe0+arg.idx); } void x87_fucomp( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xdd, 0xe8+arg.idx); } void x87_fucompp( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xda, 0xe9); } void x87_fxch( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); assert(arg.file == file_x87); emit_2ub(p, 0xd9, 0xc8+arg.idx); } void x87_fabs( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xe1); } void x87_fchs( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xe0); } void x87_fcos( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xff); } void x87_fprndint( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfc); } void x87_fscale( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfd); } void x87_fsin( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfe); } void x87_fsincos( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfb); } void x87_fsqrt( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xfa); } void x87_fxtract( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf4); } @@ -1270,7 +1261,7 @@ void x87_fxtract( struct x86_function *p ) */ void x87_f2xm1( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf0); } @@ -1279,7 +1270,7 @@ void x87_f2xm1( struct x86_function *p ) */ void x87_fyl2x( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf1); } @@ -1290,14 +1281,14 @@ void x87_fyl2x( struct x86_function *p ) */ void x87_fyl2xp1( struct x86_function *p ) { - DUMP( __FUNCTION__ ); + DUMP(); emit_2ub(p, 0xd9, 0xf9); } void x87_fld( struct x86_function *p, struct x86_reg arg ) { - DUMP_R( __FUNCTION__, arg ); + DUMP_R( arg ); if (arg.file == file_x87) emit_2ub(p, 0xd9, 0xc0 + arg.idx); else { @@ -1308,7 +1299,7 @@ void x87_fld( struct x86_function *p, struct x86_reg arg ) void x87_fst( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd0 + dst.idx); else { @@ -1319,7 +1310,7 @@ void x87_fst( struct x86_function *p, struct x86_reg dst ) void x87_fstp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xdd, 0xd8 + dst.idx); else { @@ -1330,7 +1321,7 @@ void x87_fstp( struct x86_function *p, struct x86_reg dst ) void x87_fcom( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd0 + dst.idx); else { @@ -1341,7 +1332,7 @@ void x87_fcom( struct x86_function *p, struct x86_reg dst ) void x87_fcomp( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); if (dst.file == file_x87) emit_2ub(p, 0xd8, 0xd8 + dst.idx); else { @@ -1353,7 +1344,7 @@ void x87_fcomp( struct x86_function *p, struct x86_reg dst ) void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) { - DUMP_R( __FUNCTION__, dst ); + DUMP_R( dst ); assert(dst.file == file_REG32); if (dst.idx == reg_AX && @@ -1383,7 +1374,7 @@ void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1397,7 +1388,7 @@ void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); assert(dst.file == file_MMX && (src.file == file_MMX || src.mod != mod_REG)); @@ -1411,7 +1402,7 @@ void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6e, 0x7e, dst, src ); @@ -1421,7 +1412,7 @@ void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) { - DUMP_RR( __FUNCTION__, dst, src ); + DUMP_RR( dst, src ); p->need_emms = 1; emit_1ub(p, X86_TWOB); emit_op_modrm( p, 0x6f, 0x7f, dst, src ); @@ -1449,6 +1440,7 @@ void x86_init_func( struct x86_function *p ) p->size = 0; p->store = NULL; p->csr = p->store; + DUMP_START(); } void x86_init_func_size( struct x86_function *p, unsigned code_size ) @@ -1459,6 +1451,7 @@ void x86_init_func_size( struct x86_function *p, unsigned code_size ) p->store = p->error_overflow; } p->csr = p->store; + DUMP_START(); } void x86_release_func( struct x86_function *p ) @@ -1474,6 +1467,7 @@ void x86_release_func( struct x86_function *p ) void (*x86_get_func( struct x86_function *p ))(void) { + DUMP_END(); if (DISASSEM && p->store) debug_printf("disassemble %p %p\n", p->store, p->csr); -- cgit v1.2.3 From 73706deef59c35472d2410411403f30c9603f22f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:48:08 +0100 Subject: rtasm: quieten sse_enabled debug --- src/gallium/auxiliary/rtasm/rtasm_cpu.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c index 175245a9f6..f01e12faa0 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c +++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c @@ -32,7 +32,16 @@ static boolean rtasm_sse_enabled(void) { - return !debug_get_bool_option("GALLIUM_NOSSE", FALSE); + static boolean firsttime = 1; + static boolean enabled; + + /* This gets called quite often at the moment: + */ + if (firsttime) { + enabled = !debug_get_bool_option("GALLIUM_NOSSE", FALSE); + firsttime = FALSE; + } + return enabled; } int rtasm_cpu_has_sse(void) -- cgit v1.2.3 From a945420ae6f96f0d7024f97e37ffd31329865a84 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 19:48:21 +0100 Subject: rtasm: debug some missing funcs --- src/gallium/auxiliary/rtasm/rtasm_x86sse.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c index 10796c540d..3cd45d7dd9 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c +++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c @@ -364,6 +364,7 @@ void x86_jcc( struct x86_function *p, unsigned char *label ) { intptr_t offset = pointer_to_intptr( label ) - (pointer_to_intptr( x86_get_label(p) ) + 2); + DUMP_I(cc); if (offset <= 127 && offset >= -128) { emit_1ub(p, 0x70 + cc); @@ -381,6 +382,7 @@ void x86_jcc( struct x86_function *p, unsigned char *x86_jcc_forward( struct x86_function *p, enum x86_cc cc ) { + DUMP_I(cc); emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, 0); return x86_get_label(p); @@ -1365,6 +1367,7 @@ void x87_fnstsw( struct x86_function *p, struct x86_reg dst ) void mmx_emms( struct x86_function *p ) { + DUMP(); assert(p->need_emms); emit_2ub(p, 0x0f, 0x77); p->need_emms = 0; -- cgit v1.2.3 From fb1c09305ea8cb727514c53a0346d90e78eeb05f Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 15:15:31 -0400 Subject: Use llvm 2.3 (2.2 won't work because of a lot of problems, e.g. lack of constant vectors handling in execution engine) --- src/gallium/auxiliary/gallivm/Makefile | 12 +++--- src/gallium/auxiliary/gallivm/instructions.cpp | 42 +++++++++---------- src/gallium/auxiliary/gallivm/instructions.h | 4 +- src/gallium/auxiliary/gallivm/instructionssoa.cpp | 49 ++++++++++++----------- src/gallium/auxiliary/gallivm/instructionssoa.h | 4 +- src/gallium/auxiliary/gallivm/storage.cpp | 32 +++++++-------- src/gallium/auxiliary/gallivm/storagesoa.cpp | 10 ++--- src/gallium/auxiliary/gallivm/tgsitollvm.cpp | 4 +- 8 files changed, 79 insertions(+), 78 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile index 6bfd187fb3..c3f7bfba93 100644 --- a/src/gallium/auxiliary/gallivm/Makefile +++ b/src/gallium/auxiliary/gallivm/Makefile @@ -65,14 +65,14 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES) gallivm_builtins.cpp: llvm_builtins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin - (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ - rm temp.bin + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin + (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp1.bin gallivmsoabuiltins.cpp: soabuiltins.c - clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp.bin - (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ - rm temp.bin + clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin + (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@ + rm temp2.bin # Emacs tags tags: diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp index b35d6790f7..95a670edaf 100644 --- a/src/gallium/auxiliary/gallivm/instructions.cpp +++ b/src/gallium/auxiliary/gallivm/instructions.cpp @@ -139,12 +139,12 @@ llvm::Value *Instructions::callFSqrt(llvm::Value *val) // predeclare the intrinsic std::vector fsqrtArgs; fsqrtArgs.push_back(Type::FloatTy); - ParamAttrsList *fsqrtPal = 0; + PAListPtr fsqrtPal; FunctionType* fsqrtType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/fsqrtArgs, /*isVarArg=*/false); - m_llvmFSqrt = new Function( + m_llvmFSqrt = Function::Create( /*Type=*/fsqrtType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"llvm.sqrt.f32", m_mod); @@ -196,12 +196,12 @@ llvm::Value *Instructions::callFAbs(llvm::Value *val) // predeclare the intrinsic std::vector fabsArgs; fabsArgs.push_back(Type::FloatTy); - ParamAttrsList *fabsPal = 0; + PAListPtr fabsPal; FunctionType* fabsType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/fabsArgs, /*isVarArg=*/false); - m_llvmFAbs = new Function( + m_llvmFAbs = Function::Create( /*Type=*/fabsType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"fabs", m_mod); @@ -239,12 +239,12 @@ llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2) std::vector powArgs; powArgs.push_back(Type::FloatTy); powArgs.push_back(Type::FloatTy); - ParamAttrsList *powPal = 0; + PAListPtr powPal; FunctionType* powType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/powArgs, /*isVarArg=*/false); - m_llvmPow = new Function( + m_llvmPow = Function::Create( /*Type=*/powType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"llvm.pow.f32", m_mod); @@ -338,12 +338,12 @@ llvm::Value * Instructions::callFloor(llvm::Value *val) // predeclare the intrinsic std::vector floorArgs; floorArgs.push_back(Type::FloatTy); - ParamAttrsList *floorPal = 0; + PAListPtr floorPal; FunctionType* floorType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/floorArgs, /*isVarArg=*/false); - m_llvmFloor = new Function( + m_llvmFloor = Function::Create( /*Type=*/floorType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"floorf", m_mod); @@ -381,12 +381,12 @@ llvm::Value * Instructions::callFLog(llvm::Value *val) // predeclare the intrinsic std::vector flogArgs; flogArgs.push_back(Type::FloatTy); - ParamAttrsList *flogPal = 0; + PAListPtr flogPal; FunctionType* flogType = FunctionType::get( /*Result=*/Type::FloatTy, /*Params=*/flogArgs, /*isVarArg=*/false); - m_llvmFlog = new Function( + m_llvmFlog = Function::Create( /*Type=*/flogType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"logf", m_mod); @@ -509,12 +509,12 @@ void Instructions::printVector(llvm::Value *val) llvm::Function * Instructions::declarePrintf() { std::vector args; - ParamAttrsList *params = 0; + PAListPtr params; FunctionType* funcTy = FunctionType::get( /*Result=*/IntegerType::get(32), /*Params=*/args, /*isVarArg=*/true); - Function* func_printf = new Function( + Function* func_printf = Function::Create( /*Type=*/funcTy, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/"printf", m_mod); @@ -638,8 +638,8 @@ llvm::Value * Instructions::abs(llvm::Value *in) void Instructions::ifop(llvm::Value *in) { - BasicBlock *ifthen = new BasicBlock(name("ifthen"), m_func,0); - BasicBlock *ifend = new BasicBlock(name("ifthenend"), m_func,0); + BasicBlock *ifthen = BasicBlock::Create(name("ifthen"), m_func,0); + BasicBlock *ifend = BasicBlock::Create(name("ifthenend"), m_func,0); //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0); //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0); @@ -665,7 +665,7 @@ llvm::BasicBlock * Instructions::currentBlock() const void Instructions::elseop() { assert(!m_ifStack.empty()); - BasicBlock *ifend = new BasicBlock(name("ifend"), m_func,0); + BasicBlock *ifend = BasicBlock::Create(name("ifend"), m_func,0); m_builder.CreateBr(ifend); m_builder.SetInsertPoint(m_ifStack.top()); currentBlock()->setName(name("ifelse")); @@ -692,8 +692,8 @@ llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, void Instructions::beginLoop() { - BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); - BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); + BasicBlock *begin = BasicBlock::Create(name("loop"), m_func,0); + BasicBlock *end = BasicBlock::Create(name("endloop"), m_func,0); m_builder.CreateBr(begin); Loop loop; @@ -716,7 +716,7 @@ void Instructions::endLoop() void Instructions::brk() { assert(!m_loopStack.empty()); - BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); + BasicBlock *unr = BasicBlock::Create(name("unreachable"), m_func,0); m_builder.CreateBr(m_loopStack.top().end); m_builder.SetInsertPoint(unr); } @@ -765,13 +765,13 @@ llvm::Function * Instructions::declareFunc(int label) args.push_back(vecPtr); args.push_back(vecPtr); args.push_back(vecPtr); - ParamAttrsList *params = 0; + PAListPtr params; FunctionType *funcType = FunctionType::get( /*Result=*/Type::VoidTy, /*Params=*/args, /*isVarArg=*/false); std::string name = createFuncName(label); - Function *func = new Function( + Function *func = Function::Create( /*Type=*/funcType, /*Linkage=*/GlobalValue::ExternalLinkage, /*Name=*/name.c_str(), m_mod); @@ -789,7 +789,7 @@ void Instructions::bgnSub(unsigned label) ptr_INPUT->setName("INPUT"); m_storage->pushArguments(ptr_INPUT); - llvm::BasicBlock *entry = new BasicBlock("entry", func, 0); + llvm::BasicBlock *entry = BasicBlock::Create("entry", func, 0); m_func = func; m_builder.SetInsertPoint(entry); diff --git a/src/gallium/auxiliary/gallivm/instructions.h b/src/gallium/auxiliary/gallivm/instructions.h index 9ebc17dd8e..19ca84ddc6 100644 --- a/src/gallium/auxiliary/gallivm/instructions.h +++ b/src/gallium/auxiliary/gallivm/instructions.h @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -125,7 +125,7 @@ private: llvm::Module *m_mod; llvm::Function *m_func; char m_name[32]; - llvm::LLVMFoldingBuilder m_builder; + llvm::IRBuilder m_builder; int m_idx; llvm::VectorType *m_floatVecType; diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp index 3c16a3692d..f0122802db 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp +++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp @@ -38,6 +38,7 @@ #include #include #include +//#include #include #include @@ -237,32 +238,32 @@ llvm::Value * InstructionsSoa::allocaTemp() std::vector indices; indices.push_back(m_storage->constantInt(0)); indices.push_back(m_storage->constantInt(0)); - GetElementPtrInst *getElem = new GetElementPtrInst(alloca, - indices.begin(), - indices.end(), - name("allocaPtr"), - m_builder.GetInsertBlock()); + GetElementPtrInst *getElem = GetElementPtrInst::Create(alloca, + indices.begin(), + indices.end(), + name("allocaPtr"), + m_builder.GetInsertBlock()); return getElem; } std::vector InstructionsSoa::allocaToResult(llvm::Value *allocaPtr) { - GetElementPtrInst *xElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(0), - name("xPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *yElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(1), - name("yPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *zElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(2), - name("zPtr"), - m_builder.GetInsertBlock()); - GetElementPtrInst *wElemPtr = new GetElementPtrInst(allocaPtr, - m_storage->constantInt(3), - name("wPtr"), - m_builder.GetInsertBlock()); + GetElementPtrInst *xElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(0), + name("xPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *yElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(1), + name("yPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *zElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(2), + name("zPtr"), + m_builder.GetInsertBlock()); + GetElementPtrInst *wElemPtr = GetElementPtrInst::Create(allocaPtr, + m_storage->constantInt(3), + name("wPtr"), + m_builder.GetInsertBlock()); std::vector res(4); res[0] = new LoadInst(xElemPtr, name("xRes"), false, m_builder.GetInsertBlock()); @@ -388,10 +389,10 @@ void InstructionsSoa::injectFunction(llvm::Function *originalFunc, int op) llvm::Function *func = 0; if (originalFunc->isDeclaration()) { std::cout << "function decleration" <getFunctionType(), GlobalValue::ExternalLinkage, - originalFunc->getName(), currentModule()); + func = Function::Create(originalFunc->getFunctionType(), GlobalValue::ExternalLinkage, + originalFunc->getName(), currentModule()); func->setCallingConv(CallingConv::C); - const ParamAttrsList *pal = 0; + const PAListPtr pal; func->setParamAttrs(pal); currentModule()->dump(); } else { diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.h b/src/gallium/auxiliary/gallivm/instructionssoa.h index b9104ea286..060ee72f2e 100644 --- a/src/gallium/auxiliary/gallivm/instructionssoa.h +++ b/src/gallium/auxiliary/gallivm/instructionssoa.h @@ -29,7 +29,7 @@ #define INSTRUCTIONSSOA_H #include -#include +#include #include #include @@ -87,7 +87,7 @@ private: const std::vector in3); void injectFunction(llvm::Function *originalFunc, int op = TGSI_OPCODE_LAST); private: - llvm::LLVMFoldingBuilder m_builder; + llvm::IRBuilder m_builder; StorageSoa *m_storage; std::map m_functionsMap; diff --git a/src/gallium/auxiliary/gallivm/storage.cpp b/src/gallium/auxiliary/gallivm/storage.cpp index c4326de8c5..9d9fd12360 100644 --- a/src/gallium/auxiliary/gallivm/storage.cpp +++ b/src/gallium/auxiliary/gallivm/storage.cpp @@ -186,26 +186,26 @@ llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ) if ((mask & TGSI_WRITEMASK_X)) { llvm::Value *x = new ExtractElementInst(src, unsigned(0), name("x"), m_block); - dst = new InsertElementInst(dst, x, unsigned(0), - name("dstx"), m_block); + dst = InsertElementInst::Create(dst, x, unsigned(0), + name("dstx"), m_block); } if ((mask & TGSI_WRITEMASK_Y)) { llvm::Value *y = new ExtractElementInst(src, unsigned(1), name("y"), m_block); - dst = new InsertElementInst(dst, y, unsigned(1), - name("dsty"), m_block); + dst = InsertElementInst::Create(dst, y, unsigned(1), + name("dsty"), m_block); } if ((mask & TGSI_WRITEMASK_Z)) { llvm::Value *z = new ExtractElementInst(src, unsigned(2), name("z"), m_block); - dst = new InsertElementInst(dst, z, unsigned(2), - name("dstz"), m_block); + dst = InsertElementInst::Create(dst, z, unsigned(2), + name("dstz"), m_block); } if ((mask & TGSI_WRITEMASK_W)) { llvm::Value *w = new ExtractElementInst(src, unsigned(3), name("w"), m_block); - dst = new InsertElementInst(dst, w, unsigned(3), - name("dstw"), m_block); + dst = InsertElementInst::Create(dst, w, unsigned(3), + name("dstw"), m_block); } return dst; } @@ -308,11 +308,11 @@ llvm::Value * Storage::elemPtr(Args arg) std::vector indices; indices.push_back(constantInt(0)); indices.push_back(constantInt(static_cast(arg))); - GetElementPtrInst *getElem = new GetElementPtrInst(m_INPUT, - indices.begin(), - indices.end(), - name("input_ptr"), - m_block); + GetElementPtrInst *getElem = GetElementPtrInst::Create(m_INPUT, + indices.begin(), + indices.end(), + name("input_ptr"), + m_block); return new LoadInst(getElem, name("input_field"), false, m_block); } @@ -322,7 +322,7 @@ llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, GetElementPtrInst *getElem = 0; if (indIdx) { - getElem = new GetElementPtrInst(ptr, + getElem = GetElementPtrInst::Create(ptr, BinaryOperator::create(Instruction::Add, indIdx, constantInt(idx), @@ -331,7 +331,7 @@ llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx, name("field"), m_block); } else { - getElem = new GetElementPtrInst(ptr, + getElem = GetElementPtrInst::Create(ptr, constantInt(idx), name("field"), m_block); @@ -350,7 +350,7 @@ void Storage::setKilElement(llvm::Value *val) std::vector indices; indices.push_back(constantInt(0)); indices.push_back(constantInt(static_cast(KilArg))); - GetElementPtrInst *elem = new GetElementPtrInst(m_INPUT, + GetElementPtrInst *elem = GetElementPtrInst::Create(m_INPUT, indices.begin(), indices.end(), name("kil_ptr"), diff --git a/src/gallium/auxiliary/gallivm/storagesoa.cpp b/src/gallium/auxiliary/gallivm/storagesoa.cpp index bb6fe3d7e1..0e6e68c9d7 100644 --- a/src/gallium/auxiliary/gallivm/storagesoa.cpp +++ b/src/gallium/auxiliary/gallivm/storagesoa.cpp @@ -207,11 +207,11 @@ llvm::Value * StorageSoa::elementPointer(llvm::Value *ptr, llvm::Value *index, indices.push_back(index); indices.push_back(constantInt(channel)); - GetElementPtrInst *getElem = new GetElementPtrInst(ptr, - indices.begin(), - indices.end(), - name("ptr"), - m_block); + GetElementPtrInst *getElem = GetElementPtrInst::Create(ptr, + indices.begin(), + indices.end(), + name("ptr"), + m_block); return getElem; } diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp index ab9e7a06fb..ab8c851f14 100644 --- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp +++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp @@ -1014,7 +1014,7 @@ tgsi_to_llvm(struct gallivm_ir *ir, const struct tgsi_token *tokens) Value *ptr_INPUT = args++; ptr_INPUT->setName("input"); - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0); tgsi_parse_init(&parse, tokens); @@ -1085,7 +1085,7 @@ llvm::Module * tgsi_to_llvmir(struct gallivm_ir *ir, Value *temps = args++; temps->setName("temps"); - BasicBlock *label_entry = new BasicBlock("entry", shader, 0); + BasicBlock *label_entry = BasicBlock::Create("entry", shader, 0); tgsi_parse_init(&parse, tokens); -- cgit v1.2.3 From c2afa182f31ed4a8be01078c2b8bedcd881cd157 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 20:25:06 +0100 Subject: mesa: remove st_cache.c --- src/mesa/state_tracker/st_cache.c | 181 -------------------------------------- 1 file changed, 181 deletions(-) delete mode 100644 src/mesa/state_tracker/st_cache.c diff --git a/src/mesa/state_tracker/st_cache.c b/src/mesa/state_tracker/st_cache.c deleted file mode 100644 index 7ee4fadc37..0000000000 --- a/src/mesa/state_tracker/st_cache.c +++ /dev/null @@ -1,181 +0,0 @@ -/************************************************************************** - * - * 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 - */ - -#include "st_cache.h" - -#include "st_context.h" - -#include "pipe/p_state.h" - -#include "cso_cache/cso_cache.h" -#include "cso_cache/cso_hash.h" - - -/* Those function will either find the state of the given template - * in the cache or they will create a new state from the given - * template, insert it in the cache and return it. - */ - -/* - * If the driver returns 0 from the create method then they will assign - * the data member of the cso to be the template itself. - */ - -const struct cso_blend * st_cached_blend_state(struct st_context *st, - const struct pipe_blend_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); - struct cso_hash_iter iter = cso_find_state_template(st->cache, - hash_key, CSO_BLEND, - (void*)templ); - if (cso_hash_iter_is_null(iter)) { - struct cso_blend *cso = malloc(sizeof(struct cso_blend)); - memcpy(&cso->state, templ, sizeof(struct pipe_blend_state)); - cso->data = st->pipe->create_blend_state(st->pipe, &cso->state); - if (!cso->data) - cso->data = &cso->state; - cso->delete_state = (cso_state_callback)st->pipe->delete_blend_state; - cso->context = st->pipe; - iter = cso_insert_state(st->cache, hash_key, CSO_BLEND, cso); - } - return ((struct cso_blend *)cso_hash_iter_data(iter)); -} - -const struct cso_sampler * -st_cached_sampler_state(struct st_context *st, - const struct pipe_sampler_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); - struct cso_hash_iter iter = cso_find_state_template(st->cache, - hash_key, CSO_SAMPLER, - (void*)templ); - if (cso_hash_iter_is_null(iter)) { - struct cso_sampler *cso = malloc(sizeof(struct cso_sampler)); - memcpy(&cso->state, templ, sizeof(struct pipe_sampler_state)); - cso->data = st->pipe->create_sampler_state(st->pipe, &cso->state); - if (!cso->data) - cso->data = &cso->state; - cso->delete_state = (cso_state_callback)st->pipe->delete_sampler_state; - cso->context = st->pipe; - iter = cso_insert_state(st->cache, hash_key, CSO_SAMPLER, cso); - } - return (struct cso_sampler*)(cso_hash_iter_data(iter)); -} - -const struct cso_depth_stencil_alpha * -st_cached_depth_stencil_alpha_state(struct st_context *st, - const struct pipe_depth_stencil_alpha_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_depth_stencil_alpha_state)); - struct cso_hash_iter iter = cso_find_state_template(st->cache, - hash_key, - CSO_DEPTH_STENCIL_ALPHA, - (void*)templ); - if (cso_hash_iter_is_null(iter)) { - struct cso_depth_stencil_alpha *cso = malloc(sizeof(struct cso_depth_stencil_alpha)); - memcpy(&cso->state, templ, sizeof(struct pipe_depth_stencil_alpha_state)); - cso->data = st->pipe->create_depth_stencil_alpha_state(st->pipe, &cso->state); - if (!cso->data) - cso->data = &cso->state; - cso->delete_state = (cso_state_callback)st->pipe->delete_depth_stencil_alpha_state; - cso->context = st->pipe; - iter = cso_insert_state(st->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); - } - return (struct cso_depth_stencil_alpha*)(cso_hash_iter_data(iter)); -} - -const struct cso_rasterizer* st_cached_rasterizer_state( - struct st_context *st, - const struct pipe_rasterizer_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_rasterizer_state)); - struct cso_hash_iter iter = cso_find_state_template(st->cache, - hash_key, CSO_RASTERIZER, - (void*)templ); - if (cso_hash_iter_is_null(iter)) { - struct cso_rasterizer *cso = malloc(sizeof(struct cso_rasterizer)); - memcpy(&cso->state, templ, sizeof(struct pipe_rasterizer_state)); - cso->data = st->pipe->create_rasterizer_state(st->pipe, &cso->state); - if (!cso->data) - cso->data = &cso->state; - cso->delete_state = (cso_state_callback)st->pipe->delete_rasterizer_state; - cso->context = st->pipe; - iter = cso_insert_state(st->cache, hash_key, CSO_RASTERIZER, cso); - } - return (struct cso_rasterizer*)(cso_hash_iter_data(iter)); -} - -const struct cso_fragment_shader * -st_cached_fs_state(struct st_context *st, - const struct pipe_shader_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_shader_state)); - struct cso_hash_iter iter = cso_find_state_template(st->cache, - hash_key, CSO_FRAGMENT_SHADER, - (void*)templ); - if (cso_hash_iter_is_null(iter)) { - struct cso_fragment_shader *cso = malloc(sizeof(struct cso_fragment_shader)); - memcpy(&cso->state, templ, sizeof(struct pipe_shader_state)); - cso->data = st->pipe->create_fs_state(st->pipe, &cso->state); - if (!cso->data) - cso->data = &cso->state; - cso->delete_state = (cso_state_callback)st->pipe->delete_fs_state; - cso->context = st->pipe; - iter = cso_insert_state(st->cache, hash_key, CSO_FRAGMENT_SHADER, cso); - } - return (struct cso_fragment_shader*)(cso_hash_iter_data(iter)); -} - -const struct cso_vertex_shader * -st_cached_vs_state(struct st_context *st, - const struct pipe_shader_state *templ) -{ - unsigned hash_key = cso_construct_key((void*)templ, - sizeof(struct pipe_shader_state)); - struct cso_hash_iter iter = cso_find_state_template(st->cache, - hash_key, CSO_VERTEX_SHADER, - (void*)templ); - if (cso_hash_iter_is_null(iter)) { - struct cso_vertex_shader *cso = malloc(sizeof(struct cso_vertex_shader)); - memcpy(&cso->state, templ, sizeof(struct pipe_shader_state)); - cso->data = st->pipe->create_vs_state(st->pipe, &cso->state); - if (!cso->data) - cso->data = &cso->state; - cso->delete_state = (cso_state_callback)st->pipe->delete_vs_state; - cso->context = st->pipe; - iter = cso_insert_state(st->cache, hash_key, CSO_VERTEX_SHADER, cso); - } - return (struct cso_vertex_shader*)(cso_hash_iter_data(iter)); -} -- cgit v1.2.3 From 1dc5e56f3e48b629daa18c2d8631c96bda638eb6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 20:25:47 +0100 Subject: cso: provide functions to bind fs/vs handles directly --- src/gallium/auxiliary/cso_cache/cso_context.c | 32 ++++++++++++++++++++------- src/gallium/auxiliary/cso_cache/cso_context.h | 4 ++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 87995c80c3..e6366e7b14 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -422,6 +422,16 @@ void cso_restore_rasterizer(struct cso_context *ctx) } +void cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ) +{ + if (ctx->fragment_shader != handle) { + ctx->fragment_shader = handle; + ctx->pipe->bind_fs_state(ctx->pipe, handle); + } +} + + void cso_set_fragment_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -453,10 +463,7 @@ void cso_set_fragment_shader(struct cso_context *ctx, handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data; } - if (ctx->fragment_shader != handle) { - ctx->fragment_shader = handle; - ctx->pipe->bind_fs_state(ctx->pipe, handle); - } + cso_set_fragment_shader_handle( ctx, handle ); } void cso_save_fragment_shader(struct cso_context *ctx) @@ -476,6 +483,16 @@ void cso_restore_fragment_shader(struct cso_context *ctx) } +void cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ) +{ + if (ctx->vertex_shader != handle) { + ctx->vertex_shader = handle; + ctx->pipe->bind_vs_state(ctx->pipe, handle); + } +} + + void cso_set_vertex_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) @@ -503,12 +520,11 @@ void cso_set_vertex_shader(struct cso_context *ctx, handle = ((struct cso_vertex_shader *)cso_hash_iter_data(iter))->data; } - if (ctx->vertex_shader != handle) { - ctx->vertex_shader = handle; - ctx->pipe->bind_vs_state(ctx->pipe, handle); - } + cso_set_vertex_shader_handle( ctx, handle ); } + + void cso_save_vertex_shader(struct cso_context *ctx) { assert(!ctx->vertex_shader_saved); diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 665e8d9911..945f4881a8 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -96,6 +96,8 @@ void cso_restore_sampler_textures( struct cso_context *cso ); * (eg mesa's internall-generated texenv programs), it will be up to * the state tracker to implement their own specialized caching. */ +void cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ); void cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_fragment_shader(struct cso_context *cso); @@ -103,6 +105,8 @@ void cso_restore_fragment_shader(struct cso_context *cso); +void cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ); void cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_vertex_shader(struct cso_context *cso); -- cgit v1.2.3 From 01dfa6cde157321f565bab949f23f367ed20fa0e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 20:26:19 +0100 Subject: use cso fs/vs handle functions --- src/gallium/auxiliary/util/u_blit.c | 4 ++-- src/gallium/auxiliary/util/u_gen_mipmap.c | 4 ++-- src/mesa/state_tracker/st_atom_shader.c | 4 ++-- src/mesa/state_tracker/st_cb_bitmap.c | 4 ++-- src/mesa/state_tracker/st_cb_clear.c | 4 ++-- src/mesa/state_tracker/st_cb_drawpixels.c | 4 ++-- src/mesa/state_tracker/st_program.h | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index be5e83e834..0938b03820 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -318,8 +318,8 @@ util_blit_pixels(struct blit_state *ctx, cso_set_sampler_textures(ctx->cso, 1, &tex); /* shaders */ - cso_set_fragment_shader(ctx->cso, ctx->fs); - cso_set_vertex_shader(ctx->cso, ctx->vs); + cso_set_fragment_shader_handle(ctx->cso, ctx->fs); + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); /* drawing dest */ memset(&fb, 0, sizeof(fb)); diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index f0c4063b28..9822a25ca6 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -888,8 +888,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); - cso_set_fragment_shader(ctx->cso, ctx->fs); - cso_set_vertex_shader(ctx->cso, ctx->vs); + cso_set_fragment_shader_handle(ctx->cso, ctx->fs); + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); #if 0 cso_set_viewport(ctx->cso, &ctx->viewport); #endif diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index 4a641a4a73..3f5ec71112 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -273,8 +273,8 @@ update_linkage( struct st_context *st ) st->vp = stvp; st->fp = stfp; - cso_set_vertex_shader(st->cso_context, stvp->driver_shader); - cso_set_fragment_shader(st->cso_context, stfp->driver_shader); + cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader); + cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader); st->vertex_result_to_slot = xvp->output_to_slot; } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 1b863143e0..71a848ea54 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -446,10 +446,10 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_set_rasterizer(cso, &st->bitmap.rasterizer); /* fragment shader state: TEX lookup program */ - cso_set_fragment_shader(cso, stfp->driver_shader); + cso_set_fragment_shader_handle(cso, stfp->driver_shader); /* vertex shader state: position + texcoord pass-through */ - cso_set_vertex_shader(cso, st->bitmap.vs); + cso_set_vertex_shader_handle(cso, st->bitmap.vs); /* sampler / texture state */ cso_single_sampler(cso, 0, &st->bitmap.sampler); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index bb27faad21..dac346a06c 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -274,8 +274,8 @@ clear_with_quad(GLcontext *ctx, cso_set_rasterizer(st->cso_context, &st->clear.raster); cso_set_viewport(st->cso_context, &st->clear.viewport); - cso_set_fragment_shader(st->cso_context, st->clear.fs); - cso_set_vertex_shader(st->cso_context, st->clear.vs); + cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); + cso_set_vertex_shader_handle(st->cso_context, st->clear.vs); /* draw quad matching scissor rect (XXX verify coord round-off) */ draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 75261c3350..3921500659 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -545,10 +545,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* fragment shader state: TEX lookup program */ - cso_set_fragment_shader(cso, stfp->driver_shader); + cso_set_fragment_shader_handle(cso, stfp->driver_shader); /* vertex shader state: position + texcoord pass-through */ - cso_set_vertex_shader(cso, stvp->driver_shader); + cso_set_vertex_shader_handle(cso, stvp->driver_shader); /* texture sampling state: */ diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 63d6590540..dced31e88e 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -61,7 +61,7 @@ struct st_fragment_program GLuint input_map[PIPE_MAX_SHADER_INPUTS]; struct pipe_shader_state state; - struct pipe_shader_state *driver_shader; + void *driver_shader; GLuint param_state; @@ -88,7 +88,7 @@ struct st_vertex_program GLuint num_inputs; struct pipe_shader_state state; - struct pipe_shader_state *driver_shader; + void *driver_shader; /** For using our private draw module (glRasterPos) */ struct draw_vertex_shader *draw_shader; -- cgit v1.2.3 From e406ad5912985920a0d796f1ada58b40316590ed Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 21:01:38 +0100 Subject: draw: squash a couple of memory leaks --- src/gallium/auxiliary/draw/draw_pt_fetch.c | 3 +++ src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index c588710b75..f98bce6eac 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -166,6 +166,9 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { + if (fetch->translate) + fetch->translate->release( fetch->translate ); + 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 7735173042..68b2c5b1e3 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -264,6 +264,11 @@ static void fetch_emit_finish( struct draw_pt_middle_end *middle ) static void fetch_emit_destroy( struct draw_pt_middle_end *middle ) { + struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; + + if (feme->translate) + feme->translate->release( feme->translate ); + FREE(middle); } -- cgit v1.2.3 From 9a0e6860d3b4602515f39593ed9af00cee7bb106 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Apr 2008 21:05:11 +0100 Subject: cso: disable not-really-working cso_set_*_shader() funcs --- src/gallium/auxiliary/cso_cache/cso_context.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index e6366e7b14..3840dd2239 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -432,6 +432,9 @@ void cso_set_fragment_shader_handle(struct cso_context *ctx, } +/* Not really working: + */ +#if 0 void cso_set_fragment_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -465,6 +468,7 @@ void cso_set_fragment_shader(struct cso_context *ctx, cso_set_fragment_shader_handle( ctx, handle ); } +#endif void cso_save_fragment_shader(struct cso_context *ctx) { @@ -493,7 +497,9 @@ void cso_set_vertex_shader_handle(struct cso_context *ctx, } - +/* Not really working: + */ +#if 0 void cso_set_vertex_shader(struct cso_context *ctx, const struct pipe_shader_state *templ) { @@ -522,6 +528,7 @@ void cso_set_vertex_shader(struct cso_context *ctx, cso_set_vertex_shader_handle( ctx, handle ); } +#endif -- cgit v1.2.3 From 9fe63929011cd9c4d86ab6525555a3e53423c854 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 15:44:51 -0400 Subject: initial stab at error handling in cso --- src/gallium/auxiliary/cso_cache/cso_context.c | 98 +++++++++++++++++---------- src/gallium/auxiliary/cso_cache/cso_context.h | 34 +++++----- 2 files changed, 80 insertions(+), 52 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 3840dd2239..6040522a46 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -139,8 +139,8 @@ void cso_destroy_context( struct cso_context *ctx ) * the data member of the cso to be the template itself. */ -void cso_set_blend(struct cso_context *ctx, - const struct pipe_blend_state *templ) +enum pipe_error cso_set_blend(struct cso_context *ctx, + const struct pipe_blend_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state)); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, @@ -149,8 +149,9 @@ void cso_set_blend(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_blend *cso = MALLOC(sizeof(struct cso_blend)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; cso->state = *templ; cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state); @@ -168,6 +169,7 @@ void cso_set_blend(struct cso_context *ctx, ctx->blend = handle; ctx->pipe->bind_blend_state(ctx->pipe, handle); } + return PIPE_OK; } void cso_save_blend(struct cso_context *ctx) @@ -187,12 +189,12 @@ void cso_restore_blend(struct cso_context *ctx) -void cso_single_sampler(struct cso_context *ctx, - unsigned idx, - const struct pipe_sampler_state *templ) +enum pipe_error cso_single_sampler(struct cso_context *ctx, + unsigned idx, + const struct pipe_sampler_state *templ) { void *handle = NULL; - + if (templ != NULL) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state)); struct cso_hash_iter iter = cso_find_state_template(ctx->cache, @@ -200,9 +202,10 @@ void cso_single_sampler(struct cso_context *ctx, (void*)templ); if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler)); - + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + cso->state = *templ; cso->data = ctx->pipe->create_sampler_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_sampler_state; @@ -217,11 +220,12 @@ void cso_single_sampler(struct cso_context *ctx, } ctx->samplers[idx] = handle; + return PIPE_OK; } void cso_single_sampler_done( struct cso_context *ctx ) { - unsigned i; + unsigned i; /* find highest non-null sampler */ for (i = PIPE_MAX_SAMPLERS; i > 0; i--) { @@ -232,8 +236,8 @@ void cso_single_sampler_done( struct cso_context *ctx ) ctx->nr_samplers = i; if (ctx->hw.nr_samplers != ctx->nr_samplers || - memcmp(ctx->hw.samplers, - ctx->samplers, + memcmp(ctx->hw.samplers, + ctx->samplers, ctx->nr_samplers * sizeof(void *)) != 0) { memcpy(ctx->hw.samplers, ctx->samplers, ctx->nr_samplers * sizeof(void *)); @@ -243,22 +247,36 @@ void cso_single_sampler_done( struct cso_context *ctx ) } } -void cso_set_samplers( struct cso_context *ctx, - unsigned nr, - const struct pipe_sampler_state **templates ) +/* + * If the function encouters any errors it will return the + * last one. Done to always try to set as many samplers + * as possible. + */ +enum pipe_error cso_set_samplers( struct cso_context *ctx, + unsigned nr, + const struct pipe_sampler_state **templates ) { unsigned i; - + enum pipe_error temp, error = PIPE_OK; + /* TODO: fastpath */ - for (i = 0; i < nr; i++) - cso_single_sampler( ctx, i, templates[i] ); + for (i = 0; i < nr; i++) { + temp = cso_single_sampler( ctx, i, templates[i] ); + if (temp != PIPE_OK) + error = temp; + } + + for ( ; i < ctx->nr_samplers; i++) { + temp = cso_single_sampler( ctx, i, NULL ); + if (temp != PIPE_OK) + error = temp; + } - for ( ; i < ctx->nr_samplers; i++) - cso_single_sampler( ctx, i, NULL ); - cso_single_sampler_done( ctx ); + + return error; } void cso_save_samplers(struct cso_context *ctx) @@ -294,7 +312,7 @@ void cso_set_sampler_textures( struct cso_context *ctx, void cso_save_sampler_textures( struct cso_context *ctx ) { uint i; - + ctx->nr_textures_saved = ctx->nr_textures; for (i = 0; i < ctx->nr_textures; i++) { assert(!ctx->textures_saved[i]); @@ -323,9 +341,8 @@ void cso_restore_sampler_textures( struct cso_context *ctx ) - -void cso_set_depth_stencil_alpha(struct cso_context *ctx, - const struct pipe_depth_stencil_alpha_state *templ) +enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, + const struct pipe_depth_stencil_alpha_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_depth_stencil_alpha_state)); @@ -336,8 +353,9 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, void *handle; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_depth_stencil_alpha *cso = MALLOC(sizeof(struct cso_depth_stencil_alpha)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; cso->state = *templ; cso->data = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &cso->state); @@ -355,6 +373,7 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx, ctx->depth_stencil = handle; ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, handle); } + return PIPE_OK; } void cso_save_depth_stencil_alpha(struct cso_context *ctx) @@ -374,8 +393,8 @@ void cso_restore_depth_stencil_alpha(struct cso_context *ctx) -void cso_set_rasterizer(struct cso_context *ctx, - const struct pipe_rasterizer_state *templ) +enum pipe_error cso_set_rasterizer(struct cso_context *ctx, + const struct pipe_rasterizer_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_rasterizer_state)); @@ -385,8 +404,9 @@ void cso_set_rasterizer(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_rasterizer *cso = MALLOC(sizeof(struct cso_rasterizer)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; cso->state = *templ; cso->data = ctx->pipe->create_rasterizer_state(ctx->pipe, &cso->state); @@ -404,6 +424,7 @@ void cso_set_rasterizer(struct cso_context *ctx, ctx->rasterizer = handle; ctx->pipe->bind_rasterizer_state(ctx->pipe, handle); } + return PIPE_OK; } void cso_save_rasterizer(struct cso_context *ctx) @@ -422,6 +443,7 @@ void cso_restore_rasterizer(struct cso_context *ctx) } +<<<<<<< HEAD:src/gallium/auxiliary/cso_cache/cso_context.c void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ) { @@ -435,8 +457,8 @@ void cso_set_fragment_shader_handle(struct cso_context *ctx, /* Not really working: */ #if 0 -void cso_set_fragment_shader(struct cso_context *ctx, - const struct pipe_shader_state *templ) +enum pipe_error cso_set_fragment_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) { const struct tgsi_token *tokens = templ->tokens; unsigned num_tokens = tgsi_num_tokens(tokens); @@ -449,10 +471,12 @@ void cso_set_fragment_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_fragment_shader *cso = MALLOC(sizeof(struct cso_fragment_shader) + tokens_size); struct tgsi_token *cso_tokens = (struct tgsi_token *)((char *)cso + sizeof(*cso)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + memcpy(cso_tokens, tokens, tokens_size); cso->state.tokens = cso_tokens; cso->data = ctx->pipe->create_fs_state(ctx->pipe, &cso->state); @@ -467,6 +491,7 @@ void cso_set_fragment_shader(struct cso_context *ctx, } cso_set_fragment_shader_handle( ctx, handle ); + return PIPE_OK; } #endif @@ -500,8 +525,8 @@ void cso_set_vertex_shader_handle(struct cso_context *ctx, /* Not really working: */ #if 0 -void cso_set_vertex_shader(struct cso_context *ctx, - const struct pipe_shader_state *templ) +enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, + const struct pipe_shader_state *templ) { unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_shader_state)); @@ -511,9 +536,11 @@ void cso_set_vertex_shader(struct cso_context *ctx, void *handle = NULL; if (cso_hash_iter_is_null(iter)) { - /* FIXME: handle OOM */ struct cso_vertex_shader *cso = MALLOC(sizeof(struct cso_vertex_shader)); + if (!cso) + return PIPE_ERROR_OUT_OF_MEMORY; + cso->state = *templ; cso->data = ctx->pipe->create_vs_state(ctx->pipe, &cso->state); cso->delete_state = (cso_state_callback)ctx->pipe->delete_vs_state; @@ -527,6 +554,7 @@ void cso_set_vertex_shader(struct cso_context *ctx, } cso_set_vertex_shader_handle( ctx, handle ); + return PIPE_OK; } #endif diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 945f4881a8..ab46b93d5a 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -31,6 +31,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "pipe/p_error.h" #ifdef __cplusplus @@ -45,39 +46,39 @@ void cso_destroy_context( struct cso_context *cso ); -void cso_set_blend( struct cso_context *cso, - const struct pipe_blend_state *blend ); +enum pipe_error cso_set_blend( struct cso_context *cso, + const struct pipe_blend_state *blend ); void cso_save_blend(struct cso_context *cso); void cso_restore_blend(struct cso_context *cso); -void cso_set_depth_stencil_alpha( struct cso_context *cso, - const struct pipe_depth_stencil_alpha_state *dsa ); +enum pipe_error cso_set_depth_stencil_alpha( struct cso_context *cso, + const struct pipe_depth_stencil_alpha_state *dsa ); void cso_save_depth_stencil_alpha(struct cso_context *cso); void cso_restore_depth_stencil_alpha(struct cso_context *cso); -void cso_set_rasterizer( struct cso_context *cso, - const struct pipe_rasterizer_state *rasterizer ); +enum pipe_error cso_set_rasterizer( struct cso_context *cso, + const struct pipe_rasterizer_state *rasterizer ); void cso_save_rasterizer(struct cso_context *cso); void cso_restore_rasterizer(struct cso_context *cso); -void cso_set_samplers( struct cso_context *cso, - unsigned count, - const struct pipe_sampler_state **states ); +enum pipe_error cso_set_samplers( struct cso_context *cso, + unsigned count, + const struct pipe_sampler_state **states ); void cso_save_samplers(struct cso_context *cso); void cso_restore_samplers(struct cso_context *cso); /* Alternate interface to support state trackers that like to modify * samplers one at a time: */ -void cso_single_sampler( struct cso_context *cso, - unsigned nr, - const struct pipe_sampler_state *states ); +enum pipe_error cso_single_sampler( struct cso_context *cso, + unsigned nr, + const struct pipe_sampler_state *states ); void cso_single_sampler_done( struct cso_context *cso ); @@ -98,17 +99,16 @@ void cso_restore_sampler_textures( struct cso_context *cso ); */ void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ); -void cso_set_fragment_shader( struct cso_context *cso, - const struct pipe_shader_state *shader ); +enum pipe_error cso_set_fragment_shader( struct cso_context *cso, + const struct pipe_shader_state *shader ); void cso_save_fragment_shader(struct cso_context *cso); void cso_restore_fragment_shader(struct cso_context *cso); - void cso_set_vertex_shader_handle(struct cso_context *ctx, void *handle ); -void cso_set_vertex_shader( struct cso_context *cso, - const struct pipe_shader_state *shader ); +enum pipe_error cso_set_vertex_shader( struct cso_context *cso, + const struct pipe_shader_state *shader ); void cso_save_vertex_shader(struct cso_context *cso); void cso_restore_vertex_shader(struct cso_context *cso); -- cgit v1.2.3 From 0879237725eca893318137b795d4234300a37e9a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 16:04:27 -0400 Subject: handle some of the possible allocation failures within the hash itself --- src/gallium/auxiliary/cso_cache/cso_context.c | 36 ++++++++++++++++++++++++--- src/gallium/auxiliary/cso_cache/cso_hash.c | 17 +++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 6040522a46..364a413580 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -159,6 +159,11 @@ enum pipe_error cso_set_blend(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_BLEND, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -212,6 +217,11 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_SAMPLER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -362,7 +372,12 @@ enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx, cso->delete_state = (cso_state_callback)ctx->pipe->delete_depth_stencil_alpha_state; cso->context = ctx->pipe; - cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); + iter = cso_insert_state(ctx->cache, hash_key, CSO_DEPTH_STENCIL_ALPHA, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -413,7 +428,12 @@ enum pipe_error cso_set_rasterizer(struct cso_context *ctx, cso->delete_state = (cso_state_callback)ctx->pipe->delete_rasterizer_state; cso->context = ctx->pipe; - cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); + iter = cso_insert_state(ctx->cache, hash_key, CSO_RASTERIZER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -442,8 +462,6 @@ void cso_restore_rasterizer(struct cso_context *ctx) ctx->rasterizer_saved = NULL; } - -<<<<<<< HEAD:src/gallium/auxiliary/cso_cache/cso_context.c void cso_set_fragment_shader_handle(struct cso_context *ctx, void *handle ) { @@ -484,6 +502,11 @@ enum pipe_error cso_set_fragment_shader(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_FRAGMENT_SHADER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { @@ -547,6 +570,11 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, cso->context = ctx->pipe; iter = cso_insert_state(ctx->cache, hash_key, CSO_VERTEX_SHADER, cso); + if (cso_hash_iter_is_null(iter)) { + FREE(cso); + return PIPE_ERROR_OUT_OF_MEMORY; + } + handle = cso->data; } else { diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index ddce3822f7..8d867f86d2 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -110,6 +110,10 @@ cso_hash_create_node(struct cso_hash *hash, struct cso_node **anextNode) { struct cso_node *node = cso_data_allocate_node(hash->data.d); + + if (!node) + return NULL; + node->key = akey; node->value = avalue; @@ -219,6 +223,11 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, { struct cso_node **nextNode = cso_hash_find_node(hash, key); struct cso_node *node = cso_hash_create_node(hash, key, data, nextNode); + if (!node) { + struct cso_hash_iter null_iter = {hash, 0}; + return null_iter; + } + struct cso_hash_iter iter = {hash, node}; return iter; } @@ -227,7 +236,15 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, struct cso_hash * cso_hash_create(void) { struct cso_hash *hash = MALLOC_STRUCT(cso_hash); + if (!hash) + return NULL; + hash->data.d = MALLOC_STRUCT(cso_hash_data); + if (!hash->data.d) { + FREE(hash); + return NULL; + } + hash->data.d->fakeNext = 0; hash->data.d->buckets = 0; hash->data.d->size = 0; -- cgit v1.2.3 From ed187d39a6e0fd921b2a45a143d88ac4b66eee91 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 21 Apr 2008 16:40:27 -0400 Subject: make the api consistent (all set functions return pipe_error status) --- src/gallium/auxiliary/cso_cache/cso_context.c | 39 +++++++++++++++------------ src/gallium/auxiliary/cso_cache/cso_context.h | 26 +++++++++--------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 364a413580..2d98a34edf 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -303,9 +303,9 @@ void cso_restore_samplers(struct cso_context *ctx) } -void cso_set_sampler_textures( struct cso_context *ctx, - uint count, - struct pipe_texture **textures ) +enum pipe_error cso_set_sampler_textures( struct cso_context *ctx, + uint count, + struct pipe_texture **textures ) { uint i; @@ -317,6 +317,8 @@ void cso_set_sampler_textures( struct cso_context *ctx, pipe_texture_reference(&ctx->textures[i], NULL); ctx->pipe->set_sampler_textures(ctx->pipe, count, textures); + + return PIPE_OK; } void cso_save_sampler_textures( struct cso_context *ctx ) @@ -462,13 +464,14 @@ void cso_restore_rasterizer(struct cso_context *ctx) ctx->rasterizer_saved = NULL; } -void cso_set_fragment_shader_handle(struct cso_context *ctx, - void *handle ) +enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ) { if (ctx->fragment_shader != handle) { ctx->fragment_shader = handle; ctx->pipe->bind_fs_state(ctx->pipe, handle); } + return PIPE_OK; } @@ -513,8 +516,7 @@ enum pipe_error cso_set_fragment_shader(struct cso_context *ctx, handle = ((struct cso_fragment_shader *)cso_hash_iter_data(iter))->data; } - cso_set_fragment_shader_handle( ctx, handle ); - return PIPE_OK; + return cso_set_fragment_shader_handle( ctx, handle ); } #endif @@ -535,13 +537,14 @@ void cso_restore_fragment_shader(struct cso_context *ctx) } -void cso_set_vertex_shader_handle(struct cso_context *ctx, - void *handle ) +enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ) { if (ctx->vertex_shader != handle) { ctx->vertex_shader = handle; ctx->pipe->bind_vs_state(ctx->pipe, handle); } + return PIPE_OK; } @@ -581,8 +584,7 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx, handle = ((struct cso_vertex_shader *)cso_hash_iter_data(iter))->data; } - cso_set_vertex_shader_handle( ctx, handle ); - return PIPE_OK; + return cso_set_vertex_shader_handle( ctx, handle ); } #endif @@ -606,14 +608,15 @@ void cso_restore_vertex_shader(struct cso_context *ctx) -void cso_set_framebuffer(struct cso_context *ctx, - const struct pipe_framebuffer_state *fb) +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))*/) { ctx->fb = *fb; ctx->pipe->set_framebuffer_state(ctx->pipe, fb); } + return PIPE_OK; } void cso_save_framebuffer(struct cso_context *ctx) @@ -630,13 +633,14 @@ void cso_restore_framebuffer(struct cso_context *ctx) } -void cso_set_viewport(struct cso_context *ctx, - const struct pipe_viewport_state *vp) +enum pipe_error cso_set_viewport(struct cso_context *ctx, + const struct pipe_viewport_state *vp) { if (memcmp(&ctx->vp, vp, sizeof(*vp))) { ctx->vp = *vp; ctx->pipe->set_viewport_state(ctx->pipe, vp); } + return PIPE_OK; } void cso_save_viewport(struct cso_context *ctx) @@ -656,11 +660,12 @@ void cso_restore_viewport(struct cso_context *ctx) -void cso_set_blend_color(struct cso_context *ctx, - const struct pipe_blend_color *bc) +enum pipe_error cso_set_blend_color(struct cso_context *ctx, + const struct pipe_blend_color *bc) { if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) { ctx->blend_color = *bc; ctx->pipe->set_blend_color(ctx->pipe, bc); } + return PIPE_OK; } diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index ab46b93d5a..0405944132 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -84,9 +84,9 @@ void cso_single_sampler_done( struct cso_context *cso ); -void cso_set_sampler_textures( struct cso_context *cso, - uint count, - struct pipe_texture **textures ); +enum pipe_error cso_set_sampler_textures( struct cso_context *cso, + uint count, + struct pipe_texture **textures ); void cso_save_sampler_textures( struct cso_context *cso ); void cso_restore_sampler_textures( struct cso_context *cso ); @@ -97,16 +97,16 @@ void cso_restore_sampler_textures( struct cso_context *cso ); * (eg mesa's internall-generated texenv programs), it will be up to * the state tracker to implement their own specialized caching. */ -void cso_set_fragment_shader_handle(struct cso_context *ctx, - void *handle ); +enum pipe_error cso_set_fragment_shader_handle(struct cso_context *ctx, + void *handle ); enum pipe_error cso_set_fragment_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_fragment_shader(struct cso_context *cso); void cso_restore_fragment_shader(struct cso_context *cso); -void cso_set_vertex_shader_handle(struct cso_context *ctx, - void *handle ); +enum pipe_error cso_set_vertex_shader_handle(struct cso_context *ctx, + void *handle ); enum pipe_error cso_set_vertex_shader( struct cso_context *cso, const struct pipe_shader_state *shader ); void cso_save_vertex_shader(struct cso_context *cso); @@ -114,20 +114,20 @@ void cso_restore_vertex_shader(struct cso_context *cso); -void cso_set_framebuffer(struct cso_context *cso, - const struct pipe_framebuffer_state *fb); +enum pipe_error cso_set_framebuffer(struct cso_context *cso, + const struct pipe_framebuffer_state *fb); void cso_save_framebuffer(struct cso_context *cso); void cso_restore_framebuffer(struct cso_context *cso); -void cso_set_viewport(struct cso_context *cso, - const struct pipe_viewport_state *vp); +enum pipe_error cso_set_viewport(struct cso_context *cso, + const struct pipe_viewport_state *vp); void cso_save_viewport(struct cso_context *cso); void cso_restore_viewport(struct cso_context *cso); -void cso_set_blend_color(struct cso_context *cso, - const struct pipe_blend_color *bc); +enum pipe_error cso_set_blend_color(struct cso_context *cso, + const struct pipe_blend_color *bc); #ifdef __cplusplus -- cgit v1.2.3 From 83fec372b45eb0af9e2d83549b3d92afb17c38af Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Tue, 22 Apr 2008 11:26:26 +0200 Subject: cso: Fix build on Win32. --- src/gallium/auxiliary/cso_cache/cso_hash.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_hash.c b/src/gallium/auxiliary/cso_cache/cso_hash.c index 8d867f86d2..0646efd952 100644 --- a/src/gallium/auxiliary/cso_cache/cso_hash.c +++ b/src/gallium/auxiliary/cso_cache/cso_hash.c @@ -228,8 +228,10 @@ struct cso_hash_iter cso_hash_insert(struct cso_hash *hash, return null_iter; } - struct cso_hash_iter iter = {hash, node}; - return iter; + { + struct cso_hash_iter iter = {hash, node}; + return iter; + } } } -- cgit v1.2.3 From 09b668615852eb28cb6289baf84faaf3b6ccc3c2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 10:57:06 +0100 Subject: softpipe: make NUM_ENTRIES 32 so that div/mods are easier --- src/gallium/drivers/softpipe/sp_tile_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c index 19f71887e7..edafd93d8b 100644 --- a/src/gallium/drivers/softpipe/sp_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tile_cache.c @@ -39,7 +39,7 @@ #include "sp_surface.h" #include "sp_tile_cache.h" -#define NUM_ENTRIES 30 +#define NUM_ENTRIES 32 /** XXX move these */ -- cgit v1.2.3 From a5b87f249ef79b1a8d8b9dbe72879b7ac9eb133c Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:01:41 +0100 Subject: softpipe: implement SP_NO_RAST env var --- src/gallium/drivers/softpipe/sp_clear.c | 3 +++ src/gallium/drivers/softpipe/sp_context.c | 3 +++ src/gallium/drivers/softpipe/sp_context.h | 2 ++ src/gallium/drivers/softpipe/sp_setup.c | 10 ++++++++++ 4 files changed, 18 insertions(+) diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c index 39aed151c7..1236706891 100644 --- a/src/gallium/drivers/softpipe/sp_clear.c +++ b/src/gallium/drivers/softpipe/sp_clear.c @@ -49,6 +49,9 @@ softpipe_clear(struct pipe_context *pipe, struct pipe_surface *ps, struct softpipe_context *softpipe = softpipe_context(pipe); uint i; + if (softpipe->no_rast) + return; + #if 0 softpipe_update_derived(softpipe); /* not needed?? */ #endif diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 8c84ddbe19..200fb415ac 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -219,6 +219,9 @@ softpipe_create( struct pipe_screen *screen, assert(softpipe->draw); softpipe->setup = sp_draw_render_stage(softpipe); + if (GETENV( "SP_NO_RAST" ) != NULL) + softpipe->no_rast = TRUE; + if (GETENV( "SP_VBUF" ) != NULL) { sp_init_vbuf(softpipe); } diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 0e1d5e561d..b3e2b2e435 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -86,6 +86,8 @@ struct softpipe_context { unsigned num_vertex_elements; unsigned num_vertex_buffers; + boolean no_rast; + /* Counter for occlusion queries. Note this supports overlapping * queries. */ diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 813d703108..0bf2b2dc3e 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -726,6 +726,9 @@ void setup_tri( struct setup_context *setup, { float det = calc_det(v0, v1, v2); + if (setup->softpipe->no_rast) + return; + /* debug_printf("%s\n", __FUNCTION__ ); */ @@ -934,6 +937,9 @@ setup_line(struct setup_context *setup, int dy = y1 - y0; int xstep, ystep; + if (setup->softpipe->no_rast) + return; + if (dx == 0 && dy == 0) return; @@ -1052,6 +1058,10 @@ setup_point( struct setup_context *setup, const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; + + if (softpipe->no_rast) + return; + /* For points, all interpolants are constant-valued. * However, for point sprites, we'll need to setup texcoords appropriately. * XXX: which coefficients are the texcoords??? -- cgit v1.2.3 From d07ed9216cc7033fecb5bce661bbaf79189bb391 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:01:56 +0100 Subject: xlib: implement SP_NO_RAST env var --- src/gallium/winsys/xlib/xm_winsys.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 9a20bdfb69..5a424d0ac7 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -84,6 +84,7 @@ struct xmesa_surface struct pipe_surface surface; int tileSize; + boolean no_swap; }; @@ -252,6 +253,9 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf) const struct xmesa_surface *xm_surf = xmesa_surface((struct pipe_surface *) surf); + if (xm_surf->no_swap) + return; + if (xm_surf->tileSize) { xmesa_display_surface_tiled(b, surf); return; @@ -529,6 +533,13 @@ static struct pipe_surface * xm_surface_alloc(struct pipe_winsys *ws) { struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface); + static boolean no_swap = 0; + static boolean firsttime = 1; + + if (firsttime) { + no_swap = getenv("SP_NO_RAST") != NULL; + firsttime = 0; + } assert(ws); @@ -540,7 +551,9 @@ xm_surface_alloc(struct pipe_winsys *ws) xms->tileSize = 32; /** probably temporary */ } #endif - + + xms->no_swap = no_swap; + return &xms->surface; } -- cgit v1.2.3 From 6a9f6625b38c3669769568d122958993f4a8d5b3 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:15:51 +0100 Subject: xlib: shortcircuit no-op makecurrent --- src/gallium/winsys/xlib/fakeglx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gallium/winsys/xlib/fakeglx.c b/src/gallium/winsys/xlib/fakeglx.c index 902a755075..6e04cb4117 100644 --- a/src/gallium/winsys/xlib/fakeglx.c +++ b/src/gallium/winsys/xlib/fakeglx.c @@ -1504,6 +1504,13 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, #endif } + if (MakeCurrent_PrevContext == ctx && + MakeCurrent_PrevDrawable == draw && + MakeCurrent_PrevReadable == read && + MakeCurrent_PrevDrawBuffer == drawBuffer && + MakeCurrent_PrevReadBuffer == readBuffer) + return True; + MakeCurrent_PrevContext = ctx; MakeCurrent_PrevDrawable = draw; MakeCurrent_PrevReadable = read; -- cgit v1.2.3 From 57987ea67320e79e4c2d7e66388806148ece09b5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 11:26:07 +0100 Subject: draw: disable broken edgeflag code - didn't work & was killing performance --- src/gallium/auxiliary/draw/draw_pt_vcache.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 3cc2941f96..153055417d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -106,7 +106,7 @@ static unsigned add_edgeflag( struct vcache_frontend *vcache, unsigned idx, unsigned mask ) { - if (mask && draw_pt_get_edgeflag(vcache->draw, idx)) + if (0 && mask && draw_pt_get_edgeflag(vcache->draw, idx)) return idx | DRAW_PT_EDGEFLAG; else return idx; @@ -116,7 +116,7 @@ static unsigned add_edgeflag( struct vcache_frontend *vcache, static unsigned add_reset_stipple( unsigned idx, unsigned reset ) { - if (reset) + if (0 && reset) return idx | DRAW_PT_RESET_STIPPLE; else return idx; @@ -128,9 +128,9 @@ static void vcache_triangle( struct vcache_frontend *vcache, unsigned i1, unsigned i2 ) { - vcache_elt(vcache, i0 | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE); - vcache_elt(vcache, i1 | DRAW_PT_EDGEFLAG); - vcache_elt(vcache, i2 | DRAW_PT_EDGEFLAG); + vcache_elt(vcache, i0 /* | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE */ ); + vcache_elt(vcache, i1 /* | DRAW_PT_EDGEFLAG */); + vcache_elt(vcache, i2 /* | DRAW_PT_EDGEFLAG */); vcache_check_flush(vcache); } @@ -142,11 +142,12 @@ static void vcache_ef_triangle( struct vcache_frontend *vcache, unsigned i1, unsigned i2 ) { +/* i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 ); i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 ); i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 ); - i0 = add_reset_stipple( i0, reset_stipple ); +*/ vcache_elt(vcache, i0); vcache_elt(vcache, i1); -- cgit v1.2.3 From b4b3a73bdf68adc1d9fbadac913aa6cf60d648d5 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Tue, 22 Apr 2008 19:47:02 +0900 Subject: pipebuffer: Temporarily allow simultaneous CPU writes. Also, fast path for re-fencing the same buffer multiple times with the same fence. --- src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 65b6584003..27032b0c4c 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -215,15 +215,21 @@ 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 */ + /* 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; @@ -353,6 +359,16 @@ buffer_fence(struct pb_buffer *buf, /* FIXME: receive this as a parameter */ unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0; + if(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; + } + if(fenced_buffer_serialize(fenced_buf, flags) != PIPE_OK) { /* FIXME: propagate error */ (void)0; -- cgit v1.2.3 From 57b85e197b33d39063d431500016dffcce46ab7c Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Tue, 22 Apr 2008 12:18:31 +0100 Subject: gallium: Don't link x86sse.c into libmesa.a. Otherwise we get a symbol clash with the copy in src/gallium/util . --- src/mesa/SConscript | 1 - src/mesa/sources | 1 - 2 files changed, 2 deletions(-) diff --git a/src/mesa/SConscript b/src/mesa/SConscript index a10c34c8c5..80fbdb41f0 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -222,7 +222,6 @@ ASM_C_SOURCES = [ 'x86/x86.c', 'x86/3dnow.c', 'x86/sse.c', - 'x86/rtasm/x86sse.c', 'sparc/sparc.c', 'ppc/common_ppc.c', 'x86-64/x86-64.c', diff --git a/src/mesa/sources b/src/mesa/sources index a4e2026e4b..5c7ff50cc6 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -245,7 +245,6 @@ ASM_C_SOURCES = \ x86/x86.c \ x86/3dnow.c \ x86/sse.c \ - x86/rtasm/x86sse.c \ sparc/sparc.c \ ppc/common_ppc.c \ x86-64/x86-64.c -- cgit v1.2.3 From fd4acd6fdaaad4871327d081f5501680ed9da2ed Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Tue, 22 Apr 2008 14:22:11 +0100 Subject: gallium: How about restoring shaders instead of saving them again... --- src/mesa/state_tracker/st_cb_bitmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 71a848ea54..701d1e397e 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -490,8 +490,8 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_restore_samplers(cso); cso_restore_sampler_textures(cso); cso_restore_viewport(cso); - cso_save_fragment_shader(cso); - cso_save_vertex_shader(cso); + cso_restore_fragment_shader(cso); + cso_restore_vertex_shader(cso); } -- cgit v1.2.3 From f9b1d47d652778012fd35552ffc51717ac0b6f79 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 15:15:21 +0100 Subject: softpipe: do something sensible on an error path, squash warning --- src/gallium/drivers/softpipe/sp_tex_sample.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 34da6356d7..5b63f97997 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -651,7 +651,9 @@ shadow_compare(uint compare_func, k = 0; break; default: + k = 0; assert(0); + break; } rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k; -- cgit v1.2.3 From 88f8eed3c4430505b1436b6c5b0114d34c33f822 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 15:26:38 +0100 Subject: cso: fix vs/fs confusion --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 2d98a34edf..23b1f5a032 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -600,7 +600,7 @@ void cso_restore_vertex_shader(struct cso_context *ctx) { assert(ctx->vertex_shader_saved); if (ctx->vertex_shader_saved != ctx->vertex_shader) { - ctx->pipe->bind_fs_state(ctx->pipe, ctx->vertex_shader_saved); + ctx->pipe->bind_vs_state(ctx->pipe, ctx->vertex_shader_saved); ctx->vertex_shader = ctx->vertex_shader_saved; } ctx->vertex_shader_saved = NULL; -- cgit v1.2.3 From 1f0f029ba6f22ef4ada01fcdc153da91571a7963 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 20:32:22 +0100 Subject: softpipe: squash warning --- src/gallium/drivers/softpipe/sp_state_fs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 2921066ce3..525cea9eed 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -82,7 +82,6 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { - struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; assert(fs != softpipe->fs); -- cgit v1.2.3 From 0588858702d1a5c9c08573ea6817e2e149473cf6 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 20:50:20 +0100 Subject: draw: allow drivers to query pipeline state more easily Also, provide a separate flag to say whether the driver can handle clipping/rhw tasks, in addition to the API flag which indicates they have already been done. --- src/gallium/auxiliary/draw/draw_context.c | 13 ++++++++++ src/gallium/auxiliary/draw/draw_context.h | 12 +++++++++ src/gallium/auxiliary/draw/draw_pipe_validate.c | 30 ++++++++++++---------- src/gallium/auxiliary/draw/draw_private.h | 7 +++-- src/gallium/auxiliary/draw/draw_pt.c | 6 +++-- .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 2 +- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 11 +++++--- 7 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b4dbdccd61..b916b27877 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -122,6 +122,19 @@ void draw_set_rasterizer_state( struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->rasterizer = raster; + draw->bypass_clipping = (draw->rasterizer->bypass_clipping || + draw->driver.bypass_clipping); +} + + +void draw_set_driver_clipping( struct draw_context *draw, + boolean bypass_clipping ) +{ + draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + + draw->driver.bypass_clipping = bypass_clipping; + draw->bypass_clipping = (draw->rasterizer->bypass_clipping || + draw->driver.bypass_clipping); } diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 2742001698..c5c3d3b09e 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -148,4 +148,16 @@ struct vbuf_render; void draw_set_render( struct draw_context *draw, struct vbuf_render *render ); +void draw_set_driver_clipping( struct draw_context *draw, + boolean bypass_clipping ); + +/******************************************************************************* + * Draw pipeline + */ +boolean draw_need_pipeline(const struct draw_context *draw, + const struct pipe_rasterizer_state *rasterizer, + unsigned prim ); + + + #endif /* DRAW_CONTEXT_H */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c index a2e0812c89..6be1d369c3 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_validate.c +++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c @@ -32,6 +32,7 @@ #include "pipe/p_defines.h" #include "draw_private.h" #include "draw_pipe.h" +#include "draw_context.h" static boolean points( unsigned prim ) { @@ -57,7 +58,8 @@ static boolean triangles( unsigned prim ) * pipeline stages. */ boolean -draw_need_pipeline(const struct draw_context *draw, +draw_need_pipeline(const struct draw_context *draw, + const struct pipe_rasterizer_state *rasterizer, unsigned int prim ) { /* Don't have to worry about triangles turning into lines/points @@ -67,30 +69,30 @@ draw_need_pipeline(const struct draw_context *draw, if (lines(prim)) { /* line stipple */ - if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) + if (rasterizer->line_stipple_enable && draw->pipeline.line_stipple) return TRUE; /* wide lines */ - if (draw->rasterizer->line_width > draw->pipeline.wide_line_threshold) + if (rasterizer->line_width > draw->pipeline.wide_line_threshold) return TRUE; /* AA lines */ - if (draw->rasterizer->line_smooth && draw->pipeline.aaline) + if (rasterizer->line_smooth && draw->pipeline.aaline) return TRUE; } if (points(prim)) { /* large points */ - if (draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) + if (rasterizer->point_size > draw->pipeline.wide_point_threshold) return TRUE; /* AA points */ - if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) + if (rasterizer->point_smooth && draw->pipeline.aapoint) return TRUE; /* point sprites */ - if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite) + if (rasterizer->point_sprite && draw->pipeline.point_sprite) return TRUE; } @@ -98,20 +100,20 @@ draw_need_pipeline(const struct draw_context *draw, if (triangles(prim)) { /* polygon stipple */ - if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple) + if (rasterizer->poly_stipple_enable && draw->pipeline.pstipple) return TRUE; /* unfilled polygons */ - if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || - draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) + if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || + rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) return TRUE; /* polygon offset */ - if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw) + if (rasterizer->offset_cw || rasterizer->offset_ccw) return TRUE; /* two-side lighting */ - if (draw->rasterizer->light_twoside) + if (rasterizer->light_twoside) return TRUE; } @@ -120,7 +122,7 @@ draw_need_pipeline(const struct draw_context *draw, * * Generally this isn't a reason to require the pipeline, though. * - if (draw->rasterizer->cull_mode) + if (rasterizer->cull_mode) return TRUE; */ @@ -239,7 +241,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) /* Clip stage */ - if (!draw->rasterizer->bypass_clipping) + if (!draw->bypass_clipping) { draw->pipeline.clip->next = next; next = draw->pipeline.clip; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index da973e868b..83b81f66a0 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -174,7 +174,12 @@ struct draw_context } pt; + struct { + boolean bypass_clipping; + } driver; + boolean flushing; + boolean bypass_clipping; /* set if either api or driver bypass_clipping true */ /* pipe state that we need: */ const struct pipe_rasterizer_state *rasterizer; @@ -243,8 +248,6 @@ void draw_pipeline_run( struct draw_context *draw, void draw_pipeline_flush( struct draw_context *draw, unsigned flags ); -boolean draw_need_pipeline(const struct draw_context *draw, - unsigned prim ); /******************************************************************************* diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 9f8e8d3d62..f5a3bf390e 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -58,11 +58,13 @@ draw_pt_arrays(struct draw_context *draw, opt |= PT_PIPELINE; } - if (draw_need_pipeline(draw, prim)) { + if (draw_need_pipeline(draw, + draw->rasterizer, + prim)) { opt |= PT_PIPELINE; } - if (!draw->rasterizer->bypass_clipping) { + if (!draw->bypass_clipping) { opt |= PT_CLIPTEST; } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 98a2cb45e4..f0763dad8d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -81,7 +81,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, * but gl vs dx9 clip spaces. */ draw_pt_post_vs_prepare( fpme->post_vs, - draw->rasterizer->bypass_clipping, + draw->bypass_clipping, draw->identity_viewport, draw->rasterizer->gl_rasterization_rules ); diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index 581f044dae..e5e38fa264 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -94,8 +94,10 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, struct vertex_header *out = vertices; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; + boolean clipped = FALSE; unsigned j; - unsigned clipped = 0; + + if (0) debug_printf("%s\n"); for (j = 0; j < count; j++) { out->clip[0] = out->data[0][0]; @@ -108,10 +110,11 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, out->clipmask = compute_clipmask_gl(out->clip, pvs->draw->plane, pvs->draw->nr_planes); - clipped += out->clipmask; if (out->clipmask == 0) { + clipped = TRUE; + /* divide by w */ float w = 1.0f / out->data[0][3]; @@ -142,7 +145,7 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs, const float *trans = pvs->draw->viewport.translate; unsigned j; - debug_printf("%s\n", __FUNCTION__); + if (0) debug_printf("%s\n", __FUNCTION__); for (j = 0; j < count; j++) { /* Viewport mapping only, no cliptest/rhw divide */ @@ -165,7 +168,7 @@ static boolean post_vs_none( struct pt_post_vs *pvs, unsigned count, unsigned stride ) { - debug_printf("%s\n", __FUNCTION__); + if (0) debug_printf("%s\n", __FUNCTION__); return FALSE; } -- cgit v1.2.3 From 4ebede8c7f43a83adfc73dcca783de2e9efcd9ba Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 22 Apr 2008 21:17:21 +0100 Subject: Revert "softpipe: squash warning" This reverts commit 1f0f029ba6f22ef4ada01fcdc153da91571a7963. Which broke the debug build. --- src/gallium/drivers/softpipe/sp_state_fs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 525cea9eed..2921066ce3 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -82,6 +82,7 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs) void softpipe_delete_fs_state(struct pipe_context *pipe, void *fs) { + struct softpipe_context *softpipe = softpipe_context(pipe); struct sp_fragment_shader *state = fs; assert(fs != softpipe->fs); -- cgit v1.2.3 From b456f1374fc958e53efc80ee38ef343f580c1d6b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 14:41:32 -0600 Subject: gallium: st_translate_fragment_program() is void now The return value was never used. --- src/mesa/state_tracker/st_program.c | 5 +---- src/mesa/state_tracker/st_program.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 4d1ef1bf3d..3648ded8a1 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -315,7 +315,7 @@ st_translate_vertex_program(struct st_context *st, * \param tokensOut destination for TGSI tokens * \return pointer to cached pipe_shader object. */ -const struct cso_fragment_shader * +void st_translate_fragment_program(struct st_context *st, struct st_fragment_program *stfp, const GLuint inputMapping[]) @@ -325,7 +325,6 @@ st_translate_fragment_program(struct st_context *st, GLuint outputMapping[FRAG_RESULT_MAX]; GLuint defaultInputMapping[FRAG_ATTRIB_MAX]; struct pipe_shader_state fs; - const struct cso_fragment_shader *cso; GLuint interpMode[16]; /* XXX size? */ GLuint attr; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; @@ -475,7 +474,5 @@ st_translate_fragment_program(struct st_context *st, if (TGSI_DEBUG) tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ ); - - return cso; } diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index dced31e88e..e58b8a1851 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -111,7 +111,7 @@ st_vertex_program( struct gl_vertex_program *vp ) } -extern const struct cso_fragment_shader * +extern void st_translate_fragment_program(struct st_context *st, struct st_fragment_program *fp, const GLuint inputMapping[]); -- cgit v1.2.3 From 8f4f89c04383b2100f6d856270cad62dfe8a6354 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 14:42:36 -0600 Subject: gallium: remove assertions It's possible the current vs/fs is null when cso_save_vertex/fragment_shader() is called. --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 23b1f5a032..0523cb1949 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -528,7 +528,6 @@ void cso_save_fragment_shader(struct cso_context *ctx) void cso_restore_fragment_shader(struct cso_context *ctx) { - assert(ctx->fragment_shader_saved); if (ctx->fragment_shader_saved != ctx->fragment_shader) { ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved); ctx->fragment_shader = ctx->fragment_shader_saved; @@ -598,7 +597,6 @@ void cso_save_vertex_shader(struct cso_context *ctx) void cso_restore_vertex_shader(struct cso_context *ctx) { - assert(ctx->vertex_shader_saved); if (ctx->vertex_shader_saved != ctx->vertex_shader) { ctx->pipe->bind_vs_state(ctx->pipe, ctx->vertex_shader_saved); ctx->vertex_shader = ctx->vertex_shader_saved; -- cgit v1.2.3 From 465bc9473a0122d8f66ac1b4a69459e9bd889799 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:15:49 -0600 Subject: gallium: move the vertex print/debug code --- src/gallium/drivers/softpipe/sp_setup.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 0bf2b2dc3e..7df8fc5f67 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -299,13 +299,6 @@ static boolean setup_sort_vertices( struct setup_context *setup, const float (*v1)[4], const float (*v2)[4] ) { -#if DEBUG_VERTS - debug_printf("Triangle:\n"); - print_vertex(setup, v0); - print_vertex(setup, v1); - print_vertex(setup, v2); -#endif - setup->vprovoke = v2; /* determine bottom to top order of vertices */ @@ -738,7 +731,12 @@ void setup_tri( struct setup_context *setup, setup->numFragsWritten = 0; #endif - +#if DEBUG_VERTS + debug_printf("Triangle:\n"); + print_vertex(setup, v0); + print_vertex(setup, v1); + print_vertex(setup, v2); +#endif if (cull_tri( setup, det )) return; -- cgit v1.2.3 From aaa43218f34fc9897b280d6cf9bc1a31bbb7dafc Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:22:21 -0600 Subject: gallium: setup an identity viewport --- src/gallium/auxiliary/util/u_gen_mipmap.c | 35 +++++-------------------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 9822a25ca6..ff5881b979 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -61,6 +61,7 @@ struct gen_mipmap_state struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; + struct pipe_viewport_state viewport; struct pipe_shader_state vert_shader; struct pipe_shader_state frag_shader; @@ -723,9 +724,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; ctx->sampler.normalized_coords = 1; - -#if 0 - /* viewport */ + /* viewport state (identity, verts are in wincoords) */ ctx->viewport.scale[0] = 1.0; ctx->viewport.scale[1] = 1.0; ctx->viewport.scale[2] = 1.0; @@ -734,7 +733,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->viewport.translate[1] = 0.0; ctx->viewport.translate[2] = 0.0; ctx->viewport.translate[3] = 0.0; -#endif /* vertex shader */ { @@ -825,26 +823,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) } -#if 0 -static void -simple_viewport(struct pipe_context *pipe, uint width, uint height) -{ - struct pipe_viewport_state vp; - - vp.scale[0] = 0.5 * width; - vp.scale[1] = -0.5 * height; - vp.scale[2] = 1.0; - vp.scale[3] = 1.0; - vp.translate[0] = 0.5 * width; - vp.translate[1] = 0.5 * height; - vp.translate[2] = 0.0; - vp.translate[3] = 0.0; - - pipe->set_viewport_state(pipe, &vp); -} -#endif - - /** * Generate mipmap images. It's assumed all needed texture memory is * already allocated. @@ -882,17 +860,16 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); + cso_save_viewport(ctx->cso); /* bind our state */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + cso_set_viewport(ctx->cso, &ctx->viewport); cso_set_fragment_shader_handle(ctx->cso, ctx->fs); cso_set_vertex_shader_handle(ctx->cso, ctx->vs); -#if 0 - cso_set_viewport(ctx->cso, &ctx->viewport); -#endif /* init framebuffer state */ memset(&fb, 0, sizeof(fb)); @@ -928,9 +905,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, ctx->sampler.lod_bias = (float) srcLevel; cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); -#if 0 - simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]); -#endif cso_set_sampler_textures(ctx->cso, 1, &pt); @@ -958,4 +932,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); + cso_restore_viewport(ctx->cso); } -- cgit v1.2.3 From 0939a986a8a7dbb8d30c505fcaad8d2718a6527d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:25:55 -0600 Subject: gallium: update comment about bypass clipping/viewport --- src/gallium/auxiliary/util/u_gen_mipmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index ff5881b979..dfdb5f16fe 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -713,7 +713,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; - ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + ctx->rasterizer.bypass_clipping = 1; /*ctx->rasterizer.bypass_vs = 1;*/ /* sampler state */ -- cgit v1.2.3 From 22cbf6a70437dfa12c10600e5a496ea5771cfc56 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 16:29:48 -0600 Subject: gallium: setup an identity viewport This fixes broken blits. --- src/gallium/auxiliary/util/u_blit.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 0938b03820..1105066cb8 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -57,6 +57,7 @@ struct blit_state struct pipe_depth_stencil_alpha_state depthstencil; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; + struct pipe_viewport_state viewport; struct pipe_shader_state vert_shader; struct pipe_shader_state frag_shader; @@ -100,7 +101,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; - ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */ + ctx->rasterizer.bypass_clipping = 1; /*ctx->rasterizer.bypass_vs = 1;*/ /* samplers */ @@ -113,8 +114,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) ctx->sampler.mag_img_filter = 0; /* set later */ ctx->sampler.normalized_coords = 1; -#if 0 - /* viewport */ + /* viewport (identity, we setup vertices in wincoords) */ ctx->viewport.scale[0] = 1.0; ctx->viewport.scale[1] = 1.0; ctx->viewport.scale[2] = 1.0; @@ -123,7 +123,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) ctx->viewport.translate[1] = 0.0; ctx->viewport.translate[2] = 0.0; ctx->viewport.translate[3] = 0.0; -#endif /* vertex shader */ { @@ -302,11 +301,13 @@ util_blit_pixels(struct blit_state *ctx, cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); + cso_save_viewport(ctx->cso); /* set misc state we care about */ cso_set_blend(ctx->cso, &ctx->blend); cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil); cso_set_rasterizer(ctx->cso, &ctx->rasterizer); + cso_set_viewport(ctx->cso, &ctx->viewport); /* sampler */ ctx->sampler.min_img_filter = filter; @@ -348,6 +349,7 @@ util_blit_pixels(struct blit_state *ctx, cso_restore_framebuffer(ctx->cso); cso_restore_fragment_shader(ctx->cso); cso_restore_vertex_shader(ctx->cso); + cso_restore_viewport(ctx->cso); /* free the texture */ pipe_surface_reference(&texSurf, NULL); -- cgit v1.2.3 From 500c41b8ba3ad025c69e63a2c74da90674a8037d Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:11:58 -0400 Subject: Fix reporting of clipped vertices. --- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c index e5e38fa264..f98e130ed6 100644 --- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c +++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c @@ -94,7 +94,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, struct vertex_header *out = vertices; const float *scale = pvs->draw->viewport.scale; const float *trans = pvs->draw->viewport.translate; - boolean clipped = FALSE; + unsigned clipped = 0; unsigned j; if (0) debug_printf("%s\n"); @@ -110,11 +110,10 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs, out->clipmask = compute_clipmask_gl(out->clip, pvs->draw->plane, pvs->draw->nr_planes); + clipped += out->clipmask; if (out->clipmask == 0) { - clipped = TRUE; - /* divide by w */ float w = 1.0f / out->data[0][3]; -- cgit v1.2.3 From f088b53769aacbee20135d912c33d688b6002011 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:20:34 -0400 Subject: Cache translate's structs for emits and fetches. Results in a fair speed improvement. --- src/gallium/auxiliary/draw/draw_pt_emit.c | 63 ++++++++++++++++++++++++++--- src/gallium/auxiliary/draw/draw_pt_fetch.c | 65 ++++++++++++++++++++++++++---- 2 files changed, 114 insertions(+), 14 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 490da4cca3..d35329aba0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -33,13 +33,66 @@ #include "draw/draw_pt.h" #include "translate/translate.h" +#include "cso_cache/cso_cache.h" +#include "cso_cache/cso_hash.h" struct pt_emit { struct draw_context *draw; struct translate *translate; + + struct cso_hash *hash; }; +static INLINE unsigned translate_hash_key_size(struct translate_key *key) +{ + unsigned size = sizeof(struct translate_key) - + sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); + return size; +} + +static INLINE unsigned create_key(struct translate_key *key) +{ + unsigned hash_key; + unsigned size = translate_hash_key_size(key); + /*debug_printf("key size = %d, (els = %d)\n", + size, key->nr_elements);*/ + hash_key = cso_construct_key(key, size); + return hash_key; +} + +static struct translate *cached_translate(struct pt_emit *emit, + struct translate_key *key) +{ + unsigned hash_key = create_key(key); + struct cso_hash_iter iter = cso_hash_find(emit->hash, hash_key); + struct translate *translate = 0; + + if (cso_hash_iter_is_null(iter)) { + translate = translate_create(key); + cso_hash_insert(emit->hash, hash_key, translate); + /*debug_printf("\tCREATED with %d\n", hash_key);*/ + } else { + translate = cso_hash_iter_data(iter); + /*debug_printf("\tOK with %d\n", hash_key);*/ + } + + return translate; +} + + +static INLINE void delete_translates(struct pt_emit *emit) +{ + struct cso_hash *hash = emit->hash; + struct cso_hash_iter iter = cso_hash_first_node(hash); + while (!cso_hash_iter_is_null(iter)) { + struct translate *state = (struct translate*)cso_hash_iter_data(iter); + iter = cso_hash_iter_next(iter); + if (state) { + state->release(state); + } + } +} void draw_pt_emit_prepare( struct pt_emit *emit, unsigned prim ) @@ -123,10 +176,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit, if (!emit->translate || memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) { - if (emit->translate) - emit->translate->release(emit->translate); - - emit->translate = translate_create( &hw_key ); + emit->translate = cached_translate(emit, &hw_key); } } @@ -188,14 +238,15 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) return NULL; emit->draw = draw; + emit->hash = cso_hash_create(); return emit; } void draw_pt_emit_destroy( struct pt_emit *emit ) { - if (emit->translate) - emit->translate->release( emit->translate ); + delete_translates(emit); + cso_hash_delete(emit->hash); FREE(emit); } diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c index f98bce6eac..93da811ed8 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c @@ -33,16 +33,67 @@ #include "draw/draw_pt.h" #include "translate/translate.h" +#include "cso_cache/cso_cache.h" +#include "cso_cache/cso_hash.h" struct pt_fetch { struct draw_context *draw; struct translate *translate; - + unsigned vertex_size; + + struct cso_hash *hash; }; +static INLINE unsigned translate_hash_key_size(struct translate_key *key) +{ + unsigned size = sizeof(struct translate_key) - + sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); + return size; +} + +static INLINE unsigned create_key(struct translate_key *key) +{ + unsigned hash_key; + unsigned size = translate_hash_key_size(key); + /*debug_printf("key size = %d, (els = %d)\n", + size, key->nr_elements);*/ + hash_key = cso_construct_key(key, size); + return hash_key; +} + +static struct translate *cached_translate(struct pt_fetch *fetch, + struct translate_key *key) +{ + unsigned hash_key = create_key(key); + struct cso_hash_iter iter = cso_hash_find(fetch->hash, hash_key); + struct translate *translate = 0; + + if (cso_hash_iter_is_null(iter)) { + translate = translate_create(key); + cso_hash_insert(fetch->hash, hash_key, translate); + /*debug_printf("\tCREATED with %d\n", hash_key);*/ + } else { + translate = cso_hash_iter_data(iter); + /*debug_printf("\tOK with %d\n", hash_key);*/ + } + + return translate; +} +static INLINE void delete_translates(struct pt_fetch *fetch) +{ + struct cso_hash *hash = fetch->hash; + struct cso_hash_iter iter = cso_hash_first_node(hash); + while (!cso_hash_iter_is_null(iter)) { + struct translate *state = (struct translate*)cso_hash_iter_data(iter); + iter = cso_hash_iter_next(iter); + if (state) { + state->release(state); + } + } +} /* Perform the fetch from API vertex elements & vertex buffers, to a * contiguous set of float[4] attributes as required for the @@ -112,10 +163,7 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch, if (!fetch->translate || memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) { - if (fetch->translate) - fetch->translate->release(fetch->translate); - - fetch->translate = translate_create( &key ); + fetch->translate = cached_translate(fetch, &key); { static struct vertex_header vh = { 0, 0, 0, 0xffff }; @@ -159,15 +207,16 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch); if (!fetch) return NULL; - + fetch->draw = draw; + fetch->hash = cso_hash_create(); return fetch; } void draw_pt_fetch_destroy( struct pt_fetch *fetch ) { - if (fetch->translate) - fetch->translate->release( fetch->translate ); + delete_translates(fetch); + cso_hash_delete(fetch->hash); FREE(fetch); } -- cgit v1.2.3 From d8f2e400cfe6e32e82d1656d3483905343124b97 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:30:31 -0400 Subject: Fix a crash. Rasterizer can be null --- src/gallium/auxiliary/draw/draw_context.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b916b27877..db92a53ed2 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -122,8 +122,9 @@ void draw_set_rasterizer_state( struct draw_context *draw, draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); draw->rasterizer = raster; - draw->bypass_clipping = (draw->rasterizer->bypass_clipping || - draw->driver.bypass_clipping); + draw->bypass_clipping = + ((draw->rasterizer && draw->rasterizer->bypass_clipping) || + draw->driver.bypass_clipping); } -- cgit v1.2.3 From 36feb5eacf16467d06d5cd9f63d19f17f933f1ef Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Tue, 22 Apr 2008 18:32:29 -0400 Subject: In case the 'func' is deleting the state move the iterator before calling it. --- src/gallium/auxiliary/cso_cache/cso_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c index f607528fdc..63464e0705 100644 --- a/src/gallium/auxiliary/cso_cache/cso_cache.c +++ b/src/gallium/auxiliary/cso_cache/cso_cache.c @@ -334,10 +334,10 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type, iter = cso_hash_first_node(hash); while (!cso_hash_iter_is_null(iter)) { void *state = cso_hash_iter_data(iter); + iter = cso_hash_iter_next(iter); if (state) { func(state, user_data); } - iter = cso_hash_iter_next(iter); } } -- cgit v1.2.3 From 1977fbff6010af0a5bd0bba7c0367b7713185a92 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 18:38:13 -0600 Subject: gallium: don't set buffer status to undefined in display_front_buffer() --- src/mesa/state_tracker/st_cb_flush.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index 1b3402cee2..5e866b0d41 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -67,7 +67,9 @@ display_front_buffer(struct st_context *st) st->pipe->winsys->flush_frontbuffer( st->pipe->winsys, front_surf, st->pipe->priv ); + /* st->frontbuffer_status = FRONT_STATUS_UNDEFINED; + */ } -- cgit v1.2.3 From 33f3938d2d6340b31d758c96bd35f858c6c8267d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 18:38:37 -0600 Subject: gallium: fix some bitmap frag shader issues If texturing happens to be enabled when glBitmap() is called, need to be careful about choosing a sampler unit, etc. --- src/mesa/state_tracker/st_cb_bitmap.c | 85 +++++++++++++++++++++------------- src/mesa/state_tracker/st_cb_program.c | 4 ++ src/mesa/state_tracker/st_context.h | 3 -- src/mesa/state_tracker/st_program.h | 4 ++ 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 701d1e397e..7752b40e8b 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -105,7 +105,7 @@ struct bitmap_cache * This program will be combined with the user's fragment program. */ static struct st_fragment_program * -make_bitmap_fragment_program(GLcontext *ctx) +make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex) { struct st_fragment_program *stfp; struct gl_program *p; @@ -130,7 +130,7 @@ make_bitmap_fragment_program(GLcontext *ctx) p->Instructions[ic].DstReg.Index = 0; p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT; p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0; - p->Instructions[ic].TexSrcUnit = 0; + p->Instructions[ic].TexSrcUnit = samplerIndex; p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; ic++; @@ -148,7 +148,7 @@ make_bitmap_fragment_program(GLcontext *ctx) p->InputsRead = FRAG_BIT_TEX0; p->OutputsWritten = 0x0; - p->SamplersUsed = 0x1; /* sampler 0 (bit 0) is used */ + p->SamplersUsed = (1 << samplerIndex); stfp = (struct st_fragment_program *) p; stfp->Base.UsesKill = GL_TRUE; @@ -158,6 +158,19 @@ make_bitmap_fragment_program(GLcontext *ctx) } +static int +find_free_bit(uint bitfield) +{ + int i; + for (i = 0; i < 32; i++) { + if ((bitfield & (1 << i)) == 0) { + return i; + } + } + return -1; +} + + /** * Combine basic bitmap fragment program with the user-defined program. */ @@ -165,28 +178,26 @@ static struct st_fragment_program * combined_bitmap_fragment_program(GLcontext *ctx) { struct st_context *st = ctx->st; - struct st_fragment_program *stfp; - - if (!st->bitmap.program) { - /* create the basic bitmap fragment program */ - st->bitmap.program = make_bitmap_fragment_program(ctx); - } + struct st_fragment_program *stfp = st->fp; - if (st->bitmap.user_prog_sn == st->fp->serialNo) { - /* re-use */ - stfp = st->bitmap.combined_prog; - } - else { - /* Concatenate the bitmap program with the current user-defined program. + if (!stfp->bitmap_program) { + /* + * Generate new program which is the user-defined program prefixed + * with the bitmap sampler/kill instructions. */ - stfp = (struct st_fragment_program *) - _mesa_combine_programs(ctx, - &st->bitmap.program->Base.Base, - &st->fp->Base.Base); + struct st_fragment_program *bitmap_prog; + uint sampler; + sampler = find_free_bit(st->fp->Base.Base.SamplersUsed); + bitmap_prog = make_bitmap_fragment_program(ctx, sampler); + + stfp->bitmap_program = (struct st_fragment_program *) + _mesa_combine_programs(ctx, + &bitmap_prog->Base.Base, &stfp->Base.Base); + stfp->bitmap_program->bitmap_sampler = sampler; #if 0 { - struct gl_program *p = &stfp->Base.Base; + struct gl_program *p = &stfp->bitmap_program->Base.Base; printf("Combined bitmap program:\n"); _mesa_print_program(p); printf("InputsRead: 0x%x\n", p->InputsRead); @@ -196,11 +207,7 @@ combined_bitmap_fragment_program(GLcontext *ctx) #endif /* translate to TGSI tokens */ - st_translate_fragment_program(st, stfp, NULL); - - /* save new program, update serial numbers */ - st->bitmap.user_prog_sn = st->fp->serialNo; - st->bitmap.combined_prog = stfp; + st_translate_fragment_program(st, stfp->bitmap_program, NULL); } /* Ideally we'd have updated the pipe constants during the normal @@ -208,7 +215,7 @@ combined_bitmap_fragment_program(GLcontext *ctx) */ st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT); - return stfp; + return stfp->bitmap_program; } @@ -451,10 +458,25 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, /* vertex shader state: position + texcoord pass-through */ cso_set_vertex_shader_handle(cso, st->bitmap.vs); - /* sampler / texture state */ - cso_single_sampler(cso, 0, &st->bitmap.sampler); - cso_single_sampler_done(cso); - pipe->set_sampler_textures(pipe, 1, &pt); + /* user samplers, plus our bitmap sampler */ + { + struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; + uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_samplers); + uint i; + for (i = 0; i < st->state.num_samplers; i++) { + samplers[i] = &st->state.samplers[i]; + } + samplers[stfp->bitmap_sampler] = &st->bitmap.sampler; + cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers); } + + /* user textures, plus the bitmap texture */ + { + struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; + uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_textures); + memcpy(textures, st->state.sampler_texture, sizeof(textures)); + textures[stfp->bitmap_sampler] = pt; + cso_set_sampler_textures(cso, num, textures); + } /* viewport state: viewport matching window dims */ { @@ -771,6 +793,7 @@ st_destroy_bitmap(struct st_context *st) { struct pipe_context *pipe = st->pipe; +#if 0 if (st->bitmap.combined_prog) { st_delete_program(st->ctx, &st->bitmap.combined_prog->Base.Base); } @@ -778,7 +801,7 @@ st_destroy_bitmap(struct st_context *st) if (st->bitmap.program) { st_delete_program(st->ctx, &st->bitmap.program->Base.Base); } - +#endif if (st->bitmap.vs) { pipe->delete_vs_state(pipe, st->bitmap.vs); st->bitmap.vs = NULL; diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 003ec0d2b7..67f8b1f8eb 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -159,6 +159,10 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) stfp->state.tokens = NULL; } + if (stfp->bitmap_program) { + st_delete_program(ctx, &stfp->bitmap_program->Base.Base); + } + st_free_translated_vertex_programs(st, stfp->vertex_programs); } break; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index ae1ba41d4f..2851770d4c 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -144,9 +144,6 @@ struct st_context /** for glBitmap */ struct { - struct st_fragment_program *program; /**< bitmap tex/kil program */ - GLuint user_prog_sn; /**< user fragment program serial no. */ - struct st_fragment_program *combined_prog; struct pipe_rasterizer_state rasterizer; struct pipe_sampler_state sampler; struct pipe_shader_state vert_shader; diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index e58b8a1851..1a2062131d 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -69,6 +69,10 @@ struct st_fragment_program * outputs match this fragment program's inputs. */ struct translated_vertex_program *vertex_programs; + + /** Program prefixed with glBitmap prologue */ + struct st_fragment_program *bitmap_program; + uint bitmap_sampler; }; -- cgit v1.2.3 From 91e37b71404a83b5e4258e129a2753f7c8fd0706 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 19:10:52 -0600 Subject: gallium: fix bad logic in bind_pstip_fragment_shader(): use &&, not || --- src/gallium/auxiliary/draw/draw_pipe_pstipple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index 61bdd29aa0..aec485a6e7 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -469,7 +469,7 @@ pstip_create_sampler(struct pstip_stage *pstip) static boolean bind_pstip_fragment_shader(struct pstip_stage *pstip) { - if (!pstip->fs->pstip_fs || + if (!pstip->fs->pstip_fs && !generate_pstip_fs(pstip)) return FALSE; -- cgit v1.2.3 From 72fd5b9c5a78792ad8c1fe7c8713a3583008c50a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Apr 2008 19:11:59 -0600 Subject: gallium: added a flushing_vcache flag, test in draw_do_flush() Fixes broken polygon stipple, aaline, aapoint stages --- src/gallium/auxiliary/draw/draw_context.c | 2 +- src/gallium/auxiliary/draw/draw_private.h | 1 + src/gallium/auxiliary/draw/draw_pt_vcache.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index db92a53ed2..f90187816b 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -367,7 +367,7 @@ draw_set_mapped_element_buffer( struct draw_context *draw, */ void draw_do_flush( struct draw_context *draw, unsigned flags ) { - if (!draw->flushing) + if (!draw->flushing && !draw->vcache_flushing) { draw->flushing = TRUE; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 83b81f66a0..39aa81b43c 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -179,6 +179,7 @@ struct draw_context } driver; boolean flushing; + boolean vcache_flushing; boolean bypass_clipping; /* set if either api or driver bypass_clipping true */ /* pipe state that we need: */ diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 153055417d..afcff41043 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -63,6 +63,7 @@ struct vcache_frontend { static void vcache_flush( struct vcache_frontend *vcache ) { + vcache->draw->vcache_flushing = TRUE; if (vcache->draw_count) { vcache->middle->run( vcache->middle, vcache->fetch_elts, @@ -74,6 +75,7 @@ static void vcache_flush( struct vcache_frontend *vcache ) memset(vcache->in, ~0, sizeof(vcache->in)); vcache->fetch_count = 0; vcache->draw_count = 0; + vcache->draw->vcache_flushing = FALSE; } static void vcache_check_flush( struct vcache_frontend *vcache ) -- cgit v1.2.3 From 6fc530ccda2971a5d99a955ad90ae9762238040f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 23 Apr 2008 12:38:37 +1000 Subject: fix non-i386 builds --- src/gallium/auxiliary/translate/translate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c index 86ebeae2a7..b04bc6eefd 100644 --- a/src/gallium/auxiliary/translate/translate.c +++ b/src/gallium/auxiliary/translate/translate.c @@ -38,9 +38,11 @@ struct translate *translate_create( const struct translate_key *key ) { struct translate *translate = NULL; +#if defined(__i386__) || defined(__386__) || defined(i386) translate = translate_sse2_create( key ); if (translate) return translate; +#endif return translate_generic_create( key ); } -- cgit v1.2.3