From 7b971a50088caeeb2d66d99dbf6bef580a01c5d9 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 16 May 2007 15:14:20 -0700 Subject: WIP: Replace TTM buffer pool manager with a simplified interface. The interface is not solid yet (some simplification to do still, and adjustment for 0-copy), and the drivers are not converted. However, the new interface allows using the same calls to support either a TTM or a classic static allocation backend, with the static backend allowing a more limited feature set. --- src/mesa/drivers/dri/Makefile.template | 3 +- src/mesa/drivers/dri/common/dri_bufmgr.c | 506 ++------------- src/mesa/drivers/dri/common/dri_bufmgr.h | 203 ++++-- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 871 ++++++++++++++++++++++++++ src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 356 +++++++++++ src/mesa/drivers/dri/common/dri_bufpool.h | 86 --- src/mesa/drivers/dri/common/dri_drmpool.c | 227 ------- 7 files changed, 1455 insertions(+), 797 deletions(-) create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr_fake.c create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr_ttm.c delete mode 100644 src/mesa/drivers/dri/common/dri_bufpool.h delete mode 100644 src/mesa/drivers/dri/common/dri_drmpool.c (limited to 'src') diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 5261a4b55d..3d0389c60c 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -13,7 +13,8 @@ COMMON_SOURCES = \ COMMON_BM_SOURCES = \ ../common/dri_bufmgr.c \ - ../common/dri_drmpool.c + ../common/dri_bufmgr_ttm.c \ + ../common/dri_bufmgr_fake.c ifeq ($(WINDOW_SYSTEM),dri) diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index 65d6545965..fc2d4a0665 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -1,493 +1,123 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * All Rights Reserved. - * +/* + * Copyright © 2007 Intel Corporation + * * 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: - * + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS 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. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - * Keith Whitwell */ -#include -#include -#include "glthread.h" -#include "errno.h" +#include "mtypes.h" #include "dri_bufmgr.h" -#include "string.h" -#include "imports.h" -#include "dri_bufpool.h" -_glthread_DECLARE_STATIC_MUTEX(bmMutex); - -/* - * TODO: Introduce fence pools in the same way as - * buffer object pools. +/** @file dri_bufmgr.c + * + * Convenience functions for buffer management methods. */ - - -typedef struct _DriFenceObject -{ - int fd; - _glthread_Mutex mutex; - int refCount; - const char *name; - drmFence fence; -} DriFenceObject; - -typedef struct _DriBufferObject -{ - DriBufferPool *pool; - _glthread_Mutex mutex; - int refCount; - const char *name; - unsigned flags; - unsigned hint; - unsigned alignment; - void *private; -} DriBufferObject; - - -void -bmError(int val, const char *file, const char *function, int line) -{ - _mesa_printf("Fatal video memory manager error \"%s\".\n" - "Check kernel logs or set the LIBGL_DEBUG\n" - "environment variable to \"verbose\" for more info.\n" - "Detected in file %s, line %d, function %s.\n", - strerror(-val), file, line, function); -#ifndef NDEBUG - abort(); -#else - abort(); -#endif -} - -DriFenceObject * -driFenceBuffers(int fd, char *name, unsigned flags) -{ - DriFenceObject *fence = (DriFenceObject *) malloc(sizeof(*fence)); - int ret; - - if (!fence) - BM_CKFATAL(-EINVAL); - - _glthread_LOCK_MUTEX(bmMutex); - fence->refCount = 1; - fence->name = name; - fence->fd = fd; - _glthread_INIT_MUTEX(fence->mutex); - ret = drmFenceBuffers(fd, flags, &fence->fence); - _glthread_UNLOCK_MUTEX(bmMutex); - if (ret) { - free(fence); - BM_CKFATAL(ret); - } - return fence; -} - - -unsigned -driFenceType(DriFenceObject * fence) +dri_bo * +dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, + unsigned int alignment, unsigned int flags, unsigned int hint) { - unsigned ret; - - _glthread_LOCK_MUTEX(bmMutex); - ret = fence->fence.flags; - _glthread_UNLOCK_MUTEX(bmMutex); - - return ret; + return bufmgr->bo_alloc(bufmgr, name, size, alignment, flags, hint); } - -DriFenceObject * -driFenceReference(DriFenceObject * fence) +dri_bo * +dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, + unsigned long size, void *virtual, unsigned int flags, + unsigned int hint) { - _glthread_LOCK_MUTEX(bmMutex); - ++fence->refCount; - _glthread_UNLOCK_MUTEX(bmMutex); - return fence; + return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual, + flags, hint); } void -driFenceUnReference(DriFenceObject * fence) +dri_bo_reference(dri_bo *bo) { - if (!fence) - return; - - _glthread_LOCK_MUTEX(bmMutex); - if (--fence->refCount == 0) { - drmFenceDestroy(fence->fd, &fence->fence); - free(fence); - } - _glthread_UNLOCK_MUTEX(bmMutex); + bo->bufmgr->bo_reference(bo); } void -driFenceFinish(DriFenceObject * fence, unsigned type, int lazy) +dri_bo_unreference(dri_bo *bo) { - int ret; - unsigned flags = (lazy) ? DRM_FENCE_FLAG_WAIT_LAZY : 0; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = drmFenceWait(fence->fd, flags, &fence->fence, type); - _glthread_UNLOCK_MUTEX(fence->mutex); - BM_CKFATAL(ret); + bo->bufmgr->bo_unreference(bo); } int -driFenceSignaled(DriFenceObject * fence, unsigned type) +dri_bo_map(dri_bo *buf, GLboolean write_enable) { - int signaled; - int ret; - - if (fence == NULL) - return GL_TRUE; - - _glthread_LOCK_MUTEX(fence->mutex); - ret = drmFenceSignaled(fence->fd, &fence->fence, type, &signaled); - _glthread_UNLOCK_MUTEX(fence->mutex); - BM_CKFATAL(ret); - return signaled; -} - - -extern drmBO * -driBOKernel(struct _DriBufferObject *buf) -{ - drmBO *ret; - - assert(buf->private != NULL); - ret = buf->pool->kernel(buf->pool, buf->private); - if (!ret) - BM_CKFATAL(-EINVAL); - - return ret; -} - -void -driBOWaitIdle(struct _DriBufferObject *buf, int lazy) -{ - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, lazy)); - _glthread_UNLOCK_MUTEX(buf->mutex); + return buf->bufmgr->bo_map(buf, write_enable); } -void * -driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) -{ - void *virtual; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, flags, hint, &virtual)); - _glthread_UNLOCK_MUTEX(buf->mutex); - return virtual; -} - -void -driBOUnmap(struct _DriBufferObject *buf) -{ - assert(buf->private != NULL); - - buf->pool->unmap(buf->pool, buf->private); -} - -unsigned long -driBOOffset(struct _DriBufferObject *buf) -{ - unsigned long ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->offset(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -unsigned -driBOFlags(struct _DriBufferObject *buf) -{ - unsigned ret; - - assert(buf->private != NULL); - - _glthread_LOCK_MUTEX(buf->mutex); - ret = buf->pool->flags(buf->pool, buf->private); - _glthread_UNLOCK_MUTEX(buf->mutex); - return ret; -} - -struct _DriBufferObject * -driBOReference(struct _DriBufferObject *buf) -{ - _glthread_LOCK_MUTEX(bmMutex); - if (++buf->refCount == 1) { - BM_CKFATAL(-EINVAL); - } - _glthread_UNLOCK_MUTEX(bmMutex); - return buf; -} - -void -driBOUnReference(struct _DriBufferObject *buf) -{ - int tmp; - - if (!buf) - return; - - _glthread_LOCK_MUTEX(bmMutex); - tmp = --buf->refCount; - _glthread_UNLOCK_MUTEX(bmMutex); - if (!tmp) { - buf->pool->destroy(buf->pool, buf->private); - free(buf); - } -} - -void -driBOData(struct _DriBufferObject *buf, - unsigned size, const void *data, unsigned flags) -{ - void *virtual; - int newBuffer; - struct _DriBufferPool *pool; - - _glthread_LOCK_MUTEX(buf->mutex); - pool = buf->pool; - if (!pool->create) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "driBOData called on invalid buffer\n"); - BM_CKFATAL(-EINVAL); - } - newBuffer = !buf->private || (pool->size(pool, buf->private) < size) || - pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &virtual); - - if (newBuffer) { - if (buf->private) - pool->destroy(pool, buf->private); - if (!flags) - flags = buf->flags; - buf->private = pool->create(pool, size, flags, 0, buf->alignment); - if (!buf->private) - BM_CKFATAL(-ENOMEM); - BM_CKFATAL(pool->map(pool, buf->private, - DRM_BO_FLAG_WRITE, - DRM_BO_HINT_DONT_BLOCK, &virtual)); - } - - if (data != NULL) - memcpy(virtual, data, size); - - BM_CKFATAL(pool->unmap(pool, buf->private)); - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, const void *data) -{ - void *virtual; - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_WRITE, 0, &virtual)); - memcpy((unsigned char *) virtual + offset, data, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, void *data) -{ - void *virtual; - - _glthread_LOCK_MUTEX(buf->mutex); - if (size && data) { - BM_CKFATAL(buf->pool->map(buf->pool, buf->private, - DRM_BO_FLAG_READ, 0, &virtual)); - memcpy(data, (unsigned char *) virtual + offset, size); - BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - -void -driBOSetStatic(struct _DriBufferObject *buf, - unsigned long offset, - unsigned long size, void *virtual, unsigned flags) -{ - _glthread_LOCK_MUTEX(buf->mutex); - if (buf->private != NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer for setStatic\n"); - BM_CKFATAL(-EINVAL); - } - if (buf->pool->setstatic == NULL) { - _mesa_error(NULL, GL_INVALID_OPERATION, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-EINVAL); - } - - if (!flags) - flags = buf->flags; - - buf->private = buf->pool->setstatic(buf->pool, offset, size, - virtual, flags); - if (!buf->private) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, - "Invalid buffer pool for setStatic\n"); - BM_CKFATAL(-ENOMEM); - } - _glthread_UNLOCK_MUTEX(buf->mutex); -} - - - -void -driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, unsigned flags, unsigned hint) +int +dri_bo_unmap(dri_bo *buf) { - struct _DriBufferObject *buf; - int i; - - flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | - DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; - - - for (i = 0; i < n; ++i) { - buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); - if (!buf) - BM_CKFATAL(-ENOMEM); - - _glthread_INIT_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(bmMutex); - buf->refCount = 1; - _glthread_UNLOCK_MUTEX(bmMutex); - buf->flags = flags; - buf->hint = hint; - buf->name = name; - buf->alignment = alignment; - buf->pool = pool; - _glthread_UNLOCK_MUTEX(buf->mutex); - buffers[i] = buf; - } + return buf->bufmgr->bo_unmap(buf); } -void -driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) -{ - int i; - - for (i = 0; i < n; ++i) { - driBOUnReference(buffers[i]); - } -} - - -void -driInitBufMgr(int fd) +int +dri_bo_validate(dri_bo *buf, unsigned int flags) { - ; + return buf->bufmgr->bo_validate(buf, flags); } - -void -driBOCreateList(int target, drmBOList * list) +dri_fence * +dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed) { - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmBOCreateList(target, list)); - _glthread_UNLOCK_MUTEX(bmMutex); + return bufmgr->fence_validated(bufmgr, name, flushed); } void -driBOResetList(drmBOList * list) +dri_fence_reference(dri_fence *fence) { - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmBOResetList(list)); - _glthread_UNLOCK_MUTEX(bmMutex); + fence->bufmgr->fence_reference(fence); } void -driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, - unsigned flags, unsigned mask) +dri_fence_unreference(dri_fence *fence) { - int newItem; - - _glthread_LOCK_MUTEX(buf->mutex); - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmAddValidateItem(list, driBOKernel(buf), - flags, mask, &newItem)); - _glthread_UNLOCK_MUTEX(bmMutex); - - /* - * Tell userspace pools to validate the buffer. This should be a - * noop if the pool is already validated. - * FIXME: We should have a list for this as well. - */ - - if (buf->pool->validate) { - BM_CKFATAL(buf->pool->validate(buf->pool, buf->private)); - } - - _glthread_UNLOCK_MUTEX(buf->mutex); + fence->bufmgr->fence_unreference(fence); } void -driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +dri_bo_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, const void *data) { - _glthread_LOCK_MUTEX(buf->mutex); - BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); - _glthread_UNLOCK_MUTEX(buf->mutex); + if (size == 0 || data == NULL) + return; + dri_bo_map(bo, GL_TRUE); + memcpy((unsigned char *)bo->virtual + offset, data, size); + dri_bo_unmap(bo); } -void -driBOValidateList(int fd, drmBOList * list) -{ - _glthread_LOCK_MUTEX(bmMutex); - BM_CKFATAL(drmBOValidateList(fd, list)); - _glthread_UNLOCK_MUTEX(bmMutex); -} void -driPoolTakeDown(struct _DriBufferPool *pool) +dri_bo_get_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, void *data) { - pool->takeDown(pool); + if (size == 0 || data == NULL) + return; + dri_bo_map(bo, GL_FALSE); + memcpy(data, (unsigned char *)bo->virtual + offset, size); + dri_bo_unmap(bo); } diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 01f149ae4e..eafee88b88 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -1,5 +1,6 @@ /************************************************************************** * + * Copyright © 2007 Intel Corporation * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA * All Rights Reserved. * @@ -28,43 +29,142 @@ /* * Authors: Thomas Hellström * Keith Whitwell + * Eric Anholt */ #ifndef _DRI_BUFMGR_H_ #define _DRI_BUFMGR_H_ #include +typedef struct _dri_bufmgr dri_bufmgr; +typedef struct _dri_bo dri_bo; +typedef struct _dri_fence dri_fence; -struct _DriFenceObject; -struct _DriBufferObject; -struct _DriBufferPool; +struct _dri_bo { + /** Size in bytes of the buffer object. */ + unsigned long size; + /** + * Card virtual address (offset from the beginning of the aperture) for the + * object. Only valid while validated. + */ + unsigned long offset; + /** + * Virtual address for accessing the buffer data. Only valid while mapped. + */ + void *virtual; + /** Buffer manager context associated with this buffer object */ + dri_bufmgr *bufmgr; +}; -extern struct _DriFenceObject *driFenceBuffers(int fd, char *name, - unsigned flags); +struct _dri_fence { + /** + * This is an ORed mask of DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE, and + * DRM_FLAG_EXE indicating the operations associated with this fence. + * + * It is constant for the life of the fence object. + */ + unsigned int type; + /** Buffer manager context associated with this fence */ + dri_bufmgr *bufmgr; +}; -extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); +/** + * Context for a buffer manager instance. + * + * Contains public methods followed by private storage for the buffer manager. + */ +struct _dri_bufmgr { + /** + * Allocate a buffer object. + * + * Buffer objects are not necessarily initially mapped into CPU virtual + * address space or graphics device aperture. They must be mapped using + * bo_map() to be used by the CPU, and validated for use using bo_validate() + * to be used from the graphics device. + * + * XXX: flags/hint reason to live? + */ + dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, + unsigned long size, unsigned int alignment, + unsigned int flags, unsigned int hint); -extern void driFenceUnReference(struct _DriFenceObject *fence); + /** + * Allocates a buffer object for a static allocation. + * + * Static allocations are ones such as the front buffer that are offered by + * the X Server, which are never evicted and never moved. + * + * XXX: flags/hint reason to live? + */ + dri_bo *(*bo_alloc_static)(dri_bufmgr *bufmgr_ctx, const char *name, + unsigned long offset, unsigned long size, + void *virtual, unsigned int flags, + unsigned int hint); -extern void -driFenceFinish(struct _DriFenceObject *fence, unsigned type, int lazy); + /** Takes a reference on a buffer object */ + void (*bo_reference)(dri_bo *bo); -extern int driFenceSignaled(struct _DriFenceObject *fence, unsigned type); -extern unsigned driFenceType(struct _DriFenceObject *fence); + /** + * Releases a reference on a buffer object, freeing the data if + * rerefences remain. + */ + void (*bo_unreference)(dri_bo *bo); -/* - * Return a pointer to the libdrm buffer object this DriBufferObject - * uses. - */ + /** + * Maps the buffer into userspace. + * + * This function will block waiting for any existing fence on the buffer to + * clear, first. The resulting mapping is available at buf->virtual. +\ */ + int (*bo_map)(dri_bo *buf, GLboolean write_enable); + + /** Reduces the refcount on the userspace mapping of the buffer object. */ + int (*bo_unmap)(dri_bo *buf); + + /** + * Makes the buffer accessible to the graphics chip. + * + * The resulting offset of the buffer within the graphics aperture is then + * available at buf->offset until the buffer is fenced. + * + * Flags should consist of the memory types that the buffer may be validated + * into and the read/write/exe flags appropriate to the use of the buffer. + */ + int (*bo_validate)(dri_bo *buf, unsigned int flags); + + /** + * Associates the current set of validated buffers with a fence. + * + * Once fenced, the buffer manager will allow the validated buffers to be + * evicted when the graphics device's execution has passed the fence + * command. + * + * The fence object will have flags for the sum of the read/write/exe flags + * of the validated buffers associated with it. + */ + dri_fence * (*fence_validated)(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed); + + /** Takes a reference on a fence object */ + void (*fence_reference)(dri_fence *fence); -extern drmBO *driBOKernel(struct _DriBufferObject *buf); -extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, - unsigned hint); -extern void driBOUnmap(struct _DriBufferObject *buf); -extern unsigned long driBOOffset(struct _DriBufferObject *buf); -extern unsigned driBOFlags(struct _DriBufferObject *buf); -extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); -extern void driBOUnReference(struct _DriBufferObject *buf); + /** + * Releases a reference on a fence object, freeing the data if + * rerefences remain. + */ + void (*fence_unreference)(dri_fence *fence); + + /** + * Blocks until the given fence is signaled. + */ + void (*fence_wait)(dri_fence *fence); + + /** + * Checks and returns whether the given fence is signaled. + */ +}; + +/* extern void driBOData(struct _DriBufferObject *r_buf, unsigned size, const void *data, unsigned flags); extern void driBOSubData(struct _DriBufferObject *buf, @@ -73,27 +173,40 @@ extern void driBOSubData(struct _DriBufferObject *buf, extern void driBOGetSubData(struct _DriBufferObject *buf, unsigned long offset, unsigned long size, void *data); -extern void driGenBuffers(struct _DriBufferPool *pool, - const char *name, - unsigned n, - struct _DriBufferObject *buffers[], - unsigned alignment, unsigned flags, unsigned hint); -extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); -extern void driInitBufMgr(int fd); -extern void driBOCreateList(int target, drmBOList * list); -extern void driBOResetList(drmBOList * list); -extern void driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, - unsigned flags, unsigned mask); -extern void driBOValidateList(int fd, drmBOList * list); - -extern void driBOFence(struct _DriBufferObject *buf, - struct _DriFenceObject *fence); - -extern void driPoolTakeDown(struct _DriBufferPool *pool); -extern void driBOSetStatic(struct _DriBufferObject *buf, - unsigned long offset, - unsigned long size, void *virtual, unsigned flags); -extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); -extern void driPoolTakeDown(struct _DriBufferPool *pool); +*/ + +dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, + unsigned int alignment, unsigned int flags, + unsigned int hint); +dri_bo *dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, + void *virtual, unsigned int flags, + unsigned int hint); +void dri_bo_reference(dri_bo *bo); +void dri_bo_unreference(dri_bo *bo); +int dri_bo_map(dri_bo *buf, GLboolean write_enable); +int dri_bo_unmap(dri_bo *buf); +int dri_bo_validate(dri_bo *buf, unsigned int flags); +dri_fence *dri_fence_validated(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed); +void dri_fence_reference(dri_fence *fence); +void dri_fence_unreference(dri_fence *fence); + +void dri_bo_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, const void *data); +void dri_bo_get_subdata(dri_bo *bo, unsigned long offset, + unsigned long size, void *data); + +dri_bufmgr *dri_bufmgr_ttm_init(int fd, unsigned int fence_type, + unsigned int fence_type_flush); + +void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); +dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, + unsigned long size, + unsigned int (*fence_emit)(void *private), + int (*fence_wait)(void *private, + unsigned int cookie), + void *driver_priv); +void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); #endif diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c new file mode 100644 index 0000000000..2519808851 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -0,0 +1,871 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Originally a fake version of the buffer manager so that we can + * prototype the changes in a driver fairly quickly, has been fleshed + * out to a fully functional interim solution. + * + * Basically wraps the old style memory management in the new + * programming interface, but is more expressive and avoids many of + * the bugs in the old texture manager. + */ +#include "mtypes.h" +#include "dri_bufmgr.h" +#include "drm.h" + +#include "simple_list.h" +#include "mm.h" +#include "imports.h" + +#define DBG(...) + +/* Internal flags: + */ +#define BM_NO_BACKING_STORE DRM_BO_FLAG_MEM_PRIV0 +#define BM_NO_FENCE_SUBDATA DRM_BO_FLAG_MEM_PRIV1 + +/* Wrapper around mm.c's mem_block, which understands that you must + * wait for fences to expire before memory can be freed. This is + * specific to our use of memcpy for uploads - an upload that was + * processed through the command queue wouldn't need to care about + * fences. + */ +struct block { + struct block *next, *prev; + struct mem_block *mem; /* BM_MEM_AGP */ + + unsigned referenced:1; + unsigned on_hardware:1; + unsigned fenced:1; + + unsigned fence; /* BM_MEM_AGP, Split to read_fence, write_fence */ + + dri_bo *bo; + void *virtual; +}; + +typedef struct _bufmgr_fake { + dri_bufmgr bufmgr; + + _glthread_Mutex mutex; /**< for thread safety */ + + unsigned long low_offset; + unsigned long size; + void *virtual; + + struct mem_block *heap; + struct block lru; /* only allocated, non-fence-pending blocks here */ + + unsigned buf_nr; /* for generating ids */ + + struct block referenced; /* after bmBufferOffset */ + struct block on_hardware; /* after bmValidateBuffers */ + struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ + /* then to bufmgr->lru or free() */ + + unsigned int last_fence; + + unsigned fail:1; + unsigned need_fence:1; + GLboolean thrashing; + + /** + * Driver callback to emit a fence, returning the cookie. + * + * Currently, this also requires that a write flush be emitted before + * emitting the fence, but this should change. + */ + unsigned int (*fence_emit)(void *private); + /** Driver callback to wait for a fence cookie to have passed. */ + int (*fence_wait)(void *private, unsigned int fence_cookie); + /** Driver-supplied argument to driver callbacks */ + void *driver_priv; +} dri_bufmgr_fake; + +typedef struct _dri_bo_fake { + dri_bo bo; + + unsigned id; /* debug only */ + const char *name; + + unsigned dirty:1; + unsigned int refcount; + /* Flags may consist of any of the DRM_BO flags, plus + * DRM_BO_NO_BACKING_STORE and BM_NO_FENCE_SUBDATA, which are the first two + * driver private flags. + */ + unsigned int flags; + unsigned int alignment; + GLboolean is_static; + + struct block *block; + void *backing_store; + void (*invalidate_cb)(dri_bufmgr *bufmgr, void * ); + void *invalidate_ptr; +} dri_bo_fake; + +typedef struct _dri_fence_fake { + dri_fence fence; + + const char *name; + unsigned int refcount; + unsigned int fence_cookie; + GLboolean flushed; +} dri_fence_fake; + +static int clear_fenced(dri_bufmgr_fake *bufmgr_fake, + unsigned int fence_cookie); + +#define MAXFENCE 0x7fffffff + +static GLboolean FENCE_LTE( unsigned a, unsigned b ) +{ + if (a == b) + return GL_TRUE; + + if (a < b && b - a < (1<<24)) + return GL_TRUE; + + if (a > b && MAXFENCE - a + b < (1<<24)) + return GL_TRUE; + + return GL_FALSE; +} + +static unsigned int +_fence_emit_internal(dri_bufmgr_fake *bufmgr_fake) +{ + bufmgr_fake->last_fence = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); + return bufmgr_fake->last_fence; +} + +static void +_fence_wait_internal(dri_bufmgr_fake *bufmgr_fake, unsigned int cookie) +{ + int ret; + + ret = bufmgr_fake->fence_wait(bufmgr_fake->driver_priv, cookie); + if (ret != 0) { + _mesa_printf("%s:%d: Error %d waiting for fence.\n", + __FILE__, __LINE__); + abort(); + } + clear_fenced(bufmgr_fake, cookie); +} + +static GLboolean +_fence_test(dri_bufmgr_fake *bufmgr_fake, unsigned fence) +{ + /* Slight problem with wrap-around: + */ + return fence == 0 || FENCE_LTE(fence, bufmgr_fake->last_fence); +} + +/** + * Allocate a memory manager block for the buffer. + */ +static GLboolean +alloc_block(dri_bo *bo) +{ + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + dri_bufmgr_fake *bufmgr_fake= (dri_bufmgr_fake *)bo->bufmgr; + struct block *block = (struct block *)calloc(sizeof *block, 1); + unsigned int align_log2 = ffs(bo_fake->alignment); + GLuint sz; + + if (!block) + return GL_FALSE; + + sz = (bo->size + bo_fake->alignment - 1) & ~(bo_fake->alignment - 1); + + block->mem = mmAllocMem(bufmgr_fake->heap, sz, align_log2, 0); + if (!block->mem) { + free(block); + return GL_FALSE; + } + + make_empty_list(block); + + /* Insert at head or at tail??? + */ + insert_at_tail(&bufmgr_fake->lru, block); + + block->virtual = bufmgr_fake->virtual + block->mem->ofs; + block->bo = bo; + + bo_fake->block = block; + + return GL_TRUE; +} + +/* Release the card storage associated with buf: + */ +static void free_block(dri_bufmgr_fake *bufmgr_fake, struct block *block) +{ + DBG("free block %p\n", block); + + if (!block) + return; + + if (block->referenced) { + _mesa_printf("tried to free block on referenced list\n"); + assert(0); + } + else if (block->on_hardware) { + block->bo = NULL; + } + else if (block->fenced) { + block->bo = NULL; + } + else { + DBG(" - free immediately\n"); + remove_from_list(block); + + mmFreeMem(block->mem); + free(block); + } +} + +static void +alloc_backing_store(dri_bo *bo) +{ + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + assert(!bo_fake->backing_store); + assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + + bo_fake->backing_store = ALIGN_MALLOC(bo->size, 64); +} + +static void +free_backing_store(dri_bo *bo) +{ + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + + if (bo_fake->backing_store) { + ALIGN_FREE(bo_fake->backing_store); + bo_fake->backing_store = NULL; + } +} + +static void +set_dirty(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + if (bo_fake->flags & BM_NO_BACKING_STORE) + bo_fake->invalidate_cb(&bufmgr_fake->bufmgr, bo_fake->invalidate_ptr); + + assert(!(bo_fake->flags & DRM_BO_FLAG_NO_EVICT)); + + DBG("set_dirty - buf %d\n", bo_fake->id); + bo_fake->dirty = 1; +} + +static GLboolean +evict_lru(dri_bufmgr_fake *bufmgr_fake, GLuint max_fence) +{ + struct block *block, *tmp; + + DBG("%s\n", __FUNCTION__); + + foreach_s(block, tmp, &bufmgr_fake->lru) { + dri_bo_fake *bo_fake = (dri_bo_fake *)block->bo; + + if (bo_fake != NULL && (bo_fake->flags & BM_NO_FENCE_SUBDATA)) + continue; + + if (block->fence && max_fence && !FENCE_LTE(block->fence, max_fence)) + return 0; + + set_dirty(&bo_fake->bo); + bo_fake->block = NULL; + + free_block(bufmgr_fake, block); + return GL_TRUE; + } + + return GL_FALSE; +} + +#define foreach_s_rev(ptr, t, list) \ + for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev) + +static GLboolean +evict_mru(dri_bufmgr_fake *bufmgr_fake) +{ + struct block *block, *tmp; + + DBG("%s\n", __FUNCTION__); + + foreach_s_rev(block, tmp, &bufmgr_fake->lru) { + dri_bo_fake *bo_fake = (dri_bo_fake *)block->bo; + + if (bo_fake && (bo_fake->flags & BM_NO_FENCE_SUBDATA)) + continue; + + set_dirty(&bo_fake->bo); + bo_fake->block = NULL; + + free_block(bufmgr_fake, block); + return GL_TRUE; + } + + return GL_FALSE; +} + +/** + * Removes all objects from the fenced list older than the given fence. + */ +static int clear_fenced(dri_bufmgr_fake *bufmgr_fake, + unsigned int fence_cookie) +{ + struct block *block, *tmp; + int ret = 0; + + foreach_s(block, tmp, &bufmgr_fake->fenced) { + assert(block->fenced); + + if (_fence_test(bufmgr_fake, block->fence)) { + + block->fenced = 0; + + if (!block->bo) { + DBG("delayed free: offset %x sz %x\n", + block->mem->ofs, block->mem->size); + remove_from_list(block); + mmFreeMem(block->mem); + free(block); + } + else { + DBG("return to lru: offset %x sz %x\n", + block->mem->ofs, block->mem->size); + move_to_tail(&bufmgr_fake->lru, block); + } + + ret = 1; + } + else { + /* Blocks are ordered by fence, so if one fails, all from + * here will fail also: + */ + break; + } + } + + /* Also check the referenced list: + */ + foreach_s(block, tmp, &bufmgr_fake->referenced ) { + if (block->fenced && _fence_test(bufmgr_fake, block->fence)) { + block->fenced = 0; + } + } + + DBG("%s: %d\n", __FUNCTION__, ret); + return ret; +} + +static void fence_blocks(dri_bufmgr_fake *bufmgr_fake, unsigned fence) +{ + struct block *block, *tmp; + + foreach_s (block, tmp, &bufmgr_fake->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->bo, fence); + block->fence = fence; + + block->on_hardware = 0; + block->fenced = 1; + + /* Move to tail of pending list here + */ + move_to_tail(&bufmgr_fake->fenced, block); + } + + /* Also check the referenced list: + */ + foreach_s (block, tmp, &bufmgr_fake->referenced) { + if (block->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->bo, fence); + + block->fence = fence; + block->on_hardware = 0; + block->fenced = 1; + } + } + + assert(is_empty_list(&bufmgr_fake->on_hardware)); +} + +static GLboolean evict_and_alloc_block(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + assert(bo_fake->block == NULL); + + /* Search for already free memory: + */ + if (alloc_block(bo)) + return GL_TRUE; + + /* If we're not thrashing, allow lru eviction to dig deeper into + * recently used textures. We'll probably be thrashing soon: + */ + if (!bufmgr_fake->thrashing) { + while (evict_lru(bufmgr_fake, 0)) + if (alloc_block(bo)) + return GL_TRUE; + } + + /* Keep thrashing counter alive? + */ + if (bufmgr_fake->thrashing) + bufmgr_fake->thrashing = 20; + + /* Wait on any already pending fences - here we are waiting for any + * freed memory that has been submitted to hardware and fenced to + * become available: + */ + while (!is_empty_list(&bufmgr_fake->fenced)) { + GLuint fence = bufmgr_fake->fenced.next->fence; + _fence_wait_internal(bufmgr_fake, fence); + + if (alloc_block(bo)) + return GL_TRUE; + } + + if (!is_empty_list(&bufmgr_fake->on_hardware)) { + while (!is_empty_list(&bufmgr_fake->fenced)) { + GLuint fence = bufmgr_fake->fenced.next->fence; + _fence_wait_internal(bufmgr_fake, fence); + } + + if (!bufmgr_fake->thrashing) { + DBG("thrashing\n"); + } + bufmgr_fake->thrashing = 20; + + if (alloc_block(bo)) + return GL_TRUE; + } + + while (evict_mru(bufmgr_fake)) + if (alloc_block(bo)) + return GL_TRUE; + + DBG("%s 0x%x bytes failed\n", __FUNCTION__, bo->size); + + assert(is_empty_list(&bufmgr_fake->on_hardware)); + assert(is_empty_list(&bufmgr_fake->fenced)); + + return GL_FALSE; +} + +/*********************************************************************** + * Public functions + */ + +/** + * Wait for hardware idle by emitting a fence and waiting for it. + */ +static void +dri_bufmgr_fake_wait_idle(dri_bufmgr_fake *bufmgr_fake) +{ + unsigned int cookie; + + cookie = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); + _fence_wait_internal(bufmgr_fake->driver_priv, cookie); +} + +/* Specifically ignore texture memory sharing. + * -- just evict everything + * -- and wait for idle + */ +void +dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + { + struct block *block, *tmp; + + assert(is_empty_list(&bufmgr_fake->referenced)); + + bufmgr_fake->need_fence = 1; + bufmgr_fake->fail = 0; + + /* Wait for hardware idle. We don't know where acceleration has been + * happening, so we'll need to wait anyway before letting anything get + * put on the card again. + */ + dri_bufmgr_fake_wait_idle(bufmgr_fake); + + assert(is_empty_list(&bufmgr_fake->fenced)); + assert(is_empty_list(&bufmgr_fake->on_hardware)); + + foreach_s(block, tmp, &bufmgr_fake->lru) { + assert(_fence_test(bufmgr_fake, block->fence)); + set_dirty(block->bo); + } + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static dri_bo * +dri_fake_alloc(dri_bufmgr *bufmgr, const char *name, + unsigned long size, unsigned int alignment, unsigned int flags, + unsigned int hint) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake; + + bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + bo_fake = calloc(1, sizeof(*bo_fake)); + if (!bo_fake) + return NULL; + + bo_fake->bo.size = size; + bo_fake->bo.offset = -1; + bo_fake->bo.virtual = NULL; + bo_fake->bo.bufmgr = bufmgr; + bo_fake->refcount = 1; + + /* Alignment must be a power of two */ + assert((alignment & (alignment - 1)) == 0); + if (alignment == 0) + alignment = 1; + bo_fake->alignment = alignment; + bo_fake->id = ++bufmgr_fake->buf_nr; + bo_fake->name = name; + bo_fake->flags = flags; + bo_fake->is_static = GL_FALSE; + + return &bo_fake->bo; +} + +static dri_bo * +dri_fake_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, void *virtual, + unsigned int flags, unsigned int hint) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake; + + bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + bo_fake = calloc(1, sizeof(*bo_fake)); + if (!bo_fake) + return NULL; + + bo_fake->bo.size = size; + bo_fake->bo.offset = offset; + bo_fake->bo.virtual = virtual; + bo_fake->bo.bufmgr = bufmgr; + bo_fake->refcount = 1; + bo_fake->name = name; + bo_fake->flags = flags; + bo_fake->is_static = GL_TRUE; + + return &bo_fake->bo; +} + +static void +dri_fake_bo_reference(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + bo_fake->refcount++; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static void +dri_fake_bo_unreference(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + if (!bo) + return; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + if (--bo_fake->refcount == 0) { + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + /* No remaining references, so free it */ + if (bo_fake->block) + free_block(bufmgr_fake, bo_fake->block); + free_backing_store(bo); + free(bo); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +/** + * Map a buffer into bo->virtual, allocating either card memory space (If + * BM_NO_BACKING_STORE or DRM_BO_FLAG_NO_EVICT) or backing store, as necessary. + */ +static int +dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + /* Static buffers are always mapped. */ + if (bo_fake->is_static) + return 0; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + { + DBG("bmMapBuffer %d\n", bo_fake->id); + + if (bo->virtual != NULL) { + _mesa_printf("%s: already mapped\n", __FUNCTION__); + abort(); + } + else if (bo_fake->flags & (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT)) { + + if (!bo_fake->block && !evict_and_alloc_block(bo)) { + DBG("%s: alloc failed\n", __FUNCTION__); + bufmgr_fake->fail = 1; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return 1; + } + else { + assert(bo_fake->block); + bo_fake->dirty = 0; + + if (!(bo_fake->flags & BM_NO_FENCE_SUBDATA)) + dri_bufmgr_fake_wait_idle(bufmgr_fake); + + bo->virtual = bo_fake->block->virtual; + } + } + else { + if (write_enable) + set_dirty(bo); + + if (bo_fake->backing_store == 0) + alloc_backing_store(bo); + + bo->virtual = bo_fake->backing_store; + } + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return 0; +} + +static int +dri_fake_bo_unmap(dri_bo *bo) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + /* Static buffers are always mapped. */ + if (bo_fake->is_static) + return 0; + + if (bo == NULL) + return 0; + + bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + + bo->virtual = NULL; + + return 0; +} + +static int +dri_fake_bo_validate(dri_bo *bo, unsigned int flags) +{ + dri_bufmgr_fake *bufmgr_fake; + dri_bo_fake *bo_fake = (dri_bo_fake *)bo; + + /* XXX: Sanity-check whether we've already validated this one under + * different flags. See drmAddValidateItem(). + */ + + bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + { + /* Allocate the card memory */ + if (!bo_fake->block && !evict_and_alloc_block(bo)) { + bufmgr_fake->fail = 1; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return -1; + } + + assert(bo_fake->block); + assert(bo_fake->block->bo == &bo_fake->bo); + + DBG("Add buf %d (block %p, dirty %d) to referenced list\n", + bo_fake->id, bo_fake->block, bo_fake->dirty); + + move_to_tail(&bufmgr_fake->referenced, bo_fake->block); + bo_fake->block->referenced = 1; + + bo->offset = bo_fake->block->mem->ofs; + + /* Upload the buffer contents if necessary */ + if (bo_fake->dirty) { + DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", bo_fake->id, + bo_fake->name, bo->size, block->mem->ofs); + + assert(!(bo_fake->flags & + (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT))); + + /* Actually, should be able to just wait for a fence on the memory, + * which we would be tracking when we free it. Waiting for idle is + * a sufficiently large hammer for now. + */ + dri_bufmgr_fake_wait_idle(bufmgr_fake); + + memcpy(bo_fake->block->virtual, bo_fake->backing_store, bo->size); + + bo_fake->block->referenced = 0; + bo_fake->block->on_hardware = 1; + move_to_tail(&bufmgr_fake->on_hardware, bo_fake->block); + } + + bufmgr_fake->need_fence = 1; + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + + return 0; +} + +static dri_fence * +dri_fake_fence_validated(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed) +{ + dri_fence_fake *fence_fake; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + unsigned int cookie; + + fence_fake = malloc(sizeof(*fence_fake)); + if (!fence_fake) + return NULL; + + fence_fake->refcount = 1; + fence_fake->name = name; + fence_fake->flushed = flushed; + fence_fake->fence.bufmgr = bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + cookie = _fence_emit_internal(bufmgr_fake); + fence_fake->fence_cookie = cookie; + fence_blocks(bufmgr_fake, cookie); + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + + return &fence_fake->fence; +} + +static void +dri_fake_fence_reference(dri_fence *fence) +{ + dri_fence_fake *fence_fake = (dri_fence_fake *)fence; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + ++fence_fake->refcount; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static void +dri_fake_fence_unreference(dri_fence *fence) +{ + dri_fence_fake *fence_fake = (dri_fence_fake *)fence; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + + if (!fence) + return; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + if (--fence_fake->refcount == 0) { + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + free(fence); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +static void +dri_fake_fence_wait(dri_fence *fence) +{ + dri_fence_fake *fence_fake = (dri_fence_fake *)fence; + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); + _fence_wait_internal(bufmgr_fake->driver_priv, fence_fake->fence_cookie); + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); +} + +dri_bufmgr * +dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, + unsigned long size, + unsigned int (*fence_emit)(void *private), + int (*fence_wait)(void *private, unsigned int cookie), + void *driver_priv) +{ + dri_bufmgr_fake *bufmgr_fake; + + bufmgr_fake = malloc(sizeof(*bufmgr_fake)); + + /* Initialize allocator */ + make_empty_list(&bufmgr_fake->referenced); + make_empty_list(&bufmgr_fake->fenced); + make_empty_list(&bufmgr_fake->on_hardware); + + bufmgr_fake->low_offset = low_offset; + bufmgr_fake->virtual = low_virtual; + bufmgr_fake->size = size; + bufmgr_fake->heap = mmInit(low_offset, size); + + _glthread_INIT_MUTEX(bufmgr_fake->mutex); + + /* Hook in methods */ + bufmgr_fake->bufmgr.bo_alloc = dri_fake_alloc; + bufmgr_fake->bufmgr.bo_alloc_static = dri_fake_alloc_static; + bufmgr_fake->bufmgr.bo_reference = dri_fake_bo_reference; + bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference; + bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map; + bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap; + bufmgr_fake->bufmgr.bo_validate = dri_fake_bo_validate; + bufmgr_fake->bufmgr.fence_validated = dri_fake_fence_validated; + bufmgr_fake->bufmgr.fence_wait = dri_fake_fence_wait; + bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference; + bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference; + + return &bufmgr_fake->bufmgr; +} diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c new file mode 100644 index 0000000000..edf2a923ce --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -0,0 +1,356 @@ +/************************************************************************** + * + * Copyright © 2007 Intel Corporation + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + * Eric Anholt + */ + +#include +#include +#include +#include "glthread.h" +#include "errno.h" +#include "mtypes.h" +#include "dri_bufmgr.h" +#include "string.h" +#include "imports.h" + +typedef struct _dri_bufmgr_ttm { + dri_bufmgr bufmgr; + + int fd; + _glthread_Mutex mutex; + unsigned int fence_type; + unsigned int fence_type_flush; +} dri_bufmgr_ttm; + +typedef struct _dri_bo_ttm { + dri_bo bo; + + int refcount; /* Protected by bufmgr->mutex */ + drmBO drm_bo; +} dri_bo_ttm; + +typedef struct _dri_fence_ttm +{ + dri_fence fence; + + int refcount; /* Protected by bufmgr->mutex */ + /** Fence type from when the fence was created, used for later waits */ + unsigned int type; + const char *name; + drmFence drm_fence; +} dri_fence_ttm; + +#if 0 +int +driFenceSignaled(DriFenceObject * fence, unsigned type) +{ + int signaled; + int ret; + + if (fence == NULL) + return GL_TRUE; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = drmFenceSignaled(bufmgr_ttm->fd, &fence->fence, type, &signaled); + _glthread_UNLOCK_MUTEX(fence->mutex); + BM_CKFATAL(ret); + return signaled; +} +#endif + +static dri_bo * +dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, + unsigned long size, unsigned int alignment, unsigned int flags, + unsigned int hint) +{ + dri_bufmgr_ttm *ttm_bufmgr; + dri_bo_ttm *ttm_buf; + unsigned int pageSize = getpagesize(); + int ret; + + ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; + + ttm_buf = malloc(sizeof(*ttm_buf)); + if (!ttm_buf) + return NULL; + + ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize, + NULL, drm_bo_type_dc, + flags, hint, &ttm_buf->drm_bo); + if (ret != 0) { + free(ttm_buf); + return NULL; + } + ttm_buf->bo.size = ttm_buf->drm_bo.size; + ttm_buf->bo.offset = ttm_buf->drm_bo.offset; + ttm_buf->bo.virtual = NULL; + ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->refcount = 1; + + return &ttm_buf->bo; +} + +static dri_bo * +dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, void *virtual, + unsigned int flags, unsigned int hint) +{ + dri_bufmgr_ttm *ttm_bufmgr; + dri_bo_ttm *ttm_buf; + int ret; + + ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; + + ttm_buf = malloc(sizeof(*ttm_buf)); + if (!ttm_buf) + return NULL; + + ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0, + NULL, drm_bo_type_fake, + flags, 0, &ttm_buf->drm_bo); + if (ret != 0) { + free(ttm_buf); + return NULL; + } + ttm_buf->bo.size = ttm_buf->drm_bo.size; + ttm_buf->bo.offset = ttm_buf->drm_bo.offset; + ttm_buf->bo.virtual = virtual; + ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->refcount = 1; + + return &ttm_buf->bo; +} + +static void +dri_ttm_bo_reference(dri_bo *buf) +{ + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + ttm_buf->refcount++; + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static void +dri_ttm_bo_unreference(dri_bo *buf) +{ + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + if (--ttm_buf->refcount == 0) { + drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo); + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); + free(buf); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static int +dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable) +{ + dri_bufmgr_ttm *bufmgr_ttm; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + unsigned int flags; + + bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + + flags = DRM_BO_FLAG_READ; + if (write_enable) + flags |= DRM_BO_FLAG_WRITE; + + return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual); +} + +static int +dri_ttm_bo_unmap(dri_bo *buf) +{ + dri_bufmgr_ttm *bufmgr_ttm; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + + if (buf == NULL) + return 0; + + bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + + buf->virtual = NULL; + + return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo); +} + +static int +dri_ttm_validate(dri_bo *buf, unsigned int flags) +{ + dri_bufmgr_ttm *bufmgr_ttm; + dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf; + unsigned int mask; + int err; + + /* XXX: Sanity-check whether we've already validated this one under + * different flags. See drmAddValidateItem(). + */ + + bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + + /* Calculate the appropriate mask to pass to the DRM. There appears to be + * be a direct relationship to flags, so it's unnecessary to have it passed + * in as an argument. + */ + mask = DRM_BO_MASK_MEM; + mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE); + + err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, mask, 0); + + if (err == 0) { + /* XXX: add to fence list for sanity checking */ + } + + return err; +} + +static dri_fence * +dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, + GLboolean flushed) +{ + dri_fence_ttm *fence_ttm = malloc(sizeof(*fence_ttm)); + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; + int ret; + unsigned int type; + + if (!fence_ttm) + return NULL; + + if (flushed) + type = bufmgr_ttm->fence_type_flush; + else + type = bufmgr_ttm->fence_type; + + fence_ttm->refcount = 1; + fence_ttm->name = name; + fence_ttm->type = type; + fence_ttm->fence.bufmgr = bufmgr; + ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); + if (ret) { + free(fence_ttm); + return NULL; + } + return &fence_ttm->fence; +} + +static void +dri_ttm_fence_reference(dri_fence *fence) +{ + dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence; + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + ++fence_ttm->refcount; + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static void +dri_ttm_fence_unreference(dri_fence *fence) +{ + dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence; + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr; + + if (!fence) + return; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + if (--fence_ttm->refcount == 0) { + drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence); + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); + free(fence); + return; + } + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); +} + +static void +dri_ttm_fence_wait(dri_fence *fence) +{ + dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence; + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr; + int ret; + + _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); + ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, + fence_ttm->type); + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); + if (ret != 0) { + _mesa_printf("%s:%d: Error %d waiting for fence %s.\n", + __FILE__, __LINE__, fence_ttm->name); + abort(); + } +} + +/** + * Initializes the TTM buffer manager, which uses the kernel to allocate, map, + * and manage map buffer objections. + * + * \param fd File descriptor of the opened DRM device. + * \param fence_type Driver-specific fence type used for fences with no flush. + * \param fence_type_flush Driver-specific fence type used for fences with a + * flush. + */ +dri_bufmgr * +dri_bufmgr_ttm_init(int fd, unsigned int fence_type, + unsigned int fence_type_flush) +{ + dri_bufmgr_ttm *bufmgr_ttm; + + bufmgr_ttm = malloc(sizeof(*bufmgr_ttm)); + bufmgr_ttm->fd = fd; + bufmgr_ttm->fence_type = fence_type; + bufmgr_ttm->fence_type_flush = fence_type_flush; + _glthread_INIT_MUTEX(bufmgr_ttm->mutex); + + bufmgr_ttm->bufmgr.bo_alloc = dri_ttm_alloc; + bufmgr_ttm->bufmgr.bo_alloc_static = dri_ttm_alloc_static; + bufmgr_ttm->bufmgr.bo_reference = dri_ttm_bo_reference; + bufmgr_ttm->bufmgr.bo_unreference = dri_ttm_bo_unreference; + bufmgr_ttm->bufmgr.bo_map = dri_ttm_bo_map; + bufmgr_ttm->bufmgr.bo_unmap = dri_ttm_bo_unmap; + bufmgr_ttm->bufmgr.bo_validate = dri_ttm_validate; + bufmgr_ttm->bufmgr.fence_validated = dri_ttm_fence_validated; + bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference; + bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference; + bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; + + return &bufmgr_ttm->bufmgr; +} diff --git a/src/mesa/drivers/dri/common/dri_bufpool.h b/src/mesa/drivers/dri/common/dri_bufpool.h deleted file mode 100644 index c6fb2c3ce0..0000000000 --- a/src/mesa/drivers/dri/common/dri_bufpool.h +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#ifndef _DRI_BUFPOOL_H_ -#define _DRI_BUFPOOL_H_ - -#include -struct _DriFenceObject; - -typedef struct _DriBufferPool -{ - int fd; - int (*map) (struct _DriBufferPool * pool, void *private, - unsigned flags, int hint, void **virtual); - int (*unmap) (struct _DriBufferPool * pool, void *private); - int (*destroy) (struct _DriBufferPool * pool, void *private); - unsigned long (*offset) (struct _DriBufferPool * pool, void *private); - unsigned (*flags) (struct _DriBufferPool * pool, void *private); - unsigned long (*size) (struct _DriBufferPool * pool, void *private); - void *(*create) (struct _DriBufferPool * pool, unsigned long size, - unsigned flags, unsigned hint, unsigned alignment); - int (*fence) (struct _DriBufferPool * pool, void *private, - struct _DriFenceObject * fence); - drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); - int (*validate) (struct _DriBufferPool * pool, void *private); - void *(*setstatic) (struct _DriBufferPool * pool, unsigned long offset, - unsigned long size, void *virtual, unsigned flags); - int (*waitIdle) (struct _DriBufferPool *pool, void *private, - int lazy); - void (*takeDown) (struct _DriBufferPool * pool); - void *data; -} DriBufferPool; - -extern void bmError(int val, const char *file, const char *function, - int line); -#define BM_CKFATAL(val) \ - do{ \ - int tstVal = (val); \ - if (tstVal) \ - bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ - } while(0); - - - - - -/* - * Builtin pools. - */ - -/* - * Kernel buffer objects. Size in multiples of page size. Page size aligned. - */ - -extern struct _DriBufferPool *driDRMPoolInit(int fd); -extern struct _DriBufferPool *driDRMStaticPoolInit(int fd); - -#endif diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c deleted file mode 100644 index b5b324be50..0000000000 --- a/src/mesa/drivers/dri/common/dri_drmpool.c +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "dri_bufpool.h" - -/* - * Buffer pool implementation using DRM buffer objects as DRI buffer objects. - */ - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, unsigned flags, unsigned hint, - unsigned alignment) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - unsigned pageSize = getpagesize(); - - if (!buf) - return NULL; - - if ((alignment > pageSize) && (alignment % pageSize)) { - return NULL; - } - - ret = drmBOCreate(pool->fd, 0, size, alignment / pageSize, - NULL, drm_bo_type_dc, - flags, hint, buf); - if (ret) { - free(buf); - return NULL; - } - - return (void *) buf; -} - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - int ret; - drmBO *buf = (drmBO *) private; - ret = drmBODestroy(pool->fd, buf); - free(buf); - return ret; -} - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) -{ - drmBO *buf = (drmBO *) private; - - return drmBOMap(pool->fd, buf, flags, hint, virtual); -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return drmBOUnmap(pool->fd, buf); -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return buf->offset; -} - -static unsigned -pool_flags(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return buf->flags; -} - - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - drmBO *buf = (drmBO *) private; - return buf->size; -} - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - /* - * Noop. The kernel handles all fencing. - */ - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - return (drmBO *) private; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) -{ - drmBO *buf = (drmBO *) private; - return drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); -} - - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - free(pool); -} - - -struct _DriBufferPool * -driDRMPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->setstatic = NULL; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->data = NULL; - return pool; -} - - -static void * -pool_setstatic(struct _DriBufferPool *pool, unsigned long offset, - unsigned long size, void *virtual, unsigned flags) -{ - drmBO *buf = (drmBO *) malloc(sizeof(*buf)); - int ret; - - if (!buf) - return NULL; - - ret = drmBOCreate(pool->fd, offset, size, 0, NULL, drm_bo_type_fake, - flags, 0, buf); - - if (ret) { - free(buf); - return NULL; - } - - buf->virtual = virtual; - - return (void *) buf; -} - - -struct _DriBufferPool * -driDRMStaticPoolInit(int fd) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - - if (!pool) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = NULL; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = NULL; - pool->setstatic = &pool_setstatic; - pool->waitIdle = &pool_waitIdle; - pool->takeDown = &pool_takedown; - pool->data = NULL; - return pool; -} -- cgit v1.2.3 From cfc21190af1038f204d38ab4764a9c731b0323a5 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 17 May 2007 15:28:01 -0700 Subject: Convert i915tex to the new interface and make it compile. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 6 + src/mesa/drivers/dri/common/dri_bufmgr.h | 12 +- src/mesa/drivers/dri/i915tex/Makefile | 3 +- src/mesa/drivers/dri/i915tex/i830_context.h | 6 +- src/mesa/drivers/dri/i915tex/i830_metaops.c | 2 +- src/mesa/drivers/dri/i915tex/i830_texstate.c | 7 +- src/mesa/drivers/dri/i915tex/i830_vtbl.c | 3 - src/mesa/drivers/dri/i915tex/i915_context.h | 6 +- src/mesa/drivers/dri/i915tex/i915_metaops.c | 2 +- src/mesa/drivers/dri/i915tex/i915_texstate.c | 8 +- src/mesa/drivers/dri/i915tex/i915_vtbl.c | 3 - src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 178 +++------ src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 21 +- src/mesa/drivers/dri/i915tex/intel_batchpool.c | 418 --------------------- src/mesa/drivers/dri/i915tex/intel_blit.c | 35 +- src/mesa/drivers/dri/i915tex/intel_blit.h | 6 +- .../drivers/dri/i915tex/intel_buffer_objects.c | 68 ++-- .../drivers/dri/i915tex/intel_buffer_objects.h | 8 +- src/mesa/drivers/dri/i915tex/intel_context.c | 18 +- src/mesa/drivers/dri/i915tex/intel_context.h | 18 +- src/mesa/drivers/dri/i915tex/intel_ioctl.c | 19 +- src/mesa/drivers/dri/i915tex/intel_ioctl.h | 4 +- src/mesa/drivers/dri/i915tex/intel_pixel_draw.c | 14 +- src/mesa/drivers/dri/i915tex/intel_pixel_read.c | 18 +- src/mesa/drivers/dri/i915tex/intel_regions.c | 86 +++-- src/mesa/drivers/dri/i915tex/intel_regions.h | 8 +- src/mesa/drivers/dri/i915tex/intel_screen.c | 112 +++--- src/mesa/drivers/dri/i915tex/intel_screen.h | 19 +- src/mesa/drivers/dri/i915tex/intel_tex_image.c | 9 +- src/mesa/drivers/dri/i965/intel_context.c | 6 +- 30 files changed, 320 insertions(+), 803 deletions(-) delete mode 100644 src/mesa/drivers/dri/i915tex/intel_batchpool.c (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index fc2d4a0665..f60d3b0db6 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -85,6 +85,12 @@ dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed) return bufmgr->fence_validated(bufmgr, name, flushed); } +void +dri_fence_wait(dri_fence *fence) +{ + fence->bufmgr->fence_wait(fence); +} + void dri_fence_reference(dri_fence *fence) { diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index eafee88b88..62ed9d3821 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -164,17 +164,6 @@ struct _dri_bufmgr { */ }; -/* -extern void driBOData(struct _DriBufferObject *r_buf, - unsigned size, const void *data, unsigned flags); -extern void driBOSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - const void *data); -extern void driBOGetSubData(struct _DriBufferObject *buf, - unsigned long offset, unsigned long size, - void *data); -*/ - dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, unsigned int alignment, unsigned int flags, unsigned int hint); @@ -189,6 +178,7 @@ int dri_bo_unmap(dri_bo *buf); int dri_bo_validate(dri_bo *buf, unsigned int flags); dri_fence *dri_fence_validated(dri_bufmgr *bufmgr, const char *name, GLboolean flushed); +void dri_fence_wait(dri_fence *fence); void dri_fence_reference(dri_fence *fence); void dri_fence_unreference(dri_fence *fence); diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index b218929dce..27fb29e9c2 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -50,8 +50,7 @@ DRIVER_SOURCES = \ intel_state.c \ intel_tris.c \ intel_fbo.c \ - intel_depthstencil.c \ - intel_batchpool.c + intel_depthstencil.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/i915tex/i830_context.h b/src/mesa/drivers/dri/i915tex/i830_context.h index 3d754103c0..9397fa45b5 100644 --- a/src/mesa/drivers/dri/i915tex/i830_context.h +++ b/src/mesa/drivers/dri/i915tex/i830_context.h @@ -114,10 +114,10 @@ struct i830_hw_state struct intel_region *depth_region; /* Regions aren't actually that appropriate here as the memory may - * be from a PBO or FBO. Just use the buffer id. Will have to do - * this for draw and depth for FBO's... + * be from a PBO or FBO. Will have to do this for draw and depth for + * FBO's... */ - struct _DriBufferObject *tex_buffer[I830_TEX_UNITS]; + dri_bo *tex_buffer[I830_TEX_UNITS]; GLuint tex_offset[I830_TEX_UNITS]; GLuint emitted; /* I810_UPLOAD_* */ diff --git a/src/mesa/drivers/dri/i915tex/i830_metaops.c b/src/mesa/drivers/dri/i915tex/i830_metaops.c index f76646d89d..13e4ab3aac 100644 --- a/src/mesa/drivers/dri/i915tex/i830_metaops.c +++ b/src/mesa/drivers/dri/i915tex/i830_metaops.c @@ -238,7 +238,7 @@ set_texture_blend_replace(struct intel_context *intel) */ static GLboolean set_tex_rect_source(struct intel_context *intel, - struct _DriBufferObject *buffer, + dri_bo *buffer, GLuint offset, GLuint pitch, GLuint height, GLenum format, GLenum type) { diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c index e3f34e3944..b25ec199f8 100644 --- a/src/mesa/drivers/dri/i915tex/i830_texstate.c +++ b/src/mesa/drivers/dri/i915tex/i830_texstate.c @@ -124,7 +124,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) /*We need to refcount these. */ if (i830->state.tex_buffer[unit] != NULL) { - driBOUnReference(i830->state.tex_buffer[unit]); + dri_bo_unreference(i830->state.tex_buffer[unit]); i830->state.tex_buffer[unit] = NULL; } @@ -136,7 +136,8 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ firstImage = tObj->Image[0][intelObj->firstLevel]; - i830->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer); + dri_bo_reference(intelObj->mt->region->buffer); + i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, intelObj-> firstLevel); @@ -303,7 +304,7 @@ i830UpdateTextureState(struct intel_context *intel) I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); if (i830->state.tex_buffer[i] != NULL) { - driBOUnReference(i830->state.tex_buffer[i]); + dri_bo_unreference(i830->state.tex_buffer[i]); i830->state.tex_buffer[i] = NULL; } break; diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c index dd0670dec3..441dc660ac 100644 --- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -451,7 +451,6 @@ i830_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->draw_region->draw_offset); if (state->depth_region) { @@ -459,7 +458,6 @@ i830_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); OUT_RELOC(state->depth_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->depth_region->draw_offset); } @@ -487,7 +485,6 @@ i830_emit_state(struct intel_context *intel) if (state->tex_buffer[i]) { OUT_RELOC(state->tex_buffer[i], DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, state->tex_offset[i] | TM0S0_USE_FENCE); } else { diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h index d2713e88f9..7915385dca 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -219,10 +219,10 @@ struct i915_hw_state /* struct intel_region *tex_region[I915_TEX_UNITS]; */ /* Regions aren't actually that appropriate here as the memory may - * be from a PBO or FBO. Just use the buffer id. Will have to do - * this for draw and depth for FBO's... + * be from a PBO or FBO. Will have to do this for draw and depth for + * FBO's... */ - struct _DriBufferObject *tex_buffer[I915_TEX_UNITS]; + dri_bo *tex_buffer[I915_TEX_UNITS]; GLuint tex_offset[I915_TEX_UNITS]; diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c index 3ab62bc806..128f86e21b 100644 --- a/src/mesa/drivers/dri/i915tex/i915_metaops.c +++ b/src/mesa/drivers/dri/i915tex/i915_metaops.c @@ -326,7 +326,7 @@ meta_texture_blend_replace(struct intel_context *intel) */ static GLboolean meta_tex_rect_source(struct intel_context *intel, - struct _DriBufferObject *buffer, + dri_bo *buffer, GLuint offset, GLuint pitch, GLuint height, GLenum format, GLenum type) { diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c index e0ecdfde24..31d18759ee 100644 --- a/src/mesa/drivers/dri/i915tex/i915_texstate.c +++ b/src/mesa/drivers/dri/i915tex/i915_texstate.c @@ -129,7 +129,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) /*We need to refcount these. */ if (i915->state.tex_buffer[unit] != NULL) { - driBOUnReference(i915->state.tex_buffer[unit]); + dri_bo_unreference(i915->state.tex_buffer[unit]); i915->state.tex_buffer[unit] = NULL; } @@ -141,7 +141,9 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ firstImage = tObj->Image[0][intelObj->firstLevel]; - i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer); + dri_bo_reference(intelObj->mt->region->buffer); + i915->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, intelObj-> firstLevel); @@ -322,7 +324,7 @@ i915UpdateTextureState(struct intel_context *intel) I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); if (i915->state.tex_buffer[i] != NULL) { - driBOUnReference(i915->state.tex_buffer[i]); + dri_bo_unreference(i915->state.tex_buffer[i]); i915->state.tex_buffer[i] = NULL; } diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index 52db9a95e6..50571b7e83 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -326,7 +326,6 @@ i915_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->draw_region->draw_offset); if (state->depth_region) { @@ -334,7 +333,6 @@ i915_emit_state(struct intel_context *intel) OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); OUT_RELOC(state->depth_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, state->depth_region->draw_offset); } @@ -378,7 +376,6 @@ i915_emit_state(struct intel_context *intel) if (state->tex_buffer[i]) { OUT_RELOC(state->tex_buffer[i], DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, state->tex_offset[i]); } else { diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index c92b83bcb3..55e40d5d97 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -77,49 +77,6 @@ intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) fprintf(stderr, "END BATCH\n\n\n"); } -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - - int i; - - /* - * Get a new, free batchbuffer. - */ - - batch->size = batch->intel->intelScreen->maxBatchSize; - driBOData(batch->buffer, batch->size, NULL, 0); - - driBOResetList(&batch->list); - - /* - * Unreference buffers previously on the relocation list. - */ - - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOUnReference(r->buf); - } - - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; - - /* - * We don't refcount the batchbuffer itself since we can't destroy it - * while it's on the list. - */ - - - driBOAddListItem(&batch->list, batch->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); - - - batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); - batch->ptr = batch->map; -} - /*====================================================================== * Public functions */ @@ -129,12 +86,16 @@ intel_batchbuffer_alloc(struct intel_context *intel) struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); batch->intel = intel; + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_EXE, 0); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->size = intel->intelScreen->maxBatchSize; + batch->ptr = batch->map; - driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, - &batch->buffer, 4096, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); batch->last_fence = NULL; - driBOCreateList(20, &batch->list); intel_batchbuffer_reset(batch); return batch; } @@ -143,17 +104,16 @@ void intel_batchbuffer_free(struct intel_batchbuffer *batch) { if (batch->last_fence) { - driFenceFinish(batch->last_fence, - DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); - driFenceUnReference(batch->last_fence); + dri_fence_wait(batch->last_fence); + dri_fence_unreference(batch->last_fence); batch->last_fence = NULL; } if (batch->map) { - driBOUnmap(batch->buffer); + dri_bo_unmap(batch->buf); batch->map = NULL; } - driBOUnReference(batch->buffer); - batch->buffer = NULL; + dri_bo_unreference(batch->buf); + batch->buf = NULL; free(batch); } @@ -167,30 +127,35 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint *ptr; GLuint i; struct intel_context *intel = batch->intel; - unsigned fenceFlags; - struct _DriFenceObject *fo; - - driBOValidateList(batch->intel->driFd, &batch->list); - - /* Apply the relocations. This nasty map indicates to me that the - * whole task should be done internally by the memory manager, and - * that dma buffers probably need to be pinned within agp space. - */ - ptr = (GLuint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, - DRM_BO_HINT_ALLOW_UNFENCED_MAP); + dri_fence *fo; + GLboolean performed_rendering = GL_FALSE; + assert(batch->buf->virtual != NULL); + ptr = batch->buf->virtual; for (i = 0; i < batch->nr_relocs; i++) { struct buffer_reloc *r = &batch->reloc[i]; - ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + if (r->validate_flags & DRM_BO_FLAG_WRITE) + performed_rendering = GL_TRUE; + + dri_bo_validate(r->buf, r->validate_flags); + ptr[r->offset / 4] = r->buf->offset + r->delta; + dri_bo_unreference(r->buf); } if (INTEL_DEBUG & DEBUG_BATCH) intel_dump_batchbuffer(0, ptr, used); - driBOUnmap(batch->buffer); + dri_bo_unmap(batch->buf); batch->map = NULL; + batch->ptr = NULL; + + dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; /* Throw away non-effective packets. Won't work once we have * hardware contexts which would preserve statechanges beyond a @@ -199,45 +164,32 @@ do_flush_locked(struct intel_batchbuffer *batch, if (!(intel->numClipRects == 0 && !ignore_cliprects)) { intel_batch_ioctl(batch->intel, - driBOOffset(batch->buffer), + batch->buf->offset, used, ignore_cliprects, allow_unlock); } - - /* - * Kernel fencing. The flags tells the kernel that we've - * programmed an MI_FLUSH. - */ - - fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; - fo = driFenceBuffers(batch->intel->driFd, - "Batch fence", fenceFlags); - - /* - * User space fencing. + /* Associate a fence with the validated buffers, and note that we included + * a flush at the end. */ + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "Batch fence", GL_TRUE); - driBOFence(batch->buffer, fo); - - if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { - - /* - * Oops. We only validated a batch buffer. This means we - * didn't do any proper rendering. Discard this fence object. - */ - - driFenceUnReference(fo); - } else { - driFenceUnReference(batch->last_fence); + if (performed_rendering) { + dri_fence_unreference(batch->last_fence); batch->last_fence = fo; - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - driBOFence(r->buf, fo); - } + } else { + /* If we didn't validate any buffers for writing by the card, we don't + * need to track the fence for glFinish(). + */ + dri_fence_unreference(fo); } if (intel->numClipRects == 0 && !ignore_cliprects) { if (allow_unlock) { + /* If we are not doing any actual user-visible rendering, + * do a sched_yield to keep the app from pegging the cpu while + * achieving nothing. + */ UNLOCK_HARDWARE(intel); sched_yield(); LOCK_HARDWARE(intel); @@ -247,7 +199,7 @@ do_flush_locked(struct intel_batchbuffer *batch, } -struct _DriFenceObject * +void intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; @@ -255,7 +207,7 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) GLboolean was_locked = intel->locked; if (used == 0) - return batch->last_fence; + return; /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a * performance drain that we would like to avoid. @@ -272,10 +224,6 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) used += 8; } - driBOUnmap(batch->buffer); - batch->ptr = NULL; - batch->map = NULL; - /* TODO: Just pass the relocation list and dma buffer up to the * kernel. */ @@ -291,16 +239,14 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) /* Reset the buffer: */ intel_batchbuffer_reset(batch); - return batch->last_fence; } void intel_batchbuffer_finish(struct intel_batchbuffer *batch) { - struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); - driFenceReference(fence); - driFenceFinish(fence, 3, GL_FALSE); - driFenceUnReference(fence); + intel_batchbuffer_flush(batch); + if (batch->last_fence != NULL) + dri_fence_wait(batch->last_fence); } @@ -308,20 +254,18 @@ intel_batchbuffer_finish(struct intel_batchbuffer *batch) */ GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - GLuint flags, GLuint mask, GLuint delta) + dri_bo *buffer, + GLuint flags, GLuint delta) { - assert(batch->nr_relocs < MAX_RELOCS); + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - driBOAddListItem(&batch->list, buffer, flags, mask); + assert(batch->nr_relocs <= MAX_RELOCS); - { - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - driBOReference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - } + dri_bo_reference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->validate_flags = flags; batch->ptr += 4; return GL_TRUE; diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index 59261f7274..302a605d3c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -16,9 +16,10 @@ struct intel_context; struct buffer_reloc { - struct _DriBufferObject *buf; + dri_bo *buf; GLuint offset; GLuint delta; /* not needed? */ + GLuint validate_flags; }; struct intel_batchbuffer @@ -26,8 +27,8 @@ struct intel_batchbuffer struct bufmgr *bm; struct intel_context *intel; - struct _DriBufferObject *buffer; - struct _DriFenceObject *last_fence; + dri_bo *buf; + dri_fence *last_fence; GLuint flags; drmBOList list; @@ -48,8 +49,7 @@ void intel_batchbuffer_free(struct intel_batchbuffer *batch); void intel_batchbuffer_finish(struct intel_batchbuffer *batch); -struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer - *batch); +void intel_batchbuffer_flush(struct intel_batchbuffer *batch); void intel_batchbuffer_reset(struct intel_batchbuffer *batch); @@ -65,9 +65,8 @@ void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, GLuint bytes); GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - struct _DriBufferObject *buffer, - GLuint flags, - GLuint mask, GLuint offset); + dri_bo *buffer, + GLuint flags, GLuint offset); /* Inline functions - might actually be better off with these * non-inlined. Certainly better off switching all command packets to @@ -113,9 +112,9 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch, #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) -#define OUT_RELOC(buf,flags,mask,delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ +#define OUT_RELOC(buf, flags, delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ } while (0) #define ADVANCE_BATCH() do { } while(0) diff --git a/src/mesa/drivers/dri/i915tex/intel_batchpool.c b/src/mesa/drivers/dri/i915tex/intel_batchpool.c deleted file mode 100644 index 3c17c50204..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_batchpool.c +++ /dev/null @@ -1,418 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "imports.h" -#include "glthread.h" -#include "dri_bufpool.h" -#include "dri_bufmgr.h" -#include "intel_screen.h" - -typedef struct -{ - drmMMListHead head; - struct _BPool *parent; - struct _DriFenceObject *fence; - unsigned long start; - int unfenced; - int mapped; -} BBuf; - -typedef struct _BPool -{ - _glthread_Mutex mutex; - unsigned long bufSize; - unsigned poolSize; - unsigned numFree; - unsigned numTot; - unsigned numDelayed; - unsigned checkDelayed; - drmMMListHead free; - drmMMListHead delayed; - drmMMListHead head; - drmBO kernelBO; - void *virtual; - BBuf *bufs; -} BPool; - - -static BPool * -createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, - unsigned checkDelayed) -{ - BPool *p = (BPool *) malloc(sizeof(*p)); - BBuf *buf; - int i; - - if (!p) - return NULL; - - p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); - if (!p->bufs) { - free(p); - return NULL; - } - - DRMINITLISTHEAD(&p->free); - DRMINITLISTHEAD(&p->head); - DRMINITLISTHEAD(&p->delayed); - - p->numTot = numBufs; - p->numFree = numBufs; - p->bufSize = bufSize; - p->numDelayed = 0; - p->checkDelayed = checkDelayed; - - _glthread_INIT_MUTEX(p->mutex); - - if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, - flags, 0, &p->kernelBO)) { - free(p->bufs); - free(p); - return NULL; - } - if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, - &p->virtual)) { - drmBODestroy(fd, &p->kernelBO); - free(p->bufs); - free(p); - return NULL; - } - - /* - * We unmap the buffer so that we can validate it later. Note that this is - * just a synchronizing operation. The buffer will have a virtual mapping - * until it is destroyed. - */ - - drmBOUnmap(fd, &p->kernelBO); - - buf = p->bufs; - for (i = 0; i < numBufs; ++i) { - buf->parent = p; - buf->fence = NULL; - buf->start = i * bufSize; - buf->mapped = 0; - buf->unfenced = 0; - DRMLISTADDTAIL(&buf->head, &p->free); - buf++; - } - - return p; -} - - -static void -pool_checkFree(BPool * p, int wait) -{ - drmMMListHead *list, *prev; - BBuf *buf; - int signaled = 0; - int i; - - list = p->delayed.next; - - if (p->numDelayed > 3) { - for (i = 0; i < p->numDelayed; i += 3) { - list = list->next; - } - } - - prev = list->prev; - for (; list != &p->delayed; list = prev, prev = list->prev) { - - buf = DRMLISTENTRY(BBuf, list, head); - - if (!signaled) { - if (wait) { - driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); - signaled = 1; - } - else { - signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); - } - } - - if (!signaled) - break; - - driFenceUnReference(buf->fence); - buf->fence = NULL; - DRMLISTDEL(list); - p->numDelayed--; - DRMLISTADD(list, &p->free); - p->numFree++; - } -} - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, unsigned flags, unsigned hint, - unsigned alignment) -{ - BPool *p = (BPool *) pool->data; - - drmMMListHead *item; - - if (alignment && (alignment != 4096)) - return NULL; - - _glthread_LOCK_MUTEX(p->mutex); - - if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); - - if (p->numFree == 0) { - fprintf(stderr, "Out of fixed size buffer objects\n"); - BM_CKFATAL(-ENOMEM); - } - - item = p->free.next; - - if (item == &p->free) { - fprintf(stderr, "Fixed size buffer pool corruption\n"); - } - - DRMLISTDEL(item); - --p->numFree; - - _glthread_UNLOCK_MUTEX(p->mutex); - return (void *) DRMLISTENTRY(BBuf, item, head); -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - if (buf->fence) { - DRMLISTADDTAIL(&buf->head, &p->delayed); - p->numDelayed++; - } - else { - buf->unfenced = 0; - DRMLISTADD(&buf->head, &p->free); - p->numFree++; - } - - if ((p->numDelayed % p->checkDelayed) == 0) - pool_checkFree(p, 0); - - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) -{ - - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - /* - * Currently Mesa doesn't have any condition variables to resolve this - * cleanly in a multithreading environment. - * We bail out instead. - */ - - if (buf->mapped) { - fprintf(stderr, "Trying to map already mapped buffer object\n"); - BM_CKFATAL(-EINVAL); - } - -#if 0 - if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { - fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" - " 0x%08x %d\n", hint, flags, buf->start); - BM_CKFATAL(-EINVAL); - } - -#endif - - if (buf->fence) { - _glthread_UNLOCK_MUTEX(p->mutex); - return -EBUSY; - } - - buf->mapped = GL_TRUE; - *virtual = (unsigned char *) p->virtual + buf->start; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) -{ - BBuf *buf = (BBuf *) private; - driFenceFinish(buf->fence, 0, lazy); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - - buf->mapped = 0; - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return p->kernelBO.offset + buf->start; -} - -static unsigned -pool_flags(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->kernelBO.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->bufSize; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - if (buf->fence) { - driFenceUnReference(buf->fence); - } - buf->fence = fence; - buf->unfenced = 0; - driFenceReference(buf->fence); - _glthread_UNLOCK_MUTEX(p->mutex); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return &p->kernelBO; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - BPool *p = (BPool *) pool->data; - - /* - * Wait on outstanding fences. - */ - - _glthread_LOCK_MUTEX(p->mutex); - while ((p->numFree < p->numTot) && p->numDelayed) { - _glthread_UNLOCK_MUTEX(p->mutex); - sched_yield(); - pool_checkFree(p, GL_TRUE); - _glthread_LOCK_MUTEX(p->mutex); - } - - drmBODestroy(pool->fd, &p->kernelBO); - free(p->bufs); - _glthread_UNLOCK_MUTEX(p->mutex); - free(p); - free(pool); -} - - -struct _DriBufferPool * -driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, unsigned checkDelayed) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); - if (!pool->data) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = &pool_validate; - pool->waitIdle = &pool_waitIdle; - pool->setstatic = NULL; - pool->takeDown = &pool_takedown; - return pool; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c index dbe4ba2ac5..ef596bdfc5 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.c +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -67,8 +67,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, intelScreen = intel->intelScreen; if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->last_swap_fence); + dri_fence_wait(intel->last_swap_fence); + dri_fence_unreference(intel->last_swap_fence); intel->last_swap_fence = NULL; } intel->last_swap_fence = intel->first_swap_fence; @@ -140,19 +140,20 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, OUT_BATCH((pbox->y2 << 16) | pbox->x2); OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + 0); OUT_BATCH((pbox->y1 << 16) | pbox->x1); OUT_BATCH(BR13 & 0xffff); OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + 0); ADVANCE_BATCH(); } if (intel->first_swap_fence) - driFenceUnReference(intel->first_swap_fence); - intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(intel->first_swap_fence); + dri_fence_unreference(intel->first_swap_fence); + intel_batchbuffer_flush(intel->batch); + dri_fence_reference(intel->first_swap_fence); + intel->first_swap_fence = intel->batch->last_fence; } UNLOCK_HARDWARE(intel); @@ -165,7 +166,7 @@ void intelEmitFillBlit(struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort x, GLshort y, GLshort w, GLshort h, GLuint color) { @@ -199,8 +200,7 @@ intelEmitFillBlit(struct intel_context *intel, OUT_BATCH(BR13); OUT_BATCH((y << 16) | x); OUT_BATCH(((y + h) << 16) | (x + w)); - OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); OUT_BATCH(color); ADVANCE_BATCH(); } @@ -236,10 +236,10 @@ void intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct _DriBufferObject *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort src_x, GLshort src_y, GLshort dst_x, GLshort dst_y, @@ -297,12 +297,10 @@ intelEmitCopyBlit(struct intel_context *intel, OUT_BATCH(BR13); OUT_BATCH((dst_y << 16) | dst_x); OUT_BATCH((dst_y2 << 16) | dst_x2); - OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); OUT_BATCH((src_y << 16) | src_x); OUT_BATCH(((GLint) src_pitch & 0xffff)); - OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, src_offset); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, src_offset); ADVANCE_BATCH(); } else { @@ -312,12 +310,10 @@ intelEmitCopyBlit(struct intel_context *intel, OUT_BATCH((0 << 16) | dst_x); OUT_BATCH((h << 16) | dst_x2); OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset + dst_y * dst_pitch); OUT_BATCH((0 << 16) | src_x); OUT_BATCH(((GLint) src_pitch & 0xffff)); OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, src_offset + src_y * src_pitch); ADVANCE_BATCH(); } @@ -420,7 +416,7 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) /* OK, clear this renderbuffer */ struct intel_region *irb_region = intel_get_rb_region(fb, buf); - struct _DriBufferObject *write_buffer = + dri_bo *write_buffer = intel_region_buffer(intel->intelScreen, irb_region, all ? INTEL_WRITE_FULL : INTEL_WRITE_PART); @@ -483,7 +479,6 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask) OUT_BATCH((b.y1 << 16) | b.x1); OUT_BATCH((b.y2 << 16) | b.x2); OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, irb_region->draw_offset); OUT_BATCH(clearVal); ADVANCE_BATCH(); diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.h b/src/mesa/drivers/dri/i915tex/intel_blit.h index e7bc280f58..a66af86359 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.h +++ b/src/mesa/drivers/dri/i915tex/intel_blit.h @@ -40,10 +40,10 @@ extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); extern void intelEmitCopyBlit(struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct _DriBufferObject *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort srcx, GLshort srcy, GLshort dstx, GLshort dsty, @@ -53,7 +53,7 @@ extern void intelEmitCopyBlit(struct intel_context *intel, extern void intelEmitFillBlit(struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct _DriBufferObject *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLshort x, GLshort y, GLshort w, GLshort h, GLuint color); diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index ba3c7f0c1f..6d72ea3fa2 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -35,6 +35,17 @@ #include "intel_regions.h" #include "dri_bufmgr.h" +/** Allocates a new dri_bo to store the data for the buffer object. */ +static void +intel_bufferobj_alloc_buffer(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + intel_obj->buffer = dri_bo_alloc(intel->intelScreen->bufmgr, "bufferobj", + intel_obj->Base.Size, 64, + DRM_BO_FLAG_MEM_LOCAL | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); +} + /** * There is some duplication between mesa's bufferobjects and our * bufmgr buffers. Both have an integer handle and a hashtable to @@ -44,21 +55,15 @@ static struct gl_buffer_object * intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) { - struct intel_context *intel = intel_context(ctx); struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object); _mesa_initialize_buffer_object(&obj->Base, name, target); - driGenBuffers(intel->intelScreen->regionPool, - "bufferobj", 1, &obj->buffer, 64, - DRM_BO_FLAG_MEM_LOCAL | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, - 0); + obj->buffer = NULL; return &obj->Base; } - /* Break the COW tie to the region. The region gets to keep the data. */ void @@ -68,15 +73,9 @@ intel_bufferobj_release_region(struct intel_context *intel, assert(intel_obj->region->buffer == intel_obj->buffer); intel_obj->region->pbo = NULL; intel_obj->region = NULL; - driBOUnReference(intel_obj->buffer); - intel_obj->buffer = NULL; - /* This leads to a large number of buffer deletion/creation events. - * Currently the drm doesn't like that: - */ - driGenBuffers(intel->intelScreen->regionPool, - "buffer object", 1, &intel_obj->buffer, 64, 0, 0); - driBOData(intel_obj->buffer, intel_obj->Base.Size, NULL, 0); + dri_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; } /* Break the COW tie to the region. Both the pbo and the region end @@ -107,7 +106,7 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) intel_bufferobj_release_region(intel, intel_obj); } else if (intel_obj->buffer) { - driDeleteBuffers(1, &intel_obj->buffer); + dri_bo_unreference(intel_obj->buffer); } _mesa_free(intel_obj); @@ -137,7 +136,15 @@ intel_bufferobj_data(GLcontext * ctx, if (intel_obj->region) intel_bufferobj_release_region(intel, intel_obj); - driBOData(intel_obj->buffer, size, data, 0); + if (intel_obj->buffer != NULL && intel_obj->buffer->size != size) { + dri_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; + } + + intel_bufferobj_alloc_buffer(intel, intel_obj); + + if (data != NULL) + dri_bo_subdata(intel_obj->buffer, 0, size, data); } @@ -162,7 +169,7 @@ intel_bufferobj_subdata(GLcontext * ctx, if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); - driBOSubData(intel_obj->buffer, offset, size, data); + dri_bo_subdata(intel_obj->buffer, offset, size, data); } @@ -179,7 +186,7 @@ intel_bufferobj_get_subdata(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - driBOGetSubData(intel_obj->buffer, offset, size, data); + dri_bo_subdata(intel_obj->buffer, offset, size, data); } @@ -202,8 +209,13 @@ intel_bufferobj_map(GLcontext * ctx, if (intel_obj->region) intel_bufferobj_cow(intel, intel_obj); - obj->Pointer = driBOMap(intel_obj->buffer, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + if (intel_obj->buffer == NULL) { + obj->Pointer = NULL; + return NULL; + } + + dri_bo_map(intel_obj->buffer, GL_TRUE); + obj->Pointer = intel_obj->buffer->virtual; return obj->Pointer; } @@ -218,21 +230,25 @@ intel_bufferobj_unmap(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - assert(obj->Pointer); - driBOUnmap(intel_obj->buffer); - obj->Pointer = NULL; + if (intel_obj->buffer != NULL) { + assert(obj->Pointer); + dri_bo_unmap(intel_obj->buffer); + obj->Pointer = NULL; + } return GL_TRUE; } -struct _DriBufferObject * +dri_bo * intel_bufferobj_buffer(struct intel_context *intel, struct intel_buffer_object *intel_obj, GLuint flag) { if (intel_obj->region) { if (flag == INTEL_WRITE_PART) intel_bufferobj_cow(intel, intel_obj); - else if (flag == INTEL_WRITE_FULL) + else if (flag == INTEL_WRITE_FULL) { intel_bufferobj_release_region(intel, intel_obj); + intel_bufferobj_alloc_buffer(intel, intel_obj); + } } return intel_obj->buffer; diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h index afe9b2f7cf..db579a8ae4 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h @@ -41,7 +41,7 @@ struct gl_buffer_object; struct intel_buffer_object { struct gl_buffer_object Base; - struct _DriBufferObject *buffer; /* the low-level buffer manager's buffer handle */ + dri_bo *buffer; /* the low-level buffer manager's buffer handle */ struct intel_region *region; /* Is there a zero-copy texture associated with this (pixel) @@ -51,9 +51,9 @@ struct intel_buffer_object /* Get the bm buffer associated with a GL bufferobject: */ -struct _DriBufferObject *intel_bufferobj_buffer(struct intel_context *intel, - struct intel_buffer_object - *obj, GLuint flag); +dri_bo *intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object + *obj, GLuint flag); /* Hook the bufferobject implementation into mesa: */ diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 6a3456e154..7db672cce3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -303,9 +303,8 @@ intelFinish(GLcontext * ctx) struct intel_context *intel = intel_context(ctx); intelFlush(ctx); if (intel->batch->last_fence) { - driFenceFinish(intel->batch->last_fence, - 0, GL_FALSE); - driFenceUnReference(intel->batch->last_fence); + dri_fence_wait(intel->batch->last_fence); + dri_fence_unreference(intel->batch->last_fence); intel->batch->last_fence = NULL; } intelCheckFrontRotate(ctx); @@ -441,7 +440,6 @@ intelInitContext(struct intel_context *intel, intel->RenderIndex = ~0; fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->iw.irq_seq = -1; intel->irqsEmitted = 0; intel->do_irqs = (intel->intelScreen->irq_active && @@ -514,13 +512,13 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv) intel_batchbuffer_free(intel->batch); if (intel->last_swap_fence) { - driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->last_swap_fence); + dri_fence_wait(intel->last_swap_fence); + dri_fence_unreference(intel->last_swap_fence); intel->last_swap_fence = NULL; } if (intel->first_swap_fence) { - driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); - driFenceUnReference(intel->first_swap_fence); + dri_fence_wait(intel->first_swap_fence); + dri_fence_unreference(intel->first_swap_fence); intel->first_swap_fence = NULL; } @@ -664,14 +662,14 @@ intelContendedLock(struct intel_context *intel, GLuint flags) */ if (batchMap != NULL) { - driBOUnmap(intel->batch->buffer); + dri_bo_unmap(intel->batch->buf); intel->batch->map = NULL; } intel_batchbuffer_reset(intel->batch); if (batchMap == NULL) { - driBOUnmap(intel->batch->buffer); + dri_bo_unmap(intel->batch->buf); intel->batch->map = NULL; } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 44c20af7f8..429f53cb51 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -50,7 +50,6 @@ struct intel_region; struct intel_context; -struct _DriBufferObject; typedef void (*intel_tri_func) (struct intel_context *, intelVertex *, intelVertex *, intelVertex *); @@ -164,12 +163,12 @@ struct intel_context void (*meta_import_pixel_state) (struct intel_context * intel); - GLboolean(*meta_tex_rect_source) (struct intel_context * intel, - struct _DriBufferObject * buffer, - GLuint offset, - GLuint pitch, - GLuint height, - GLenum format, GLenum type); + GLboolean(*meta_tex_rect_source) (struct intel_context * intel, + dri_bo * buffer, + GLuint offset, + GLuint pitch, + GLuint height, + GLenum format, GLenum type); void (*rotate_window) (struct intel_context * intel, __DRIdrawablePrivate * dPriv, GLuint srcBuf); @@ -181,8 +180,8 @@ struct intel_context GLuint Fallback; GLuint NewGLState; - struct _DriFenceObject *last_swap_fence; - struct _DriFenceObject *first_swap_fence; + dri_fence *last_swap_fence; + dri_fence *first_swap_fence; struct intel_batchbuffer *batch; @@ -256,7 +255,6 @@ struct intel_context GLuint do_usleeps; int do_irqs; GLuint irqsEmitted; - drm_i915_irq_wait_t iw; drm_context_t hHWContext; drmLock *driHwLock; diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.c b/src/mesa/drivers/dri/i915tex/intel_ioctl.c index 3250c6b3a9..6e76737c78 100644 --- a/src/mesa/drivers/dri/i915tex/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.c @@ -45,18 +45,15 @@ #define FILE_DEBUG_FLAG DEBUG_IOCTL int -intelEmitIrqLocked(struct intel_context *intel) +intelEmitIrqLocked(intelScreenPrivate *intelScreen) { drmI830IrqEmit ie; int ret, seq; - assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == - (DRM_LOCK_HELD | intel->hHWContext)); - ie.irq_seq = &seq; - ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, - &ie, sizeof(ie)); + ret = drmCommandWriteRead(intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_EMIT, &ie, sizeof(ie)); if (ret) { fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); exit(1); @@ -68,18 +65,18 @@ intelEmitIrqLocked(struct intel_context *intel) } void -intelWaitIrq(struct intel_context *intel, int seq) +intelWaitIrq(intelScreenPrivate *intelScreen, int seq) { + drm_i915_irq_wait_t iw; int ret; DBG("%s %d\n", __FUNCTION__, seq); - intel->iw.irq_seq = seq; + iw.irq_seq = seq; do { - ret = - drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, - sizeof(intel->iw)); + ret = drmCommandWrite(intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_WAIT, &iw, sizeof(iw)); } while (ret == -EAGAIN || ret == -EINTR); if (ret) { diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.h b/src/mesa/drivers/dri/i915tex/intel_ioctl.h index e8d07de893..7a5b175ed1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_ioctl.h +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.h @@ -30,8 +30,8 @@ #include "intel_context.h" -void intelWaitIrq(struct intel_context *intel, int seq); -int intelEmitIrqLocked(struct intel_context *intel); +void intelWaitIrq(intelScreenPrivate *intelScreen, int seq); +int intelEmitIrqLocked(intelScreenPrivate *intelScreen); void intel_batch_ioctl(struct intel_context *intel, GLuint start_offset, diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c index 10a079896a..cbb583d3a2 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c @@ -217,7 +217,7 @@ do_blit_drawpixels(GLcontext * ctx, struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); GLuint src_offset; GLuint rowLength; - struct _DriFenceObject *fence = NULL; + dri_fence *fence = NULL; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -298,8 +298,7 @@ do_blit_drawpixels(GLcontext * ctx, drm_clip_rect_t *box = dPriv->pClipRects; drm_clip_rect_t rect; drm_clip_rect_t dest_rect; - struct _DriBufferObject *src_buffer = - intel_bufferobj_buffer(intel, src, INTEL_READ); + dri_bo *src_buffer = intel_bufferobj_buffer(intel, src, INTEL_READ); int i; dest_rect.x1 = dPriv->x + x; @@ -324,14 +323,15 @@ do_blit_drawpixels(GLcontext * ctx, ctx->Color.ColorLogicOpEnabled ? ctx->Color.LogicOp : GL_COPY); } - fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(fence); + intel_batchbuffer_flush(intel->batch); + fence = intel->batch->last_fence; + dri_fence_reference(fence); } UNLOCK_HARDWARE(intel); if (fence) { - driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); - driFenceUnReference(fence); + dri_fence_wait(fence); + dri_fence_unreference(fence); } if (INTEL_DEBUG & DEBUG_PIXEL) diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c index 24e49ae066..a22844926c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c @@ -173,7 +173,7 @@ do_blit_readpixels(GLcontext * ctx, struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); GLuint dst_offset; GLuint rowLength; - struct _DriFenceObject *fence = NULL; + dri_fence *fence = NULL; if (INTEL_DEBUG & DEBUG_PIXEL) _mesa_printf("%s\n", __FUNCTION__); @@ -241,9 +241,9 @@ do_blit_readpixels(GLcontext * ctx, GLboolean all = (width * height * src->cpp == dst->Base.Size && x == 0 && dst_offset == 0); - struct _DriBufferObject *dst_buffer = - intel_bufferobj_buffer(intel, dst, all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); + dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; drm_clip_rect_t *box = dPriv->pClipRects; @@ -275,16 +275,16 @@ do_blit_readpixels(GLcontext * ctx, GL_COPY); } - fence = intel_batchbuffer_flush(intel->batch); - driFenceReference(fence); + intel_batchbuffer_flush(intel->batch); + fence = intel->batch->last_fence; + dri_fence_reference(fence); } UNLOCK_HARDWARE(intel); if (fence) { - driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, - GL_FALSE); - driFenceUnReference(fence); + dri_fence_wait(fence); + dri_fence_unreference(fence); } if (INTEL_DEBUG & DEBUG_PIXEL) diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index a114bdf896..9c005c0e5d 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -52,8 +52,17 @@ void intel_region_idle(intelScreenPrivate *intelScreen, struct intel_region *region) { DBG("%s\n", __FUNCTION__); - if (region && region->buffer) - driBOWaitIdle(region->buffer, GL_FALSE); + /* XXX: Using this function is likely bogus -- it ought to only have been + * used before a map, anyway, but leave this cheap implementation of it + * for now. + */ + if (region && region->buffer) { + /* Mapping it for read will ensure that any acceleration to the region + * would have landed already. + */ + dri_bo_map(region->buffer, GL_TRUE); + dri_bo_unmap(region->buffer); + } } /* XXX: Thread safety? @@ -66,8 +75,8 @@ intel_region_map(intelScreenPrivate *intelScreen, struct intel_region *region) if (region->pbo) intel_region_cow(intelScreen, region); - region->map = driBOMap(region->buffer, - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + dri_bo_map(region->buffer, GL_TRUE); + region->map = region->buffer->virtual; } return region->map; @@ -78,13 +87,11 @@ intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *region) { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - driBOUnmap(region->buffer); + dri_bo_unmap(region->buffer); region->map = NULL; } } -#undef TEST_CACHED_TEXTURES - struct intel_region * intel_region_alloc(intelScreenPrivate *intelScreen, GLuint cpp, GLuint pitch, GLuint height) @@ -98,16 +105,8 @@ intel_region_alloc(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - driGenBuffers(intelScreen->regionPool, - "region", 1, ®ion->buffer, 64, -#ifdef TEST_CACHED_TEXTURES - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_BIND_CACHED | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, -#else - 0, -#endif - 0); - driBOData(region->buffer, pitch * cpp * height, NULL, 0); + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + pitch * cpp * height, 64, 0, 0); return region; } @@ -138,7 +137,7 @@ intel_region_release(struct intel_region **region) if ((*region)->pbo) (*region)->pbo->region = NULL; (*region)->pbo = NULL; - driBOUnReference((*region)->buffer); + dri_bo_unreference((*region)->buffer); free(*region); } *region = NULL; @@ -160,16 +159,13 @@ intel_region_create_static(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - /* - * We use a "shared" buffer type to indicate buffers created and - * shared by others. - */ - - driGenBuffers(intelScreen->staticPool, "static region", 1, - ®ion->buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); + /* XXX: questionable flags */ + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", + offset, pitch * cpp * height, virtual, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE, 0); return region; } @@ -195,13 +191,14 @@ intel_region_update_static(intelScreenPrivate *intelScreen, * shared by others. */ - driDeleteBuffers(1, ®ion->buffer); - driGenBuffers(intelScreen->staticPool, "static region", 1, - ®ion->buffer, 64, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); - driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); - + dri_bo_unreference(region->buffer); + /* XXX: questionable flags */ + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", + offset, pitch * cpp * height, virtual, + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | + DRM_BO_FLAG_WRITE, 0); } @@ -376,17 +373,19 @@ intel_region_attach_pbo(intelScreenPrivate *intelScreen, } if (region->buffer) { - driDeleteBuffers(1, ®ion->buffer); + dri_bo_unreference(region->buffer); region->buffer = NULL; } region->pbo = pbo; region->pbo->region = region; - region->buffer = driBOReference(pbo->buffer); + dri_bo_reference(pbo->buffer); + region->buffer = pbo->buffer; } -/* Break the COW tie to the pbo. The pbo gets to keep the data. +/* Break the COW tie to the pbo and allocate a new buffer. + * The pbo gets to keep the data. */ void intel_region_release_pbo(intelScreenPrivate *intelScreen, @@ -395,13 +394,12 @@ intel_region_release_pbo(intelScreenPrivate *intelScreen, assert(region->buffer == region->pbo->buffer); region->pbo->region = NULL; region->pbo = NULL; - driBOUnReference(region->buffer); + dri_bo_unreference(region->buffer); region->buffer = NULL; - driGenBuffers(intelScreen->regionPool, - "region", 1, ®ion->buffer, 64, 0, 0); - driBOData(region->buffer, - region->cpp * region->pitch * region->height, NULL, 0); + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + region->pitch * region->cpp * region->height, + 64, 0, 0); } /* Break the COW tie to the pbo. Both the pbo and the region end up @@ -457,7 +455,7 @@ intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region) } } -struct _DriBufferObject * +dri_bo * intel_region_buffer(intelScreenPrivate *intelScreen, struct intel_region *region, GLuint flag) { diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h index d938c107a4..9623cf7bd5 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.h +++ b/src/mesa/drivers/dri/i915tex/intel_regions.h @@ -44,7 +44,7 @@ struct intel_buffer_object; */ struct intel_region { - struct _DriBufferObject *buffer; /**< buffer manager's buffer ID */ + dri_bo *buffer; /**< buffer manager's buffer */ GLuint refcount; /**< Reference count for region */ GLuint cpp; /**< bytes per pixel */ GLuint pitch; /**< in pixels */ @@ -134,8 +134,8 @@ void intel_region_release_pbo(intelScreenPrivate *intelScreen, void intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region); -struct _DriBufferObject *intel_region_buffer(intelScreenPrivate *intelScreen, - struct intel_region *region, - GLuint flag); +dri_bo *intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint flag); #endif diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 9034ee1b22..a1b8070f81 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -46,7 +46,7 @@ #include "intel_fbo.h" #include "i830_dri.h" -#include "dri_bufpool.h" +#include "dri_bufmgr.h" #include "intel_regions.h" #include "intel_batchbuffer.h" @@ -120,16 +120,22 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) return GL_FALSE; } -#if 0 - _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *) & intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; + if (0) + _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); + if (intelScreen->tex.size != 0) { + intelScreen->ttm = GL_FALSE; + + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *) & intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + } else { + intelScreen->ttm = GL_TRUE; } -#endif + if (0) printf("Mappings: front: %p back: %p third: %p depth: %p tex: %p\n", intelScreen->front.map, @@ -138,6 +144,32 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) return GL_TRUE; } +/** Driver-specific fence emit implementation for the fake memory manager. */ +static unsigned int +intel_fence_emit(void *private) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + unsigned int fence; + + /* XXX: Need to emit a flush, if we haven't already (at least with the + * current batchbuffer implementation, we have). + */ + + fence = intelEmitIrqLocked(intelScreen); + + return fence; +} + +/** Driver-specific fence wait implementation for the fake memory manager. */ +static int +intel_fence_wait(void *private, unsigned int cookie) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + + intelWaitIrq(intelScreen, cookie); + + return 0; +} static struct intel_region * intel_recreate_static(intelScreenPrivate *intelScreen, @@ -393,7 +425,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) intelScreenPrivate *intelScreen; I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; drmI830Sarea *sarea; - unsigned batchPoolSize = 1024*1024; PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> @@ -422,11 +453,11 @@ intelInitDriver(__DRIscreenPrivate * sPriv) sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); - intelScreen->maxBatchSize = BATCH_SZ; intelScreen->deviceID = gDRIPriv->deviceID; if (intelScreen->deviceID == PCI_CHIP_I865_G) intelScreen->maxBatchSize = 4096; - batchPoolSize /= intelScreen->maxBatchSize; + else + intelScreen->maxBatchSize = BATCH_SZ; intelScreen->mem = gDRIPriv->mem; intelScreen->cpp = gDRIPriv->cpp; @@ -452,24 +483,6 @@ intelInitDriver(__DRIscreenPrivate * sPriv) return GL_FALSE; } -#if 0 - - /* - * FIXME: Remove this code and its references. - */ - - intelScreen->tex.offset = gDRIPriv->textureOffset; - intelScreen->logTextureGranularity = gDRIPriv->logTextureGranularity; - intelScreen->tex.handle = gDRIPriv->textures; - intelScreen->tex.size = gDRIPriv->textureSize; - -#else - intelScreen->tex.offset = 0; - intelScreen->logTextureGranularity = 0; - intelScreen->tex.handle = 0; - intelScreen->tex.size = 0; -#endif - intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; if (0) @@ -517,27 +530,18 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->regionPool = driDRMPoolInit(sPriv->fd); - - if (!intelScreen->regionPool) - return GL_FALSE; - - intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); - - if (!intelScreen->staticPool) - return GL_FALSE; - - intelScreen->texPool = intelScreen->regionPool; - - intelScreen->batchPool = driBatchPoolInit(sPriv->fd, - DRM_BO_FLAG_EXE | - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_MEM_LOCAL, - intelScreen->maxBatchSize, - batchPoolSize, 5); - if (!intelScreen->batchPool) { - fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); - return GL_FALSE; + if (intelScreen->ttm) { + intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW); + } else { + intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, + intelScreen->tex.map, + intelScreen->tex.size, + intel_fence_emit, + intel_fence_wait, + intelScreen); } intel_recreate_static_regions(intelScreen); @@ -553,9 +557,7 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv) intelUnmapScreenRegions(intelScreen); - driPoolTakeDown(intelScreen->regionPool); - driPoolTakeDown(intelScreen->staticPool); - driPoolTakeDown(intelScreen->batchPool); + /* XXX: bufmgr teardown */ FREE(intelScreen); sPriv->private = NULL; } diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h index 05e2f1f2ea..168793d05a 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.h +++ b/src/mesa/drivers/dri/i915tex/intel_screen.h @@ -33,7 +33,7 @@ #include "intel_rotate.h" #include "i830_common.h" #include "xmlconfig.h" -#include "dri_bufpool.h" +#include "dri_bufmgr.h" /* XXX: change name or eliminate to avoid conflict with "struct * intel_region"!!! @@ -90,11 +90,15 @@ typedef struct * Configuration cache with default values for all contexts */ driOptionCache optionCache; - struct _DriBufferPool *batchPool; - struct _DriBufferPool *texPool; - struct _DriBufferPool *regionPool; - struct _DriBufferPool *staticPool; + + dri_bufmgr *bufmgr; unsigned int maxBatchSize; + + /** + * This value indicates that the kernel memory manager is being used + * instead of the fake client-side memory manager. + */ + GLboolean ttm; } intelScreenPrivate; @@ -121,11 +125,6 @@ extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); -extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, - unsigned checkDelayed); - extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); extern void diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c index 42679ef9db..f9c8bc5801 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c @@ -221,11 +221,10 @@ try_pbo_upload(struct intel_context *intel, intelFlush(&intel->ctx); LOCK_HARDWARE(intel); { - struct _DriBufferObject *src_buffer = - intel_bufferobj_buffer(intel, pbo, INTEL_READ); - struct _DriBufferObject *dst_buffer = - intel_region_buffer(intel->intelScreen, intelImage->mt->region, - INTEL_WRITE_FULL); + dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); + dri_bo *dst_buffer = intel_region_buffer(intel->intelScreen, + intelImage->mt->region, + INTEL_WRITE_FULL); intelEmitCopyBlit(intel, diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 10eb9a2e28..422eb96097 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -656,7 +656,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; if (intel->aub_wrap) { - bm_fake_NotifyContendedLockTake( intel ); + bm_fake_NotifyContendedLockTake( intel ); intel->vtbl.lost_hardware( intel ); intel->vtbl.aub_wrap(intel); intel->aub_wrap = 0; @@ -667,7 +667,7 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->vtbl.lost_hardware( intel ); } - /* Make sure nothing has been emitted prior to getting the lock: + /* Make sure nothing has been emitted prior to getting the lock: */ assert(intel->batch->map == 0); @@ -700,8 +700,6 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) intel->vtbl.note_unlock( intel ); intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); _glthread_UNLOCK_MUTEX(lockMutex); } -- cgit v1.2.3 From 1f08f5d97068ea89f0fa527520a2ccb0a69ea50b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 17 May 2007 15:36:26 -0700 Subject: Rename the i915tex_dri.so driver to just i915_dri.so again. --- src/mesa/drivers/dri/i915tex/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index 27fb29e9c2..c6a29149c7 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -LIBNAME = i915tex_dri.so +LIBNAME = i915_dri.so MINIGLX_SOURCES = server/intel_dri.c -- cgit v1.2.3 From b12b24a430e2d328cbe102612b8a152e5c925cbf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 17 May 2007 15:36:43 -0700 Subject: Restore missing intel_batchbuffer_reset() which was needed. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 55e40d5d97..67fca371a7 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -80,12 +80,16 @@ intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) /*====================================================================== * Public functions */ -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) { - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } - batch->intel = intel; batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", intel->intelScreen->maxBatchSize, 4096, DRM_BO_FLAG_MEM_TT | @@ -94,9 +98,17 @@ intel_batchbuffer_alloc(struct intel_context *intel) batch->map = batch->buf->virtual; batch->size = intel->intelScreen->maxBatchSize; batch->ptr = batch->map; +} + +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + batch->intel = intel; batch->last_fence = NULL; intel_batchbuffer_reset(batch); + return batch; } -- cgit v1.2.3 From 4cf2cc0d18df67d1d550b777c8db2e088f1c4188 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 11:29:55 -0700 Subject: Ratchet required version down to 1.5 (pre-TTM). --- src/mesa/drivers/dri/i915tex/intel_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index a1b8070f81..e268af91f1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -879,7 +879,7 @@ __driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 5, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 7, 0 }; + static const __DRIversion drm_expected = { 1, 5, 0 }; dri_interface = interface; -- cgit v1.2.3 From bb1bb88bab809ce47fc5669ceb294b83ed164975 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 11:55:00 -0700 Subject: Fix some use-before-initialize in bufmgr_fake. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 2519808851..0ef3199d5f 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -846,6 +846,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, make_empty_list(&bufmgr_fake->referenced); make_empty_list(&bufmgr_fake->fenced); make_empty_list(&bufmgr_fake->on_hardware); + make_empty_list(&bufmgr_fake->lru); bufmgr_fake->low_offset = low_offset; bufmgr_fake->virtual = low_virtual; @@ -867,5 +868,9 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference; bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference; + bufmgr_fake->fence_emit = fence_emit; + bufmgr_fake->fence_wait = fence_wait; + bufmgr_fake->driver_priv = driver_priv; + return &bufmgr_fake->bufmgr; } -- cgit v1.2.3 From 180f0bb964cd7aa233233dbe3bc6605e07ef1d4c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:09:34 -0700 Subject: Kill old struct bufmgr members. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 1 - src/mesa/drivers/dri/i915tex/intel_context.h | 5 ----- 2 files changed, 6 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index 302a605d3c..82a3d49fca 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -24,7 +24,6 @@ struct buffer_reloc struct intel_batchbuffer { - struct bufmgr *bm; struct intel_context *intel; dri_bo *buf; diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 429f53cb51..e75dd64fe1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -215,11 +215,6 @@ struct intel_context GLboolean hw_stipple; GLboolean strict_conformance; - /* AGP memory buffer manager: - */ - struct bufmgr *bm; - - /* State for intelvb.c and inteltris.c. */ GLuint RenderIndex; -- cgit v1.2.3 From 71648a088ee7bfb1a535f32c8afdef4dc2d43e9e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:10:05 -0700 Subject: Dead code elimination and fix bufmgr_fake_wait_idle. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 0ef3199d5f..914410e4ba 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -501,7 +501,7 @@ dri_bufmgr_fake_wait_idle(dri_bufmgr_fake *bufmgr_fake) unsigned int cookie; cookie = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); - _fence_wait_internal(bufmgr_fake->driver_priv, cookie); + _fence_wait_internal(bufmgr_fake, cookie); } /* Specifically ignore texture memory sharing. @@ -688,7 +688,6 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) static int dri_fake_bo_unmap(dri_bo *bo) { - dri_bufmgr_fake *bufmgr_fake; dri_bo_fake *bo_fake = (dri_bo_fake *)bo; /* Static buffers are always mapped. */ @@ -698,8 +697,6 @@ dri_fake_bo_unmap(dri_bo *bo) if (bo == NULL) return 0; - bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; - bo->virtual = NULL; return 0; -- cgit v1.2.3 From b0529dcc7bf6aa8330da19d98daa0abaa932cc97 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:39:00 -0700 Subject: Zero out bufmgr_fake on alloc. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 914410e4ba..191e16af61 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -837,7 +837,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, { dri_bufmgr_fake *bufmgr_fake; - bufmgr_fake = malloc(sizeof(*bufmgr_fake)); + bufmgr_fake = calloc(1, sizeof(*bufmgr_fake)); /* Initialize allocator */ make_empty_list(&bufmgr_fake->referenced); -- cgit v1.2.3 From 425d0c6305f7781788077452ae9e2de595b0961d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:57:34 -0700 Subject: Fix double-counting of low_offset in block->virtual. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 191e16af61..1820da5b44 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -214,7 +214,8 @@ alloc_block(dri_bo *bo) */ insert_at_tail(&bufmgr_fake->lru, block); - block->virtual = bufmgr_fake->virtual + block->mem->ofs; + block->virtual = bufmgr_fake->virtual + + block->mem->ofs - bufmgr_fake->low_offset; block->bo = bo; bo_fake->block = block; -- cgit v1.2.3 From 431baf221ea7858ecb5edb2a5a01b5f993147a4d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 12:59:39 -0700 Subject: Allow unreference with a NULL argument. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index f60d3b0db6..dd76e8ead6 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -58,6 +58,9 @@ dri_bo_reference(dri_bo *bo) void dri_bo_unreference(dri_bo *bo) { + if (bo == NULL) + return; + bo->bufmgr->bo_unreference(bo); } @@ -100,6 +103,9 @@ dri_fence_reference(dri_fence *fence) void dri_fence_unreference(dri_fence *fence) { + if (fence == NULL) + return; + fence->bufmgr->fence_unreference(fence); } -- cgit v1.2.3 From a926b7397bb19dea74995bcb02c0ee5438e4a63c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 13:47:21 -0700 Subject: Fix another mis-calling of _fence_wait_internal. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 1820da5b44..daa09cc5cd 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -825,7 +825,7 @@ dri_fake_fence_wait(dri_fence *fence) dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; _glthread_LOCK_MUTEX(bufmgr_fake->mutex); - _fence_wait_internal(bufmgr_fake->driver_priv, fence_fake->fence_cookie); + _fence_wait_internal(bufmgr_fake, fence_fake->fence_cookie); _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); } -- cgit v1.2.3 From c085e350df593ab2af60f53b86265db4c3eab38a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 18 May 2007 13:47:46 -0700 Subject: Fix a refcounting mistake with first_swap_fence. --- src/mesa/drivers/dri/i915tex/intel_blit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c index ef596bdfc5..5d97f08434 100644 --- a/src/mesa/drivers/dri/i915tex/intel_blit.c +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -152,8 +152,8 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv, if (intel->first_swap_fence) dri_fence_unreference(intel->first_swap_fence); intel_batchbuffer_flush(intel->batch); - dri_fence_reference(intel->first_swap_fence); intel->first_swap_fence = intel->batch->last_fence; + dri_fence_reference(intel->first_swap_fence); } UNLOCK_HARDWARE(intel); -- cgit v1.2.3 From 8b8d4d3e106b1ca7174c834a2f9b494922fc6e72 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 10:49:32 -0700 Subject: Notify the fake buffer manager on contended lock take. --- src/mesa/drivers/dri/i915tex/intel_context.c | 10 ++++++++++ src/mesa/drivers/dri/i915tex/server/i830_common.h | 1 + 2 files changed, 11 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 4f58f56ada..696845a7fc 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -638,6 +638,16 @@ intelContendedLock(struct intel_context *intel, GLuint flags) if (dPriv) DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + /* If the last consumer of the texture memory wasn't us, notify the fake + * bufmgr and record the new owner. We should have the memory shared + * between contexts of a single fake bufmgr, but this will at least make + * things correct for now. + */ + if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) { + sarea->texAge = intel->hHWContext; + dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + } + if (sarea->width != intelScreen->width || sarea->height != intelScreen->height || sarea->rotation != intelScreen->current_rotation) { diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h index d4d58886ce..7a76957c6a 100644 --- a/src/mesa/drivers/dri/i915tex/server/i830_common.h +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -85,6 +85,7 @@ typedef struct { int last_enqueue; /* last time a buffer was enqueued */ int last_dispatch; /* age of the most recently dispatched buffer */ int ctxOwner; /* last context to upload state */ + /** Last context that used the buffer manager. */ int texAge; int pf_enabled; /* is pageflipping allowed? */ int pf_active; -- cgit v1.2.3 From 2b325a9f32e4478d324feaa9fcc3706b8bae4a3b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 10:53:33 -0700 Subject: Remove unused intel_batchpool.c. This may need to be implemented again, but probably not as a buffer manager (pool). --- src/mesa/drivers/dri/i915tex/intel_batchpool.c | 418 ------------------------- 1 file changed, 418 deletions(-) delete mode 100644 src/mesa/drivers/dri/i915tex/intel_batchpool.c (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchpool.c b/src/mesa/drivers/dri/i915tex/intel_batchpool.c deleted file mode 100644 index 2503b8a62a..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_batchpool.c +++ /dev/null @@ -1,418 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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 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 - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Authors: Thomas Hellström - */ - -#include -#include -#include -#include "imports.h" -#include "glthread.h" -#include "dri_bufpool.h" -#include "dri_bufmgr.h" -#include "intel_screen.h" - -typedef struct -{ - drmMMListHead head; - struct _BPool *parent; - struct _DriFenceObject *fence; - unsigned long start; - int unfenced; - int mapped; -} BBuf; - -typedef struct _BPool -{ - _glthread_Mutex mutex; - unsigned long bufSize; - unsigned poolSize; - unsigned numFree; - unsigned numTot; - unsigned numDelayed; - unsigned checkDelayed; - drmMMListHead free; - drmMMListHead delayed; - drmMMListHead head; - drmBO kernelBO; - void *virtual; - BBuf *bufs; -} BPool; - - -static BPool * -createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, - unsigned checkDelayed) -{ - BPool *p = (BPool *) malloc(sizeof(*p)); - BBuf *buf; - int i; - - if (!p) - return NULL; - - p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); - if (!p->bufs) { - free(p); - return NULL; - } - - DRMINITLISTHEAD(&p->free); - DRMINITLISTHEAD(&p->head); - DRMINITLISTHEAD(&p->delayed); - - p->numTot = numBufs; - p->numFree = numBufs; - p->bufSize = bufSize; - p->numDelayed = 0; - p->checkDelayed = checkDelayed; - - _glthread_INIT_MUTEX(p->mutex); - - if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, - flags, DRM_BO_HINT_DONT_FENCE, &p->kernelBO)) { - free(p->bufs); - free(p); - return NULL; - } - if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, - &p->virtual)) { - drmBODestroy(fd, &p->kernelBO); - free(p->bufs); - free(p); - return NULL; - } - - /* - * We unmap the buffer so that we can validate it later. Note that this is - * just a synchronizing operation. The buffer will have a virtual mapping - * until it is destroyed. - */ - - drmBOUnmap(fd, &p->kernelBO); - - buf = p->bufs; - for (i = 0; i < numBufs; ++i) { - buf->parent = p; - buf->fence = NULL; - buf->start = i * bufSize; - buf->mapped = 0; - buf->unfenced = 0; - DRMLISTADDTAIL(&buf->head, &p->free); - buf++; - } - - return p; -} - - -static void -pool_checkFree(BPool * p, int wait) -{ - drmMMListHead *list, *prev; - BBuf *buf; - int signaled = 0; - int i; - - list = p->delayed.next; - - if (p->numDelayed > 3) { - for (i = 0; i < p->numDelayed; i += 3) { - list = list->next; - } - } - - prev = list->prev; - for (; list != &p->delayed; list = prev, prev = list->prev) { - - buf = DRMLISTENTRY(BBuf, list, head); - - if (!signaled) { - if (wait) { - driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); - signaled = 1; - } - else { - signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); - } - } - - if (!signaled) - break; - - driFenceUnReference(buf->fence); - buf->fence = NULL; - DRMLISTDEL(list); - p->numDelayed--; - DRMLISTADD(list, &p->free); - p->numFree++; - } -} - -static void * -pool_create(struct _DriBufferPool *pool, - unsigned long size, unsigned flags, unsigned hint, - unsigned alignment) -{ - BPool *p = (BPool *) pool->data; - - drmMMListHead *item; - - if (alignment && (alignment != 4096)) - return NULL; - - _glthread_LOCK_MUTEX(p->mutex); - - if (p->numFree == 0) - pool_checkFree(p, GL_TRUE); - - if (p->numFree == 0) { - fprintf(stderr, "Out of fixed size buffer objects\n"); - BM_CKFATAL(-ENOMEM); - } - - item = p->free.next; - - if (item == &p->free) { - fprintf(stderr, "Fixed size buffer pool corruption\n"); - } - - DRMLISTDEL(item); - --p->numFree; - - _glthread_UNLOCK_MUTEX(p->mutex); - return (void *) DRMLISTENTRY(BBuf, item, head); -} - - -static int -pool_destroy(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - if (buf->fence) { - DRMLISTADDTAIL(&buf->head, &p->delayed); - p->numDelayed++; - } - else { - buf->unfenced = 0; - DRMLISTADD(&buf->head, &p->free); - p->numFree++; - } - - if ((p->numDelayed % p->checkDelayed) == 0) - pool_checkFree(p, 0); - - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - - -static int -pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, - int hint, void **virtual) -{ - - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - - /* - * Currently Mesa doesn't have any condition variables to resolve this - * cleanly in a multithreading environment. - * We bail out instead. - */ - - if (buf->mapped) { - fprintf(stderr, "Trying to map already mapped buffer object\n"); - BM_CKFATAL(-EINVAL); - } - -#if 0 - if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { - fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" - " 0x%08x %d\n", hint, flags, buf->start); - BM_CKFATAL(-EINVAL); - } - -#endif - - if (buf->fence) { - _glthread_UNLOCK_MUTEX(p->mutex); - return -EBUSY; - } - - buf->mapped = GL_TRUE; - *virtual = (unsigned char *) p->virtual + buf->start; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static int -pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) -{ - BBuf *buf = (BBuf *) private; - driFenceFinish(buf->fence, 0, lazy); - return 0; -} - -static int -pool_unmap(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - - buf->mapped = 0; - return 0; -} - -static unsigned long -pool_offset(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return p->kernelBO.offset + buf->start; -} - -static unsigned -pool_flags(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->kernelBO.flags; -} - -static unsigned long -pool_size(struct _DriBufferPool *pool, void *private) -{ - BPool *p = (BPool *) pool->data; - - return p->bufSize; -} - - -static int -pool_fence(struct _DriBufferPool *pool, void *private, - struct _DriFenceObject *fence) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - _glthread_LOCK_MUTEX(p->mutex); - if (buf->fence) { - driFenceUnReference(buf->fence); - } - buf->fence = fence; - buf->unfenced = 0; - driFenceReference(buf->fence); - _glthread_UNLOCK_MUTEX(p->mutex); - - return 0; -} - -static drmBO * -pool_kernel(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - - return &p->kernelBO; -} - -static int -pool_validate(struct _DriBufferPool *pool, void *private) -{ - BBuf *buf = (BBuf *) private; - BPool *p = buf->parent; - _glthread_LOCK_MUTEX(p->mutex); - buf->unfenced = GL_TRUE; - _glthread_UNLOCK_MUTEX(p->mutex); - return 0; -} - -static void -pool_takedown(struct _DriBufferPool *pool) -{ - BPool *p = (BPool *) pool->data; - - /* - * Wait on outstanding fences. - */ - - _glthread_LOCK_MUTEX(p->mutex); - while ((p->numFree < p->numTot) && p->numDelayed) { - _glthread_UNLOCK_MUTEX(p->mutex); - sched_yield(); - pool_checkFree(p, GL_TRUE); - _glthread_LOCK_MUTEX(p->mutex); - } - - drmBODestroy(pool->fd, &p->kernelBO); - free(p->bufs); - _glthread_UNLOCK_MUTEX(p->mutex); - free(p); - free(pool); -} - - -struct _DriBufferPool * -driBatchPoolInit(int fd, unsigned flags, - unsigned long bufSize, - unsigned numBufs, unsigned checkDelayed) -{ - struct _DriBufferPool *pool; - - pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); - if (!pool) - return NULL; - - pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); - if (!pool->data) - return NULL; - - pool->fd = fd; - pool->map = &pool_map; - pool->unmap = &pool_unmap; - pool->destroy = &pool_destroy; - pool->offset = &pool_offset; - pool->flags = &pool_flags; - pool->size = &pool_size; - pool->create = &pool_create; - pool->fence = &pool_fence; - pool->kernel = &pool_kernel; - pool->validate = &pool_validate; - pool->waitIdle = &pool_waitIdle; - pool->setstatic = NULL; - pool->takeDown = &pool_takedown; - return pool; -} -- cgit v1.2.3 From b0b84529cf1d61d3a53d402f039b442260788624 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 11:08:55 -0700 Subject: Enable INTEL_DEBUG environment variable. --- src/mesa/drivers/dri/i915tex/intel_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index e75dd64fe1..d03c4c5dd1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -342,7 +342,7 @@ __memcpy(void *to, const void *from, size_t n) /* ================================================================ * Debugging: */ -#define DO_DEBUG 0 +#define DO_DEBUG 1 #if DO_DEBUG extern int INTEL_DEBUG; #else -- cgit v1.2.3 From b1fcabefa2f3fa81a20c1556383458315bb49bbf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 21 May 2007 13:06:12 -0700 Subject: Don't read beyond the end of the buffer with INTEL_DEBUG=bat. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 67fca371a7..42ec0ae980 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -67,13 +67,23 @@ */ static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint size) { int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 4) - fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", - offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", size / 4); + for (i = 0; i < size / 4; i += 4) { + char dw1[11], dw2[11] = "", dw3[11] = "", dw4[11] = ""; + + sprintf(dw1, "0x%08x", ptr[i]); + if (i + 1 < size / 4) + sprintf(dw2, "0x%08x", ptr[i + 1]); + if (i + 2 < size / 4) + sprintf(dw3, "0x%08x", ptr[i + 2]); + if (i + 3 < size / 4) + sprintf(dw4, "0x%08x", ptr[i + 3]); + fprintf(stderr, "0x%x:\t%s %s %s %s\n", offset + i * 4, + dw1, dw2, dw3, dw4); + } fprintf(stderr, "END BATCH\n\n\n"); } -- cgit v1.2.3 From b9323aa2cb4563fba1b328dbc802d673449056ac Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 24 May 2007 16:55:06 -0700 Subject: Replace the flags/hint arguments to bo_alloc{,_static} with a location mask. Now, allocations only take locations, rather than a variety of unused flags. The only interesting flag before was the no_move/no_evict pair for scanout and similar buffers, which the DRI drivers don't use. That will be readded when we get to using this code for display buffer allocation, by adding a pin/unpin call (dynamic pinning/unpinning may be useful for VT switching and root window resizing). This commit changes one instance of DRM_BO_FLAG_MEM_LOCAL with DRM_BO_FLAG_MEM_TT, which appeared to have been unintentional. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 22 +++++++++++++---- src/mesa/drivers/dri/common/dri_bufmgr.h | 15 ++++-------- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 20 ++++++++-------- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 28 ++++++++++++++++++---- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 3 +-- .../drivers/dri/i915tex/intel_buffer_objects.c | 3 +-- src/mesa/drivers/dri/i915tex/intel_regions.c | 14 ++++------- 7 files changed, 61 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index 154e7841a0..840fc7601a 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -35,18 +35,30 @@ dri_bo * dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, - unsigned int alignment, unsigned int flags, unsigned int hint) + unsigned int alignment, unsigned int location_mask) { - return bufmgr->bo_alloc(bufmgr, name, size, alignment, flags, hint); + assert((location_mask & ~(DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_PRIV0 | + DRM_BO_FLAG_MEM_PRIV1 | DRM_BO_FLAG_MEM_PRIV2 | + DRM_BO_FLAG_MEM_PRIV3 | + DRM_BO_FLAG_MEM_PRIV4)) == 0); + + return bufmgr->bo_alloc(bufmgr, name, size, alignment, location_mask); } dri_bo * dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, - unsigned long size, void *virtual, unsigned int flags, - unsigned int hint) + unsigned long size, void *virtual, + unsigned int location_mask) { + assert((location_mask & ~(DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_PRIV0 | + DRM_BO_FLAG_MEM_PRIV1 | DRM_BO_FLAG_MEM_PRIV2 | + DRM_BO_FLAG_MEM_PRIV3 | + DRM_BO_FLAG_MEM_PRIV4)) == 0); + return bufmgr->bo_alloc_static(bufmgr, name, offset, size, virtual, - flags, hint); + location_mask); } void diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 62ed9d3821..6aac54b7f4 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -81,25 +81,20 @@ struct _dri_bufmgr { * address space or graphics device aperture. They must be mapped using * bo_map() to be used by the CPU, and validated for use using bo_validate() * to be used from the graphics device. - * - * XXX: flags/hint reason to live? */ dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, unsigned long size, unsigned int alignment, - unsigned int flags, unsigned int hint); + unsigned int location_mask); /** * Allocates a buffer object for a static allocation. * * Static allocations are ones such as the front buffer that are offered by * the X Server, which are never evicted and never moved. - * - * XXX: flags/hint reason to live? */ dri_bo *(*bo_alloc_static)(dri_bufmgr *bufmgr_ctx, const char *name, unsigned long offset, unsigned long size, - void *virtual, unsigned int flags, - unsigned int hint); + void *virtual, unsigned int location_mask); /** Takes a reference on a buffer object */ void (*bo_reference)(dri_bo *bo); @@ -165,12 +160,10 @@ struct _dri_bufmgr { }; dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, - unsigned int alignment, unsigned int flags, - unsigned int hint); + unsigned int alignment, unsigned int location_mask); dri_bo *dri_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, unsigned long size, - void *virtual, unsigned int flags, - unsigned int hint); + void *virtual, unsigned int location_mask); void dri_bo_reference(dri_bo *bo); void dri_bo_unreference(dri_bo *bo); int dri_bo_map(dri_bo *buf, GLboolean write_enable); diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index daa09cc5cd..90a2ff85f9 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -541,9 +541,9 @@ dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) } static dri_bo * -dri_fake_alloc(dri_bufmgr *bufmgr, const char *name, - unsigned long size, unsigned int alignment, unsigned int flags, - unsigned int hint) +dri_fake_bo_alloc(dri_bufmgr *bufmgr, const char *name, + unsigned long size, unsigned int alignment, + unsigned int location_mask) { dri_bufmgr_fake *bufmgr_fake; dri_bo_fake *bo_fake; @@ -567,16 +567,16 @@ dri_fake_alloc(dri_bufmgr *bufmgr, const char *name, bo_fake->alignment = alignment; bo_fake->id = ++bufmgr_fake->buf_nr; bo_fake->name = name; - bo_fake->flags = flags; + bo_fake->flags = 0; bo_fake->is_static = GL_FALSE; return &bo_fake->bo; } static dri_bo * -dri_fake_alloc_static(dri_bufmgr *bufmgr, const char *name, - unsigned long offset, unsigned long size, void *virtual, - unsigned int flags, unsigned int hint) +dri_fake_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, + unsigned long offset, unsigned long size, + void *virtual, unsigned int location_mask) { dri_bufmgr_fake *bufmgr_fake; dri_bo_fake *bo_fake; @@ -593,7 +593,7 @@ dri_fake_alloc_static(dri_bufmgr *bufmgr, const char *name, bo_fake->bo.bufmgr = bufmgr; bo_fake->refcount = 1; bo_fake->name = name; - bo_fake->flags = flags; + bo_fake->flags = DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; bo_fake->is_static = GL_TRUE; return &bo_fake->bo; @@ -854,8 +854,8 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, _glthread_INIT_MUTEX(bufmgr_fake->mutex); /* Hook in methods */ - bufmgr_fake->bufmgr.bo_alloc = dri_fake_alloc; - bufmgr_fake->bufmgr.bo_alloc_static = dri_fake_alloc_static; + bufmgr_fake->bufmgr.bo_alloc = dri_fake_bo_alloc; + bufmgr_fake->bufmgr.bo_alloc_static = dri_fake_bo_alloc_static; bufmgr_fake->bufmgr.bo_reference = dri_fake_bo_reference; bufmgr_fake->bufmgr.bo_unreference = dri_fake_bo_unreference; bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map; diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index edf2a923ce..a721a7ce5c 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -89,13 +89,14 @@ driFenceSignaled(DriFenceObject * fence, unsigned type) static dri_bo * dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, - unsigned long size, unsigned int alignment, unsigned int flags, - unsigned int hint) + unsigned long size, unsigned int alignment, + unsigned int location_mask) { dri_bufmgr_ttm *ttm_bufmgr; dri_bo_ttm *ttm_buf; unsigned int pageSize = getpagesize(); int ret; + unsigned int flags, hint; ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; @@ -103,6 +104,15 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, if (!ttm_buf) return NULL; + /* The mask argument doesn't do anything for us that we want other than + * determine which pool (TTM or local) the buffer is allocated into, so just + * pass all of the allocation class flags. + */ + flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_EXE; + /* No hints we want to use. */ + hint = 0; + ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize, NULL, drm_bo_type_dc, flags, hint, &ttm_buf->drm_bo); @@ -122,11 +132,12 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, static dri_bo * dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, unsigned long size, void *virtual, - unsigned int flags, unsigned int hint) + unsigned int location_mask) { dri_bufmgr_ttm *ttm_bufmgr; dri_bo_ttm *ttm_buf; int ret; + unsigned int flags, hint; ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; @@ -134,9 +145,18 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, if (!ttm_buf) return NULL; + /* The mask argument doesn't do anything for us that we want other than + * determine which pool (TTM or local) the buffer is allocated into, so just + * pass all of the allocation class flags. + */ + flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | + DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; + /* No hints we want to use. */ + hint = 0; + ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0, NULL, drm_bo_type_fake, - flags, 0, &ttm_buf->drm_bo); + flags, hint, &ttm_buf->drm_bo); if (ret != 0) { free(ttm_buf); return NULL; diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 42ec0ae980..26eecb9440 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -102,8 +102,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch) batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_EXE, 0); + DRM_BO_FLAG_MEM_TT); dri_bo_map(batch->buf, GL_TRUE); batch->map = batch->buf->virtual; batch->size = intel->intelScreen->maxBatchSize; diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index 6d72ea3fa2..1b95bfd47a 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -42,8 +42,7 @@ intel_bufferobj_alloc_buffer(struct intel_context *intel, { intel_obj->buffer = dri_bo_alloc(intel->intelScreen->bufmgr, "bufferobj", intel_obj->Base.Size, 64, - DRM_BO_FLAG_MEM_LOCAL | - DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + DRM_BO_FLAG_MEM_TT); } /** diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index 9c005c0e5d..e0574ac57b 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -106,7 +106,7 @@ intel_region_alloc(intelScreenPrivate *intelScreen, region->refcount = 1; region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", - pitch * cpp * height, 64, 0, 0); + pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); return region; } @@ -162,10 +162,7 @@ intel_region_create_static(intelScreenPrivate *intelScreen, /* XXX: questionable flags */ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE, 0); + DRM_BO_FLAG_MEM_TT); return region; } @@ -195,10 +192,7 @@ intel_region_update_static(intelScreenPrivate *intelScreen, /* XXX: questionable flags */ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_NO_MOVE | - DRM_BO_FLAG_READ | - DRM_BO_FLAG_WRITE, 0); + DRM_BO_FLAG_MEM_TT); } @@ -399,7 +393,7 @@ intel_region_release_pbo(intelScreenPrivate *intelScreen, region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", region->pitch * region->cpp * region->height, - 64, 0, 0); + 64, DRM_BO_FLAG_MEM_TT); } /* Break the COW tie to the pbo. Both the pbo and the region end up -- cgit v1.2.3 From fb7e21514f96c36e4c5abcb6621d48cb16a8c1e1 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 31 May 2007 09:34:08 -0700 Subject: Remove some stale comments. --- src/mesa/drivers/dri/i915tex/intel_regions.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index e0574ac57b..4e3cea5e05 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -159,7 +159,6 @@ intel_region_create_static(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - /* XXX: questionable flags */ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", offset, pitch * cpp * height, virtual, DRM_BO_FLAG_MEM_TT); @@ -189,7 +188,6 @@ intel_region_update_static(intelScreenPrivate *intelScreen, */ dri_bo_unreference(region->buffer); - /* XXX: questionable flags */ region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", offset, pitch * cpp * height, virtual, DRM_BO_FLAG_MEM_TT); -- cgit v1.2.3 From 2ac17c68e2d64260168a54a275e839775828f534 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 31 May 2007 09:45:45 -0700 Subject: Add buffer manager destroy function. --- src/mesa/drivers/dri/common/dri_bufmgr.c | 6 ++++++ src/mesa/drivers/dri/common/dri_bufmgr.h | 5 +++-- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 11 +++++++++++ src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 9 +++++++++ src/mesa/drivers/dri/i915tex/intel_screen.c | 2 +- 5 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c index 840fc7601a..407409bf06 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -144,3 +144,9 @@ dri_bo_get_subdata(dri_bo *bo, unsigned long offset, memcpy(data, (unsigned char *)bo->virtual + offset, size); dri_bo_unmap(bo); } + +void +dri_bufmgr_destroy(dri_bufmgr *bufmgr) +{ + bufmgr->destroy(bufmgr); +} diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 6aac54b7f4..0f8e27923b 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -155,8 +155,9 @@ struct _dri_bufmgr { void (*fence_wait)(dri_fence *fence); /** - * Checks and returns whether the given fence is signaled. + * Tears down the buffer manager instance. */ + void (*destroy)(dri_bufmgr *bufmgr); }; dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, @@ -190,6 +191,6 @@ dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, int (*fence_wait)(void *private, unsigned int cookie), void *driver_priv); -void dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); +void dri_bufmgr_destroy(dri_bufmgr *bufmgr); #endif diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 90a2ff85f9..c6202d969c 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -829,6 +829,16 @@ dri_fake_fence_wait(dri_fence *fence) _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); } +static void +dri_fake_destroy(dri_bufmgr *bufmgr) +{ + dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + + _glthread_DESTROY_MUTEX(bufmgr_fake->mutex); + mmDestroy(bufmgr_fake->heap); + free(bufmgr); +} + dri_bufmgr * dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, unsigned long size, @@ -865,6 +875,7 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, bufmgr_fake->bufmgr.fence_wait = dri_fake_fence_wait; bufmgr_fake->bufmgr.fence_reference = dri_fake_fence_reference; bufmgr_fake->bufmgr.fence_unreference = dri_fake_fence_unreference; + bufmgr_fake->bufmgr.destroy = dri_fake_destroy; bufmgr_fake->fence_emit = fence_emit; bufmgr_fake->fence_wait = fence_wait; diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index a721a7ce5c..64248a1d87 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -339,6 +339,15 @@ dri_ttm_fence_wait(dri_fence *fence) } } +static void +dri_fake_destroy(dri_bufmgr *bufmgr) +{ + dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; + + _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); + free(bufmgr); +} + /** * Initializes the TTM buffer manager, which uses the kernel to allocate, map, * and manage map buffer objections. diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 4d61407909..e3a631b696 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -557,7 +557,7 @@ intelDestroyScreen(__DRIscreenPrivate * sPriv) intelUnmapScreenRegions(intelScreen); - /* XXX: bufmgr teardown */ + dri_bufmgr_destroy(intelScreen->bufmgr); FREE(intelScreen); sPriv->private = NULL; } -- cgit v1.2.3 From 7a452b21a2fa329871062a6ee49f0d0f4928d01c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 15 Jun 2007 16:20:34 -0700 Subject: Correct a mis-count in a LOAD_STATE_IMMEDIATE_1 length argument. --- src/mesa/drivers/dri/i915tex/i915_vtbl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index 2a3ccd01a0..5d6ad8d86c 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -197,7 +197,7 @@ i915_emit_invarient_state(struct intel_context *intel) /* Need to initialize this to zero. */ - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (1)); + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | 0); OUT_BATCH(0); /* XXX: Use this */ -- cgit v1.2.3 From 2754ac0878cbcfa13a4c16b8858500d812d9bb8a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 15 Jun 2007 16:58:15 -0700 Subject: Replace intel_dump_batchbuffer with a more informational version. --- src/mesa/drivers/dri/i915tex/Makefile | 1 + src/mesa/drivers/dri/i915tex/i915_disasm.c | 617 +++++++++++++++++++++++ src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 23 +- 3 files changed, 619 insertions(+), 22 deletions(-) create mode 100644 src/mesa/drivers/dri/i915tex/i915_disasm.c (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index c6a29149c7..eb704e1538 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -33,6 +33,7 @@ DRIVER_SOURCES = \ intel_pixel_draw.c \ intel_buffers.c \ intel_blit.c \ + i915_disasm.c \ i915_tex.c \ i915_texstate.c \ i915_context.c \ diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c new file mode 100644 index 0000000000..5e49df9e1c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -0,0 +1,617 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +#include +#include +#include + +#include "i915_disasm.h" +#include "i915_reg.h" + +#define BUFFER_FAIL(_count, _len, _name) do { \ + fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ + (_name), (_count), (_len)); \ + (*failures)++; \ + return count; \ +} while (0) + +FILE *out; + +static float +int_as_float(uint32_t intval) +{ + union intfloat { + uint32_t i; + float f; + } uval; + + uval.i = intval; + return uval.f; +} + +static void +instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, + char *fmt, ...) +{ + va_list va; + + fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); + va_start(va, fmt); + vfprintf(out, fmt, va); + va_end(va); +} + + +static int +decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_mi[] = { + { 0x08, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 1, 1, "MI_FLUSH" }, + { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 1, 1, "MI_NOOP" }, + { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, + }; + + + for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); + opcode++) { + if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); + if (opcodes_mi[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_mi[opcode].min_len || + len > opcodes_mi[opcode].max_len) + { + fprintf(out, "Bad length in %s\n", + opcodes_mi[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_mi[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_2d[] = { + { 0x40, 5, 5, "COLOR_BLT" }, + { 0x43, 6, 6, "SRC_COPY_BLT" }, + { 0x01, 8, 8, "XY_SETUP_BLT" }, + { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, + { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, + { 0x24, 2, 2, "XY_PIXEL_BLT" }, + { 0x25, 3, 3, "XY_SCANLINES_BLT" }, + { 0x26, 4, 4, "Y_TEXT_BLT" }, + { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, + { 0x50, 6, 6, "XY_COLOR_BLT" }, + { 0x51, 6, 6, "XY_PAT_BLT" }, + { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, + { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, + { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, + { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, + { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, + { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, + { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, + { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, + { 0x55, 9, 9, "XY_FULL_BLT" }, + { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, + { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, + { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, + { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, + { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, + }; + + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); + opcode++) { + if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); + if (opcodes_2d[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_2d[opcode].min_len || + len > opcodes_2d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_2d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + switch ((data[0] & 0x00f80000) >> 19) { + case 0x11: + instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); + return 1; + case 0x10: + instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); + return 1; + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int len, i, c, opcode, word, map, sampler, instr; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d_1d[] = { + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, + { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, + { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, + { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, + { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, + { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, + { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, + { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, + { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, + { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, + { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, + { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, + { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, + { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, + }; + + switch ((data[0] & 0x00ff0000) >> 16) { + case 0x07: + /* This instruction is unusual. A 0 length means just 1 DWORD instead of + * 2. The 0 length is specified in one place to be unsupported, but + * stated to be required in another, and 0 length LOAD_INDIRECTs appear + * to cause no harm at least. + */ + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); + len = (data[0] & 0x000000ff) + 1; + i = 1; + if (data[0] & (0x01 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SIS.0\n"); + instr_out(data, hw_offset, i++, "SIS.1\n"); + } + if (data[0] & (0x02 << 8)) { + if (i + 1 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "DIS.0\n"); + } + if (data[0] & (0x04 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SSB.0\n"); + instr_out(data, hw_offset, i++, "SSB.1\n"); + } + if (data[0] & (0x08 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "MSB.0\n"); + instr_out(data, hw_offset, i++, "MSB.1\n"); + } + if (data[0] & (0x10 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSP.0\n"); + instr_out(data, hw_offset, i++, "PSP.1\n"); + } + if (data[0] & (0x20 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSC.0\n"); + instr_out(data, hw_offset, i++, "PSC.1\n"); + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + return len; + } + return len; + case 0x04: + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); + len = (data[0] & 0x0000000f) + 2; + i = 1; + for (word = 0; word <= 7; word++) { + if (data[0] & (1 << (4 + word))) { + if (i >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + instr_out(data, hw_offset, i++, "S%d\n", word); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + } + return len; + case 0x00: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + + i = 1; + for (map = 0; map <= 15; map++) { + if (data[1] & (1 << map)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "map %d MS2\n", map); + instr_out(data, hw_offset, i++, "map %d MS3\n", map); + instr_out(data, hw_offset, i++, "map %d MS4\n", map); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + return len; + } + return len; + case 0x06: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + len = (data[0] & 0x000000ff) + 2; + + i = 1; + for (c = 0; c <= 31; c++) { + if (data[1] & (1 << c)) { + if (i + 4 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); + instr_out(data, hw_offset, i, "C%d.X = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Y = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Z = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.W = %f\n", + c, int_as_float(data[i])); + i++; + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + } + return len; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); + len = (data[0] & 0x000000ff) + 2; + if ((len - 1) % 3 != 0 || len > 370) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); + (*failures)++; + } + i = 1; + for (instr = 0; instr < (len - 1) / 3; instr++) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + } + return len; + case 0x01: + instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + i = 1; + for (sampler = 0; sampler <= 15; sampler++) { + if (data[1] & (1 << sampler)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); + instr_out(data, hw_offset, i++, "sampler %d SS2\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS3\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS4\n", + sampler); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); + (*failures)++; + } + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); + opcode++) + { + if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); + if (opcodes_3d_1d[opcode].max_len > 1) { + len = (data[0] & 0x0000ffff) + 2; + if (len < opcodes_3d_1d[opcode].min_len || + len > opcodes_3d_1d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", + opcodes_3d_1d[opcode].name); + (*failures)++; + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, + int *failures) +{ + char immediate = (data[0] & (1 << 23)) == 0; + unsigned int len, i; + + /* XXX: 3DPRIM_DIB not supported */ + if (immediate) { + len = (data[0] & 0x0003ffff) + 2; + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline\n"); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + /* indirect vertices */ + len = data[0] & 0x0000ffff; /* index count */ + if (data[0] & (1 << 17)) { + /* random vertex access */ + if (count < (len + 1) / 2 + 1) { + BUFFER_FAIL(count, (len + 1) / 2 + 1, + "3DPRIMITIVE random indirect"); + } + instr_out(data, hw_offset, 0, + "3DPRIMITIVE random indirect (%d)\n", len); + if (len == 0) { + /* vertex indices continue until 0xffff is found */ + for (i = 1; i < count; i++) { + if ((data[i] & 0xffff) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: (terminator)\n"); + return i; + } else if ((data[i] >> 16) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: 0x%04x, " + "(terminator)\n", + data[i] & 0xffff); + return i; + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + fprintf(out, + "3DPRIMITIVE: no terminator found in index buffer\n"); + (*failures)++; + return count; + } else { + /* fixed size vertex index buffer */ + for (i = 0; i < len; i += 2) { + if (i * 2 == len - 1) { + instr_out(data, hw_offset, i, + " indices: 0x%04x\n", + data[i] & 0xffff); + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + } + return (len + 1) / 2 + 1; + } else { + /* sequential vertex access */ + if (count < 2) + BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); + instr_out(data, hw_offset, 0, + "3DPRIMITIVE sequential indirect, %d starting from %d\n", + len, data[1] & 0xffff); + instr_out(data, hw_offset, 1, " start\n"); + return 2; + } + } + + + + return len; +} + +static int +decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, + { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, + { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, + { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, + { 0x0d, 1, 1, "3DSTATE_MODES_4" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** + * Decodes an i830-i915 batch buffer, writing the output to stdout. + * + * \param data batch buffer contents + * \param count number of DWORDs to decode in the batch buffer + * \param hw_offset hardware address for the buffer + */ +int +i915_disasm(uint32_t *data, int count, uint32_t hw_offset) +{ + int index = 0; + int failures = 0; + + out = stdout; + + while (index < count) { + switch ((data[index] & 0xe0000000) >> 29) { + case 0x0: + index += decode_mi(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x2: + index += decode_2d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x3: + index += decode_3d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + default: + instr_out(data, hw_offset, index, "UNKNOWN\n"); + failures++; + index++; + break; + } + fflush(out); + } + + return failures; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 26eecb9440..1edbb618d3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -66,27 +66,6 @@ * modifying cliprects ??? */ -static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint size) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", size / 4); - for (i = 0; i < size / 4; i += 4) { - char dw1[11], dw2[11] = "", dw3[11] = "", dw4[11] = ""; - - sprintf(dw1, "0x%08x", ptr[i]); - if (i + 1 < size / 4) - sprintf(dw2, "0x%08x", ptr[i + 1]); - if (i + 2 < size / 4) - sprintf(dw3, "0x%08x", ptr[i + 2]); - if (i + 3 < size / 4) - sprintf(dw4, "0x%08x", ptr[i + 3]); - fprintf(stderr, "0x%x:\t%s %s %s %s\n", offset + i * 4, - dw1, dw2, dw3, dw4); - } - fprintf(stderr, "END BATCH\n\n\n"); -} - /*====================================================================== * Public functions */ @@ -166,7 +145,7 @@ do_flush_locked(struct intel_batchbuffer *batch, } if (INTEL_DEBUG & DEBUG_BATCH) - intel_dump_batchbuffer(0, ptr, used); + i915_disasm(ptr, used / 4, 0); dri_bo_unmap(batch->buf); batch->map = NULL; -- cgit v1.2.3 From 1ddbfd779b2e11131d3c86406497fe970d8f816b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Jun 2007 12:19:42 -0700 Subject: Test for TTM presence initially rather than test for lack of classic aperture. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 13 +++++++++++++ src/mesa/drivers/dri/i915tex/intel_screen.c | 20 ++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index a721a7ce5c..508d4f5053 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -353,6 +353,7 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, unsigned int fence_type_flush) { dri_bufmgr_ttm *bufmgr_ttm; + dri_bo *test_alloc; bufmgr_ttm = malloc(sizeof(*bufmgr_ttm)); bufmgr_ttm->fd = fd; @@ -372,5 +373,17 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference; bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; + /* Attempt an allocation to make sure that the DRM was actually set up for + * TTM. + */ + test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation", + 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT); + if (test_alloc == NULL) { + _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); + free(bufmgr_ttm); + return NULL; + } + dri_bo_unreference(test_alloc); + return &bufmgr_ttm->bufmgr; } diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 4d61407909..1ae2819ae2 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -123,8 +123,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) if (0) _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); if (intelScreen->tex.size != 0) { - intelScreen->ttm = GL_FALSE; - if (drmMap(sPriv->fd, intelScreen->tex.handle, intelScreen->tex.size, @@ -132,8 +130,6 @@ intelMapScreenRegions(__DRIscreenPrivate * sPriv) intelUnmapScreenRegions(intelScreen); return GL_FALSE; } - } else { - intelScreen->ttm = GL_TRUE; } if (0) @@ -530,12 +526,16 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - if (intelScreen->ttm) { - intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, - DRM_FENCE_TYPE_EXE, - DRM_FENCE_TYPE_EXE | - DRM_I915_FENCE_TYPE_RW); - } else { + intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW); + if (intelScreen->bufmgr == NULL) { + if (intelScreen->tex.size == 0) { + fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", + __func__, __LINE__); + return GL_FALSE; + } intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, intelScreen->tex.map, intelScreen->tex.size, -- cgit v1.2.3 From bf0ae055de73e0cf66085e02ad4881bea497e4cb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 18 Jun 2007 12:20:07 -0700 Subject: Fix TTM static allocation flags. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 508d4f5053..47ea42ad55 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -150,7 +150,7 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, * pass all of the allocation class flags. */ flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; + DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_MOVE; /* No hints we want to use. */ hint = 0; -- cgit v1.2.3 From 1a49cd7f5b22eb326b25bddf24a02f68b8150a8d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 09:49:24 -0700 Subject: Add missing i915_disasm.h header and adjust copyright formatting on the .c --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 6 +++--- src/mesa/drivers/dri/i915tex/i915_disasm.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/mesa/drivers/dri/i915tex/i915_disasm.h (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index 5e49df9e1c..29db5763f0 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -17,9 +17,9 @@ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS 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. + * 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: * Eric Anholt diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.h b/src/mesa/drivers/dri/i915tex/i915_disasm.h new file mode 100644 index 0000000000..c74b036068 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.h @@ -0,0 +1,28 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +int i915_disasm(uint32_t *data, int count, uint32_t hw_offset); -- cgit v1.2.3 From f972f58d8003de9495af82e7927fb962f460b083 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 11:44:48 -0700 Subject: Improve fake bufmgr debugging, and don't try to migrate static buffers. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 39 +++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 90a2ff85f9..8bae4d8b34 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -41,7 +41,11 @@ #include "mm.h" #include "imports.h" +#if 0 +#define DBG(...) _mesa_printf(__VA_ARGS__) +#else #define DBG(...) +#endif /* Internal flags: */ @@ -570,6 +574,9 @@ dri_fake_bo_alloc(dri_bufmgr *bufmgr, const char *name, bo_fake->flags = 0; bo_fake->is_static = GL_FALSE; + DBG("drm_bo_alloc: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); + return &bo_fake->bo; } @@ -592,10 +599,14 @@ dri_fake_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, bo_fake->bo.virtual = virtual; bo_fake->bo.bufmgr = bufmgr; bo_fake->refcount = 1; + bo_fake->id = ++bufmgr_fake->buf_nr; bo_fake->name = name; bo_fake->flags = DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; bo_fake->is_static = GL_TRUE; + DBG("drm_bo_alloc_static: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); + return &bo_fake->bo; } @@ -648,7 +659,8 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) _glthread_LOCK_MUTEX(bufmgr_fake->mutex); { - DBG("bmMapBuffer %d\n", bo_fake->id); + DBG("drm_bo_map: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); if (bo->virtual != NULL) { _mesa_printf("%s: already mapped\n", __FUNCTION__); @@ -698,6 +710,9 @@ dri_fake_bo_unmap(dri_bo *bo) if (bo == NULL) return 0; + DBG("drm_bo_unmap: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); + bo->virtual = NULL; return 0; @@ -713,22 +728,32 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) * different flags. See drmAddValidateItem(). */ + DBG("drm_bo_validate: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, + bo_fake->bo.size / 1024); bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; _glthread_LOCK_MUTEX(bufmgr_fake->mutex); { + if (bo_fake->is_static) { + /* Add it to the needs-fence list */ + bufmgr_fake->need_fence = 1; + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + return 0; + } + /* Allocate the card memory */ if (!bo_fake->block && !evict_and_alloc_block(bo)) { bufmgr_fake->fail = 1; _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + DBG("Failed to validate buf %d:%s\n", bo_fake->id, bo_fake->name); return -1; } assert(bo_fake->block); assert(bo_fake->block->bo == &bo_fake->bo); - DBG("Add buf %d (block %p, dirty %d) to referenced list\n", - bo_fake->id, bo_fake->block, bo_fake->dirty); + DBG("Add buf %d:%s (block %p, dirty %d) to referenced list\n", + bo_fake->id, bo_fake->name, bo_fake->block, bo_fake->dirty); move_to_tail(&bufmgr_fake->referenced, bo_fake->block); bo_fake->block->referenced = 1; @@ -737,8 +762,8 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) /* Upload the buffer contents if necessary */ if (bo_fake->dirty) { - DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", bo_fake->id, - bo_fake->name, bo->size, block->mem->ofs); + DBG("Upload dirty buf %d:%s, sz %d offset 0x%x\n", bo_fake->id, + bo_fake->name, bo->size, bo_fake->block->mem->ofs); assert(!(bo_fake->flags & (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT))); @@ -786,6 +811,8 @@ dri_fake_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_blocks(bufmgr_fake, cookie); _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); + DBG("drm_fence_validated: 0x%08x cookie\n", fence_fake->fence_cookie); + return &fence_fake->fence; } @@ -824,6 +851,8 @@ dri_fake_fence_wait(dri_fence *fence) dri_fence_fake *fence_fake = (dri_fence_fake *)fence; dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)fence->bufmgr; + DBG("drm_fence_wait: 0x%08x cookie\n", fence_fake->fence_cookie); + _glthread_LOCK_MUTEX(bufmgr_fake->mutex); _fence_wait_internal(bufmgr_fake, fence_fake->fence_cookie); _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); -- cgit v1.2.3 From f3f29d632e8a51914b87e087d6ab4d1d6f47b7d7 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 12:53:07 -0700 Subject: Add decoding of inline primitives in debug output. --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 138 ++++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index 29db5763f0..ebb634654f 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -40,7 +40,9 @@ return count; \ } while (0) -FILE *out; +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; static float int_as_float(uint32_t intval) @@ -303,6 +305,17 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) if (data[0] & (1 << (4 + word))) { if (i >= count) BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + + /* save vertex state for decode */ + if (word == 2) { + saved_s2_set = 1; + saved_s2 = data[i]; + } + if (word == 4) { + saved_s4_set = 1; + saved_s4 = data[i]; + } + instr_out(data, hw_offset, i++, "S%d\n", word); } } @@ -437,17 +450,122 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, { char immediate = (data[0] & (1 << 23)) == 0; unsigned int len, i; + char *primtype; + + switch ((data[0] >> 18) & 0xf) { + case 0x0: primtype = "TRILIST"; break; + case 0x1: primtype = "TRISTRIP"; break; + case 0x2: primtype = "TRISTRIP_REVERSE"; break; + case 0x3: primtype = "TRIFAN"; break; + case 0x4: primtype = "POLYGON"; break; + case 0x5: primtype = "LINELIST"; break; + case 0x6: primtype = "LINESTRIP"; break; + case 0x7: primtype = "RECTLIST"; break; + case 0x8: primtype = "POINTLIST"; break; + case 0x9: primtype = "DIB"; break; + case 0xa: primtype = "CLEAR_RECT"; break; + default: primtype = "unknown"; break; + } /* XXX: 3DPRIM_DIB not supported */ if (immediate) { len = (data[0] & 0x0003ffff) + 2; - instr_out(data, hw_offset, 0, "3DPRIMITIVE inline\n"); + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); if (count < len) BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); - for (i = 1; i < len; i++) { - instr_out(data, hw_offset, i, - " vertex data (%f float)\n", - int_as_float(data[i])); + if (!saved_s2_set || !saved_s4_set) { + fprintf(out, "unknown vertex format\n"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + unsigned int vertex = 0; + for (i = 1; i < len;) { + unsigned int tc; + +#define VERTEX_OUT(fmt, ...) do { \ + if (i < len) \ + instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ + else \ + fprintf(out, " missing data in V%d\n", vertex); \ + i++; \ +} while (0) + + VERTEX_OUT("X = %f", int_as_float(data[i])); + VERTEX_OUT("Y = %f", int_as_float(data[i])); + switch (saved_s4 >> 6 & 0x7) { + case 0x1: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + case 0x3: + break; + case 0x4: + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + default: + fprintf(out, "bad S4 position mask\n"); + } + + if (saved_s4 & (1 << 10)) { + VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 11)) { + VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 12)) + VERTEX_OUT("width = 0x%08x)", data[i]); + + for (tc = 0; tc <= 7; tc++) { + switch ((saved_s2 >> (tc * 4)) & 0xf) { + case 0x0: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + break; + case 0x1: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); + break; + case 0x3: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + break; + case 0x4: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + break; + case 0x5: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); + break; + case 0xf: + break; + default: + fprintf(out, "bad S2.T%d format\n", tc); + } + } + vertex++; + } } } else { /* indirect vertices */ @@ -459,7 +577,7 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, "3DPRIMITIVE random indirect"); } instr_out(data, hw_offset, 0, - "3DPRIMITIVE random indirect (%d)\n", len); + "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); if (len == 0) { /* vertex indices continue until 0xffff is found */ for (i = 1; i < count; i++) { @@ -503,15 +621,13 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, if (count < 2) BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); instr_out(data, hw_offset, 0, - "3DPRIMITIVE sequential indirect, %d starting from %d\n", - len, data[1] & 0xffff); + "3DPRIMITIVE sequential indirect %s, %d starting from " + "%d\n", primtype, len, data[1] & 0xffff); instr_out(data, hw_offset, 1, " start\n"); return 2; } } - - return len; } -- cgit v1.2.3 From 5d9dc02cbecd94f822f853fd01878784596f4eba Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 21 Jun 2007 12:57:15 -0700 Subject: Reset saved state for disasm when we've lost the context. --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 7 +++++++ src/mesa/drivers/dri/i915tex/i915_disasm.h | 1 + src/mesa/drivers/dri/i915tex/intel_context.c | 3 +++ 3 files changed, 11 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index ebb634654f..6ac34a1480 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -731,3 +731,10 @@ i915_disasm(uint32_t *data, int count, uint32_t hw_offset) return failures; } + +void i915_disasm_context_reset() +{ + saved_s2_set = 0; + saved_s4_set = 1; +} + diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.h b/src/mesa/drivers/dri/i915tex/i915_disasm.h index c74b036068..5eb620f9a4 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.h +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.h @@ -26,3 +26,4 @@ */ int i915_disasm(uint32_t *data, int count, uint32_t hw_offset); +void i915_disasm_context_reset(); diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index 696845a7fc..9d3f946830 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -59,6 +59,7 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" #include "intel_fbo.h" +#include "i915_disasm.h" #include "drirenderbuffer.h" #include "vblank.h" @@ -646,6 +647,8 @@ intelContendedLock(struct intel_context *intel, GLuint flags) if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) { sarea->texAge = intel->hHWContext; dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + if (INTEL_DEBUG & DEBUG_BATCH) + i915_disasm_context_reset(); } if (sarea->width != intelScreen->width || -- cgit v1.2.3 From 23e0ca2ebb0d123c7a40bb8b3687adb407c95504 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jul 2007 13:56:38 -0700 Subject: Fix copy'n'pasteo that broke display lists. --- src/mesa/drivers/dri/i915tex/intel_buffer_objects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index 1b95bfd47a..3c73c402d9 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -185,7 +185,7 @@ intel_bufferobj_get_subdata(GLcontext * ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - dri_bo_subdata(intel_obj->buffer, offset, size, data); + dri_bo_get_subdata(intel_obj->buffer, offset, size, data); } -- cgit v1.2.3 From f7643b96e9e526a7610dec51650546e4b916ccd2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Jul 2007 15:45:49 -0700 Subject: bufmgr_fake: Keep the bufmgr lock held while freeing a block. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index e08b5b3c7f..003ac49f3b 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -632,11 +632,11 @@ dri_fake_bo_unreference(dri_bo *bo) _glthread_LOCK_MUTEX(bufmgr_fake->mutex); if (--bo_fake->refcount == 0) { - _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); /* No remaining references, so free it */ if (bo_fake->block) free_block(bufmgr_fake, bo_fake->block); free_backing_store(bo); + _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); free(bo); return; } -- cgit v1.2.3 From d086f7ab2e38fc2b5398aed6823453ae53e5dcb8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 6 Jul 2007 12:01:33 -0700 Subject: bufmgr_ttm: hook up destroy function, track buffer names. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index fd432ba3f7..4c3624382c 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -56,6 +56,7 @@ typedef struct _dri_bo_ttm { int refcount; /* Protected by bufmgr->mutex */ drmBO drm_bo; + const char *name; } dri_bo_ttm; typedef struct _dri_fence_ttm @@ -124,6 +125,7 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.offset = ttm_buf->drm_bo.offset; ttm_buf->bo.virtual = NULL; ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->name = name; ttm_buf->refcount = 1; return &ttm_buf->bo; @@ -165,6 +167,7 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.offset = ttm_buf->drm_bo.offset; ttm_buf->bo.virtual = virtual; ttm_buf->bo.bufmgr = bufmgr; + ttm_buf->name = name; ttm_buf->refcount = 1; return &ttm_buf->bo; @@ -340,7 +343,7 @@ dri_ttm_fence_wait(dri_fence *fence) } static void -dri_fake_destroy(dri_bufmgr *bufmgr) +dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr) { dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr; @@ -381,6 +384,7 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference; bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference; bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; + bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy; /* Attempt an allocation to make sure that the DRM was actually set up for * TTM. -- cgit v1.2.3 From 9a4cc2e90595a41d3d3cb6a752e4b5a089a213d2 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 25 Jul 2007 10:12:23 -0700 Subject: Add notes about bufmgr initialization failures. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 1 + src/mesa/drivers/dri/i915tex/intel_screen.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 4c3624382c..6e29199cd8 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -392,6 +392,7 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation", 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT); if (test_alloc == NULL) { + fprintf(stderr, "TTM test allocation failed\n"); _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); free(bufmgr_ttm); return NULL; diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 89cf3ea913..a0471019e4 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -536,6 +536,8 @@ intelInitDriver(__DRIscreenPrivate * sPriv) __func__, __LINE__); return GL_FALSE; } + fprintf(stderr, "[%s:%u] Failed to init TTM buffer manager, falling back" + " to classic.\n", __func__, __LINE__); intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, intelScreen->tex.map, intelScreen->tex.size, -- cgit v1.2.3 From efda5cb6263631175aa2efe46df9322b3c5775ee Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Jul 2007 08:22:09 -0600 Subject: don't use rgba_line() if CHAN_BITS==32 --- src/mesa/swrast/s_lines.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c index 15ef6233ed..3de438760b 100644 --- a/src/mesa/swrast/s_lines.c +++ b/src/mesa/swrast/s_lines.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -279,7 +279,11 @@ _swrast_choose_line( GLcontext *ctx ) || ctx->Line.StippleFlag) { /* no texture, but Z, fog, width>1, stipple, etc. */ if (rgbmode) +#if CHAN_BITS == 32 + USE(general_line); +#else USE(rgba_line); +#endif else USE(ci_line); } -- cgit v1.2.3 From 51b728cf9aff383142a2a1e220a7d8963d1ca189 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Jul 2007 08:22:28 -0600 Subject: fix color interpolation for CHAN_BITS==32 --- src/mesa/swrast/s_span.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index f23272c2be..cfc65bee87 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1358,7 +1358,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) #if CHAN_BITS == 32 if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { - interpolate_int_colors(ctx, span); + interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); } #else if ((span->arrayMask & SPAN_RGBA) == 0) { -- cgit v1.2.3 From 9ed040c3c9afe06a8f6b28bc223751e3b2d65fe3 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Jul 2007 11:39:11 -0600 Subject: generate error upon writing to varying var in fragment program (bug 11733) --- src/mesa/shader/slang/slang_codegen.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 35e80e0452..c1664a5ccb 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2236,7 +2236,9 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) } if (var->type.qualifier == SLANG_QUAL_CONST || var->type.qualifier == SLANG_QUAL_ATTRIBUTE || - var->type.qualifier == SLANG_QUAL_UNIFORM) { + var->type.qualifier == SLANG_QUAL_UNIFORM || + (var->type.qualifier == SLANG_QUAL_VARYING && + A->program->Target == GL_FRAGMENT_PROGRAM_ARB)) { slang_info_log_error(A->log, "illegal assignment to read-only variable '%s'", (char *) oper->children[0].a_id); @@ -2264,10 +2266,11 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) lhs = _slang_gen_operation(A, &oper->children[0]); if (lhs) { - if (lhs->Store->File != PROGRAM_OUTPUT && - lhs->Store->File != PROGRAM_TEMPORARY && - lhs->Store->File != PROGRAM_VARYING && - lhs->Store->File != PROGRAM_UNDEFINED) { + if (!(lhs->Store->File == PROGRAM_OUTPUT || + lhs->Store->File == PROGRAM_TEMPORARY || + (lhs->Store->File == PROGRAM_VARYING && + A->program->Target == GL_VERTEX_PROGRAM_ARB) || + lhs->Store->File == PROGRAM_UNDEFINED)) { slang_info_log_error(A->log, "illegal assignment to read-only l-value"); return NULL; -- cgit v1.2.3 From e3cef5887540016a6d198598cb50bebe09e3f4cf Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Jul 2007 15:32:02 -0600 Subject: Fix function call bug 11731. Also, fix up IR_CALL/IR_FUNC confusion. --- src/mesa/shader/slang/slang_codegen.c | 27 +++++++++++++++++++-------- src/mesa/shader/slang/slang_emit.c | 16 +++++++++------- src/mesa/shader/slang/slang_ir.c | 2 +- src/mesa/shader/slang/slang_ir.h | 2 -- 4 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index c1664a5ccb..8b2bdd74b5 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -536,7 +536,7 @@ new_not(slang_ir_node *n) static slang_ir_node * new_inlined_function_call(slang_ir_node *code, slang_label *name) { - slang_ir_node *n = new_node1(IR_FUNC, code); + slang_ir_node *n = new_node1(IR_CALL, code); assert(name); if (n) n->Label = name; @@ -1202,17 +1202,29 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, /* non-assembly function */ inlined = slang_inline_function_call(A, fun, oper, dest); if (inlined && _slang_find_node_type(inlined, SLANG_OPER_RETURN)) { - /* This inlined function has one or more 'return' statements. + slang_operation *callOper; + /* The function we're calling has one or more 'return' statements. * So, we can't truly inline this function because we need to * implement 'return' with RET (and CAL). + * Nevertheless, we performed "inlining" to make a new instance + * of the function body to deal with static register allocation. + * * XXX check if there's one 'return' and if it's the very last * statement in the function - we can optimize that case. */ assert(inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE || inlined->type == SLANG_OPER_SEQUENCE); - inlined->type = SLANG_OPER_INLINED_CALL; - inlined->fun = fun; - inlined->label = _slang_label_new_unique((char*) fun->header.a_name); + if (_slang_function_has_return_value(fun) && !dest) { + assert(inlined->children[0].type == SLANG_OPER_VARIABLE_DECL); + assert(inlined->children[2].type == SLANG_OPER_IDENTIFIER); + callOper = &inlined->children[1]; + } + else { + callOper = inlined; + } + callOper->type = SLANG_OPER_INLINED_CALL; + callOper->fun = fun; + callOper->label = _slang_label_new_unique((char*) fun->header.a_name); } } @@ -1949,8 +1961,7 @@ static slang_ir_node * _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) { const GLboolean haveReturnValue - = (oper->num_children == 1 && - oper->children[0].type != SLANG_OPER_VOID); + = (oper->num_children == 1 && oper->children[0].type != SLANG_OPER_VOID); /* error checking */ assert(A->CurFunction); @@ -1960,7 +1971,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) return NULL; } else if (!haveReturnValue && - A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { + A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { slang_info_log_error(A->log, "return statement requires an expression"); return NULL; } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 02c74095a9..fe13f2865c 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -780,16 +780,18 @@ emit_label(slang_emit_info *emitInfo, const slang_ir_node *n) /** - * Emit code for an inlined function call (subroutine). + * Emit code for a function call. + * Note that for each time a function is called, we emit the function's + * body code again because the set of available registers may be different. */ static struct prog_instruction * -emit_func(slang_emit_info *emitInfo, slang_ir_node *n) +emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n) { struct gl_program *progSave; struct prog_instruction *inst; GLuint subroutineId; - assert(n->Opcode == IR_FUNC); + assert(n->Opcode == IR_CALL); assert(n->Label); /* save/push cur program */ @@ -1687,10 +1689,10 @@ emit(slang_emit_info *emitInfo, slang_ir_node *n) case IR_KILL: return emit_kill(emitInfo); - case IR_FUNC: - /* new variable scope for subroutines/function calls*/ + case IR_CALL: + /* new variable scope for subroutines/function calls */ _slang_push_var_table(emitInfo->vt); - inst = emit_func(emitInfo, n); + inst = emit_fcall(emitInfo, n); _slang_pop_var_table(emitInfo->vt); return inst; @@ -1782,7 +1784,7 @@ _slang_resolve_subroutines(slang_emit_info *emitInfo) emitInfo->NumSubroutines = 0; /* Examine CAL instructions. - * At this point, the BranchTarget field of the CAL instructions is + * At this point, the BranchTarget field of the CAL instruction is * the number/id of the subroutine to call (an index into the * emitInfo->Subroutines list). * Translate that into an actual instruction location now. diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c index a29f302687..92e8d0345e 100644 --- a/src/mesa/shader/slang/slang_ir.c +++ b/src/mesa/shader/slang/slang_ir.c @@ -311,7 +311,7 @@ _slang_print_ir_tree(const slang_ir_node *n, int indent) printf("RETURN\n"); break; case IR_CALL: - printf("CALL\n"); + printf("CALL %s\n", n->Label->Name); break; case IR_LOOP: diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 69db4b5451..c7c0ddbf9a 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -62,8 +62,6 @@ typedef enum IR_RETURN, /* return from subroutine */ IR_CALL, /* call subroutine */ - IR_FUNC, /* inlined function code */ - IR_LOOP, /* high-level loop-begin / loop-end */ /* Children[0] = loop body */ /* Children[1] = loop tail code, or NULL */ -- cgit v1.2.3 From 0fb0d9715c9bcdcc3437a64a0f03c1c1153e9f29 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 26 Jul 2007 16:42:05 -0600 Subject: fix-up inlined/non-inlined function inconsistencies --- src/mesa/shader/slang/slang_codegen.c | 19 +++++++++++-------- src/mesa/shader/slang/slang_compile_operation.h | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 8b2bdd74b5..24185cf677 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -491,6 +491,9 @@ new_node0(slang_ir_opcode op) } +/** + * Create sequence of two nodes. + */ static slang_ir_node * new_seq(slang_ir_node *left, slang_ir_node *right) { @@ -531,10 +534,10 @@ new_not(slang_ir_node *n) /** - * Inlined subroutine. + * Non-inlined function call. */ static slang_ir_node * -new_inlined_function_call(slang_ir_node *code, slang_label *name) +new_function_call(slang_ir_node *code, slang_label *name) { slang_ir_node *n = new_node1(IR_CALL, code); assert(name); @@ -1222,7 +1225,7 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, else { callOper = inlined; } - callOper->type = SLANG_OPER_INLINED_CALL; + callOper->type = SLANG_OPER_NON_INLINED_CALL; callOper->fun = fun; callOper->label = _slang_label_new_unique((char*) fun->header.a_name); } @@ -2585,7 +2588,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) _slang_free_ir_tree(tree); return NULL; /* error must have occured */ } - tree = tree ? new_seq(tree, n) : n; + tree = new_seq(tree, n); } #if 00 @@ -2813,17 +2816,17 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return n; } - case SLANG_OPER_INLINED_CALL: + case SLANG_OPER_NON_INLINED_CALL: case SLANG_OPER_SEQUENCE: { slang_ir_node *tree = NULL; GLuint i; for (i = 0; i < oper->num_children; i++) { slang_ir_node *n = _slang_gen_operation(A, &oper->children[i]); - tree = tree ? new_seq(tree, n) : n; + tree = new_seq(tree, n); } - if (oper->type == SLANG_OPER_INLINED_CALL) { - tree = new_inlined_function_call(tree, oper->label); + if (oper->type == SLANG_OPER_NON_INLINED_CALL) { + tree = new_function_call(tree, oper->label); } return tree; } diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h index d497b6f66f..d5cbe779a6 100644 --- a/src/mesa/shader/slang/slang_compile_operation.h +++ b/src/mesa/shader/slang/slang_compile_operation.h @@ -93,7 +93,7 @@ typedef enum slang_operation_type_ SLANG_OPER_NOT, /* "!" [expr] */ SLANG_OPER_SUBSCRIPT, /* [expr] "[" [expr] "]" */ SLANG_OPER_CALL, /* [func name] [param] [param] [...] */ - SLANG_OPER_INLINED_CALL, /* inlined function call */ + SLANG_OPER_NON_INLINED_CALL, /* a real function call */ SLANG_OPER_FIELD, /* i.e.: ".next" or ".xzy" or ".xxx" etc */ SLANG_OPER_POSTINCREMENT, /* [var] "++" */ SLANG_OPER_POSTDECREMENT /* [var] "--" */ -- cgit v1.2.3 From 35f35294cd5cc3ca32354b1de0e398ad73c70716 Mon Sep 17 00:00:00 2001 From: Zhang Date: Fri, 27 Jul 2007 11:19:35 -0600 Subject: more Mingw32 fixes --- docs/README.MINGW32 | 22 ++++++++++++++++---- include/GL/gl.h | 6 +----- include/GL/glut.h | 2 +- include/GL/mesa_wgl.h | 3 --- progs/samples/Makefile.mgw | 21 +++---------------- src/glu/sgi/Makefile.mgw | 35 ++++++++++++++++--------------- src/glut/glx/Makefile.mgw | 41 +++++++++++++++--------------------- src/mesa/Makefile.mgw | 52 +++++++++++++++++++++++----------------------- 8 files changed, 84 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/docs/README.MINGW32 b/docs/README.MINGW32 index 138dd43eac..9477b2bd31 100644 --- a/docs/README.MINGW32 +++ b/docs/README.MINGW32 @@ -91,9 +91,11 @@ Running the Build: -*******************This section is added by Heromyth***************************** -Updated on 2007-7-21, by Heromyth +******This section is added by Heromyth ************* +==================== +Updated on 2007-7-21 +==================== Notice: 1) The generated DLLs are *not* compatible with the ones built @@ -115,7 +117,7 @@ For example, run: , and delete all the lines where all the wgl*() functions are. Because they would be conflicted with the ones in \include\GL\mesa_wgl.h. -======= Conflicted Functions List ====== +>>>>>>>>>> Conflicted Functions List >>>>>>>>>> WINGDIAPI BOOL WINAPI wglCopyContext(HGLRC,HGLRC,UINT); WINGDIAPI HGLRC WINAPI wglCreateContext(HDC); WINGDIAPI HGLRC WINAPI wglCreateLayerContext(HDC,int); @@ -134,6 +136,18 @@ WINGDIAPI BOOL WINAPI wglUseFontBitmapsA(HDC,DWORD,DWORD,DWORD); WINGDIAPI BOOL WINAPI wglUseFontBitmapsW(HDC,DWORD,DWORD,DWORD); WINGDIAPI BOOL WINAPI wglUseFontOutlinesA(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT); WINGDIAPI BOOL WINAPI wglUseFontOutlinesW(HDC,DWORD,DWORD,DWORD,FLOAT,FLOAT,int,LPGLYPHMETRICSFLOAT); -=================== +<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + +==================== +Updated on 2007-7-22 +==================== + I havn't thought that I would find a better way to solve my problems so soon. +I changed the method in which the import-libs and DLLs are made. After this update, +the DLLs of MESA are more optimized and more compatible. + It seems that there is no need to keep the building way of 'NO-STDCALL'.The +way of USING_STDCALL is so nice! The file \configs\config.mgw is +also not needed, and can be deleted safely! + + ********************************************************************************* \ No newline at end of file diff --git a/include/GL/gl.h b/include/GL/gl.h index 09195aa136..3891a71875 100644 --- a/include/GL/gl.h +++ b/include/GL/gl.h @@ -58,11 +58,7 @@ # else /* for use with static link lib build of Win32 edition only */ # define GLAPI extern # endif /* _STATIC_MESA support */ -# if defined(__MINGW32__) && defined(GL_NO_STDCALL) /* The generated DLLs by MingW with STDCALL are not compatible with the ones done by Microsoft's compilers */ -# define GLAPIENTRY -# else -# define GLAPIENTRY __stdcall -# endif +# define GLAPIENTRY __stdcall #elif defined(__CYGWIN__) && defined(USE_OPENGL32) /* use native windows opengl32 */ # define GLAPI extern # define GLAPIENTRY __stdcall diff --git a/include/GL/glut.h b/include/GL/glut.h index e286349f9b..137b8efa13 100644 --- a/include/GL/glut.h +++ b/include/GL/glut.h @@ -112,7 +112,7 @@ extern _CRTIMP void __cdecl exit(int); and redifinition of Windows system defs, also removes requirement of pretty much any standard windows header from this file */ -#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__) +#if (_MSC_VER >= 800) || defined(__MINGW32__) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__) # define GLUTAPIENTRY __stdcall #else # define GLUTAPIENTRY diff --git a/include/GL/mesa_wgl.h b/include/GL/mesa_wgl.h index 1d774571d9..57147232b7 100644 --- a/include/GL/mesa_wgl.h +++ b/include/GL/mesa_wgl.h @@ -81,8 +81,6 @@ WGLAPI int GLAPIENTRY wglChoosePixelFormat(HDC, const PIXELFORMATDESCRIPTOR *) WGLAPI int GLAPIENTRY wglDescribePixelFormat(HDC,int, unsigned int, LPPIXELFORMATDESCRIPTOR); WGLAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc); - -#if defined(GL_NO_STDCALL) || !defined(__MINGW32__) WGLAPI int GLAPIENTRY wglCopyContext(HGLRC, HGLRC, unsigned int); WGLAPI HGLRC GLAPIENTRY wglCreateContext(HDC); WGLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC,int); @@ -101,7 +99,6 @@ WGLAPI int GLAPIENTRY wglUseFontBitmapsA(HDC, unsigned long, unsigned long, un WGLAPI int GLAPIENTRY wglUseFontBitmapsW(HDC, unsigned long, unsigned long, unsigned long); WGLAPI int GLAPIENTRY wglUseFontOutlinesA(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT); WGLAPI int GLAPIENTRY wglUseFontOutlinesW(HDC, unsigned long, unsigned long, unsigned long, float,float, int, LPGLYPHMETRICSFLOAT); -#endif #ifndef __MINGW32__ WGLAPI int GLAPIENTRY SwapBuffers(HDC); diff --git a/progs/samples/Makefile.mgw b/progs/samples/Makefile.mgw index 3b2fd785de..8bb975be9d 100644 --- a/progs/samples/Makefile.mgw +++ b/progs/samples/Makefile.mgw @@ -53,14 +53,9 @@ TOP = ../.. -include $(TOP)/configs/config.mgw -ALL_USING_STDCALL ?= 1 -GL_USING_STDCALL ?= 1 -GLUT_USING_STDCALL ?= 1 - CC = mingw32-gcc CFLAGS = -Wall -pedantic -CFLAGS += -O2 -ffast-math +CFLAGS += -O2 -ffast-math -D_DLL CFLAGS += -I$(TOP)/include -I../util ifeq ($(FX),1) CFLAGS += -DFX @@ -68,17 +63,6 @@ endif CFLAGS += -DGLUT_DISABLE_ATEXIT_HACK -ifeq ($(GL_USING_STDCALL),0) - CFLAGS += -DGL_NO_STDCALL -endif - -ifeq ($(GLUT_USING_STDCALL),1) - CFLAGS += -D_STDCALL_SUPPORTED -else - CFLAGS += -DGLUT_NO_STDCALL -endif - - LD = mingw32-g++ LDFLAGS = -s -L$(TOP)/lib @@ -87,7 +71,8 @@ LDLIBS = -lglut32 -lglu32 -lopengl32 .c.o: $(CC) -o $@ $(CFLAGS) -c $< %.exe: ../util/readtex.o ../util/showbuffer.o %.o - $(LD) -o $@ $(LDFLAGS) $^ $(LDLIBS) + $(LD) -o $@ $(LDFLAGS) $(LDLIBS) $^ + all: $(error Must specify to build) diff --git a/src/glu/sgi/Makefile.mgw b/src/glu/sgi/Makefile.mgw index 43b421e737..d00d97a3b6 100644 --- a/src/glu/sgi/Makefile.mgw +++ b/src/glu/sgi/Makefile.mgw @@ -70,30 +70,31 @@ TOOLS_PREFIX = mingw32- TOP = ../../.. - LIBDIR = $(TOP)/lib -GLU_DLL = glu32.dll -GLU_IMP = libglu32.a -GLU_DEF = glu.def +LIB_NAME = glu32 +DLL_EXT = .dll +IMP_EXT = .a +LIB_PRE = lib +STRIP = -s + +AR = ar +ARFLAGS = crus +DLLTOOL = dlltool -include $(TOP)/configs/config.mgw -GL_USING_STDCALL ?= 1 +GLU_DLL = $(LIB_NAME)$(DLL_EXT) +GLU_IMP = $(LIB_PRE)$(LIB_NAME)$(IMP_EXT) +GLU_DEF = $(LIB_NAME).def LDLIBS = -L$(LIBDIR) -lopengl32 -LDFLAGS = -Wl,--out-implib=$(LIBDIR)/$(GLU_IMP) -Wl,--output-def=$(LIBDIR)/$(GLU_DEF) +LDFLAGS = $(STRIP) -shared -fPIC -Wl,--kill-at CFLAGS += -DBUILD_GLU32 -D_DLL -ifeq ($(GL_USING_STDCALL),1) - LDFLAGS += -Wl,--add-stdcall-alias -else - CFLAGS += -DGL_NO_STDCALL -endif -CC = gcc +CC = $(TOOLS_PREFIX)gcc CFLAGS += -DNDEBUG -DLIBRARYBUILD -I$(TOP)/include -Iinclude -CXX = g++ +CXX = $(TOOLS_PREFIX)g++ CXXFLAGS = $(CFLAGS) -Ilibnurbs/internals -Ilibnurbs/interface -Ilibnurbs/nurbtess AR = ar @@ -216,9 +217,9 @@ $(LIBDIR): mkdir -p $(LIBDIR) $(LIBDIR)/$(GLU_DLL) $(LIBDIR)/$(GLU_IMP): $(OBJECTS) - g++ -shared -fPIC -o $(LIBDIR)/$(GLU_DLL) $(LDFLAGS) \ - $^ $(LDLIBS) - + $(CXX) $(LDFLAGS) -o $(LIBDIR)/$(GLU_DLL) $^ $(LDLIBS) + $(DLLTOOL) --as=as --dllname $(LIB_NAME) --output-def $(LIBDIR)/$(GLU_DEF) $^ + $(DLLTOOL) --as=as -k --dllname $(LIB_NAME) --output-lib $(LIBDIR)/$(GLU_IMP) --def $(LIBDIR)/$(GLU_DEF) clean: diff --git a/src/glut/glx/Makefile.mgw b/src/glut/glx/Makefile.mgw index ae4eb6addc..9fff2e1503 100644 --- a/src/glut/glx/Makefile.mgw +++ b/src/glut/glx/Makefile.mgw @@ -74,35 +74,29 @@ TOP = ../../.. LIBDIR = $(TOP)/lib -GLUT_DLL = glut32.dll -GLUT_IMP = libglut32.a -GLUT_DEF = glut.def +LIB_NAME = glut32 -include $(TOP)/configs/config.mgw -GLUT_USING_STDCALL ?= 1 +DLL_EXT = .dll +IMP_EXT = .a +LIB_PRE = lib +STRIP = -s +AR = ar +ARFLAGS = crus +DLLTOOL = dlltool +GLUT_DLL = $(LIB_NAME)$(DLL_EXT) +GLUT_IMP = $(LIB_PRE)$(LIB_NAME)$(IMP_EXT) +GLUT_DEF = $(LIB_NAME).def LDLIBS = -L$(LIBDIR) -lwinmm -lgdi32 -luser32 -lopengl32 -lglu32 -LDFLAGS = -Wl,--out-implib=$(LIBDIR)/$(GLUT_IMP) -Wl,--output-def=$(LIBDIR)/$(GLUT_DEF) +LDFLAGS = $(STRIP) -shared -fPIC -Wl,--kill-at CFLAGS += -DBUILD_GLUT32 -DGLUT_BUILDING_LIB -DMESA -D_DLL - -ifeq ($(GL_USING_STDCALL),0) - CFLAGS += -DGL_NO_STDCALL -endif - -ifeq ($(GLUT_USING_STDCALL),1) - CFLAGS += -D_STDCALL_SUPPORTED - LDFLAGS += -Wl,--add-stdcall-alias -else - CFLAGS += -DGLUT_NO_STDCALL -endif - CFLAGS += -DNDEBUG -DLIBRARYBUILD -I$(TOP)/include -CC = gcc -CXX = g++ +CC = $(TOOLS_PREFIX)gcc +CXX = $(TOOLS_PREFIX)g++ CXXFLAGS = $(CFLAGS) AR = ar @@ -189,10 +183,9 @@ $(LIBDIR): mkdir -p $(LIBDIR) $(LIBDIR)/$(GLUT_DLL) $(LIBDIR)/$(GLUT_IMP): $(OBJECTS) - $(CXX) -shared -fPIC -o $(LIBDIR)/$(GLUT_DLL) $(LDFLAGS) \ - $^ $(LDLIBS) - - + $(CXX) $(LDFLAGS) -o $(LIBDIR)/$(GLUT_DLL) $^ $(LDLIBS) + $(DLLTOOL) --as=as --dllname $(LIB_NAME) --output-def $(LIBDIR)/$(GLUT_DEF) $^ + $(DLLTOOL) --as=as -k --dllname $(LIB_NAME) --output-lib $(LIBDIR)/$(GLUT_IMP) --def $(LIBDIR)/$(GLUT_DEF) clean: -$(call UNLINK,*.o) \ No newline at end of file diff --git a/src/mesa/Makefile.mgw b/src/mesa/Makefile.mgw index 3b52834bd1..6244ded876 100644 --- a/src/mesa/Makefile.mgw +++ b/src/mesa/Makefile.mgw @@ -69,39 +69,37 @@ # Set this to the prefix of your build tools, i.e. mingw32- TOOLS_PREFIX = mingw32- +ifeq ($(ICD),1) + LIB_NAME = mesa32 +else + LIB_NAME = opengl32 +endif +DLL_EXT = .dll +IMP_EXT = .a +LIB_PRE = lib +STRIP = -s + +AR = ar +ARFLAGS = crus +DLLTOOL = dlltool TOP = ../.. GLIDE ?= $(TOP)/glide3 LIBDIR = $(TOP)/lib -ifeq ($(ICD),1) - GL_DLL = mesa32.dll - GL_IMP = libmesa32.a -else - GL_DLL = opengl32.dll - GL_IMP = libopengl32.a -endif - -GL_DEF = gl.def -include $(TOP)/configs/config.mgw -GL_USING_STDCALL ?= 1 +GL_DLL = $(LIB_NAME)$(DLL_EXT) +GL_IMP = $(LIB_PRE)$(LIB_NAME)$(IMP_EXT) MESA_LIB = libmesa.a +CC = $(TOOLS_PREFIX)gcc LDLIBS = -lgdi32 -luser32 -liberty -LDFLAGS = -Wl,--out-implib=$(LIBDIR)/$(GL_IMP) -Wl,--output-def=$(LIBDIR)/gl.def - -CC = $(TOOLS_PREFIX)gcc -CFLAGS += -DBUILD_GL32 -D_OPENGL32_ -D_DLL -DMESA_MINWARN -DNDEBUG -D_USRDLL -DGDI_EXPORTS +LDFLAGS = $(STRIP) -shared -fPIC -Wl,--kill-at -ifeq ($(GL_USING_STDCALL),1) - LDFLAGS += -Wl,--add-stdcall-alias -else - CFLAGS += -DGL_NO_STDCALL -endif +CFLAGS += -DBUILD_GL32 -D_DLL -DMESA_MINWARN +CFLAGS += -DNDEBUG -DUSE_EXTERNAL_DXTN_LIB=1 -CFLAGS += -DUSE_EXTERNAL_DXTN_LIB=1 ifeq ($(FX),1) CFLAGS += -I$(GLIDE)/include -DFX LDLIBS += -L$(GLIDE)/lib -lglide3x @@ -112,12 +110,11 @@ else CFLAGS += -DUSE_MGL_NAMESPACE GL_DEF = drivers/windows/icd/mesa.def else - GL_DEF = drivers/windows/gdi/mesa.def + GL_DEF = $(LIB_NAME).def endif endif -AR = ar -ARFLAGS = crus + UNLINK = del $(subst /,\,$(1)) ifneq ($(wildcard $(addsuffix /rm.exe,$(subst ;, ,$(PATH)))),) @@ -173,14 +170,17 @@ RESOURCE = $(GL_RES:.rc=.res) .rc.res: windres -o $@ -Irc -Ocoff $< + all: $(LIBDIR) $(LIBDIR)/$(GL_DLL) $(LIBDIR)/$(GL_IMP) $(LIBDIR): mkdir -p $(LIBDIR) $(LIBDIR)/$(GL_DLL) $(LIBDIR)/$(GL_IMP): $(OBJECTS) $(RESOURCE) - $(CC) -shared -fPIC -o $(LIBDIR)/$(GL_DLL) $(LDFLAGS) \ - $^ $(LDLIBS) + $(CC) $(LDFLAGS) -o $(LIBDIR)/$(GL_DLL) $^ $(LDLIBS) + $(DLLTOOL) --as=as --dllname $(LIB_NAME) --output-def $(LIBDIR)/$(GL_DEF) $^ + $(DLLTOOL) --as=as -k --dllname $(LIB_NAME) --output-lib $(LIBDIR)/$(GL_IMP) --def $(LIBDIR)/$(GL_DEF) + $(X86_OBJECTS): x86/matypes.h -- cgit v1.2.3 From a188ba4bf9364df24842d8727f4c7ddb2f894a2c Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sun, 29 Jul 2007 18:04:28 +0200 Subject: Fix crashes when the frag prog can't be handled in hardware (#11131) Must not change to/from swrast after Render.Start or bad things will happen. (Driver will still somewhat incorrectly report an implementation error, and apps can't really figure out if a prog is natively supported as validation is later - could try doing it earlier to give some hint at least, even though native status may still change later due to fog etc.) --- src/mesa/drivers/dri/i915tex/i830_vtbl.c | 6 ++++++ src/mesa/drivers/dri/i915tex/i915_vtbl.c | 8 +++++++- src/mesa/drivers/dri/i915tex/intel_context.h | 1 + src/mesa/drivers/dri/i915tex/intel_render.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c index e432648ada..a3db6c0c0c 100644 --- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -60,6 +60,11 @@ do { \ #define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) #define TEXBIND_SET(n, x) ((x)<<((n)*4)) +static void +i830_render_prevalidate(struct intel_context *intel) +{ +} + static void i830_render_start(struct intel_context *intel) { @@ -657,5 +662,6 @@ i830InitVtbl(struct i830_context *i830) i830->intel.vtbl.update_texture_state = i830UpdateTextureState; i830->intel.vtbl.flush_cmd = i830_flush_cmd; i830->intel.vtbl.render_start = i830_render_start; + i830->intel.vtbl.render_prevalidate = i830_render_prevalidate; i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; } diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index ad333b490b..9de35d8e29 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -44,13 +44,18 @@ #include "i915_context.h" static void -i915_render_start(struct intel_context *intel) +i915_render_prevalidate(struct intel_context *intel) { struct i915_context *i915 = i915_context(&intel->ctx); i915ValidateFragmentProgram(i915); } +static void +i915_render_start(struct intel_context *intel) +{ +} + static void i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) @@ -546,6 +551,7 @@ i915InitVtbl(struct i915_context *i915) i915->intel.vtbl.lost_hardware = i915_lost_hardware; i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; i915->intel.vtbl.render_start = i915_render_start; + i915->intel.vtbl.render_prevalidate = i915_render_prevalidate; i915->intel.vtbl.set_draw_region = i915_set_draw_region; i915->intel.vtbl.update_texture_state = i915UpdateTextureState; i915->intel.vtbl.flush_cmd = i915_flush_cmd; diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 9d060eb866..ddd1439b00 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -131,6 +131,7 @@ struct intel_context void (*update_texture_state) (struct intel_context * intel); void (*render_start) (struct intel_context * intel); + void (*render_prevalidate) (struct intel_context * intel); void (*set_draw_region) (struct intel_context * intel, struct intel_region * draw_region, struct intel_region * depth_region); diff --git a/src/mesa/drivers/dri/i915tex/intel_render.c b/src/mesa/drivers/dri/i915tex/intel_render.c index f9fa55051e..c8b6d308d9 100644 --- a/src/mesa/drivers/dri/i915tex/intel_render.c +++ b/src/mesa/drivers/dri/i915tex/intel_render.c @@ -202,6 +202,8 @@ intel_run_render(GLcontext * ctx, struct tnl_pipeline_stage *stage) struct vertex_buffer *VB = &tnl->vb; GLuint i; + intel->vtbl.render_prevalidate( intel ); + /* Don't handle clipping or indexed vertices. */ if (intel->RenderIndex != 0 || -- cgit v1.2.3 From 10f5a6ac85fb5f78069b7314e40a2a23e2636192 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sun, 29 Jul 2007 18:31:36 +0200 Subject: fix fallback crashes when driver can't handle frag prog for i915 driver too (untested) --- src/mesa/drivers/dri/i915/i830_vtbl.c | 6 ++++++ src/mesa/drivers/dri/i915/i915_vtbl.c | 8 +++++++- src/mesa/drivers/dri/i915/intel_context.h | 1 + src/mesa/drivers/dri/i915/intel_render.c | 2 ++ src/mesa/drivers/dri/i915tex/i915_context.h | 6 ------ 5 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index d40cf705a3..cf1d0b0c1e 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -59,6 +59,11 @@ do { \ #define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) #define TEXBIND_SET(n, x) ((x)<<((n)*4)) + static void +i830_render_prevalidate(struct intel_context *intel) +{ +} + static void i830_render_start( intelContextPtr intel ) { GLcontext *ctx = &intel->ctx; @@ -531,4 +536,5 @@ void i830InitVtbl( i830ContextPtr i830 ) i830->intel.vtbl.update_texture_state = i830UpdateTextureState; i830->intel.vtbl.emit_flush = i830_emit_flush; i830->intel.vtbl.render_start = i830_render_start; + i830->intel.vtbl.render_prevalidate = i830_render_prevalidate; } diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index cc8a605e50..4ad95cf4e3 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -41,7 +41,8 @@ #include "i915_reg.h" #include "i915_context.h" -static void i915_render_start( intelContextPtr intel ) +static void +i915_render_prevalidate(struct intel_context *intel) { GLcontext *ctx = &intel->ctx; i915ContextPtr i915 = I915_CONTEXT(intel); @@ -54,6 +55,10 @@ static void i915_render_start( intelContextPtr intel ) } } +static void i915_render_start( intelContextPtr intel ) +{ +} + static void i915_reduced_primitive_state( intelContextPtr intel, GLenum rprim ) @@ -454,6 +459,7 @@ void i915InitVtbl( i915ContextPtr i915 ) i915->intel.vtbl.lost_hardware = i915_lost_hardware; i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; i915->intel.vtbl.render_start = i915_render_start; + i915->intel.vtbl.render_prevalidate = i915_render_prevalidate; i915->intel.vtbl.set_color_region = i915_set_color_region; i915->intel.vtbl.set_z_region = i915_set_z_region; i915->intel.vtbl.update_color_z_regions = i915_update_color_z_regions; diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 3b50107d73..914533d11b 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -112,6 +112,7 @@ struct intel_context void (*update_texture_state)( intelContextPtr intel ); void (*render_start)( intelContextPtr intel ); + void (*render_prevalidate) (struct intel_context * intel); void (*set_color_region)( intelContextPtr intel, const intelRegion *reg ); void (*set_z_region)( intelContextPtr intel, const intelRegion *reg ); void (*update_color_z_regions)(intelContextPtr intel, diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index d9438ba0fd..7bc02ba807 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -199,6 +199,8 @@ static GLboolean intel_run_render( GLcontext *ctx, struct vertex_buffer *VB = &tnl->vb; GLuint i; + intel->vtbl.render_prevalidate( intel ); + /* Don't handle clipping or indexed vertices. */ if (intel->RenderIndex != 0 || diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h index d2713e88f9..3a41d66c14 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -308,12 +308,6 @@ extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, void *sharedContextPrivate); -/*====================================================================== - * i915_texprog.c - */ -extern void i915ValidateTextureProgram(struct i915_context *i915); - - /*====================================================================== * i915_debug.c */ -- cgit v1.2.3 From dde814776c1feee30e986858782c14d9b0feeaea Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sun, 29 Jul 2007 19:40:50 +0200 Subject: fix range reduction for sin/cos in i915tex (#11609) --- src/mesa/drivers/dri/i915tex/i915_fragprog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c index a4b22a0c32..95ec50490a 100644 --- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c @@ -320,7 +320,7 @@ upload_program(struct i915_fragment_program *p) i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, - src0, i915_emit_const1f(p, 1.0 / (M_PI * 2)), 0); + src0, i915_emit_const1f(p, 1.0 / (M_PI)), 0); i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); @@ -329,7 +329,7 @@ upload_program(struct i915_fragment_program *p) i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, - tmp, i915_emit_const1f(p, (M_PI * 2)), 0); + tmp, i915_emit_const1f(p, (M_PI)), 0); /* * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 @@ -642,7 +642,7 @@ upload_program(struct i915_fragment_program *p) i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, - src0, i915_emit_const1f(p, 1.0 / (M_PI * 2)), 0); + src0, i915_emit_const1f(p, 1.0 / (M_PI)), 0); i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); @@ -651,7 +651,7 @@ upload_program(struct i915_fragment_program *p) i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, - tmp, i915_emit_const1f(p, (M_PI * 2)), 0); + tmp, i915_emit_const1f(p, (M_PI)), 0); /* * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 -- cgit v1.2.3 From ab02552cdddf9322bfaf874f85d74e7c174a0f3b Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sun, 29 Jul 2007 19:44:55 +0200 Subject: fix cos/sin range reduction for i915 driver too --- src/mesa/drivers/dri/i915/i915_fragprog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 702b878828..abca0bbffe 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -304,7 +304,7 @@ static void upload_program( struct i915_fragment_program *p ) A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, src0, - i915_emit_const1f(p, 1.0/(M_PI * 2)), + i915_emit_const1f(p, 1.0/(M_PI)), 0); i915_emit_arith( p, @@ -319,7 +319,7 @@ static void upload_program( struct i915_fragment_program *p ) A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, - i915_emit_const1f(p, (M_PI * 2)), + i915_emit_const1f(p, (M_PI)), 0); /* @@ -645,7 +645,7 @@ static void upload_program( struct i915_fragment_program *p ) A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, src0, - i915_emit_const1f(p, 1.0/(M_PI * 2)), + i915_emit_const1f(p, 1.0/(M_PI)), 0); i915_emit_arith( p, @@ -660,7 +660,7 @@ static void upload_program( struct i915_fragment_program *p ) A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, - i915_emit_const1f(p, (M_PI * 2)), + i915_emit_const1f(p, (M_PI)), 0); /* -- cgit v1.2.3 From eefb04a2b8599d4c5ec033539c1348cbe46154f9 Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Sun, 29 Jul 2007 18:26:22 -0600 Subject: fix glPointParameteriv bug 11754 --- src/mesa/main/points.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index e83db5de78..88e4989405 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -5,7 +5,7 @@ /* * Mesa 3-D graphics library - * Version: 7.0 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -82,8 +82,13 @@ _mesa_PointParameteriNV( GLenum pname, GLint param ) void GLAPIENTRY _mesa_PointParameterivNV( GLenum pname, const GLint *params ) { - const GLfloat value = (GLfloat) params[0]; - _mesa_PointParameterfvEXT(pname, &value); + GLfloat p[3]; + p[0] = (GLfloat) params[0]; + if (pname == GL_DISTANCE_ATTENUATION_EXT) { + p[1] = (GLfloat) params[1]; + p[2] = (GLfloat) params[2]; + } + _mesa_PointParameterfvEXT(pname, p); } -- cgit v1.2.3 From 60179434d15989b81e2d4757f34033009184a678 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Mon, 30 Jul 2007 10:18:11 +0800 Subject: ARB sprite point support on i965 --- src/mesa/drivers/dri/i965/brw_sf.c | 15 ++++-- src/mesa/drivers/dri/i965/brw_sf.h | 9 +++- src/mesa/drivers/dri/i965/brw_sf_emit.c | 80 +++++++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_context.c | 5 ++ 4 files changed, 105 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index d5175399d6..73232b3c7c 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -74,6 +74,11 @@ static void compile_sf_prog( struct brw_context *brw, if (c.key.attrs & (1<= VERT_RESULT_TEX0 && i <= VERT_RESULT_TEX7) { + c.point_attrs[i].CoordReplace = + brw->attribs.Point->CoordReplace[i - VERT_RESULT_TEX0]; + } else + c.point_attrs[i].CoordReplace = GL_FALSE; idx++; } @@ -90,7 +95,10 @@ static void compile_sf_prog( struct brw_context *brw, break; case SF_POINTS: c.nr_verts = 1; - brw_emit_point_setup( &c ); + if (key->do_point_sprite) + brw_emit_point_sprite_setup( &c ); + else + brw_emit_point_setup( &c ); break; case SF_UNFILLED_TRIS: c.nr_verts = 3; @@ -162,7 +170,8 @@ static void upload_sf_prog( struct brw_context *brw ) break; } - + key.do_point_sprite = brw->attribs.Point->PointSprite; + key.SpriteOrigin = brw->attribs.Point->SpriteOrigin; /* _NEW_LIGHT */ key.do_flat_shading = (brw->attribs.Light->ShadeModel == GL_FLAT); key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide); @@ -179,7 +188,7 @@ static void upload_sf_prog( struct brw_context *brw ) const struct brw_tracked_state brw_sf_prog = { .dirty = { - .mesa = (_NEW_LIGHT|_NEW_POLYGON), + .mesa = (_NEW_LIGHT|_NEW_POLYGON|_NEW_POINT), .brw = (BRW_NEW_REDUCED_PRIMITIVE), .cache = CACHE_NEW_VS_PROG }, diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index fb72b84ba8..e374e372bb 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -50,9 +50,14 @@ struct brw_sf_prog_key { GLuint do_flat_shading:1; GLuint attrs:16; GLuint frontface_ccw:1; - GLuint pad:11; + GLuint do_point_sprite:1; + GLuint pad:10; + GLenum SpriteOrigin; }; +struct brw_sf_point_tex { + GLboolean CoordReplace; +}; struct brw_sf_compile { struct brw_compile func; @@ -94,12 +99,14 @@ struct brw_sf_compile { GLubyte attr_to_idx[VERT_RESULT_MAX]; GLubyte idx_to_attr[VERT_RESULT_MAX]; + struct brw_sf_point_tex point_attrs[VERT_RESULT_MAX]; }; void brw_emit_tri_setup( struct brw_sf_compile *c ); void brw_emit_line_setup( struct brw_sf_compile *c ); void brw_emit_point_setup( struct brw_sf_compile *c ); +void brw_emit_point_sprite_setup( struct brw_sf_compile *c ); void brw_emit_anyprim_setup( struct brw_sf_compile *c ); #endif diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index cbaf018c44..7ecf9bb560 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -497,6 +497,86 @@ void brw_emit_line_setup( struct brw_sf_compile *c ) } } +void brw_emit_point_sprite_setup( struct brw_sf_compile *c ) +{ + struct brw_compile *p = &c->func; + GLuint i; + + c->nr_verts = 1; + alloc_regs(c); + copy_z_inv_w(c); + for (i = 0; i < c->nr_setup_regs; i++) + { + struct brw_sf_point_tex *tex = &c->point_attrs[c->idx_to_attr[2*i]]; + struct brw_reg a0 = offset(c->vert[0], i); + GLushort pc, pc_persp, pc_linear; + GLboolean last = calculate_masks(c, i, &pc, &pc_persp, &pc_linear); + + if (pc_persp) + { + if (!tex->CoordReplace) { + brw_set_predicate_control_flag_value(p, pc_persp); + brw_MUL(p, a0, a0, c->inv_w[0]); + } + } + + if (tex->CoordReplace) { + /* Caculate 1.0/PointWidth */ + brw_math(&c->func, + c->tmp, + BRW_MATH_FUNCTION_INV, + BRW_MATH_SATURATE_NONE, + 0, + c->dx0, + BRW_MATH_DATA_SCALAR, + BRW_MATH_PRECISION_FULL); + + if (c->key.SpriteOrigin == GL_UPPER_LEFT) { + brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); + brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); + brw_MUL(p, c->m2Cy, c->tmp, negate(c->inv_w[0])); + brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); + } else { + brw_MUL(p, c->m1Cx, c->tmp, c->inv_w[0]); + brw_MOV(p, vec1(suboffset(c->m1Cx, 1)), brw_imm_f(0.0)); + brw_MUL(p, c->m2Cy, c->tmp, c->inv_w[0]); + brw_MOV(p, vec1(suboffset(c->m2Cy, 0)), brw_imm_f(0.0)); + } + } else { + brw_MOV(p, c->m1Cx, brw_imm_ud(0)); + brw_MOV(p, c->m2Cy, brw_imm_ud(0)); + } + + { + brw_set_predicate_control_flag_value(p, pc); + if (tex->CoordReplace) { + if (c->key.SpriteOrigin == GL_UPPER_LEFT) { + brw_MUL(p, c->m3C0, c->inv_w[0], brw_imm_f(1.0)); + brw_MOV(p, vec1(suboffset(c->m3C0, 0)), brw_imm_f(0.0)); + } + else + brw_MOV(p, c->m3C0, brw_imm_f(0.0)); + } else { + brw_MOV(p, c->m3C0, a0); /* constant value */ + } + + /* Copy m0..m3 to URB. + */ + brw_urb_WRITE(p, + brw_null_reg(), + 0, + brw_vec8_grf(0, 0), + 0, /* allocate */ + 1, /* used */ + 4, /* msg len */ + 0, /* response len */ + last, /* eot */ + last, /* writes complete */ + i*4, /* urb destination offset */ + BRW_URB_SWIZZLE_TRANSPOSE); + } + } +} /* Points setup - several simplifications as all attributes are * constant across the face of the point (point sprites excluded!) diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 4f51fefe0f..a8204ee4b8 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -66,6 +66,7 @@ int INTEL_DEBUG = (0); #endif +#define need_GL_NV_point_sprite #define need_GL_ARB_multisample #define need_GL_ARB_point_parameters #define need_GL_ARB_texture_compression @@ -81,6 +82,7 @@ int INTEL_DEBUG = (0); #define need_GL_EXT_fog_coord #define need_GL_EXT_multi_draw_arrays #define need_GL_EXT_secondary_color +#define need_GL_EXT_point_parameters #include "extension_helper.h" #ifndef VERBOSE @@ -146,6 +148,7 @@ const struct dri_extension card_extensions[] = { "GL_ARB_multisample", GL_ARB_multisample_functions }, { "GL_ARB_multitexture", NULL }, { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, + { "GL_NV_point_sprite", GL_NV_point_sprite_functions }, { "GL_ARB_texture_border_clamp", NULL }, { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, { "GL_ARB_texture_cube_map", NULL }, @@ -158,6 +161,8 @@ const struct dri_extension card_extensions[] = { "GL_NV_texture_rectangle", NULL }, { "GL_EXT_texture_rectangle", NULL }, { "GL_ARB_texture_rectangle", NULL }, + { "GL_ARB_point_sprite", NULL}, + { "GL_ARB_point_parameters", NULL }, { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, -- cgit v1.2.3 From 775ebb696dffaf6fddc170862ecb375e6cdfcb9c Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 30 Jul 2007 16:17:40 +0800 Subject: Fix an error related to glPolygonStipple. As glPixelStore(GL_UNPACK) affect the bits into a stipple pattern, hence 128 bytes used to store the pattern in a display list aren't enough sometimes. --- src/mesa/main/dlist.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 293ee5fa34..f50c19f2ce 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -2723,15 +2723,17 @@ static void GLAPIENTRY save_PolygonStipple(const GLubyte * pattern) { GET_CURRENT_CONTEXT(ctx); + GLvoid *image = unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP, + pattern, &ctx->Unpack); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_STIPPLE, 1); if (n) { - void *data; - n[1].data = _mesa_malloc(32 * 4); - data = n[1].data; /* This needed for Acorn compiler */ - MEMCPY(data, pattern, 32 * 4); + n[1].data = image; + } else if (image) { + _mesa_free(image); } + if (ctx->ExecuteFlag) { CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern)); } @@ -6169,7 +6171,12 @@ execute_list(GLcontext *ctx, GLuint list) CALL_PolygonMode(ctx->Exec, (n[1].e, n[2].e)); break; case OPCODE_POLYGON_STIPPLE: - CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data)); + { + const struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = ctx->DefaultPacking; + CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data)); + ctx->Unpack = save; /* restore */ + } break; case OPCODE_POLYGON_OFFSET: CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f)); -- cgit v1.2.3 From 501b5305b939ac38177dcd73ec72f4a39296e0c4 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 30 Jul 2007 16:30:32 +0800 Subject: handle LSB_FIRST in _mesa_pack_bitmap by the way used in _mesa_unpack_bitmap --- src/mesa/main/image.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index ba46cdc1b1..8fccd44f21 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -850,7 +850,7 @@ _mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels, return NULL; } - if (packing->SkipPixels == 0) { + if ((packing->SkipPixels & 7) == 0) { _mesa_memcpy( dst, src, width_in_bytes ); if (packing->LsbFirst) { flip_bytes( dst, width_in_bytes ); @@ -942,7 +942,7 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, if (!dst) return; - if (packing->SkipPixels == 0) { + if ((packing->SkipPixels & 7) == 0) { _mesa_memcpy( dst, src, width_in_bytes ); if (packing->LsbFirst) { flip_bytes( dst, width_in_bytes ); @@ -961,20 +961,20 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, if (*s & srcMask) { *d |= dstMask; } - if (srcMask == 128) { - srcMask = 1; + if (srcMask == 1) { + srcMask = 128; s++; } else { - srcMask = srcMask << 1; + srcMask = srcMask >> 1; } - if (dstMask == 1) { - dstMask = 128; + if (dstMask == 128) { + dstMask = 1; d++; *d = 0; } else { - dstMask = dstMask >> 1; + dstMask = dstMask << 1; } } } -- cgit v1.2.3 From baac66cb0519cb85373fb079696d44e42d382577 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 30 Jul 2007 08:13:40 -0600 Subject: remove old comment, minor formatting fixes --- src/mesa/main/dlist.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index f50c19f2ce..be2f438a94 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -2716,9 +2716,6 @@ save_PolygonMode(GLenum face, GLenum mode) } -/* - * Polygon stipple must have been upacked already! - */ static void GLAPIENTRY save_PolygonStipple(const GLubyte * pattern) { @@ -2730,10 +2727,10 @@ save_PolygonStipple(const GLubyte * pattern) n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_STIPPLE, 1); if (n) { n[1].data = image; - } else if (image) { - _mesa_free(image); } - + else if (image) { + _mesa_free(image); + } if (ctx->ExecuteFlag) { CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern)); } -- cgit v1.2.3 From 2394d20dafdfa308d494fc739c63c6a4e91c8185 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 30 Jul 2007 23:50:52 +0800 Subject: Fix an error in _mesa_validate_DrawElements The field 'Data' in an obj is NULL in some dri drivers(such as i965). Use mapped pointer instead. --- src/mesa/main/api_validate.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 841c6a5302..18dead61c3 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -35,6 +35,7 @@ _mesa_validate_DrawElements(GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { + GLboolean mapped = GL_FALSE; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (count <= 0) { @@ -67,13 +68,19 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { GLuint indexBytes; + const GLvoid *map = ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + GL_READ_ONLY, + ctx->Array.ElementArrayBufferObj); /* use indices in the buffer object */ - if (!ctx->Array.ElementArrayBufferObj->Data) { + if (!map) { _mesa_warning(ctx, "DrawElements with empty vertex elements buffer!"); return GL_FALSE; } + mapped = GL_TRUE; + /* make sure count doesn't go outside buffer bounds */ if (type == GL_UNSIGNED_INT) { indexBytes = count * sizeof(GLuint); @@ -86,18 +93,18 @@ _mesa_validate_DrawElements(GLcontext *ctx, indexBytes = count * sizeof(GLushort); } - if ((GLubyte *) indices + indexBytes > - ctx->Array.ElementArrayBufferObj->Data + - ctx->Array.ElementArrayBufferObj->Size) { + if (ADD_POINTERS(map, indices) + indexBytes > + (GLubyte *)map + ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); + ctx->Driver.UnmapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + ctx->Array.ElementArrayBufferObj); return GL_FALSE; } /* Actual address is the sum of pointers. Indices may be used below. */ if (ctx->Const.CheckArrayBounds) { - indices = (const GLvoid *) - ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, - (const GLubyte *) indices); + indices = ADD_POINTERS(map, indices); } } else { @@ -126,12 +133,25 @@ _mesa_validate_DrawElements(GLcontext *ctx, if (((GLubyte *) indices)[i] > max) max = ((GLubyte *) indices)[i]; } + if (max >= ctx->Array._MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ + if (mapped) { + ctx->Driver.UnmapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + ctx->Array.ElementArrayBufferObj); + } + return GL_FALSE; } } + if (mapped) { + ctx->Driver.UnmapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + ctx->Array.ElementArrayBufferObj); + } + return GL_TRUE; } -- cgit v1.2.3 From 982dcb74fd19b88208d127b8019e2a2af979cac2 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 31 Jul 2007 00:11:22 +0800 Subject: Fix an error in _save_OBE_DrawElements In the case that a buffer object is bound to ELEMENT_ARRARY_BUFFER, it is invalid to directly dereference indices passed to glDrawElements. --- src/mesa/vbo/vbo_save_api.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index aded738143..f62be5c14c 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -864,6 +864,9 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum _ae_map_vbos( ctx ); + if (ctx->Array.ElementArrayBufferObj->Name) + indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices); + vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK ); switch (type) { -- cgit v1.2.3 From 69337ed098bdf0def6820ccdb121b08c0e139085 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 31 Jul 2007 09:10:31 +0800 Subject: i965: Use I16_UNORM instead of L16_UNORM (bug 11742) --- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index d24c618a66..d54623175b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -114,7 +114,7 @@ static GLuint translate_tex_format( GLuint mesa_format ) return BRW_SURFACEFORMAT_FXT1; case MESA_FORMAT_Z16: - return BRW_SURFACEFORMAT_L16_UNORM; + return BRW_SURFACEFORMAT_I16_UNORM; case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGB_DXT1: -- cgit v1.2.3 From e66757c8babe6968ea2e506d1214c8063cbd0760 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 31 Jul 2007 22:40:42 +0800 Subject: i965: fix bad casts in do_blit_bitmap to support WindowPos correctly --- src/mesa/drivers/dri/i965/intel_pixel_bitmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index 421fcc5e51..f3f062e651 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -226,10 +226,10 @@ do_blit_bitmap( GLcontext *ctx, dsty = dPriv->y + (dPriv->h - dsty - height); dstx = dPriv->x + dstx; - dest_rect.x1 = dstx; - dest_rect.y1 = dsty; - dest_rect.x2 = dstx + width; - dest_rect.y2 = dsty + height; + dest_rect.x1 = dstx < 0 ? 0 : dstx; + dest_rect.y1 = dsty < 0 ? 0 : dsty; + dest_rect.x2 = dstx + width < 0 ? 0 : dstx + width; + dest_rect.y2 = dsty + height < 0 ? 0 : dsty + height; for (i = 0; i < nbox; i++) { drm_clip_rect_t rect; -- cgit v1.2.3 From 59b1233e7075ff54a2cd183234f2a092eef5cc75 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 31 Jul 2007 09:31:41 -0600 Subject: glGetAttribLocation always returned 1 (bug 11774) --- src/mesa/shader/slang/slang_link.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index eaa29ba094..c8457fc483 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -329,8 +329,10 @@ _slang_resolve_attributes(struct gl_shader_program *shProg, * glVertex/position. */ for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) { - if (((1 << attr) & usedAttributes) == 0) + if (((1 << attr) & usedAttributes) == 0) { + usedAttributes |= (1 << attr); break; + } } if (attr == MAX_VERTEX_ATTRIBS) { /* too many! XXX record error log */ -- cgit v1.2.3 From 8410b3f8f9d7041440db0f178c31a5819b16495c Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 31 Jul 2007 09:43:57 -0600 Subject: fix failure caused by undeclared variable (bug 11783) --- src/mesa/shader/slang/slang_codegen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 24185cf677..d368009ca5 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2059,7 +2059,8 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) } /* XXX make copy of this initializer? */ rhs = _slang_gen_operation(A, &oper->children[0]); - assert(rhs); + if (!rhs) + return NULL; /* must have found an error */ init = new_node2(IR_MOVE, var, rhs); /*assert(rhs->Opcode != IR_SEQ);*/ n = new_seq(varDecl, init); -- cgit v1.2.3 From 5e2acfee78c9e72d67d822974e9986fe99920ccf Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 31 Jul 2007 09:21:20 -0700 Subject: Don't initialize extensions we can't support when !ttm. --- src/mesa/drivers/dri/i915tex/intel_context.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index cd4333d0d3..3eb58bdd9c 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -177,7 +177,6 @@ const struct dri_extension card_extensions[] = { {"GL_ARB_texture_mirrored_repeat", NULL}, {"GL_ARB_texture_rectangle", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, @@ -188,7 +187,6 @@ const struct dri_extension card_extensions[] = { {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, #if 1 /* XXX FBO temporary? */ {"GL_EXT_packed_depth_stencil", NULL}, @@ -211,6 +209,12 @@ const struct dri_extension card_extensions[] = { {NULL, NULL} }; +const struct dri_extension ttm_extensions[] = { + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {NULL, NULL} +}; + extern const struct tnl_pipeline_stage _intel_render_stage; static const struct tnl_pipeline_stage *intel_pipeline[] = { @@ -468,6 +472,9 @@ intelInitContext(struct intel_context *intel, /* GL_TRUE, */ GL_FALSE); + if (intelScreen->ttm) + driInitExtensions(ctx, ttm_extensions, GL_FALSE); + intel->batch = intel_batchbuffer_alloc(intel); intel->last_swap_fence = NULL; -- cgit v1.2.3 From 9c61925da0f24dfc5f4cb1ee5d50e18bfe3f39ce Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 31 Jul 2007 09:22:43 -0700 Subject: bufmgr_fake: eliminate the referenced list, which is now just on_hardware. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 49 +++++---------------------- 1 file changed, 8 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index 003ac49f3b..dab723eac0 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -62,7 +62,6 @@ struct block { struct block *next, *prev; struct mem_block *mem; /* BM_MEM_AGP */ - unsigned referenced:1; unsigned on_hardware:1; unsigned fenced:1; @@ -86,7 +85,6 @@ typedef struct _bufmgr_fake { unsigned buf_nr; /* for generating ids */ - struct block referenced; /* after bmBufferOffset */ struct block on_hardware; /* after bmValidateBuffers */ struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ /* then to bufmgr->lru or free() */ @@ -236,11 +234,7 @@ static void free_block(dri_bufmgr_fake *bufmgr_fake, struct block *block) if (!block) return; - if (block->referenced) { - _mesa_printf("tried to free block on referenced list\n"); - assert(0); - } - else if (block->on_hardware) { + if (block->on_hardware) { block->bo = NULL; } else if (block->fenced) { @@ -383,14 +377,6 @@ static int clear_fenced(dri_bufmgr_fake *bufmgr_fake, } } - /* Also check the referenced list: - */ - foreach_s(block, tmp, &bufmgr_fake->referenced ) { - if (block->fenced && _fence_test(bufmgr_fake, block->fence)) { - block->fenced = 0; - } - } - DBG("%s: %d\n", __FUNCTION__, ret); return ret; } @@ -412,19 +398,6 @@ static void fence_blocks(dri_bufmgr_fake *bufmgr_fake, unsigned fence) move_to_tail(&bufmgr_fake->fenced, block); } - /* Also check the referenced list: - */ - foreach_s (block, tmp, &bufmgr_fake->referenced) { - if (block->on_hardware) { - DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, - block->mem->size, block->bo, fence); - - block->fence = fence; - block->on_hardware = 0; - block->fenced = 1; - } - } - assert(is_empty_list(&bufmgr_fake->on_hardware)); } @@ -522,8 +495,6 @@ dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) { struct block *block, *tmp; - assert(is_empty_list(&bufmgr_fake->referenced)); - bufmgr_fake->need_fence = 1; bufmgr_fake->fail = 0; @@ -533,6 +504,9 @@ dri_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr) */ dri_bufmgr_fake_wait_idle(bufmgr_fake); + /* Check that we hadn't released the lock without having fenced the last + * set of buffers. + */ assert(is_empty_list(&bufmgr_fake->fenced)); assert(is_empty_list(&bufmgr_fake->on_hardware)); @@ -752,12 +726,6 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) assert(bo_fake->block); assert(bo_fake->block->bo == &bo_fake->bo); - DBG("Add buf %d:%s (block %p, dirty %d) to referenced list\n", - bo_fake->id, bo_fake->name, bo_fake->block, bo_fake->dirty); - - move_to_tail(&bufmgr_fake->referenced, bo_fake->block); - bo_fake->block->referenced = 1; - bo->offset = bo_fake->block->mem->ofs; /* Upload the buffer contents if necessary */ @@ -775,12 +743,12 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) dri_bufmgr_fake_wait_idle(bufmgr_fake); memcpy(bo_fake->block->virtual, bo_fake->backing_store, bo->size); - - bo_fake->block->referenced = 0; - bo_fake->block->on_hardware = 1; - move_to_tail(&bufmgr_fake->on_hardware, bo_fake->block); + bo_fake->dirty = 0; } + bo_fake->block->on_hardware = 1; + move_to_tail(&bufmgr_fake->on_hardware, bo_fake->block); + bufmgr_fake->need_fence = 1; } _glthread_UNLOCK_MUTEX(bufmgr_fake->mutex); @@ -880,7 +848,6 @@ dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, bufmgr_fake = calloc(1, sizeof(*bufmgr_fake)); /* Initialize allocator */ - make_empty_list(&bufmgr_fake->referenced); make_empty_list(&bufmgr_fake->fenced); make_empty_list(&bufmgr_fake->on_hardware); make_empty_list(&bufmgr_fake->lru); -- cgit v1.2.3 From 6fae66715be216f03f1f418d963ae6db8c83885a Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 31 Jul 2007 14:57:37 -0600 Subject: fix some FreeBSD issues --- configs/freebsd | 2 +- configs/freebsd-dri | 2 +- src/glut/glx/glut_event.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/configs/freebsd b/configs/freebsd index db7dd3b78a..447faf9f4c 100644 --- a/configs/freebsd +++ b/configs/freebsd @@ -13,7 +13,7 @@ OPT_FLAGS = -O2 PIC_FLAGS = -fPIC DEFINES = -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE -DUSE_XSHM \ - -DHZ=100 -DHAVE_POSIX_MEMALIGN + -DHZ=100 X11_INCLUDES = -I/usr/X11R6/include diff --git a/configs/freebsd-dri b/configs/freebsd-dri index 402883d1de..5a9310a04e 100644 --- a/configs/freebsd-dri +++ b/configs/freebsd-dri @@ -15,7 +15,7 @@ EXPAT_INCLUDES = -I/usr/local/include X11_INCLUDES = -I/usr/X11R6/include DEFINES = -DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER \ -DGLX_DIRECT_RENDERING -DGLX_INDIRECT_RENDERING \ - -DHAVE_ALIAS -DHAVE_POSIX_MEMALIGN + -DHAVE_ALIAS CFLAGS = $(WARN_FLAGS) $(OPT_FLAGS) $(PIC_FLAGS) -Wmissing-prototypes -std=c99 -Wundef -ffast-math \ $(ASM_FLAGS) $(X11_INCLUDES) $(DEFINES) diff --git a/src/glut/glx/glut_event.c b/src/glut/glx/glut_event.c index 4e67da674e..0a96e8cf71 100644 --- a/src/glut/glx/glut_event.c +++ b/src/glut/glx/glut_event.c @@ -24,7 +24,7 @@ # ifdef __sgi # include /* prototype for bzero used by FD_ZERO */ # endif -# if (defined(SVR4) || defined(CRAY) || defined(AIXV3)) && !defined(FD_SETSIZE) +# if (defined(__FreeBSD__) || defined(SVR4) || defined(CRAY) || defined(AIXV3)) && !defined(FD_SETSIZE) # include /* select system call interface */ # ifdef luna # include -- cgit v1.2.3 From a6dad044e24358af9fe5764ca7b342f4ed4804db Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 1 Aug 2007 11:08:05 +0800 Subject: fix fd.o bug #11788, max point size --- src/mesa/drivers/dri/i965/brw_sf_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c index 9a6e5f5f19..307fb63785 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_state.c +++ b/src/mesa/drivers/dri/i965/brw_sf_state.c @@ -185,7 +185,7 @@ static void upload_sf_unit( struct brw_context *brw ) /* _NEW_POINT */ sf.sf6.point_rast_rule = 1; /* opengl conventions */ /* XXX clamp max depends on AA vs. non-AA */ - sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 3.0) * (1<<3); + sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 255.0) * (1<<3); sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated; /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons: -- cgit v1.2.3 From e9fbf69aeab590d5f292a7ca6bdeb5d2791f9918 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 1 Aug 2007 08:40:49 -0600 Subject: fix mem leak (bug 11791) --- src/glut/glx/glut_dstr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/glut/glx/glut_dstr.c b/src/glut/glx/glut_dstr.c index ec9386f3e5..2513af4539 100644 --- a/src/glut/glx/glut_dstr.c +++ b/src/glut/glx/glut_dstr.c @@ -291,6 +291,7 @@ loadVisuals(int *nitems_return) fbmodes = (FrameBufferMode *) malloc(n * sizeof(FrameBufferMode)); if (fbmodes == NULL) { *nitems_return = -1; + free(vlist); return NULL; } for (i = 0; i < n; i++) { -- cgit v1.2.3 From f761c99d25aa71c4c761c1f876782a81c795fd5c Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 1 Aug 2007 08:41:51 -0600 Subject: fix mem leak (bug 11793) --- src/mesa/drivers/dri/common/dri_drmpool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c index 878a148b39..592ac10542 100644 --- a/src/mesa/drivers/dri/common/dri_drmpool.c +++ b/src/mesa/drivers/dri/common/dri_drmpool.c @@ -51,6 +51,7 @@ pool_create(struct _DriBufferPool *pool, return NULL; if ((alignment > pageSize) && (alignment % pageSize)) { + free(buf); return NULL; } -- cgit v1.2.3 From 394e7575a3e5694ee63008c7a7e0e4b891c181f6 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 1 Aug 2007 11:27:29 -0600 Subject: fix error code test limit (bug 11795) --- src/glu/sgi/libutil/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/glu/sgi/libutil/error.c b/src/glu/sgi/libutil/error.c index 3d1ce9b210..c200056942 100644 --- a/src/glu/sgi/libutil/error.c +++ b/src/glu/sgi/libutil/error.c @@ -82,7 +82,7 @@ gluErrorString(GLenum errorCode) if ((errorCode >= GLU_NURBS_ERROR1) && (errorCode <= GLU_NURBS_ERROR37)) { return (const GLubyte *) __gluNURBSErrorString(errorCode - (GLU_NURBS_ERROR1 - 1)); } - if ((errorCode >= GLU_TESS_ERROR1) && (errorCode <= GLU_TESS_ERROR8)) { + if ((errorCode >= GLU_TESS_ERROR1) && (errorCode <= GLU_TESS_ERROR6)) { return (const GLubyte *) __gluTessErrorString(errorCode - (GLU_TESS_ERROR1 - 1)); } return (const GLubyte *) 0; -- cgit v1.2.3 From 6bf81a5edfa287a396f30188b107ff1761039f3f Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 2 Aug 2007 14:26:12 +0800 Subject: EXT_texture_sRGB support on i965 --- src/mesa/drivers/dri/i965/brw_tex.c | 19 +++++++++++++++++ src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 5 +++++ src/mesa/drivers/dri/i965/intel_context.c | 1 + src/mesa/main/texcompress_s3tc.c | 26 ++++++++++++++++++++++++ src/mesa/main/texformat.h | 2 ++ 5 files changed, 53 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index 9d4b9867d2..f8d0c3fb6f 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -168,6 +168,25 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_DEPTH_COMPONENT32: return &_mesa_texformat_z16; + case GL_SRGB_EXT: + case GL_SRGB8_EXT: + case GL_SRGB_ALPHA_EXT: + case GL_SRGB8_ALPHA8_EXT: + case GL_SLUMINANCE_EXT: + case GL_SLUMINANCE8_EXT: + case GL_SLUMINANCE_ALPHA_EXT: + case GL_SLUMINANCE8_ALPHA8_EXT: + case GL_COMPRESSED_SRGB_EXT: + case GL_COMPRESSED_SRGB_ALPHA_EXT: + case GL_COMPRESSED_SLUMINANCE_EXT: + case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: + return &_mesa_texformat_srgb_dxt1; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return &_mesa_texformat_srgb_dxt1; + default: fprintf(stderr, "unexpected texture format %s in %s\n", _mesa_lookup_enum_by_nr(internalFormat), diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index d54623175b..acf5771e77 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -120,6 +120,11 @@ static GLuint translate_tex_format( GLuint mesa_format ) case MESA_FORMAT_RGB_DXT1: return BRW_SURFACEFORMAT_DXT1_RGB; + case MESA_FORMAT_SRGBA8: + return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB; + case MESA_FORMAT_SRGB_DXT1: + return BRW_SURFACEFORMAT_BC1_UNORM_SRGB; + default: assert(0); return 0; diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index a8204ee4b8..eafe809d3a 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -182,6 +182,7 @@ const struct dri_extension card_extensions[] = { "GL_EXT_texture_env_dot3", NULL }, { "GL_EXT_texture_filter_anisotropic", NULL }, { "GL_EXT_texture_lod_bias", NULL }, + { "GL_EXT_texture_sRGB", NULL }, { "GL_3DFX_texture_compression_FXT1", NULL }, { "GL_APPLE_client_storage", NULL }, { "GL_MESA_pack_invert", NULL }, diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index c48063d919..4f329cdf59 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -577,6 +577,32 @@ const struct gl_texture_format _mesa_texformat_rgb_dxt1 = { NULL /* StoreTexel */ }; +#if FEATURE_EXT_texture_sRGB +const struct gl_texture_format _mesa_texformat_srgb_dxt1 = { + MESA_FORMAT_SRGB_DXT1, /* MesaFormat */ + GL_RGB, /* BaseFormat */ + GL_UNSIGNED_NORMALIZED_ARB, /* DataType */ + 4, /*approx*/ /* RedBits */ + 4, /*approx*/ /* GreenBits */ + 4, /*approx*/ /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 0, /* StencilBits */ + 0, /* TexelBytes */ + texstore_rgb_dxt1, /* StoreTexImageFunc */ + NULL, /*impossible*/ /* FetchTexel1D */ + fetch_texel_2d_rgb_dxt1, /* FetchTexel2D */ + NULL, /*impossible*/ /* FetchTexel3D */ + NULL, /*impossible*/ /* FetchTexel1Df */ + fetch_texel_2d_f_rgb_dxt1, /* FetchTexel2Df */ + NULL, /*impossible*/ /* FetchTexel3Df */ + NULL /* StoreTexel */ +}; +#endif + const struct gl_texture_format _mesa_texformat_rgba_dxt1 = { MESA_FORMAT_RGBA_DXT1, /* MesaFormat */ GL_RGBA, /* BaseFormat */ diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 55851db701..82023b946d 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -97,6 +97,7 @@ enum _format { MESA_FORMAT_SRGBA8, MESA_FORMAT_SL8, MESA_FORMAT_SLA8, + MESA_FORMAT_SRGB_DXT1, /*@}*/ #endif @@ -168,6 +169,7 @@ extern const struct gl_texture_format _mesa_texformat_srgb8; extern const struct gl_texture_format _mesa_texformat_srgba8; extern const struct gl_texture_format _mesa_texformat_sl8; extern const struct gl_texture_format _mesa_texformat_sla8; +extern const struct gl_texture_format _mesa_texformat_srgb_dxt1; /*@}*/ #endif -- cgit v1.2.3 From 246d1d2522858a1bcf525d64ad165f9af11a2b4d Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 2 Aug 2007 14:35:59 +0800 Subject: Fix previous commit --- src/mesa/drivers/dri/i965/brw_tex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index f8d0c3fb6f..a62395a432 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -180,7 +180,7 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_COMPRESSED_SRGB_ALPHA_EXT: case GL_COMPRESSED_SLUMINANCE_EXT: case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: - return &_mesa_texformat_srgb_dxt1; + return &_mesa_texformat_srgba8; case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: -- cgit v1.2.3 From 505453a04e8ba5e394c34401bd9ec320ffce2423 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 2 Aug 2007 15:27:13 +0800 Subject: fix fd.o bug #11804 glPolygonMode with point sprite on i965 --- src/mesa/drivers/dri/i965/brw_defines.h | 2 ++ src/mesa/drivers/dri/i965/brw_sf_emit.c | 9 +++++++++ src/mesa/drivers/dri/i965/brw_sf_state.c | 2 ++ 3 files changed, 13 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index e8f878a701..9bb7d2f703 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -240,6 +240,8 @@ #define BRW_FRONTWINDING_CW 0 #define BRW_FRONTWINDING_CCW 1 +#define BRW_SPRITE_POINT_ENABLE 16 + #define BRW_INDEX_BYTE 0 #define BRW_INDEX_WORD 1 #define BRW_INDEX_DWORD 2 diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index 7ecf9bb560..22911a4649 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -641,6 +641,7 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) struct brw_compile *p = &c->func; struct brw_reg ip = brw_ip_reg(); struct brw_reg payload_prim = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0); + struct brw_reg payload_attr = get_element_ud(brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, 1, 0), 0); struct brw_reg primmask; struct brw_instruction *jmp; struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); @@ -681,6 +682,14 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) } brw_land_fwd_jump(p, jmp); + brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); + brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1<attribs.Point->PointSprite; sf.sf7.point_size = CLAMP(brw->attribs.Point->Size, 1.0, 255.0) * (1<<3); sf.sf7.use_point_size_state = !brw->attribs.Point->_Attenuated; -- cgit v1.2.3 From 46ac4531966e0edf802919def935c4125342e8bf Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 2 Aug 2007 11:37:57 +0100 Subject: Fix typo in logic for unalias2() --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 6eb11b19ad..d00f0c71a8 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -201,7 +201,7 @@ static void unalias2( struct brw_vs_compile *c, struct brw_reg, struct brw_reg )) { - if ((dst.file == arg0.file && dst.nr == arg0.nr) && + if ((dst.file == arg0.file && dst.nr == arg0.nr) || (dst.file == arg1.file && dst.nr == arg1.nr)) { struct brw_compile *p = &c->func; struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask); -- cgit v1.2.3 From c3e6bfc9e27038172fff47f9cc5a8a53ff7038a3 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 2 Aug 2007 08:29:55 -0600 Subject: Remove some code that was never hit (bug 11811). Also added an assertion to check that NR_MAT_ATTRIBS == MAT_ATTRIB_MAX. In the unlikely event this ever changes, maybe restore the code. --- src/mesa/vbo/vbo_context.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index ad4556c500..656b27f28c 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -112,6 +112,8 @@ static void init_mat_currval(GLcontext *ctx) struct gl_client_array *arrays = vbo->mat_currval; GLuint i; + ASSERT(NR_MAT_ATTRIBS == MAT_ATTRIB_MAX); + memset(arrays, 0, sizeof(*arrays) * NR_MAT_ATTRIBS); /* Set up a constant (StrideB == 0) array for each current @@ -137,11 +139,7 @@ static void init_mat_currval(GLcontext *ctx) break; } - if (i < MAT_ATTRIB_MAX) - cl->Ptr = (const void *)ctx->Light.Material.Attrib[i]; - else - cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i]; - + cl->Ptr = (const void *)ctx->Light.Material.Attrib[i]; cl->Type = GL_FLOAT; cl->Stride = 0; cl->StrideB = 0; -- cgit v1.2.3 From 6dae3f8c881ae90664fa826032402efb6de1bb8b Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 2 Aug 2007 08:31:44 -0600 Subject: move code to prevent NULL ptr dereference (bug 11810) --- src/mesa/drivers/dri/i915tex/intel_span.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_span.c b/src/mesa/drivers/dri/i915tex/intel_span.c index ab0874e4fd..d1f8ef06be 100644 --- a/src/mesa/drivers/dri/i915tex/intel_span.c +++ b/src/mesa/drivers/dri/i915tex/intel_span.c @@ -198,9 +198,9 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map) intel_region_map(intel->intelScreen, irb->region); else intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; } - irb->pfMap = irb->region->map; - irb->pfPitch = irb->region->pitch; } } } -- cgit v1.2.3 From 6e6a02261a7c0fcfdf9fbf17199aff4278c8e5b7 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 2 Aug 2007 08:35:13 -0600 Subject: s/MAX_TEXTURE_LEVELS/SIS_MAX_TEXTURE_LEVELS/ and add assertion (bug 11806) --- src/mesa/drivers/dri/sis/sis_tex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/sis/sis_tex.c b/src/mesa/drivers/dri/sis/sis_tex.c index be87f16e29..8fd7b26ba5 100644 --- a/src/mesa/drivers/dri/sis/sis_tex.c +++ b/src/mesa/drivers/dri/sis/sis_tex.c @@ -130,6 +130,8 @@ sisAllocTexImage( sisContextPtr smesa, sisTexObjPtr t, int level, static void sisFreeTexImage( sisContextPtr smesa, sisTexObjPtr t, int level ) { + assert(level >= 0); + assert(level < SIS_MAX_TEXTURE_LEVELS); if (t->image[level].Data == NULL) return; @@ -213,7 +215,7 @@ sisDeleteTexture( GLcontext * ctx, struct gl_texture_object *texObj ) */ return; } - for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { + for (i = 0; i < SIS_MAX_TEXTURE_LEVELS; i++) { sisFreeTexImage( smesa, t, i ); } -- cgit v1.2.3 From 89cad79b4186166f4420317472801b73410402f4 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 2 Aug 2007 08:38:01 -0600 Subject: fix double free()s (bug 11808) --- src/glu/sgi/libnurbs/interface/insurfeval.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/glu/sgi/libnurbs/interface/insurfeval.cc b/src/glu/sgi/libnurbs/interface/insurfeval.cc index b314699c7a..e4ee3ef6a2 100644 --- a/src/glu/sgi/libnurbs/interface/insurfeval.cc +++ b/src/glu/sgi/libnurbs/interface/insurfeval.cc @@ -1533,8 +1533,8 @@ void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_va } //clean up free(leftXYZ); - free(leftXYZ); - free(rightNormal); + free(rightXYZ); + free(leftNormal); free(rightNormal); } -- cgit v1.2.3 From 85421351e65c45249b038214fe8d1ca6b0d69884 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 2 Aug 2007 08:40:29 -0600 Subject: fix invalid pointer usage in bezierPatchDeleteList(), bug 11807 --- src/glu/sgi/libnurbs/interface/bezierPatch.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/glu/sgi/libnurbs/interface/bezierPatch.cc b/src/glu/sgi/libnurbs/interface/bezierPatch.cc index 836ae94e0a..5b7bda1a00 100644 --- a/src/glu/sgi/libnurbs/interface/bezierPatch.cc +++ b/src/glu/sgi/libnurbs/interface/bezierPatch.cc @@ -111,8 +111,11 @@ void bezierPatchDelete(bezierPatch *b) void bezierPatchDeleteList(bezierPatch *b) { bezierPatch *temp; - for(temp = b; temp != NULL; temp = temp->next) - bezierPatchDelete(temp); + while (b != NULL) { + temp = b; + b = b->next; + bezierPatchDelete(temp); + } } bezierPatch* bezierPatchInsert(bezierPatch *list, bezierPatch *b) -- cgit v1.2.3 From e2556b7487cb383e285f6b21c5513edd8c5d37e6 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 2 Aug 2007 08:44:34 -0600 Subject: remove unnecessary null check (bug 11814) --- src/mesa/drivers/dri/r300/r300_texmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c index 38f0da8b7c..723601ac4a 100644 --- a/src/mesa/drivers/dri/r300/r300_texmem.c +++ b/src/mesa/drivers/dri/r300/r300_texmem.c @@ -505,7 +505,7 @@ int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face) t->base.lastLevel); } - if (!t || t->base.totalSize == 0) + if (t->base.totalSize == 0) return 0; if (RADEON_DEBUG & DEBUG_SYNC) { -- cgit v1.2.3 From 2c3cb693ccb760b7b1b7bb9f37491d1499c97938 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 2 Aug 2007 09:08:29 -0600 Subject: fix stencil value masking bug 11805, and fix sizeof() bug --- src/mesa/main/image.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 8fccd44f21..9760e5f8d2 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -3733,7 +3733,7 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n, switch (dstType) { case GL_UNSIGNED_BYTE: - if (sizeof(GLstencil) == 8) { + if (sizeof(GLstencil) == 1) { _mesa_memcpy( dest, source, n ); } else { @@ -3745,14 +3745,11 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n, } break; case GL_BYTE: - if (sizeof(GLstencil) == 8) { - _mesa_memcpy( dest, source, n ); - } - else { + { GLbyte *dst = (GLbyte *) dest; GLuint i; for (i=0;i Date: Thu, 2 Aug 2007 15:55:42 -0700 Subject: Don't try to use kernel BO flags in dri_bufmgr_fake internals. --- src/mesa/drivers/dri/common/dri_bufmgr_fake.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c index dab723eac0..e0d23a3647 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_fake.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_fake.c @@ -49,8 +49,9 @@ /* Internal flags: */ -#define BM_NO_BACKING_STORE DRM_BO_FLAG_MEM_PRIV0 -#define BM_NO_FENCE_SUBDATA DRM_BO_FLAG_MEM_PRIV1 +#define BM_NO_BACKING_STORE 0x00000001 +#define BM_NO_FENCE_SUBDATA 0x00000002 +#define BM_PINNED 0x00000004 /* Wrapper around mm.c's mem_block, which understands that you must * wait for fences to expire before memory can be freed. This is @@ -254,7 +255,7 @@ alloc_backing_store(dri_bo *bo) { dri_bo_fake *bo_fake = (dri_bo_fake *)bo; assert(!bo_fake->backing_store); - assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + assert(!(bo_fake->flags & (BM_PINNED|BM_NO_BACKING_STORE))); bo_fake->backing_store = ALIGN_MALLOC(bo->size, 64); } @@ -263,7 +264,7 @@ static void free_backing_store(dri_bo *bo) { dri_bo_fake *bo_fake = (dri_bo_fake *)bo; - assert(!(bo_fake->flags & (DRM_BO_FLAG_NO_EVICT|BM_NO_BACKING_STORE))); + assert(!(bo_fake->flags & (BM_PINNED|BM_NO_BACKING_STORE))); if (bo_fake->backing_store) { ALIGN_FREE(bo_fake->backing_store); @@ -280,7 +281,7 @@ set_dirty(dri_bo *bo) if (bo_fake->flags & BM_NO_BACKING_STORE) bo_fake->invalidate_cb(&bufmgr_fake->bufmgr, bo_fake->invalidate_ptr); - assert(!(bo_fake->flags & DRM_BO_FLAG_NO_EVICT)); + assert(!(bo_fake->flags & BM_PINNED)); DBG("set_dirty - buf %d\n", bo_fake->id); bo_fake->dirty = 1; @@ -575,7 +576,7 @@ dri_fake_bo_alloc_static(dri_bufmgr *bufmgr, const char *name, bo_fake->refcount = 1; bo_fake->id = ++bufmgr_fake->buf_nr; bo_fake->name = name; - bo_fake->flags = DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE; + bo_fake->flags = BM_PINNED | DRM_BO_FLAG_NO_MOVE; bo_fake->is_static = GL_TRUE; DBG("drm_bo_alloc_static: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name, @@ -619,7 +620,7 @@ dri_fake_bo_unreference(dri_bo *bo) /** * Map a buffer into bo->virtual, allocating either card memory space (If - * BM_NO_BACKING_STORE or DRM_BO_FLAG_NO_EVICT) or backing store, as necessary. + * BM_NO_BACKING_STORE or BM_PINNED) or backing store, as necessary. */ static int dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) @@ -640,7 +641,7 @@ dri_fake_bo_map(dri_bo *bo, GLboolean write_enable) _mesa_printf("%s: already mapped\n", __FUNCTION__); abort(); } - else if (bo_fake->flags & (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT)) { + else if (bo_fake->flags & (BM_NO_BACKING_STORE|BM_PINNED)) { if (!bo_fake->block && !evict_and_alloc_block(bo)) { DBG("%s: alloc failed\n", __FUNCTION__); @@ -734,7 +735,7 @@ dri_fake_bo_validate(dri_bo *bo, unsigned int flags) bo_fake->name, bo->size, bo_fake->block->mem->ofs); assert(!(bo_fake->flags & - (BM_NO_BACKING_STORE|DRM_BO_FLAG_NO_EVICT))); + (BM_NO_BACKING_STORE|BM_PINNED))); /* Actually, should be able to just wait for a fence on the memory, * which we would be tracking when we free it. Waiting for idle is -- cgit v1.2.3 From 75a88e908242c555b3916bbf61d371e83e6a6dd0 Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Tue, 7 Aug 2007 01:00:29 +0200 Subject: nouveau: update to DRM API patchlevel 10 Finally let DRI build for nouveau. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 4 ++-- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 21 ++++++++++----------- src/mesa/drivers/dri/nouveau/nouveau_sync.h | 14 +++++++------- 4 files changed, 20 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 7b5e96b4c2..4208819d02 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -98,7 +98,7 @@ void nouveauWaitForIdle(nouveauContextPtr nmesa) // here we call the fifo initialization ioctl and fill in stuff accordingly GLboolean nouveauFifoInit(nouveauContextPtr nmesa) { - struct drm_nouveau_fifo_alloc fifo_init; + struct drm_nouveau_channel_alloc fifo_init; int i, ret; #ifdef NOUVEAU_RING_DEBUG @@ -107,7 +107,7 @@ GLboolean nouveauFifoInit(nouveauContextPtr nmesa) fifo_init.fb_ctxdma_handle = NvDmaFB; fifo_init.tt_ctxdma_handle = NvDmaTT; - ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); + ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_CHANNEL_ALLOC, &fifo_init, sizeof(fifo_init)); if (ret) { FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); return GL_FALSE; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 69b0691bb7..053680be8d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -328,7 +328,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc static const __DRIversion ddx_expected = { 1, 2, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; static const __DRIversion drm_expected = { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 9 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 #error nouveau_drm.h version doesn't match expected version #endif dri_interface = interface; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 8abc847e1e..3f5f6d54e9 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -39,25 +39,24 @@ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ volatile uint32_t *__v = (void*)nmesa->notifier_block + notifier->offset -struct drm_nouveau_notifier_alloc * +struct drm_nouveau_notifierobj_alloc * nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct drm_nouveau_notifier_alloc *notifier; + struct drm_nouveau_notifierobj_alloc *notifier; int ret; #ifdef NOUVEAU_RING_DEBUG return NULL; #endif - - notifier = CALLOC_STRUCT(drm_nouveau_notifier_alloc); + notifier = CALLOC_STRUCT(drm_nouveau_notifierobj_alloc); if (!notifier) return NULL; notifier->channel = nmesa->fifo.channel; notifier->handle = handle; notifier->count = count; - ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIER_ALLOC, + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, notifier, sizeof(*notifier)); if (ret) { MESSAGE("Failed to create notifier 0x%08x: %d\n", handle, ret); @@ -70,7 +69,7 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) void nouveau_notifier_destroy(GLcontext *ctx, - struct drm_nouveau_notifier_alloc *notifier) + struct drm_nouveau_notifierobj_alloc *notifier) { /*XXX: free notifier object.. */ FREE(notifier); @@ -78,7 +77,7 @@ nouveau_notifier_destroy(GLcontext *ctx, void nouveau_notifier_reset(GLcontext *ctx, - struct drm_nouveau_notifier_alloc *notifier, + struct drm_nouveau_notifierobj_alloc *notifier, GLuint id) { NOTIFIER(n); @@ -96,7 +95,7 @@ nouveau_notifier_reset(GLcontext *ctx, GLuint nouveau_notifier_status(GLcontext *ctx, - struct drm_nouveau_notifier_alloc *notifier, + struct drm_nouveau_notifierobj_alloc *notifier, GLuint id) { NOTIFIER(n); @@ -106,7 +105,7 @@ nouveau_notifier_status(GLcontext *ctx, GLuint nouveau_notifier_return_val(GLcontext *ctx, - struct drm_nouveau_notifier_alloc *notifier, + struct drm_nouveau_notifierobj_alloc *notifier, GLuint id) { NOTIFIER(n); @@ -116,7 +115,7 @@ nouveau_notifier_return_val(GLcontext *ctx, GLboolean nouveau_notifier_wait_status(GLcontext *ctx, - struct drm_nouveau_notifier_alloc *notifier, + struct drm_nouveau_notifierobj_alloc *notifier, GLuint id, GLuint status, GLuint timeout) { NOTIFIER(n); @@ -150,7 +149,7 @@ nouveau_notifier_wait_status(GLcontext *ctx, void nouveau_notifier_wait_nop(GLcontext *ctx, - struct drm_nouveau_notifier_alloc *notifier, + struct drm_nouveau_notifierobj_alloc *notifier, GLuint subc) { NOTIFIER(n); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index b76af17276..1ff4eca325 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -47,24 +47,24 @@ #define NV_NOTIFY 0x00000104 #define NV_NOTIFY_STYLE_WRITE_ONLY 0 -extern struct drm_nouveau_notifier_alloc * +extern struct drm_nouveau_notifierobj_alloc * nouveau_notifier_new(GLcontext *, GLuint handle, GLuint count); extern void -nouveau_notifier_destroy(GLcontext *, struct drm_nouveau_notifier_alloc *); +nouveau_notifier_destroy(GLcontext *, struct drm_nouveau_notifierobj_alloc *); extern void -nouveau_notifier_reset(GLcontext *, struct drm_nouveau_notifier_alloc *, +nouveau_notifier_reset(GLcontext *, struct drm_nouveau_notifierobj_alloc *, GLuint id); extern GLuint -nouveau_notifier_status(GLcontext *, struct drm_nouveau_notifier_alloc *, +nouveau_notifier_status(GLcontext *, struct drm_nouveau_notifierobj_alloc *, GLuint id); extern GLuint -nouveau_notifier_return_val(GLcontext *, struct drm_nouveau_notifier_alloc *, +nouveau_notifier_return_val(GLcontext *, struct drm_nouveau_notifierobj_alloc *, GLuint id); extern GLboolean -nouveau_notifier_wait_status(GLcontext *, struct drm_nouveau_notifier_alloc *, +nouveau_notifier_wait_status(GLcontext *, struct drm_nouveau_notifierobj_alloc *, GLuint id, GLuint status, GLuint timeout); extern void -nouveau_notifier_wait_nop(GLcontext *ctx, struct drm_nouveau_notifier_alloc *, +nouveau_notifier_wait_nop(GLcontext *ctx, struct drm_nouveau_notifierobj_alloc *, GLuint subc); extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx); -- cgit v1.2.3 From d05b72154319041dad38f24696638396753e0da3 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 7 Aug 2007 08:21:28 +0800 Subject: fix vbo_split_copy related bug 9962 --- src/mesa/vbo/vbo_split_copy.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index e5c4429350..685cc0fdf6 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -129,6 +129,13 @@ static GLuint attr_size( const struct gl_client_array *array ) */ static GLboolean check_flush( struct copy_context *copy ) { + GLenum mode = copy->dstprim[copy->dstprim_nr].mode; + + if (GL_TRIANGLE_STRIP == mode && + copy->dstelt_nr & 1) { /* see bug9962 */ + return GL_FALSE; + } + if (copy->dstbuf_nr + 4 > copy->dstbuf_size) return GL_TRUE; @@ -458,7 +465,7 @@ static void replay_init( struct copy_context *copy ) dst->StrideB = copy->vertex_size; dst->Ptr = copy->dstbuf + offset; dst->Enabled = GL_TRUE; - dst->Normalized = GL_TRUE; + dst->Normalized = src->Normalized; dst->BufferObj = ctx->Array.NullBufferObj; dst->_MaxElement = copy->dstbuf_size; /* may be less! */ -- cgit v1.2.3 From 0ed3ff5011442facdaccdb84518d7712833f9dab Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 7 Aug 2007 08:17:02 +0100 Subject: fix even-sized point positioning (bug 11874) --- src/mesa/swrast/s_points.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 4768fbea97..21316372e8 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -172,9 +172,9 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) } else { /* even size */ - xmin = (GLint) x - iRadius + 1; + xmin = (GLint) x - iRadius; xmax = xmin + iSize - 1; - ymin = (GLint) y - iRadius + 1; + ymin = (GLint) y - iRadius; ymax = ymin + iSize - 1; } @@ -418,9 +418,9 @@ large_point(GLcontext *ctx, const SWvertex *vert) } else { /* even size */ - xmin = (GLint) x - iRadius + 1; + xmin = (GLint) x - iRadius; xmax = xmin + iSize - 1; - ymin = (GLint) y - iRadius + 1; + ymin = (GLint) y - iRadius; ymax = ymin + iSize - 1; } -- cgit v1.2.3 From 872d1791414cd39df03f35330c1e7e9d88f229b3 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 7 Aug 2007 21:42:34 +0100 Subject: fix swizzle error test (bug 11881) --- src/mesa/shader/atifragshader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c index 4727c1a436..854c911874 100644 --- a/src/mesa/shader/atifragshader.c +++ b/src/mesa/shader/atifragshader.c @@ -440,7 +440,7 @@ _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle) _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)"); return; } - if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) { + if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) { _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)"); return; } @@ -513,7 +513,7 @@ _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle) _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)"); return; } - if ((swizzle < GL_SWIZZLE_STR_ATI) && (swizzle > GL_SWIZZLE_STQ_DQ_ATI)) { + if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) { _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)"); return; } -- cgit v1.2.3 From 237b985356b4d791ee2f184a201de9704614b9b1 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 7 Aug 2007 21:48:31 +0100 Subject: fix potential NULL dereference (bug 11880) --- src/mesa/shader/shader_api.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 1a931326af..a1e73ef125 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -377,7 +377,7 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); - const GLuint n = shProg->NumShaders; + GLuint n; GLuint i; if (!shProg || !sh) { @@ -386,6 +386,8 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) return; } + n = shProg->NumShaders; + for (i = 0; i < n; i++) { if (shProg->Shaders[i] == sh) { /* already attached */ @@ -547,7 +549,7 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); - const GLuint n = shProg->NumShaders; + GLuint n; GLuint i, j; if (!shProg) { @@ -556,6 +558,8 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) return; } + n = shProg->NumShaders; + for (i = 0; i < n; i++) { if (shProg->Shaders[i]->Name == shader) { /* found it */ -- cgit v1.2.3 From 90cc31f31bbc9039fcd9acab7d6e72f2c9a186bb Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 7 Aug 2007 21:57:29 +0100 Subject: fix potential NULL dereference (bug 11879) --- src/mesa/drivers/dri/unichrome/via_context.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index 4d25d328e3..7c73877720 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -733,14 +733,15 @@ void viaXMesaWindowMoved(struct via_context *vmesa) { __DRIdrawablePrivate *const drawable = vmesa->driDrawable; __DRIdrawablePrivate *const readable = vmesa->driReadable; - struct via_renderbuffer *const draw_buffer = - (struct via_renderbuffer *) drawable->driverPrivate; - struct via_renderbuffer *const read_buffer = - (struct via_renderbuffer *) readable->driverPrivate; + struct via_renderbuffer * draw_buffer; + struct via_renderbuffer * read_buffer; GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3; if (!drawable) return; + + draw_buffer = (struct via_renderbuffer *) drawable->driverPrivate; + read_buffer = (struct via_renderbuffer *) readable->driverPrivate; switch (vmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) { case BUFFER_BIT_BACK_LEFT: -- cgit v1.2.3 From 3973d1ad3353cd66c69e5170908a9e9ae03477fb Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 7 Aug 2007 22:06:08 +0100 Subject: move free() after dereference (bug 11878) --- src/mesa/drivers/dri/i810/i810screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c index f64c10a9ae..f8cf050d7e 100644 --- a/src/mesa/drivers/dri/i810/i810screen.c +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -288,8 +288,8 @@ i810InitDriver(__DRIscreenPrivate *sPriv) i810Screen->depth.handle, i810Screen->depth.size, (drmAddress *)&i810Screen->depth.map) != 0) { - FREE(i810Screen); drmUnmap(i810Screen->back.map, i810Screen->back.size); + FREE(i810Screen); sPriv->private = NULL; __driUtilMessage("i810InitDriver: drmMap (2) failed"); return GL_FALSE; -- cgit v1.2.3 From 6a78221a10d1c97f84e4c47e10b721aa4777d761 Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Wed, 8 Aug 2007 14:49:37 +0200 Subject: nouveau: Missing notifier -> notifierobj migration I missed this in the original migration. --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 9a0be2cb2a..fdbde51a72 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -109,12 +109,12 @@ typedef struct nouveau_context { uint64_t gart_size; /* Channel synchronisation */ - struct drm_nouveau_notifier_alloc *syncNotifier; + struct drm_nouveau_notifierobj_alloc *syncNotifier; /* ARB_occlusion_query / EXT_timer_query */ GLuint query_object_max; GLboolean * query_alloc; - struct drm_nouveau_notifier_alloc *queryNotifier; + struct drm_nouveau_notifierobj_alloc *queryNotifier; /* Additional hw-specific functions */ nouveau_hw_func hw_func; -- cgit v1.2.3 From 48c37a29fa527aabcec76731de0bee508869e835 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 9 Aug 2007 08:47:05 +0100 Subject: fix byte swap bug for GLint stencil indexes (bug 11909) --- src/mesa/main/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 9760e5f8d2..347cec66ef 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -3794,7 +3794,7 @@ _mesa_pack_stencil_span( const GLcontext *ctx, GLuint n, GLint *dst = (GLint *) dest; GLuint i; for (i=0;iSwapBytes) { _mesa_swap4( (GLuint *) dst, n ); -- cgit v1.2.3 From 2cafd749b8e4fa44863c176389f7201c7f74eca9 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 10 Aug 2007 15:14:12 +0800 Subject: i965: set mt->cpp differently with compressed texture --- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/i965/intel_tex_validate.c | 36 +++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 8486086b27..d7b1946ce3 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -75,7 +75,7 @@ struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel, mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; - mt->cpp = compressed ? 2 : cpp; + mt->cpp = cpp; mt->compressed = compressed; switch (intel->intelScreen->deviceID) { diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index 44ee94614d..8c05e7cdab 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -122,6 +122,29 @@ static void intel_texture_invalidate_cb( struct intel_context *intel, intel_texture_invalidate( (struct intel_texture_object *) ptr ); } +#include "texformat.h" +static GLuint intel_compressed_num_bytes(GLenum mesaFormat) +{ + GLuint bytes = 0; + + switch (mesaFormat) { + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + bytes = 2; + break; + + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + bytes = 4; + + default: + break; + } + + return bytes; +} /* */ @@ -132,7 +155,8 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint face, i; GLuint nr_faces = 0; struct gl_texture_image *firstImage; - + GLuint cpp = 0; + if( tObj == intel->frame_buffer_texobj ) return GL_FALSE; @@ -165,6 +189,12 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, + if (firstImage->IsCompressed) { + cpp = intel_compressed_num_bytes(firstImage->TexFormat->MesaFormat); + } else { + cpp = firstImage->TexFormat->TexelBytes; + } + /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. */ @@ -176,7 +206,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, intelObj->mt->width0 != firstImage->Width || intelObj->mt->height0 != firstImage->Height || intelObj->mt->depth0 != firstImage->Depth || - intelObj->mt->cpp != firstImage->TexFormat->TexelBytes || + intelObj->mt->cpp != cpp || intelObj->mt->compressed != firstImage->IsCompressed)) { intel_miptree_destroy(intel, intelObj->mt); @@ -199,7 +229,7 @@ GLuint intel_finalize_mipmap_tree( struct intel_context *intel, firstImage->Width, firstImage->Height, firstImage->Depth, - firstImage->TexFormat->TexelBytes, + cpp, firstImage->IsCompressed); /* Tell the buffer manager that we will manage the backing -- cgit v1.2.3 From 8ea66fa2ec9eeb6a7e869ff08d713f5e77d795e0 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 10 Aug 2007 16:23:14 +0800 Subject: i965/i915tex: applying right alignment to compressed texture, which make small textures(4x4,2x2,1x1) work well. --- src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 9 ++++-- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 16 ++++++++-- src/mesa/drivers/dri/intel/intel_tex_layout.c | 38 +++++++++++++++++++++--- src/mesa/drivers/dri/intel/intel_tex_layout.h | 1 + 4 files changed, 55 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c index 843a78eb82..fc38a28290 100644 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -325,6 +325,7 @@ intel_miptree_image_data(struct intel_context *intel, } } +extern GLuint intel_compressed_alignment(GLenum); /* Copy mipmap image between trees */ void @@ -342,8 +343,12 @@ intel_miptree_image_copy(struct intel_context *intel, const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); GLuint i; - if (dst->compressed) - height /= 4; + if (dst->compressed) { + GLuint alignment = intel_compressed_alignment(dst->internal_format); + height = (height + 3) / 4; + width = ((width + alignment - 1) & ~(alignment - 1)); + } + for (i = 0; i < depth; i++) { intel_region_copy(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index d7b1946ce3..f24f234682 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -211,7 +211,7 @@ GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, - +extern GLuint intel_compressed_alignment(GLenum); /* Upload data for a particular image. */ GLboolean intel_miptree_image_data(struct intel_context *intel, @@ -226,6 +226,16 @@ GLboolean intel_miptree_image_data(struct intel_context *intel, GLuint dst_offset = intel_miptree_image_offset(dst, face, level); const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); GLuint i; + GLuint width, height, alignment; + + width = dst->level[level].width; + height = dst->level[level].height; + + if (dst->compressed) { + alignment = intel_compressed_alignment(dst->internal_format); + width = ((width + alignment - 1) & ~(alignment - 1)); + height = (height + 3) / 4; + } DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { @@ -237,8 +247,8 @@ GLboolean intel_miptree_image_data(struct intel_context *intel, src, src_row_pitch, 0, 0, /* source x,y */ - dst->level[level].width, - dst->level[level].height)) + width, + height)) return GL_FALSE; src += src_image_pitch; } diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index fcb5cc3906..fdecd3e186 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -40,6 +40,23 @@ static int align(int value, int alignment) return (value + alignment - 1) & ~(alignment - 1); } +GLuint intel_compressed_alignment(GLenum internalFormat) +{ + GLuint alignment = 4; + + switch (internalFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + alignment = 8; + break; + + default: + break; + } + + return alignment; +} + void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) { GLint align_h = 2, align_w = 4; @@ -51,17 +68,30 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) mt->pitch = mt->width0; + if (mt->compressed) { + align_w = intel_compressed_alignment(mt->internal_format); + mt->pitch = align(mt->width0, align_w); + } + /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap. This occurs when the alignment * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ if (mt->first_level != mt->last_level) { - GLuint mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); + GLuint mip1_width; + + if (mt->compressed) { + mip1_width = align(minify(mt->width0), align_w) + + align(minify(minify(mt->width0)), align_w); + } else { + mip1_width = align(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + } - if (mip1_width > mt->width0) - mt->pitch = mip1_width; + if (mip1_width > mt->pitch) { + mt->pitch = mip1_width; + } } /* Pitch must be a whole number of dwords, even though we diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index 1e37f8f525..99d41c3629 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -39,3 +39,4 @@ static GLuint minify( GLuint d ) } extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ); +extern GLuint intel_compressed_alignment(GLenum); -- cgit v1.2.3 From db928291dcbda2a820dbb1668c43d2fb4266be7c Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 10 Aug 2007 16:37:30 +0800 Subject: i965: roland's DXTn format texture patch(bug10347) --- src/mesa/drivers/dri/i965/brw_tex.c | 12 +++++++++--- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 12 ++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_tex.c b/src/mesa/drivers/dri/i965/brw_tex.c index a62395a432..ad29316a42 100644 --- a/src/mesa/drivers/dri/i965/brw_tex.c +++ b/src/mesa/drivers/dri/i965/brw_tex.c @@ -154,13 +154,19 @@ brwChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_RGB_S3TC: case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + case GL_RGBA_S3TC: case GL_RGBA4_S3TC: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return &_mesa_texformat_rgb_dxt1; /* there is no rgba support? */ + return &_mesa_texformat_rgba_dxt5; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index acf5771e77..0a45164a0f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -116,9 +116,17 @@ static GLuint translate_tex_format( GLuint mesa_format ) case MESA_FORMAT_Z16: return BRW_SURFACEFORMAT_I16_UNORM; - case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGB_DXT1: - return BRW_SURFACEFORMAT_DXT1_RGB; + return BRW_SURFACEFORMAT_DXT1_RGB; + + case MESA_FORMAT_RGBA_DXT1: + return BRW_SURFACEFORMAT_BC1_UNORM; + + case MESA_FORMAT_RGBA_DXT3: + return BRW_SURFACEFORMAT_BC2_UNORM; + + case MESA_FORMAT_RGBA_DXT5: + return BRW_SURFACEFORMAT_BC3_UNORM; case MESA_FORMAT_SRGBA8: return BRW_SURFACEFORMAT_R8G8B8A8_UNORM_SRGB; -- cgit v1.2.3 From 4a789e408dbba7891f1436b2f42e7c0824e5ba7a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 10 Aug 2007 19:17:35 +0100 Subject: Better debugging --- src/mesa/drivers/dri/i915tex/Makefile | 1 + src/mesa/drivers/dri/i915tex/i915_debug.c | 614 +++++++++++++---------- src/mesa/drivers/dri/i915tex/i915_debug.h | 55 ++ src/mesa/drivers/dri/i915tex/i915_debug_fp.c | 331 ++++++++++++ src/mesa/drivers/dri/i915tex/i915_vtbl.c | 9 +- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 12 +- 6 files changed, 760 insertions(+), 262 deletions(-) create mode 100644 src/mesa/drivers/dri/i915tex/i915_debug.h create mode 100644 src/mesa/drivers/dri/i915tex/i915_debug_fp.c (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index b218929dce..445327f243 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -37,6 +37,7 @@ DRIVER_SOURCES = \ i915_texstate.c \ i915_context.c \ i915_debug.c \ + i915_debug_fp.c \ i915_fragprog.c \ i915_metaops.c \ i915_program.c \ diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_debug.c index 974527e14c..e22d79b167 100644 --- a/src/mesa/drivers/dri/i915tex/i915_debug.c +++ b/src/mesa/drivers/dri/i915tex/i915_debug.c @@ -25,310 +25,414 @@ * **************************************************************************/ +#include "imports.h" + #include "i915_reg.h" #include "i915_context.h" -#include - - -static const char *opcodes[0x20] = { - "NOP", - "ADD", - "MOV", - "MUL", - "MAD", - "DP2ADD", - "DP3", - "DP4", - "FRC", - "RCP", - "RSQ", - "EXP", - "LOG", - "CMP", - "MIN", - "MAX", - "FLR", - "MOD", - "TRC", - "SGE", - "SLT", - "TEXLD", - "TEXLDP", - "TEXLDB", - "TEXKILL", - "DCL", - "0x1a", - "0x1b", - "0x1c", - "0x1d", - "0x1e", - "0x1f", -}; - - -static const int args[0x20] = { - 0, /* 0 nop */ - 2, /* 1 add */ - 1, /* 2 mov */ - 2, /* 3 m ul */ - 3, /* 4 mad */ - 3, /* 5 dp2add */ - 2, /* 6 dp3 */ - 2, /* 7 dp4 */ - 1, /* 8 frc */ - 1, /* 9 rcp */ - 1, /* a rsq */ - 1, /* b exp */ - 1, /* c log */ - 3, /* d cmp */ - 2, /* e min */ - 2, /* f max */ - 1, /* 10 flr */ - 1, /* 11 mod */ - 1, /* 12 trc */ - 2, /* 13 sge */ - 2, /* 14 slt */ - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - - -static const char *regname[0x8] = { - "R", - "T", - "CONST", - "S", - "OC", - "OD", - "U", - "UNKNOWN", -}; - -static void -print_reg_type_nr(GLuint type, GLuint nr) +#include "i915_debug.h" + + + +static GLboolean debug( struct debug_stream *stream, const char *name, GLuint len ) { - switch (type) { - case REG_TYPE_T: - switch (nr) { - case T_DIFFUSE: - fprintf(stderr, "T_DIFFUSE"); - return; - case T_SPECULAR: - fprintf(stderr, "T_SPECULAR"); - return; - case T_FOG_W: - fprintf(stderr, "T_FOG_W"); - return; - default: - fprintf(stderr, "T_TEX%d", nr); - return; - } - case REG_TYPE_OC: - if (nr == 0) { - fprintf(stderr, "oC"); - return; - } - break; - case REG_TYPE_OD: - if (nr == 0) { - fprintf(stderr, "oD"); - return; - } - break; - default: - break; + GLuint i; + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + + if (len == 0) { + _mesa_printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]); + assert(0); + return GL_FALSE; } - fprintf(stderr, "%s[%d]", regname[type], nr); -} + if (stream->print_addresses) + _mesa_printf("%08x: ", stream->offset); -#define REG_SWIZZLE_MASK 0x7777 -#define REG_NEGATE_MASK 0x8888 -#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ - (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) + _mesa_printf("%s (%d dwords):\n", name, len); + for (i = 0; i < len; i++) + _mesa_printf("\t\t0x%08x\n", ptr[i]); + _mesa_printf("\n"); + stream->offset += len * sizeof(GLuint); + + return GL_TRUE; +} -static void -print_reg_neg_swizzle(GLuint reg) + +static const char *get_prim_name( GLuint val ) { - int i; - - if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && - (reg & REG_NEGATE_MASK) == 0) - return; - - fprintf(stderr, "."); - - for (i = 3; i >= 0; i--) { - if (reg & (1 << ((i * 4) + 3))) - fprintf(stderr, "-"); - - switch ((reg >> (i * 4)) & 0x7) { - case 0: - fprintf(stderr, "x"); - break; - case 1: - fprintf(stderr, "y"); - break; - case 2: - fprintf(stderr, "z"); - break; - case 3: - fprintf(stderr, "w"); - break; - case 4: - fprintf(stderr, "0"); - break; - case 5: - fprintf(stderr, "1"); - break; - default: - fprintf(stderr, "?"); - break; - } + switch (val & PRIM3D_MASK) { + case PRIM3D_TRILIST: return "TRILIST"; break; + case PRIM3D_TRISTRIP: return "TRISTRIP"; break; + case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break; + case PRIM3D_TRIFAN: return "TRIFAN"; break; + case PRIM3D_POLY: return "POLY"; break; + case PRIM3D_LINELIST: return "LINELIST"; break; + case PRIM3D_LINESTRIP: return "LINESTRIP"; break; + case PRIM3D_RECTLIST: return "RECTLIST"; break; + case PRIM3D_POINTLIST: return "POINTLIST"; break; + case PRIM3D_DIB: return "DIB"; break; + case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break; + case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break; + default: return "????"; break; } } - -static void -print_src_reg(GLuint dword) +static GLboolean debug_prim( struct debug_stream *stream, const char *name, + GLboolean dump_floats, + GLuint len ) { - GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; - GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; - print_reg_type_nr(type, nr); - print_reg_neg_swizzle(dword); + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + const char *prim = get_prim_name( ptr[0] ); + GLuint i; + + + + _mesa_printf("%s %s (%d dwords):\n", name, prim, len); + _mesa_printf("\t\t0x%08x\n", ptr[0]); + for (i = 1; i < len; i++) { + if (dump_floats) + _mesa_printf("\t\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); + else + _mesa_printf("\t\t0x%08x\n", ptr[i]); + } + + + _mesa_printf("\n"); + + stream->offset += len * sizeof(GLuint); + + return GL_TRUE; } + -void -i915_print_ureg(const char *msg, GLuint ureg) + + +static GLboolean debug_program( struct debug_stream *stream, const char *name, GLuint len ) { - fprintf(stderr, "%s: ", msg); - print_src_reg(ureg >> 8); - fprintf(stderr, "\n"); + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + + if (len == 0) { + _mesa_printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]); + assert(0); + return GL_FALSE; + } + + if (stream->print_addresses) + _mesa_printf("%08x: ", stream->offset); + + _mesa_printf("%s (%d dwords):\n", name, len); + i915_disassemble_program( ptr, len ); + + stream->offset += len * sizeof(GLuint); + return GL_TRUE; } -static void -print_dest_reg(GLuint dword) + +static GLboolean debug_chain( struct debug_stream *stream, const char *name, GLuint len ) { - GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; - GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; - print_reg_type_nr(type, nr); - if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) - return; - fprintf(stderr, "."); - if (dword & A0_DEST_CHANNEL_X) - fprintf(stderr, "x"); - if (dword & A0_DEST_CHANNEL_Y) - fprintf(stderr, "y"); - if (dword & A0_DEST_CHANNEL_Z) - fprintf(stderr, "z"); - if (dword & A0_DEST_CHANNEL_W) - fprintf(stderr, "w"); -} + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint old_offset = stream->offset + len * sizeof(GLuint); + GLuint i; + + _mesa_printf("%s (%d dwords):\n", name, len); + for (i = 0; i < len; i++) + _mesa_printf("\t\t0x%08x\n", ptr[i]); + stream->offset = ptr[1] & ~0x3; + + if (stream->offset < old_offset) + _mesa_printf("\n... skipping backwards from 0x%x --> 0x%x ...\n\n", + old_offset, stream->offset ); + else + _mesa_printf("\n... skipping from 0x%x --> 0x%x ...\n\n", + old_offset, stream->offset ); -#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) -#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) -#define GET_SRC2_REG(r) (r) + + return GL_TRUE; +} -static void -print_arith_op(GLuint opcode, const GLuint * program) +static GLboolean debug_variable_length_prim( struct debug_stream *stream ) { - if (opcode != A0_NOP) { - print_dest_reg(program[0]); - if (program[0] & A0_DEST_SATURATE) - fprintf(stderr, " = SATURATE "); - else - fprintf(stderr, " = "); - } + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + const char *prim = get_prim_name( ptr[0] ); + GLuint i, len; - fprintf(stderr, "%s ", opcodes[opcode]); + GLushort *idx = (GLushort *)(ptr+1); + for (i = 0; idx[i] != 0xffff; i++) + ; + + len = 1+(i+2)/2; + + _mesa_printf("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); + for (i = 0; i < len; i++) + _mesa_printf("\t\t0x%08x\n", ptr[i]); + _mesa_printf("\n"); + + stream->offset += len * sizeof(GLuint); + return GL_TRUE; +} - print_src_reg(GET_SRC0_REG(program[0], program[1])); - if (args[opcode] == 1) { - fprintf(stderr, "\n"); - return; - } - fprintf(stderr, ", "); - print_src_reg(GET_SRC1_REG(program[1], program[2])); - if (args[opcode] == 2) { - fprintf(stderr, "\n"); - return; +static GLboolean debug_load_immediate( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint bits = (ptr[0] >> 4) & 0xff; + GLuint i, j = 0; + + _mesa_printf("%s (%d dwords, flags: %x):\n", name, len, bits); + _mesa_printf("\t\t0x%08x\n", ptr[j++]); + + for (i = 0; i < 8; i++) { + if (bits & (1<offset += len * sizeof(GLuint); + + return GL_TRUE; } + -static void -print_tex_op(GLuint opcode, const GLuint * program) +static GLboolean debug_load_indirect( struct debug_stream *stream, + const char *name, + GLuint len ) { - print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - fprintf(stderr, " = "); + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint bits = (ptr[0] >> 8) & 0x3f; + GLuint i, j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t\t0x%08x\n", ptr[j++]); + + for (i = 0; i < 6; i++) { + if (bits & (1<> T1_ADDRESS_REG_TYPE_SHIFT) & - REG_TYPE_MASK, - (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); - fprintf(stderr, "\n"); + stream->offset += len * sizeof(GLuint); + + return GL_TRUE; } + -static void -print_dcl_op(GLuint opcode, const GLuint * program) +static GLboolean i915_debug_packet( struct debug_stream *stream ) { - fprintf(stderr, "%s ", opcodes[opcode]); - print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - fprintf(stderr, "\n"); + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint cmd = *ptr; + + switch (((cmd >> 29) & 0x7)) { + case 0x0: + switch ((cmd >> 23) & 0x3f) { + case 0x0: + return debug(stream, "MI_NOOP", 1); + case 0x3: + return debug(stream, "MI_WAIT_FOR_EVENT", 1); + case 0x4: + return debug(stream, "MI_FLUSH", 1); + case 0xA: + debug(stream, "MI_BATCH_BUFFER_END", 1); + return GL_FALSE; + case 0x22: + return debug(stream, "MI_LOAD_REGISTER_IMM", 3); + case 0x31: + return debug_chain(stream, "MI_BATCH_BUFFER_START", 2); + default: + break; + } + break; + case 0x1: + break; + case 0x2: + switch ((cmd >> 22) & 0xff) { + case 0x50: + return debug(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); + case 0x53: + return debug(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); + default: + return debug(stream, "blit command", (cmd & 0xff) + 2); + } + break; + case 0x3: + switch ((cmd >> 24) & 0x1f) { + case 0x6: + return debug(stream, "3DSTATE_ANTI_ALIASING", 1); + case 0x7: + return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1); + case 0x8: + return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2); + case 0x9: + return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1); + case 0xb: + return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1); + case 0xc: + return debug(stream, "3DSTATE_MODES5", 1); + case 0xd: + return debug(stream, "3DSTATE_MODES4", 1); + case 0x15: + return debug(stream, "3DSTATE_FOG_COLOR", 1); + case 0x16: + return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1); + case 0x1c: + /* 3DState16NP */ + switch((cmd >> 19) & 0x1f) { + case 0x10: + return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1); + case 0x11: + return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1); + default: + break; + } + break; + case 0x1d: + /* 3DStateMW */ + switch ((cmd >> 16) & 0xff) { + case 0x0: + return debug(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); + case 0x1: + return debug(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); + case 0x4: + return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2); + case 0x5: + return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2); + case 0x6: + return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2); + case 0x7: + return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2); + case 0x80: + return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2); + case 0x81: + return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2); + case 0x83: + return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2); + case 0x85: + return debug(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); + case 0x88: + return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2); + case 0x89: + return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2); + case 0x8e: + return debug(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); + case 0x97: + return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2); + case 0x98: + return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2); + case 0x99: + return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2); + case 0x9a: + return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2); + case 0x9c: + return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2); + default: + assert(0); + return 0; + } + break; + case 0x1e: + if (cmd & (1 << 23)) + return debug(stream, "???", (cmd & 0xffff) + 1); + else + return debug(stream, "", 1); + break; + case 0x1f: + if ((cmd & (1 << 23)) == 0) + return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2); + else if (cmd & (1 << 17)) + { + if ((cmd & 0xffff) == 0) + return debug_variable_length_prim(stream); + else + return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1); + } + else + return debug_prim(stream, "3DPRIM (indirect sequential)", 0, 2); + break; + default: + return debug(stream, "", 0); + } + default: + assert(0); + return 0; + } + + assert(0); + return 0; } + void -i915_disassemble_program(const GLuint * program, GLuint sz) +i915_dump_batchbuffer( GLuint *start, + GLuint *end ) { - GLuint size = program[0] & 0x1ff; - GLint i; + struct debug_stream stream; + GLuint bytes = (end - start) * 4; + GLboolean done = GL_FALSE; - fprintf(stderr, "BEGIN\n"); + fprintf(stderr, "\n\nBATCH: (%d)\n", bytes / 4); - if (size + 2 != sz) { - fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__, - size + 2, sz); - exit(1); - } + stream.offset = 0; + stream.ptr = (char *)start; + stream.print_addresses = 0; - program++; - for (i = 1; i < sz; i += 3, program += 3) { - GLuint opcode = program[0] & (0x1f << 24); + while (!done && + stream.offset < bytes && + stream.offset >= 0) + { + if (!i915_debug_packet( &stream )) + break; - if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) - print_arith_op(opcode >> 24, program); - else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) - print_tex_op(opcode >> 24, program); - else if (opcode == D0_DCL) - print_dcl_op(opcode >> 24, program); - else - fprintf(stderr, "Unknown opcode 0x%x\n", opcode); + assert(stream.offset <= bytes && + stream.offset >= 0); } - fprintf(stderr, "END\n\n"); + fprintf(stderr, "END-BATCH\n\n\n"); } + + diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.h b/src/mesa/drivers/dri/i915tex/i915_debug.h new file mode 100644 index 0000000000..0643a8c631 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_debug.h @@ -0,0 +1,55 @@ +/************************************************************************** + * + * 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 I915_DEBUG_H +#define I915_DEBUG_H + +struct i915_context; + +struct debug_stream +{ + unsigned offset; /* current gtt offset */ + char *ptr; /* pointer to gtt offset zero */ + char *end; /* pointer to gtt offset zero */ + unsigned print_addresses; +}; + + + +extern void i915_disassemble_program(const unsigned *program, unsigned sz); +extern void i915_print_ureg(const char *msg, unsigned ureg); + + +void +i915_dump_batchbuffer( unsigned *start, + unsigned *end ); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_debug_fp.c b/src/mesa/drivers/dri/i915tex/i915_debug_fp.c new file mode 100644 index 0000000000..f4e8ae95ad --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_debug_fp.c @@ -0,0 +1,331 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "i915_reg.h" +#include "i915_debug.h" +//#include "i915_fpc.h" +#include "shader/program.h" +#include "shader/prog_instruction.h" +#include "shader/prog_print.h" + +static const char *opcodes[0x20] = { + "NOP", + "ADD", + "MOV", + "MUL", + "MAD", + "DP2ADD", + "DP3", + "DP4", + "FRC", + "RCP", + "RSQ", + "EXP", + "LOG", + "CMP", + "MIN", + "MAX", + "FLR", + "MOD", + "TRC", + "SGE", + "SLT", + "TEXLD", + "TEXLDP", + "TEXLDB", + "TEXKILL", + "DCL", + "0x1a", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x1f", +}; + + +static const int args[0x20] = { + 0, /* 0 nop */ + 2, /* 1 add */ + 1, /* 2 mov */ + 2, /* 3 m ul */ + 3, /* 4 mad */ + 3, /* 5 dp2add */ + 2, /* 6 dp3 */ + 2, /* 7 dp4 */ + 1, /* 8 frc */ + 1, /* 9 rcp */ + 1, /* a rsq */ + 1, /* b exp */ + 1, /* c log */ + 3, /* d cmp */ + 2, /* e min */ + 2, /* f max */ + 1, /* 10 flr */ + 1, /* 11 mod */ + 1, /* 12 trc */ + 2, /* 13 sge */ + 2, /* 14 slt */ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + + +static const char *regname[0x8] = { + "R", + "T", + "CONST", + "S", + "OC", + "OD", + "U", + "UNKNOWN", +}; + +static void +print_reg_type_nr(GLuint type, GLuint nr) +{ + switch (type) { + case REG_TYPE_T: + switch (nr) { + case T_DIFFUSE: + _mesa_printf("T_DIFFUSE"); + return; + case T_SPECULAR: + _mesa_printf("T_SPECULAR"); + return; + case T_FOG_W: + _mesa_printf("T_FOG_W"); + return; + default: + _mesa_printf("T_TEX%d", nr); + return; + } + case REG_TYPE_OC: + if (nr == 0) { + _mesa_printf("oC"); + return; + } + break; + case REG_TYPE_OD: + if (nr == 0) { + _mesa_printf("oD"); + return; + } + break; + default: + break; + } + + _mesa_printf("%s[%d]", regname[type], nr); +} + +#define REG_SWIZZLE_MASK 0x7777 +#define REG_NEGATE_MASK 0x8888 + +#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ + (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ + (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ + (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) + + +static void +print_reg_neg_swizzle(GLuint reg) +{ + int i; + + if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && + (reg & REG_NEGATE_MASK) == 0) + return; + + _mesa_printf("."); + + for (i = 3; i >= 0; i--) { + if (reg & (1 << ((i * 4) + 3))) + _mesa_printf("-"); + + switch ((reg >> (i * 4)) & 0x7) { + case 0: + _mesa_printf("x"); + break; + case 1: + _mesa_printf("y"); + break; + case 2: + _mesa_printf("z"); + break; + case 3: + _mesa_printf("w"); + break; + case 4: + _mesa_printf("0"); + break; + case 5: + _mesa_printf("1"); + break; + default: + _mesa_printf("?"); + break; + } + } +} + + +static void +print_src_reg(GLuint dword) +{ + GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + print_reg_neg_swizzle(dword); +} + + +static void +print_dest_reg(GLuint dword) +{ + GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) + return; + _mesa_printf("."); + if (dword & A0_DEST_CHANNEL_X) + _mesa_printf("x"); + if (dword & A0_DEST_CHANNEL_Y) + _mesa_printf("y"); + if (dword & A0_DEST_CHANNEL_Z) + _mesa_printf("z"); + if (dword & A0_DEST_CHANNEL_W) + _mesa_printf("w"); +} + + +#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) +#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) +#define GET_SRC2_REG(r) (r) + + +static void +print_arith_op(GLuint opcode, const GLuint * program) +{ + if (opcode != A0_NOP) { + print_dest_reg(program[0]); + if (program[0] & A0_DEST_SATURATE) + _mesa_printf(" = SATURATE "); + else + _mesa_printf(" = "); + } + + _mesa_printf("%s ", opcodes[opcode]); + + print_src_reg(GET_SRC0_REG(program[0], program[1])); + if (args[opcode] == 1) { + _mesa_printf("\n"); + return; + } + + _mesa_printf(", "); + print_src_reg(GET_SRC1_REG(program[1], program[2])); + if (args[opcode] == 2) { + _mesa_printf("\n"); + return; + } + + _mesa_printf(", "); + print_src_reg(GET_SRC2_REG(program[2])); + _mesa_printf("\n"); + return; +} + + +static void +print_tex_op(GLuint opcode, const GLuint * program) +{ + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + _mesa_printf(" = "); + + _mesa_printf("%s ", opcodes[opcode]); + + _mesa_printf("S[%d],", program[0] & T0_SAMPLER_NR_MASK); + + print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & + REG_TYPE_MASK, + (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); + _mesa_printf("\n"); +} + +static void +print_dcl_op(GLuint opcode, const GLuint * program) +{ + _mesa_printf("%s ", opcodes[opcode]); + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + _mesa_printf("\n"); +} + + +void +i915_disassemble_program(const GLuint * program, GLuint sz) +{ + GLuint size = program[0] & 0x1ff; + GLint i; + + _mesa_printf("\t\tBEGIN\n"); + + assert(size + 2 == sz); + + program++; + for (i = 1; i < sz; i += 3, program += 3) { + GLuint opcode = program[0] & (0x1f << 24); + + _mesa_printf("\t\t"); + + if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) + print_arith_op(opcode >> 24, program); + else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) + print_tex_op(opcode >> 24, program); + else if (opcode == D0_DCL) + print_dcl_op(opcode >> 24, program); + else + _mesa_printf("Unknown opcode 0x%x\n", opcode); + } + + _mesa_printf("\t\tEND\n\n"); +} + + diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index 9de35d8e29..ff99721769 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -203,7 +203,7 @@ i915_emit_invarient_state(struct intel_context *intel) /* Need to initialize this to zero. */ - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (1)); + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0)); OUT_BATCH(0); /* XXX: Use this */ @@ -221,6 +221,7 @@ i915_emit_invarient_state(struct intel_context *intel) /* Don't support twosided stencil yet */ OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); + OUT_BATCH(0); ADVANCE_BATCH(); } @@ -252,6 +253,9 @@ get_state_size(struct i915_hw_state *state) GLuint i; GLuint sz = 0; + if (dirty & I915_UPLOAD_INVARIENT) + sz += 30 * 4; + if (dirty & I915_UPLOAD_CTX) sz += sizeof(state->Ctx); @@ -307,6 +311,7 @@ i915_emit_state(struct intel_context *intel) * causing more state to be dirty! */ dirty = get_dirty(state); + state->emitted |= dirty; if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); @@ -429,7 +434,7 @@ i915_emit_state(struct intel_context *intel) i915_disassemble_program(state->Program, state->ProgramSize); } - state->emitted |= dirty; + assert(get_dirty(state) == 0); } static void diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index c92b83bcb3..5d0fd53961 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -27,6 +27,7 @@ #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "i915_debug.h" /* Relocations in kernel space: * - pass dma buffer seperately @@ -71,9 +72,8 @@ intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) { int i; fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 4) - fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", - offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + for (i = 0; i < count / 4; i += 1) + fprintf(stderr, "\t0x%08x\n", ptr[i]); fprintf(stderr, "END BATCH\n\n\n"); } @@ -186,8 +186,10 @@ do_flush_locked(struct intel_batchbuffer *batch, ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; } - if (INTEL_DEBUG & DEBUG_BATCH) - intel_dump_batchbuffer(0, ptr, used); + + i915_dump_batchbuffer(ptr, ptr + used/4); + + intel_dump_batchbuffer(0, ptr, used); driBOUnmap(batch->buffer); batch->map = NULL; -- cgit v1.2.3 From c60113cd41ac84f8737005ca1d7a1114e3725ae5 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 11 Aug 2007 13:40:22 +0100 Subject: Improve debugging further. Pull apart some key packets into individual fields and print sanely. --- src/mesa/drivers/dri/i915tex/i915_debug.c | 445 ++++++++++++++++++++++- src/mesa/drivers/dri/i915tex/i915_debug_fp.c | 2 +- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 7 +- 3 files changed, 430 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_debug.c index e22d79b167..d5e4ff7ae0 100644 --- a/src/mesa/drivers/dri/i915tex/i915_debug.c +++ b/src/mesa/drivers/dri/i915tex/i915_debug.c @@ -50,7 +50,7 @@ static GLboolean debug( struct debug_stream *stream, const char *name, GLuint le _mesa_printf("%s (%d dwords):\n", name, len); for (i = 0; i < len; i++) - _mesa_printf("\t\t0x%08x\n", ptr[i]); + _mesa_printf("\t0x%08x\n", ptr[i]); _mesa_printf("\n"); stream->offset += len * sizeof(GLuint); @@ -89,12 +89,12 @@ static GLboolean debug_prim( struct debug_stream *stream, const char *name, _mesa_printf("%s %s (%d dwords):\n", name, prim, len); - _mesa_printf("\t\t0x%08x\n", ptr[0]); + _mesa_printf("\t0x%08x\n", ptr[0]); for (i = 1; i < len; i++) { if (dump_floats) - _mesa_printf("\t\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); + _mesa_printf("\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); else - _mesa_printf("\t\t0x%08x\n", ptr[i]); + _mesa_printf("\t0x%08x\n", ptr[i]); } @@ -137,7 +137,7 @@ static GLboolean debug_chain( struct debug_stream *stream, const char *name, GLu _mesa_printf("%s (%d dwords):\n", name, len); for (i = 0; i < len; i++) - _mesa_printf("\t\t0x%08x\n", ptr[i]); + _mesa_printf("\t0x%08x\n", ptr[i]); stream->offset = ptr[1] & ~0x3; @@ -167,7 +167,7 @@ static GLboolean debug_variable_length_prim( struct debug_stream *stream ) _mesa_printf("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); for (i = 0; i < len; i++) - _mesa_printf("\t\t0x%08x\n", ptr[i]); + _mesa_printf("\t0x%08x\n", ptr[i]); _mesa_printf("\n"); stream->offset += len * sizeof(GLuint); @@ -175,23 +175,127 @@ static GLboolean debug_variable_length_prim( struct debug_stream *stream ) } +#define BITS( dw, hi, lo, ... ) \ +do { \ + unsigned himask = ~0UL >> (31 - (hi)); \ + _mesa_printf("\t\t "); \ + _mesa_printf(__VA_ARGS__); \ + _mesa_printf(": 0x%x\n", ((dw) & himask) >> (lo)); \ +} while (0) + +#define MBZ( dw, hi, lo) do { \ + unsigned x = (dw) >> (lo); \ + unsigned lomask = (1 << (lo)) - 1; \ + unsigned himask; \ + himask = (1UL << (hi)) - 1; \ + assert ((x & himask & ~lomask) == 0); \ +} while (0) + +#define FLAG( dw, bit, ... ) \ +do { \ + if (((dw) >> (bit)) & 1) { \ + _mesa_printf("\t\t "); \ + _mesa_printf(__VA_ARGS__); \ + _mesa_printf("\n"); \ + } \ +} while (0) + static GLboolean debug_load_immediate( struct debug_stream *stream, const char *name, GLuint len ) { GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); GLuint bits = (ptr[0] >> 4) & 0xff; - GLuint i, j = 0; + GLuint j = 0; _mesa_printf("%s (%d dwords, flags: %x):\n", name, len, bits); - _mesa_printf("\t\t0x%08x\n", ptr[j++]); + _mesa_printf("\t0x%08x\n", ptr[j++]); - for (i = 0; i < 8; i++) { - if (bits & (1<> (i * 4)) & 0xf; +// if (tc != 0xf) + BITS(tc, 3, 0, "tex coord %d", i); } + j++; + } + if (bits & (1<<3)) { + _mesa_printf("\t LIS3: 0x%08x\n", ptr[j]); + j++; + } + if (bits & (1<<4)) { + _mesa_printf("\t LIS4: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 23, "point width"); + BITS(ptr[j], 22, 19, "line width"); + FLAG(ptr[j], 18, "alpha flatshade"); + FLAG(ptr[j], 17, "fog flatshade"); + FLAG(ptr[j], 16, "spec flatshade"); + FLAG(ptr[j], 15, "rgb flatshade"); + BITS(ptr[j], 14, 13, "cull mode"); + FLAG(ptr[j], 12, "vfmt: point width"); + FLAG(ptr[j], 11, "vfmt: specular/fog"); + FLAG(ptr[j], 10, "vfmt: rgba"); + FLAG(ptr[j], 9, "vfmt: depth offset"); + BITS(ptr[j], 8, 6, "vfmt: position (2==xyzw)"); + FLAG(ptr[j], 5, "force dflt diffuse"); + FLAG(ptr[j], 4, "force dflt specular"); + FLAG(ptr[j], 3, "local depth offset enable"); + FLAG(ptr[j], 2, "vfmt: fp32 fog coord"); + FLAG(ptr[j], 1, "sprite point"); + FLAG(ptr[j], 0, "antialiasing"); + j++; + } + if (bits & (1<<5)) { + _mesa_printf("\t LIS5: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 28, "rgba write disables"); + FLAG(ptr[j], 27, "force dflt point width"); + FLAG(ptr[j], 26, "last pixel enable"); + FLAG(ptr[j], 25, "global z offset enable"); + FLAG(ptr[j], 24, "fog enable"); + BITS(ptr[j], 23, 16, "stencil ref"); + BITS(ptr[j], 15, 13, "stencil test"); + BITS(ptr[j], 12, 10, "stencil fail op"); + BITS(ptr[j], 9, 7, "stencil pass z fail op"); + BITS(ptr[j], 6, 4, "stencil pass z pass op"); + FLAG(ptr[j], 3, "stencil write enable"); + FLAG(ptr[j], 2, "stencil test enable"); + FLAG(ptr[j], 1, "color dither enable"); + FLAG(ptr[j], 0, "logiop enable"); + j++; + } + if (bits & (1<<6)) { + _mesa_printf("\t LIS6: 0x%08x\n", ptr[j]); + FLAG(ptr[j], 31, "alpha test enable"); + BITS(ptr[j], 30, 28, "alpha func"); + BITS(ptr[j], 27, 20, "alpha ref"); + FLAG(ptr[j], 19, "depth test enable"); + BITS(ptr[j], 18, 16, "depth func"); + FLAG(ptr[j], 15, "blend enable"); + BITS(ptr[j], 14, 12, "blend func"); + BITS(ptr[j], 11, 8, "blend src factor"); + BITS(ptr[j], 7, 4, "blend dst factor"); + FLAG(ptr[j], 3, "depth write enable"); + FLAG(ptr[j], 2, "color write enable"); + BITS(ptr[j], 1, 0, "provoking vertex"); + j++; } + _mesa_printf("\n"); assert(j == len); @@ -212,7 +316,7 @@ static GLboolean debug_load_indirect( struct debug_stream *stream, GLuint i, j = 0; _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t\t0x%08x\n", ptr[j++]); + _mesa_printf("\t0x%08x\n", ptr[j++]); for (i = 0; i < 6; i++) { if (bits & (1<ptr + stream->offset); + int j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t0x%08x\n", ptr[j++]); + + BR13(stream, ptr[j++]); + BR22(stream, ptr[j++]); + BR23(stream, ptr[j++]); + BR09(stream, ptr[j++]); + BR26(stream, ptr[j++]); + BR11(stream, ptr[j++]); + BR12(stream, ptr[j++]); + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_color_blit( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t0x%08x\n", ptr[j++]); + + BR13(stream, ptr[j++]); + BR22(stream, ptr[j++]); + BR23(stream, ptr[j++]); + BR09(stream, ptr[j++]); + BR16(stream, ptr[j++]); + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_modes4( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 21, 18, "logicop func"); + FLAG(ptr[j], 17, "stencil test mask modify-enable"); + FLAG(ptr[j], 16, "stencil write mask modify-enable"); + BITS(ptr[j], 15, 8, "stencil test mask"); + BITS(ptr[j], 7, 0, "stencil write mask"); + j++; + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_map_state( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t0x%08x\n", ptr[j++]); + + { + _mesa_printf("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 15, 0, "map mask"); + j++; + } + + while (j < len) { + { + _mesa_printf("\t TMn.0: 0x%08x\n", ptr[j]); + _mesa_printf("\t map address: 0x%08x\n", (ptr[j] & ~0x3)); + FLAG(ptr[j], 1, "vertical line stride"); + FLAG(ptr[j], 0, "vertical line stride offset"); + j++; + } + + { + _mesa_printf("\t TMn.1: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 21, "height"); + BITS(ptr[j], 20, 10, "width"); + BITS(ptr[j], 9, 7, "surface format"); + BITS(ptr[j], 6, 3, "texel format"); + FLAG(ptr[j], 2, "use fence regs"); + FLAG(ptr[j], 1, "tiled surface"); + FLAG(ptr[j], 0, "tile walk ymajor"); + j++; + } + { + _mesa_printf("\t TMn.2: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 21, "dword pitch"); + BITS(ptr[j], 20, 15, "cube face enables"); + BITS(ptr[j], 14, 9, "max lod"); + FLAG(ptr[j], 8, "mip layout right"); + BITS(ptr[j], 7, 0, "depth"); + j++; + } + } + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_sampler_state( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t0x%08x\n", ptr[j++]); + + { + _mesa_printf("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 15, 0, "sampler mask"); + j++; + } + + while (j < len) { + { + _mesa_printf("\t TSn.0: 0x%08x\n", ptr[j]); + FLAG(ptr[j], 31, "reverse gamma"); + FLAG(ptr[j], 30, "planar to packed"); + FLAG(ptr[j], 29, "yuv->rgb"); + BITS(ptr[j], 28, 27, "chromakey index"); + BITS(ptr[j], 26, 22, "base mip level"); + BITS(ptr[j], 21, 20, "mip mode filter"); + BITS(ptr[j], 19, 17, "mag mode filter"); + BITS(ptr[j], 16, 14, "min mode filter"); + BITS(ptr[j], 13, 5, "lod bias (s4.4)"); + FLAG(ptr[j], 4, "shadow enable"); + FLAG(ptr[j], 3, "max-aniso-4"); + BITS(ptr[j], 2, 0, "shadow func"); + j++; + } + + { + _mesa_printf("\t TSn.1: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 24, "min lod"); + MBZ( ptr[j], 23, 18 ); + FLAG(ptr[j], 17, "kill pixel enable"); + FLAG(ptr[j], 16, "keyed tex filter mode"); + FLAG(ptr[j], 15, "chromakey enable"); + BITS(ptr[j], 14, 12, "tcx wrap mode"); + BITS(ptr[j], 11, 9, "tcy wrap mode"); + BITS(ptr[j], 8, 6, "tcz wrap mode"); + FLAG(ptr[j], 5, "normalized coords"); + BITS(ptr[j], 4, 1, "map (surface) index"); + FLAG(ptr[j], 0, "EAST deinterlacer enable"); + j++; + } + { + _mesa_printf("\t TSn.2: 0x%08x (default color)\n", ptr[j]); + j++; + } + } + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_dest_vars( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t0x%08x\n", ptr[j++]); + + { + _mesa_printf("\t0x%08x\n", ptr[j]); + FLAG(ptr[j], 31, "early classic ztest"); + FLAG(ptr[j], 30, "opengl tex default color"); + FLAG(ptr[j], 29, "bypass iz"); + FLAG(ptr[j], 28, "lod preclamp"); + BITS(ptr[j], 27, 26, "dither pattern"); + FLAG(ptr[j], 25, "linear gamma blend"); + FLAG(ptr[j], 24, "debug dither"); + BITS(ptr[j], 23, 20, "dstorg x"); + BITS(ptr[j], 19, 16, "dstorg y"); + MBZ (ptr[j], 15, 15 ); + BITS(ptr[j], 14, 12, "422 write select"); + BITS(ptr[j], 11, 8, "cbuf format"); + BITS(ptr[j], 3, 2, "zbuf format"); + FLAG(ptr[j], 1, "vert line stride"); + FLAG(ptr[j], 1, "vert line stride offset"); + j++; + } + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_buf_info( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + _mesa_printf("%s (%d dwords):\n", name, len); + _mesa_printf("\t0x%08x\n", ptr[j++]); + + { + _mesa_printf("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 28, 28, "aux buffer id"); + BITS(ptr[j], 27, 24, "buffer id (7=depth, 3=back)"); + FLAG(ptr[j], 23, "use fence regs"); + FLAG(ptr[j], 22, "tiled surface"); + FLAG(ptr[j], 21, "tile walk ymajor"); + MBZ (ptr[j], 20, 14); + BITS(ptr[j], 13, 2, "dword pitch"); + MBZ (ptr[j], 2, 0); + j++; + } + + _mesa_printf("\t0x%08x -- buffer base address\n", ptr[j++]); + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} static GLboolean i915_debug_packet( struct debug_stream *stream ) { @@ -292,9 +697,9 @@ static GLboolean i915_debug_packet( struct debug_stream *stream ) case 0x2: switch ((cmd >> 22) & 0xff) { case 0x50: - return debug(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); + return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); case 0x53: - return debug(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); + return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); default: return debug(stream, "blit command", (cmd & 0xff) + 2); } @@ -314,7 +719,7 @@ static GLboolean i915_debug_packet( struct debug_stream *stream ) case 0xc: return debug(stream, "3DSTATE_MODES5", 1); case 0xd: - return debug(stream, "3DSTATE_MODES4", 1); + return debug_modes4(stream, "3DSTATE_MODES4", 1); case 0x15: return debug(stream, "3DSTATE_FOG_COLOR", 1); case 0x16: @@ -334,9 +739,9 @@ static GLboolean i915_debug_packet( struct debug_stream *stream ) /* 3DStateMW */ switch ((cmd >> 16) & 0xff) { case 0x0: - return debug(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); + return debug_map_state(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); case 0x1: - return debug(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); + return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); case 0x4: return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2); case 0x5: @@ -352,13 +757,13 @@ static GLboolean i915_debug_packet( struct debug_stream *stream ) case 0x83: return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2); case 0x85: - return debug(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); + return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); case 0x88: return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2); case 0x89: return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2); case 0x8e: - return debug(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); + return debug_buf_info(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); case 0x97: return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2); case 0x98: diff --git a/src/mesa/drivers/dri/i915tex/i915_debug_fp.c b/src/mesa/drivers/dri/i915tex/i915_debug_fp.c index f4e8ae95ad..0e70b32b9e 100644 --- a/src/mesa/drivers/dri/i915tex/i915_debug_fp.c +++ b/src/mesa/drivers/dri/i915tex/i915_debug_fp.c @@ -29,7 +29,7 @@ #include "i915_reg.h" #include "i915_debug.h" -//#include "i915_fpc.h" +#include "main/imports.h" #include "shader/program.h" #include "shader/prog_instruction.h" #include "shader/prog_print.h" diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 5d0fd53961..6665629d03 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -186,10 +186,11 @@ do_flush_locked(struct intel_batchbuffer *batch, ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; } + if (INTEL_DEBUG & DEBUG_BATCH) { + if (0) i915_dump_batchbuffer(ptr, ptr + used/4); + intel_dump_batchbuffer(0, ptr, used); + } - i915_dump_batchbuffer(ptr, ptr + used/4); - - intel_dump_batchbuffer(0, ptr, used); driBOUnmap(batch->buffer); batch->map = NULL; -- cgit v1.2.3 From 6ea55d35254b7769c65f064170d8965c0bf34a27 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 11 Aug 2007 13:48:19 +0100 Subject: Make it easier to compare against the pipe driver debug code. --- src/mesa/drivers/dri/i915tex/i915_debug.c | 180 +++++++++++++-------------- src/mesa/drivers/dri/i915tex/i915_debug_fp.c | 80 ++++++------ 2 files changed, 131 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_debug.c index d5e4ff7ae0..c0e1242a0e 100644 --- a/src/mesa/drivers/dri/i915tex/i915_debug.c +++ b/src/mesa/drivers/dri/i915tex/i915_debug.c @@ -31,7 +31,7 @@ #include "i915_context.h" #include "i915_debug.h" - +#define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) static GLboolean debug( struct debug_stream *stream, const char *name, GLuint len ) { @@ -39,19 +39,19 @@ static GLboolean debug( struct debug_stream *stream, const char *name, GLuint le GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); if (len == 0) { - _mesa_printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]); + PRINTF("Error - zero length packet (0x%08x)\n", stream->ptr[0]); assert(0); return GL_FALSE; } if (stream->print_addresses) - _mesa_printf("%08x: ", stream->offset); + PRINTF("%08x: ", stream->offset); - _mesa_printf("%s (%d dwords):\n", name, len); + PRINTF("%s (%d dwords):\n", name, len); for (i = 0; i < len; i++) - _mesa_printf("\t0x%08x\n", ptr[i]); - _mesa_printf("\n"); + PRINTF("\t0x%08x\n", ptr[i]); + PRINTF("\n"); stream->offset += len * sizeof(GLuint); @@ -88,17 +88,17 @@ static GLboolean debug_prim( struct debug_stream *stream, const char *name, - _mesa_printf("%s %s (%d dwords):\n", name, prim, len); - _mesa_printf("\t0x%08x\n", ptr[0]); + PRINTF("%s %s (%d dwords):\n", name, prim, len); + PRINTF("\t0x%08x\n", ptr[0]); for (i = 1; i < len; i++) { if (dump_floats) - _mesa_printf("\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); + PRINTF("\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); else - _mesa_printf("\t0x%08x\n", ptr[i]); + PRINTF("\t0x%08x\n", ptr[i]); } - _mesa_printf("\n"); + PRINTF("\n"); stream->offset += len * sizeof(GLuint); @@ -113,15 +113,15 @@ static GLboolean debug_program( struct debug_stream *stream, const char *name, G GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); if (len == 0) { - _mesa_printf("Error - zero length packet (0x%08x)\n", stream->ptr[0]); + PRINTF("Error - zero length packet (0x%08x)\n", stream->ptr[0]); assert(0); return GL_FALSE; } if (stream->print_addresses) - _mesa_printf("%08x: ", stream->offset); + PRINTF("%08x: ", stream->offset); - _mesa_printf("%s (%d dwords):\n", name, len); + PRINTF("%s (%d dwords):\n", name, len); i915_disassemble_program( ptr, len ); stream->offset += len * sizeof(GLuint); @@ -135,17 +135,17 @@ static GLboolean debug_chain( struct debug_stream *stream, const char *name, GLu GLuint old_offset = stream->offset + len * sizeof(GLuint); GLuint i; - _mesa_printf("%s (%d dwords):\n", name, len); + PRINTF("%s (%d dwords):\n", name, len); for (i = 0; i < len; i++) - _mesa_printf("\t0x%08x\n", ptr[i]); + PRINTF("\t0x%08x\n", ptr[i]); stream->offset = ptr[1] & ~0x3; if (stream->offset < old_offset) - _mesa_printf("\n... skipping backwards from 0x%x --> 0x%x ...\n\n", + PRINTF("\n... skipping backwards from 0x%x --> 0x%x ...\n\n", old_offset, stream->offset ); else - _mesa_printf("\n... skipping from 0x%x --> 0x%x ...\n\n", + PRINTF("\n... skipping from 0x%x --> 0x%x ...\n\n", old_offset, stream->offset ); @@ -165,10 +165,10 @@ static GLboolean debug_variable_length_prim( struct debug_stream *stream ) len = 1+(i+2)/2; - _mesa_printf("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); + PRINTF("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); for (i = 0; i < len; i++) - _mesa_printf("\t0x%08x\n", ptr[i]); - _mesa_printf("\n"); + PRINTF("\t0x%08x\n", ptr[i]); + PRINTF("\n"); stream->offset += len * sizeof(GLuint); return GL_TRUE; @@ -178,9 +178,9 @@ static GLboolean debug_variable_length_prim( struct debug_stream *stream ) #define BITS( dw, hi, lo, ... ) \ do { \ unsigned himask = ~0UL >> (31 - (hi)); \ - _mesa_printf("\t\t "); \ - _mesa_printf(__VA_ARGS__); \ - _mesa_printf(": 0x%x\n", ((dw) & himask) >> (lo)); \ + PRINTF("\t\t "); \ + PRINTF(__VA_ARGS__); \ + PRINTF(": 0x%x\n", ((dw) & himask) >> (lo)); \ } while (0) #define MBZ( dw, hi, lo) do { \ @@ -194,9 +194,9 @@ do { \ #define FLAG( dw, bit, ... ) \ do { \ if (((dw) >> (bit)) & 1) { \ - _mesa_printf("\t\t "); \ - _mesa_printf(__VA_ARGS__); \ - _mesa_printf("\n"); \ + PRINTF("\t\t "); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n"); \ } \ } while (0) @@ -208,17 +208,17 @@ static GLboolean debug_load_immediate( struct debug_stream *stream, GLuint bits = (ptr[0] >> 4) & 0xff; GLuint j = 0; - _mesa_printf("%s (%d dwords, flags: %x):\n", name, len, bits); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords, flags: %x):\n", name, len, bits); + PRINTF("\t0x%08x\n", ptr[j++]); if (bits & (1<<0)) { - _mesa_printf("\t LIS0: 0x%08x\n", ptr[j]); - _mesa_printf("\t vb address: 0x%08x\n", (ptr[j] & ~0x3)); + PRINTF("\t LIS0: 0x%08x\n", ptr[j]); + PRINTF("\t vb address: 0x%08x\n", (ptr[j] & ~0x3)); BITS(ptr[j], 0, 0, "vb invalidate disable"); j++; } if (bits & (1<<1)) { - _mesa_printf("\t LIS1: 0x%08x\n", ptr[j]); + PRINTF("\t LIS1: 0x%08x\n", ptr[j]); BITS(ptr[j], 29, 24, "vb dword width"); BITS(ptr[j], 21, 16, "vb dword pitch"); BITS(ptr[j], 15, 0, "vb max index"); @@ -226,20 +226,20 @@ static GLboolean debug_load_immediate( struct debug_stream *stream, } if (bits & (1<<2)) { int i; - _mesa_printf("\t LIS2: 0x%08x\n", ptr[j]); + PRINTF("\t LIS2: 0x%08x\n", ptr[j]); for (i = 0; i < 8; i++) { unsigned tc = (ptr[j] >> (i * 4)) & 0xf; -// if (tc != 0xf) + if (tc != 0xf) BITS(tc, 3, 0, "tex coord %d", i); } j++; } if (bits & (1<<3)) { - _mesa_printf("\t LIS3: 0x%08x\n", ptr[j]); + PRINTF("\t LIS3: 0x%08x\n", ptr[j]); j++; } if (bits & (1<<4)) { - _mesa_printf("\t LIS4: 0x%08x\n", ptr[j]); + PRINTF("\t LIS4: 0x%08x\n", ptr[j]); BITS(ptr[j], 31, 23, "point width"); BITS(ptr[j], 22, 19, "line width"); FLAG(ptr[j], 18, "alpha flatshade"); @@ -261,7 +261,7 @@ static GLboolean debug_load_immediate( struct debug_stream *stream, j++; } if (bits & (1<<5)) { - _mesa_printf("\t LIS5: 0x%08x\n", ptr[j]); + PRINTF("\t LIS5: 0x%08x\n", ptr[j]); BITS(ptr[j], 31, 28, "rgba write disables"); FLAG(ptr[j], 27, "force dflt point width"); FLAG(ptr[j], 26, "last pixel enable"); @@ -279,7 +279,7 @@ static GLboolean debug_load_immediate( struct debug_stream *stream, j++; } if (bits & (1<<6)) { - _mesa_printf("\t LIS6: 0x%08x\n", ptr[j]); + PRINTF("\t LIS6: 0x%08x\n", ptr[j]); FLAG(ptr[j], 31, "alpha test enable"); BITS(ptr[j], 30, 28, "alpha func"); BITS(ptr[j], 27, 20, "alpha ref"); @@ -296,7 +296,7 @@ static GLboolean debug_load_immediate( struct debug_stream *stream, } - _mesa_printf("\n"); + PRINTF("\n"); assert(j == len); @@ -315,34 +315,34 @@ static GLboolean debug_load_indirect( struct debug_stream *stream, GLuint bits = (ptr[0] >> 8) & 0x3f; GLuint i, j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); for (i = 0; i < 6; i++) { if (bits & (1<ptr + stream->offset); int j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); BR13(stream, ptr[j++]); BR22(stream, ptr[j++]); @@ -455,8 +455,8 @@ static GLboolean debug_color_blit( struct debug_stream *stream, GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); int j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); BR13(stream, ptr[j++]); BR22(stream, ptr[j++]); @@ -476,8 +476,8 @@ static GLboolean debug_modes4( struct debug_stream *stream, GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); int j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j]); BITS(ptr[j], 21, 18, "logicop func"); FLAG(ptr[j], 17, "stencil test mask modify-enable"); FLAG(ptr[j], 16, "stencil write mask modify-enable"); @@ -497,26 +497,26 @@ static GLboolean debug_map_state( struct debug_stream *stream, GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); int j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); { - _mesa_printf("\t0x%08x\n", ptr[j]); + PRINTF("\t0x%08x\n", ptr[j]); BITS(ptr[j], 15, 0, "map mask"); j++; } while (j < len) { { - _mesa_printf("\t TMn.0: 0x%08x\n", ptr[j]); - _mesa_printf("\t map address: 0x%08x\n", (ptr[j] & ~0x3)); + PRINTF("\t TMn.0: 0x%08x\n", ptr[j]); + PRINTF("\t map address: 0x%08x\n", (ptr[j] & ~0x3)); FLAG(ptr[j], 1, "vertical line stride"); FLAG(ptr[j], 0, "vertical line stride offset"); j++; } { - _mesa_printf("\t TMn.1: 0x%08x\n", ptr[j]); + PRINTF("\t TMn.1: 0x%08x\n", ptr[j]); BITS(ptr[j], 31, 21, "height"); BITS(ptr[j], 20, 10, "width"); BITS(ptr[j], 9, 7, "surface format"); @@ -527,7 +527,7 @@ static GLboolean debug_map_state( struct debug_stream *stream, j++; } { - _mesa_printf("\t TMn.2: 0x%08x\n", ptr[j]); + PRINTF("\t TMn.2: 0x%08x\n", ptr[j]); BITS(ptr[j], 31, 21, "dword pitch"); BITS(ptr[j], 20, 15, "cube face enables"); BITS(ptr[j], 14, 9, "max lod"); @@ -549,18 +549,18 @@ static GLboolean debug_sampler_state( struct debug_stream *stream, GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); int j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); { - _mesa_printf("\t0x%08x\n", ptr[j]); + PRINTF("\t0x%08x\n", ptr[j]); BITS(ptr[j], 15, 0, "sampler mask"); j++; } while (j < len) { { - _mesa_printf("\t TSn.0: 0x%08x\n", ptr[j]); + PRINTF("\t TSn.0: 0x%08x\n", ptr[j]); FLAG(ptr[j], 31, "reverse gamma"); FLAG(ptr[j], 30, "planar to packed"); FLAG(ptr[j], 29, "yuv->rgb"); @@ -577,7 +577,7 @@ static GLboolean debug_sampler_state( struct debug_stream *stream, } { - _mesa_printf("\t TSn.1: 0x%08x\n", ptr[j]); + PRINTF("\t TSn.1: 0x%08x\n", ptr[j]); BITS(ptr[j], 31, 24, "min lod"); MBZ( ptr[j], 23, 18 ); FLAG(ptr[j], 17, "kill pixel enable"); @@ -592,7 +592,7 @@ static GLboolean debug_sampler_state( struct debug_stream *stream, j++; } { - _mesa_printf("\t TSn.2: 0x%08x (default color)\n", ptr[j]); + PRINTF("\t TSn.2: 0x%08x (default color)\n", ptr[j]); j++; } } @@ -609,11 +609,11 @@ static GLboolean debug_dest_vars( struct debug_stream *stream, GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); int j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); { - _mesa_printf("\t0x%08x\n", ptr[j]); + PRINTF("\t0x%08x\n", ptr[j]); FLAG(ptr[j], 31, "early classic ztest"); FLAG(ptr[j], 30, "opengl tex default color"); FLAG(ptr[j], 29, "bypass iz"); @@ -644,11 +644,11 @@ static GLboolean debug_buf_info( struct debug_stream *stream, GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); int j = 0; - _mesa_printf("%s (%d dwords):\n", name, len); - _mesa_printf("\t0x%08x\n", ptr[j++]); + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); { - _mesa_printf("\t0x%08x\n", ptr[j]); + PRINTF("\t0x%08x\n", ptr[j]); BITS(ptr[j], 28, 28, "aux buffer id"); BITS(ptr[j], 27, 24, "buffer id (7=depth, 3=back)"); FLAG(ptr[j], 23, "use fence regs"); @@ -660,7 +660,7 @@ static GLboolean debug_buf_info( struct debug_stream *stream, j++; } - _mesa_printf("\t0x%08x -- buffer base address\n", ptr[j++]); + PRINTF("\t0x%08x -- buffer base address\n", ptr[j++]); stream->offset += len * sizeof(GLuint); assert(j == len); @@ -820,7 +820,7 @@ i915_dump_batchbuffer( GLuint *start, GLuint bytes = (end - start) * 4; GLboolean done = GL_FALSE; - fprintf(stderr, "\n\nBATCH: (%d)\n", bytes / 4); + PRINTF("\n\nBATCH: (%d)\n", bytes / 4); stream.offset = 0; stream.ptr = (char *)start; @@ -837,7 +837,7 @@ i915_dump_batchbuffer( GLuint *start, stream.offset >= 0); } - fprintf(stderr, "END-BATCH\n\n\n"); + PRINTF("END-BATCH\n\n\n"); } diff --git a/src/mesa/drivers/dri/i915tex/i915_debug_fp.c b/src/mesa/drivers/dri/i915tex/i915_debug_fp.c index 0e70b32b9e..84347a01ef 100644 --- a/src/mesa/drivers/dri/i915tex/i915_debug_fp.c +++ b/src/mesa/drivers/dri/i915tex/i915_debug_fp.c @@ -34,6 +34,8 @@ #include "shader/prog_instruction.h" #include "shader/prog_print.h" +#define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) + static const char *opcodes[0x20] = { "NOP", "ADD", @@ -124,27 +126,27 @@ print_reg_type_nr(GLuint type, GLuint nr) case REG_TYPE_T: switch (nr) { case T_DIFFUSE: - _mesa_printf("T_DIFFUSE"); + PRINTF("T_DIFFUSE"); return; case T_SPECULAR: - _mesa_printf("T_SPECULAR"); + PRINTF("T_SPECULAR"); return; case T_FOG_W: - _mesa_printf("T_FOG_W"); + PRINTF("T_FOG_W"); return; default: - _mesa_printf("T_TEX%d", nr); + PRINTF("T_TEX%d", nr); return; } case REG_TYPE_OC: if (nr == 0) { - _mesa_printf("oC"); + PRINTF("oC"); return; } break; case REG_TYPE_OD: if (nr == 0) { - _mesa_printf("oD"); + PRINTF("oD"); return; } break; @@ -152,7 +154,7 @@ print_reg_type_nr(GLuint type, GLuint nr) break; } - _mesa_printf("%s[%d]", regname[type], nr); + PRINTF("%s[%d]", regname[type], nr); } #define REG_SWIZZLE_MASK 0x7777 @@ -173,33 +175,33 @@ print_reg_neg_swizzle(GLuint reg) (reg & REG_NEGATE_MASK) == 0) return; - _mesa_printf("."); + PRINTF("."); for (i = 3; i >= 0; i--) { if (reg & (1 << ((i * 4) + 3))) - _mesa_printf("-"); + PRINTF("-"); switch ((reg >> (i * 4)) & 0x7) { case 0: - _mesa_printf("x"); + PRINTF("x"); break; case 1: - _mesa_printf("y"); + PRINTF("y"); break; case 2: - _mesa_printf("z"); + PRINTF("z"); break; case 3: - _mesa_printf("w"); + PRINTF("w"); break; case 4: - _mesa_printf("0"); + PRINTF("0"); break; case 5: - _mesa_printf("1"); + PRINTF("1"); break; default: - _mesa_printf("?"); + PRINTF("?"); break; } } @@ -224,15 +226,15 @@ print_dest_reg(GLuint dword) print_reg_type_nr(type, nr); if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) return; - _mesa_printf("."); + PRINTF("."); if (dword & A0_DEST_CHANNEL_X) - _mesa_printf("x"); + PRINTF("x"); if (dword & A0_DEST_CHANNEL_Y) - _mesa_printf("y"); + PRINTF("y"); if (dword & A0_DEST_CHANNEL_Z) - _mesa_printf("z"); + PRINTF("z"); if (dword & A0_DEST_CHANNEL_W) - _mesa_printf("w"); + PRINTF("w"); } @@ -247,29 +249,29 @@ print_arith_op(GLuint opcode, const GLuint * program) if (opcode != A0_NOP) { print_dest_reg(program[0]); if (program[0] & A0_DEST_SATURATE) - _mesa_printf(" = SATURATE "); + PRINTF(" = SATURATE "); else - _mesa_printf(" = "); + PRINTF(" = "); } - _mesa_printf("%s ", opcodes[opcode]); + PRINTF("%s ", opcodes[opcode]); print_src_reg(GET_SRC0_REG(program[0], program[1])); if (args[opcode] == 1) { - _mesa_printf("\n"); + PRINTF("\n"); return; } - _mesa_printf(", "); + PRINTF(", "); print_src_reg(GET_SRC1_REG(program[1], program[2])); if (args[opcode] == 2) { - _mesa_printf("\n"); + PRINTF("\n"); return; } - _mesa_printf(", "); + PRINTF(", "); print_src_reg(GET_SRC2_REG(program[2])); - _mesa_printf("\n"); + PRINTF("\n"); return; } @@ -278,24 +280,24 @@ static void print_tex_op(GLuint opcode, const GLuint * program) { print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - _mesa_printf(" = "); + PRINTF(" = "); - _mesa_printf("%s ", opcodes[opcode]); + PRINTF("%s ", opcodes[opcode]); - _mesa_printf("S[%d],", program[0] & T0_SAMPLER_NR_MASK); + PRINTF("S[%d],", program[0] & T0_SAMPLER_NR_MASK); print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & REG_TYPE_MASK, (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); - _mesa_printf("\n"); + PRINTF("\n"); } static void print_dcl_op(GLuint opcode, const GLuint * program) { - _mesa_printf("%s ", opcodes[opcode]); + PRINTF("%s ", opcodes[opcode]); print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - _mesa_printf("\n"); + PRINTF("\n"); } @@ -305,7 +307,7 @@ i915_disassemble_program(const GLuint * program, GLuint sz) GLuint size = program[0] & 0x1ff; GLint i; - _mesa_printf("\t\tBEGIN\n"); + PRINTF("\t\tBEGIN\n"); assert(size + 2 == sz); @@ -313,7 +315,7 @@ i915_disassemble_program(const GLuint * program, GLuint sz) for (i = 1; i < sz; i += 3, program += 3) { GLuint opcode = program[0] & (0x1f << 24); - _mesa_printf("\t\t"); + PRINTF("\t\t"); if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) print_arith_op(opcode >> 24, program); @@ -322,10 +324,10 @@ i915_disassemble_program(const GLuint * program, GLuint sz) else if (opcode == D0_DCL) print_dcl_op(opcode >> 24, program); else - _mesa_printf("Unknown opcode 0x%x\n", opcode); + PRINTF("Unknown opcode 0x%x\n", opcode); } - _mesa_printf("\t\tEND\n\n"); + PRINTF("\t\tEND\n\n"); } -- cgit v1.2.3 From 21b37b9687b078297935062e3ad9f379b6f36519 Mon Sep 17 00:00:00 2001 From: Dan Torop Date: Sun, 12 Aug 2007 13:41:13 +0200 Subject: fix spantmp2 READ_RGBA inline asm (#11931) --- src/mesa/drivers/dri/common/spantmp2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h index 50f3cf5581..53f5f846a0 100644 --- a/src/mesa/drivers/dri/common/spantmp2.h +++ b/src/mesa/drivers/dri/common/spantmp2.h @@ -114,7 +114,7 @@ do { \ GLuint p = *(volatile GLuint *) GET_PTR(_x, _y); \ __asm__ __volatile__( "bswap %0; rorl $8, %0" \ - : "=r" (p) : "r" (p) ); \ + : "=r" (p) : "0" (p) ); \ ((GLuint *)rgba)[0] = p; \ } while (0) # elif defined( MESA_BIG_ENDIAN ) -- cgit v1.2.3 From c9e4aa2b303f9056564724ece0e2733a54d9f569 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 13 Aug 2007 11:43:37 +0800 Subject: i915: satisfy certain alignment restrictions for small compressed texture --- src/mesa/drivers/dri/i915/i915_texstate.c | 57 ++++++++++++++++++++++++++++--- src/mesa/drivers/dri/i915/intel_tex.c | 6 ++-- 2 files changed, 57 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index a19d4b6584..2b806cc36e 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -60,6 +60,33 @@ static GLint step_offsets[6][2] = { {0,2}, #define I915_TEX_UNIT_ENABLED(unit) (1<> 1); +} + static void i915LayoutTextureImages( i915ContextPtr i915, struct gl_texture_object *tObj ) { @@ -161,8 +188,15 @@ static void i915LayoutTextureImages( i915ContextPtr i915, break; } default: - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; + if (baseImage->IsCompressed) { + GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat); + + pitch = align(tObj->Image[0][firstLevel]->Width, alignment) * t->intel.texelBytes; + } else { + pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; + pitch = (pitch + 3) & ~3; + } + t->intel.base.dirty_images[0] = ~0; for ( total_height = i = 0 ; i < numLevels ; i++ ) { @@ -343,8 +377,23 @@ static void i945LayoutTextureImages( i915ContextPtr i915, break; } default: - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; + if (baseImage->IsCompressed) { + GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat); + + pitch = align(tObj->Image[0][firstLevel]->Width, alignment); + if (numLevels > 2) { + GLint width0 = align(minify(tObj->Image[0][firstLevel]->Width), alignment) + + + align(minify(minify(tObj->Image[0][firstLevel]->Width)), alignment); + + if (width0 > pitch) + pitch = width0; + } + pitch = pitch * t->intel.texelBytes; + } else { + pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; + pitch = (pitch + 3) & ~3; + } + t->intel.base.dirty_images[0] = ~0; max_offset = 0; diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c index 5bd280652a..978945f26b 100644 --- a/src/mesa/drivers/dri/i915/intel_tex.c +++ b/src/mesa/drivers/dri/i915/intel_tex.c @@ -643,17 +643,19 @@ static void intelUploadTexImage( intelContextPtr intel, switch (image->InternalFormat) { case GL_COMPRESSED_RGB_FXT1_3DFX: case GL_COMPRESSED_RGBA_FXT1_3DFX: + row_len = ((image->Width + 7) & ~7) * 2; + break; case GL_RGB_S3TC: case GL_RGB4_S3TC: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - row_len = (image->Width * 2 + 7) & ~7; + row_len = ((image->Width + 3) & ~3) * 2; break; case GL_RGBA_S3TC: case GL_RGBA4_S3TC: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - row_len = (image->Width * 4 + 15) & ~15; + row_len = ((image->Width + 3) & ~3) * 4; break; default: fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat); -- cgit v1.2.3 From 88451b04e9cd39db9cc9315aaf69e074614f22f9 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 13 Aug 2007 17:16:27 +0800 Subject: i965: fix projtex_mask projtex_mask is only an 8bit field, and wm.input_size_masks includes other attributes' information, therefore right shift is needed. --- src/mesa/drivers/dri/i965/brw_wm.c | 2 +- src/mesa/drivers/dri/i965/brw_wm_fp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 1497dc7968..904c00bef8 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -285,7 +285,7 @@ static void brw_wm_populate_key( struct brw_context *brw, /* BRW_NEW_WM_INPUT_DIMENSIONS */ - key->projtex_mask = brw->wm.input_size_masks[4-1]; + key->projtex_mask = brw->wm.input_size_masks[4-1] >> (FRAG_ATTRIB_TEX0 - FRAG_ATTRIB_WPOS); /* _NEW_LIGHT */ key->flat_shade = (brw->attribs.Light->ShadeModel == GL_FLAT); diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index ff97d87dc4..62bb081206 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -660,7 +660,7 @@ static GLboolean projtex( struct brw_wm_compile *c, return 0; /* ut2004 gun rendering !?! */ else if (src.File == PROGRAM_INPUT && GET_SWZ(src.Swizzle, W) == W && - (c->key.projtex_mask & (1<key.projtex_mask & (1<<(src.Index + FRAG_ATTRIB_WPOS - FRAG_ATTRIB_TEX0))) == 0) return 0; else return 1; -- cgit v1.2.3 From 6f4725088842fbc0069aeb51f41907b87e0a8f08 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 13 Aug 2007 11:09:48 +0100 Subject: added some missing Default1D/2DArray texture code --- src/mesa/main/context.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 00e4c8328e..6fa32b320a 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -552,6 +552,10 @@ alloc_shared_state( GLcontext *ctx ) (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap); if (ss->DefaultRect) (*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect); + if (ss->Default1DArray) + (*ctx->Driver.DeleteTexture)(ctx, ss->Default1DArray); + if (ss->Default2DArray) + (*ctx->Driver.DeleteTexture)(ctx, ss->Default2DArray); if (ss) _mesa_free(ss); return GL_FALSE; @@ -676,6 +680,9 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) ctx->Driver.DeleteTexture(ctx, ss->Default3D); ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap); ctx->Driver.DeleteTexture(ctx, ss->DefaultRect); + ctx->Driver.DeleteTexture(ctx, ss->Default1DArray); + ctx->Driver.DeleteTexture(ctx, ss->Default2DArray); + /* all other textures */ _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); _mesa_DeleteHashTable(ss->TexObjects); -- cgit v1.2.3 From 9e01b915f1243a3f551cb795b7124bd1e52ca15f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 13 Aug 2007 11:29:46 +0100 Subject: Implement mutex/locking around texture object reference counting. Use new _mesa_reference_texobj() function for referencing/unreferencing textures. Add new assertions/tests to try to detect invalid usage of deleted textures. --- src/mesa/main/attrib.c | 1 + src/mesa/main/context.c | 14 +-- src/mesa/main/fbobject.c | 22 ++-- src/mesa/main/framebuffer.c | 13 +-- src/mesa/main/mtypes.h | 1 + src/mesa/main/texobj.c | 252 +++++++++++++++++++++++--------------------- src/mesa/main/texobj.h | 4 + src/mesa/main/texstate.c | 89 ++++++---------- 8 files changed, 184 insertions(+), 212 deletions(-) (limited to 'src') diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index b422198f92..36e438a53c 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -355,6 +355,7 @@ _mesa_PushAttrib(GLbitfield mask) ctx->Texture.Unit[u].Current1DArray->RefCount++; ctx->Texture.Unit[u].Current2DArray->RefCount++; } + attr = MALLOC_STRUCT( gl_texture_attrib ); MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); /* copy state of the currently bound texture objects */ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 6fa32b320a..f360eac1e7 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -475,19 +475,12 @@ alloc_shared_state( GLcontext *ctx ) if (!ss->Default2DArray) goto cleanup; - /* Effectively bind the default textures to all texture units */ - ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default1DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS; - ss->Default2DArray->RefCount += MAX_TEXTURE_IMAGE_UNITS; + /* sanity check */ + assert(ss->Default1D->RefCount == 1); _glthread_INIT_MUTEX(ss->TexMutex); ss->TextureStateStamp = 0; - #if FEATURE_EXT_framebuffer_object ss->FrameBuffers = _mesa_NewHashTable(); if (!ss->FrameBuffers) @@ -497,10 +490,9 @@ alloc_shared_state( GLcontext *ctx ) goto cleanup; #endif - return GL_TRUE; - cleanup: +cleanup: /* Ran out of memory at some point. Free everything and return NULL */ if (ss->DisplayList) _mesa_DeleteHashTable(ss->DisplayList); diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 6f7effcce7..fcb620b39d 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -151,22 +151,18 @@ _mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att) { if (att->Type == GL_TEXTURE) { ASSERT(att->Texture); - att->Texture->RefCount--; - if (att->Texture->RefCount == 0) { - ctx->Driver.DeleteTexture(ctx, att->Texture); + if (ctx->Driver.FinishRenderTexture) { + /* tell driver we're done rendering to this texobj */ + ctx->Driver.FinishRenderTexture(ctx, att); } - else { - /* tell driver that we're done rendering to this texture. */ - if (ctx->Driver.FinishRenderTexture) { - ctx->Driver.FinishRenderTexture(ctx, att); - } - } - att->Texture = NULL; + _mesa_reference_texobj(&att->Texture, NULL); /* unbind */ + ASSERT(!att->Texture); } if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) { ASSERT(att->Renderbuffer); ASSERT(!att->Texture); - _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); + _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */ + ASSERT(!att->Renderbuffer); } att->Type = GL_NONE; att->Complete = GL_TRUE; @@ -192,8 +188,8 @@ _mesa_set_texture_attachment(GLcontext *ctx, /* new attachment */ _mesa_remove_attachment(ctx, att); att->Type = GL_TEXTURE; - att->Texture = texObj; - texObj->RefCount++; + assert(!att->Texture); + _mesa_reference_texobj(&att->Texture, texObj); } /* always update these fields */ diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index c9b30d3252..0a6de12fb8 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -38,6 +38,7 @@ #include "fbobject.h" #include "framebuffer.h" #include "renderbuffer.h" +#include "texobj.h" @@ -192,17 +193,11 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); } if (att->Texture) { - /* render to texture */ - att->Texture->RefCount--; - if (att->Texture->RefCount == 0) { - GET_CURRENT_CONTEXT(ctx); - if (ctx) { - ctx->Driver.DeleteTexture(ctx, att->Texture); - } - } + _mesa_reference_texobj(&att->Texture, NULL); } + ASSERT(!att->Renderbuffer); + ASSERT(!att->Texture); att->Type = GL_NONE; - att->Texture = NULL; } /* unbind _Depth/_StencilBuffer to decr ref counts */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 3e4c49249a..989d199a10 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1400,6 +1400,7 @@ struct gl_texture_image */ struct gl_texture_object { + _glthread_Mutex Mutex; /**< for thread safety */ GLint RefCount; /**< reference count */ GLuint Name; /**< the user-visible texture object ID */ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index df64002f99..ac70e5a22e 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -106,6 +106,7 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, _mesa_bzero(obj, sizeof(*obj)); /* init the non-zero fields */ + _glthread_INIT_MUTEX(obj->Mutex); obj->RefCount = 1; obj->Name = name; obj->Target = target; @@ -151,8 +152,17 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) { GLuint i, face; + /* + printf("TEX DELETE %p (%u)\n", (void*) texObj, texObj->Name); + */ + (void) ctx; + /* Set Target to an invalid value. With some assertions elsewhere + * we can try to detect possible use of deleted textures. + */ + texObj->Target = 0x99; + _mesa_free_colortable_data(&texObj->Palette); /* free the texture images */ @@ -164,6 +174,9 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) } } + /* destroy the mutex -- it may have allocated memory (eg on bsd) */ + _glthread_DESTROY_MUTEX(texObj->Mutex); + /* free this object */ _mesa_free(texObj); } @@ -213,6 +226,98 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, } +/** + * Check if the given texture object is valid by examining its Target field. + * For debugging only. + */ +static GLboolean +valid_texture_object(const struct gl_texture_object *tex) +{ + switch (tex->Target) { + case 0: + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_1D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: + return GL_TRUE; + case 0x99: + _mesa_problem(NULL, "invalid reference to a deleted texture object"); + return GL_FALSE; + default: + _mesa_problem(NULL, "invalid texture object Target value"); + return GL_FALSE; + } +} + + +/** + * Reference (or unreference) a texture object. + * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero). + * If 'tex' is non-null, increment its refcount. + */ +void +_mesa_reference_texobj(struct gl_texture_object **ptr, + struct gl_texture_object *tex) +{ + assert(ptr); + if (*ptr == tex) { + /* no change */ + return; + } + + if (*ptr) { + /* Unreference the old texture */ + GLboolean deleteFlag = GL_FALSE; + struct gl_texture_object *oldTex = *ptr; + + assert(valid_texture_object(oldTex)); + + _glthread_LOCK_MUTEX(oldTex->Mutex); + ASSERT(oldTex->RefCount > 0); + oldTex->RefCount--; + /* + printf("TEX DECR %p (%u) to %d\n", + (void*) oldTex, oldTex->Name, oldTex->RefCount); + */ + deleteFlag = (oldTex->RefCount == 0); + _glthread_UNLOCK_MUTEX(oldTex->Mutex); + + if (deleteFlag) { + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.DeleteTexture(ctx, oldTex); + } + + *ptr = NULL; + } + assert(!*ptr); + + if (tex) { + /* reference new texture */ + assert(valid_texture_object(tex)); + _glthread_LOCK_MUTEX(tex->Mutex); + if (tex->RefCount == 0) { + /* this texture's being deleted (look just above) */ + /* Not sure this can every really happen. Warn if it does. */ + _mesa_problem(NULL, "referencing deleted texture object"); + *ptr = NULL; + } + else { + tex->RefCount++; + /* + printf("TEX INCR %p (%u) to %d\n", + (void*) tex, tex->Name, tex->RefCount); + */ + *ptr = tex; + } + _glthread_UNLOCK_MUTEX(tex->Mutex); + } +} + + + /** * Report why a texture object is incomplete. * @@ -609,8 +714,7 @@ unbind_texobj_from_fbo(GLcontext *ctx, struct gl_texture_object *texObj) /** * Check if the given texture object is bound to any texture image units and - * unbind it if so. - * XXX all RefCount accesses should be protected by a mutex. + * unbind it if so (revert to default textures). */ static void unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj) @@ -619,42 +723,26 @@ unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj) for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { struct gl_texture_unit *unit = &ctx->Texture.Unit[u]; - struct gl_texture_object **curr = NULL; - if (texObj == unit->Current1D) { - curr = &unit->Current1D; - unit->Current1D = ctx->Shared->Default1D; + _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D); } else if (texObj == unit->Current2D) { - curr = &unit->Current2D; - unit->Current2D = ctx->Shared->Default2D; + _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D); } else if (texObj == unit->Current3D) { - curr = &unit->Current3D; - unit->Current3D = ctx->Shared->Default3D; + _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D); } else if (texObj == unit->CurrentCubeMap) { - curr = &unit->CurrentCubeMap; - unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; + _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); } else if (texObj == unit->CurrentRect) { - curr = &unit->CurrentRect; - unit->CurrentRect = ctx->Shared->DefaultRect; + _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect); } else if (texObj == unit->Current1DArray) { - curr = &unit->Current1DArray; - unit->CurrentRect = ctx->Shared->Default1DArray; + _mesa_reference_texobj(&unit->Current1DArray, ctx->Shared->Default1DArray); } else if (texObj == unit->Current2DArray) { - curr = &unit->Current1DArray; - unit->CurrentRect = ctx->Shared->Default2DArray; - } - - if (curr) { - (*curr)->RefCount++; - texObj->RefCount--; - if (texObj == unit->_Current) - unit->_Current = *curr; + _mesa_reference_texobj(&unit->Current2DArray, ctx->Shared->Default2DArray); } } } @@ -690,8 +778,6 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { - GLboolean deleted; - _mesa_lock_texture(ctx, delObj); /* Check if texture is bound to any framebuffer objects. @@ -701,10 +787,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) unbind_texobj_from_fbo(ctx, delObj); /* Check if this texture is currently bound to any texture units. - * If so, unbind it and decrement the reference count. + * If so, unbind it. */ unbind_texobj_from_texunits(ctx, delObj); + _mesa_unlock_texture(ctx, delObj); + ctx->NewState |= _NEW_TEXTURE; /* The texture _name_ is now free for re-use. @@ -714,23 +802,10 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - /* The actual texture object will not be freed until it's no - * longer bound in any context. - * XXX all RefCount accesses should be protected by a mutex. + /* Unrefernce the texobj. If refcount hits zero, the texture + * will be deleted. */ - delObj->RefCount--; - deleted = (delObj->RefCount == 0); - _mesa_unlock_texture(ctx, delObj); - - /* We know that refcount went to zero above, so this is - * the only pointer left to delObj, so we don't have to - * worry about locking any more: - */ - if (deleted) { - ASSERT(delObj->Name != 0); /* Never delete default tex objs */ - ASSERT(ctx->Driver.DeleteTexture); - (*ctx->Driver.DeleteTexture)(ctx, delObj); - } + _mesa_reference_texobj(&delObj, NULL); } } } @@ -758,7 +833,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *oldTexObj; struct gl_texture_object *newTexObj = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -766,62 +840,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) _mesa_debug(ctx, "glBindTexture %s %d\n", _mesa_lookup_enum_by_nr(target), (GLint) texName); - /* - * Get pointer to currently bound texture object (oldTexObj) - */ - switch (target) { - case GL_TEXTURE_1D: - oldTexObj = texUnit->Current1D; - break; - case GL_TEXTURE_2D: - oldTexObj = texUnit->Current2D; - break; - case GL_TEXTURE_3D: - oldTexObj = texUnit->Current3D; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->CurrentCubeMap; - break; - case GL_TEXTURE_RECTANGLE_NV: - if (!ctx->Extensions.NV_texture_rectangle) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->CurrentRect; - break; - case GL_TEXTURE_1D_ARRAY_EXT: - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->Current1DArray; - break; - case GL_TEXTURE_2D_ARRAY_EXT: - if (!ctx->Extensions.MESA_texture_array) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - oldTexObj = texUnit->Current2DArray; - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); - return; - } - - if (oldTexObj->Name == texName) { - /* XXX this might be wrong. If the texobj is in use by another - * context and a texobj parameter was changed, this might be our - * only chance to update this context's hardware state. - * Note that some applications re-bind the same texture a lot so we - * want to handle that case quickly. - */ - return; /* rebinding the same texture- no change */ - } - /* * Get pointer to new texture object (newTexObj) */ @@ -896,28 +914,30 @@ _mesa_BindTexture( GLenum target, GLuint texName ) newTexObj->Target = target; } - /* XXX all RefCount accesses should be protected by a mutex. */ - newTexObj->RefCount++; + assert(valid_texture_object(newTexObj)); - /* do the actual binding, but first flush outstanding vertices: - */ + /* flush before changing binding */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); + /* Do the actual binding. The refcount on the previously bound + * texture object will be decremented. It'll be deleted if the + * count hits zero. + */ switch (target) { case GL_TEXTURE_1D: - texUnit->Current1D = newTexObj; + _mesa_reference_texobj(&texUnit->Current1D, newTexObj); break; case GL_TEXTURE_2D: - texUnit->Current2D = newTexObj; + _mesa_reference_texobj(&texUnit->Current2D, newTexObj); break; case GL_TEXTURE_3D: - texUnit->Current3D = newTexObj; + _mesa_reference_texobj(&texUnit->Current3D, newTexObj); break; case GL_TEXTURE_CUBE_MAP_ARB: - texUnit->CurrentCubeMap = newTexObj; + _mesa_reference_texobj(&texUnit->CurrentCubeMap, newTexObj); break; case GL_TEXTURE_RECTANGLE_NV: - texUnit->CurrentRect = newTexObj; + _mesa_reference_texobj(&texUnit->CurrentRect, newTexObj); break; case GL_TEXTURE_1D_ARRAY_EXT: texUnit->Current1DArray = newTexObj; @@ -933,18 +953,6 @@ _mesa_BindTexture( GLenum target, GLuint texName ) /* Pass BindTexture call to device driver */ if (ctx->Driver.BindTexture) (*ctx->Driver.BindTexture)( ctx, target, newTexObj ); - - /* Decrement the reference count on the old texture and check if it's - * time to delete it. - */ - /* XXX all RefCount accesses should be protected by a mutex. */ - oldTexObj->RefCount--; - ASSERT(oldTexObj->RefCount >= 0); - if (oldTexObj->RefCount == 0) { - ASSERT(oldTexObj->Name != 0); - ASSERT(ctx->Driver.DeleteTexture); - (*ctx->Driver.DeleteTexture)( ctx, oldTexObj ); - } } diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index 2a2bde3601..d5374c5d6c 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -57,6 +57,10 @@ extern void _mesa_copy_texture_object( struct gl_texture_object *dest, const struct gl_texture_object *src ); +extern void +_mesa_reference_texobj(struct gl_texture_object **ptr, + struct gl_texture_object *tex); + extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index c9f8a0656e..08d083d201 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -63,31 +63,6 @@ static const struct gl_tex_env_combine_state default_combine_state = { }; -/** - * Copy a texture binding. Helper used by _mesa_copy_texture_state(). - */ -static void -copy_texture_binding(const GLcontext *ctx, - struct gl_texture_object **dst, - struct gl_texture_object *src) -{ - /* only copy if names differ (per OpenGL SI) */ - if ((*dst)->Name != src->Name) { - /* unbind/delete dest binding which we're changing */ - (*dst)->RefCount--; - if ((*dst)->RefCount == 0) { - /* time to delete this texture object */ - ASSERT((*dst)->Name != 0); - ASSERT(ctx->Driver.DeleteTexture); - /* XXX cast-away const, unfortunately */ - (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst); - } - /* make new binding, incrementing ref count */ - *dst = src; - src->RefCount++; - } -} - /** * Used by glXCopyContext to copy texture state from one context to another. @@ -144,20 +119,20 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) /* copy texture object bindings, not contents of texture objects */ _mesa_lock_context_textures(dst); - copy_texture_binding(src, &dst->Texture.Unit[i].Current1D, - src->Texture.Unit[i].Current1D); - copy_texture_binding(src, &dst->Texture.Unit[i].Current2D, - src->Texture.Unit[i].Current2D); - copy_texture_binding(src, &dst->Texture.Unit[i].Current3D, - src->Texture.Unit[i].Current3D); - copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap, - src->Texture.Unit[i].CurrentCubeMap); - copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect, - src->Texture.Unit[i].CurrentRect); - copy_texture_binding(src, &dst->Texture.Unit[i].Current1DArray, - src->Texture.Unit[i].Current1DArray); - copy_texture_binding(src, &dst->Texture.Unit[i].Current2DArray, - src->Texture.Unit[i].Current2DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D, + src->Texture.Unit[i].Current1D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D, + src->Texture.Unit[i].Current2D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D, + src->Texture.Unit[i].Current3D); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap, + src->Texture.Unit[i].CurrentCubeMap); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect, + src->Texture.Unit[i].CurrentRect); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray, + src->Texture.Unit[i].Current1DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray, + src->Texture.Unit[i].Current2DArray); _mesa_unlock_context_textures(dst); } @@ -3113,6 +3088,8 @@ alloc_proxy_textures( GLcontext *ctx ) if (!ctx->Texture.Proxy2DArray) goto cleanup; + assert(ctx->Texture.Proxy1D->RefCount == 1); + return GL_TRUE; cleanup: @@ -3172,13 +3149,14 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 ); ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 ); - texUnit->Current1D = ctx->Shared->Default1D; - texUnit->Current2D = ctx->Shared->Default2D; - texUnit->Current3D = ctx->Shared->Default3D; - texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; - texUnit->CurrentRect = ctx->Shared->DefaultRect; - texUnit->Current1DArray = ctx->Shared->Default1DArray; - texUnit->Current2DArray = ctx->Shared->Default2DArray; + /* initialize current texture object ptrs to the shared default objects */ + _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D); + _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D); + _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D); + _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); + _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect); + _mesa_reference_texobj(&texUnit->Current1DArray, ctx->Shared->Default1DArray); + _mesa_reference_texobj(&texUnit->Current2DArray, ctx->Shared->Default2DArray); } @@ -3193,23 +3171,20 @@ _mesa_init_texture(GLcontext *ctx) assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); - /* Effectively bind the default textures to all texture units */ - ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default1DArray->RefCount += MAX_TEXTURE_UNITS; - ctx->Shared->Default2DArray->RefCount += MAX_TEXTURE_UNITS; - /* Texture group */ ctx->Texture.CurrentUnit = 0; /* multitexture */ ctx->Texture._EnabledUnits = 0; - for (i=0; iTexture.SharedPalette = GL_FALSE; _mesa_init_colortable(&ctx->Texture.Palette); + for (i = 0; i < MAX_TEXTURE_UNITS; i++) + init_texture_unit( ctx, i ); + + /* After we're done initializing the context's texture state the default + * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1. + */ + assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1); + _mesa_TexEnvProgramCacheInit( ctx ); /* Allocate proxy textures */ -- cgit v1.2.3 From b7a9222dc7492181588cedd62b94482fab8e9c95 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Mon, 13 Aug 2007 13:22:43 +0200 Subject: i915tex: Make sure pitch is aligned properly for render-to-texture. Just always align texture pitch to multiples of 64 bytes for now, pending a more sophisticated scheme to do it only when really necessary. --- src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c index fc38a28290..74f6b2d851 100644 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -97,9 +97,19 @@ intel_miptree_create(struct intel_context *intel, break; } - if (ok) + if (ok) { + if (!mt->compressed) { + /* XXX: Align pitch to multiple of 64 bytes for now to allow + * render-to-texture to work in all cases. This should probably be + * replaced at some point by some scheme to only do this when really + * necessary. + */ + mt->pitch = ((mt->pitch * cpp + 63) & ~63) / cpp; + } + mt->region = intel_region_alloc(intel->intelScreen, mt->cpp, mt->pitch, mt->total_height); + } if (!mt->region) { free(mt); -- cgit v1.2.3 From 393a6255381f019586bd9acc49fbf2fd431e534e Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 13 Aug 2007 17:37:30 +0100 Subject: free any render/framebuffers left in hash tables when freeing shared state --- src/mesa/main/context.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index f360eac1e7..5fbc69693e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -640,6 +640,27 @@ delete_shader_cb(GLuint id, void *data, void *userData) } } +/** + * Callback for deleting a framebuffer object. Called by _mesa_HashDeleteAll() + */ +static void +delete_framebuffer_cb(GLuint id, void *data, void *userData) +{ + struct gl_framebuffer *fb = (struct gl_framebuffer *) data; + fb->Delete(fb); +} + +/** + * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll() + */ +static void +delete_renderbuffer_cb(GLuint id, void *data, void *userData) +{ + struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data; + rb->Delete(rb); +} + + /** * Deallocate a shared state object and all children structures. @@ -710,7 +731,9 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) #endif #if FEATURE_EXT_framebuffer_object + _mesa_HashDeleteAll(ss->FrameBuffers, delete_framebuffer_cb, ctx); _mesa_DeleteHashTable(ss->FrameBuffers); + _mesa_HashDeleteAll(ss->RenderBuffers, delete_renderbuffer_cb, ctx); _mesa_DeleteHashTable(ss->RenderBuffers); #endif -- cgit v1.2.3 From dc73217294efcba83c46183ed2f208250217486f Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 14 Aug 2007 11:56:59 +0100 Subject: Fix a few more problems with freeing FBOs/textures during context destruction. Free FBOs before textures since the later may be referenced by the former. Need to bind the context we're destroying if there isn't a current context so that ctx->DeleteTexture() etc can be used. --- src/mesa/main/context.c | 66 +++++++++++++++++++++++++++++-------------------- src/mesa/main/texobj.c | 5 +++- 2 files changed, 43 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 5fbc69693e..37a14d3004 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -647,6 +647,11 @@ static void delete_framebuffer_cb(GLuint id, void *data, void *userData) { struct gl_framebuffer *fb = (struct gl_framebuffer *) data; + /* The fact that the framebuffer is in the hashtable means its refcount + * is one, but we're removing from the hashtable now. So clear refcount. + */ + /*assert(fb->RefCount == 1);*/ + fb->RefCount = 0; fb->Delete(fb); } @@ -657,6 +662,7 @@ static void delete_renderbuffer_cb(GLuint id, void *data, void *userData) { struct gl_renderbuffer *rb = (struct gl_renderbuffer *) data; + rb->RefCount = 0; /* see comment for FBOs above */ rb->Delete(rb); } @@ -683,23 +689,6 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_HashDeleteAll(ss->DisplayList, delete_displaylist_cb, ctx); _mesa_DeleteHashTable(ss->DisplayList); - /* - * Free texture objects - */ - ASSERT(ctx->Driver.DeleteTexture); - /* the default textures */ - ctx->Driver.DeleteTexture(ctx, ss->Default1D); - ctx->Driver.DeleteTexture(ctx, ss->Default2D); - ctx->Driver.DeleteTexture(ctx, ss->Default3D); - ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap); - ctx->Driver.DeleteTexture(ctx, ss->DefaultRect); - ctx->Driver.DeleteTexture(ctx, ss->Default1DArray); - ctx->Driver.DeleteTexture(ctx, ss->Default2DArray); - - /* all other textures */ - _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); - _mesa_DeleteHashTable(ss->TexObjects); - #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_NV_fragment_program) _mesa_HashDeleteAll(ss->Programs, delete_program_cb, ctx); _mesa_DeleteHashTable(ss->Programs); @@ -737,6 +726,23 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->RenderBuffers); #endif + /* + * Free texture objects (after FBOs since some textures might have + * been bound to FBOs). + */ + ASSERT(ctx->Driver.DeleteTexture); + /* the default textures */ + ctx->Driver.DeleteTexture(ctx, ss->Default1D); + ctx->Driver.DeleteTexture(ctx, ss->Default2D); + ctx->Driver.DeleteTexture(ctx, ss->Default3D); + ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap); + ctx->Driver.DeleteTexture(ctx, ss->DefaultRect); + ctx->Driver.DeleteTexture(ctx, ss->Default1DArray); + ctx->Driver.DeleteTexture(ctx, ss->Default2DArray); + /* all other textures */ + _mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx); + _mesa_DeleteHashTable(ss->TexObjects); + _glthread_DESTROY_MUTEX(ss->Mutex); _mesa_free(ss); @@ -1190,18 +1196,19 @@ _mesa_create_context(const GLvisual *visual, void _mesa_free_context_data( GLcontext *ctx ) { - /* if we're destroying the current context, unbind it first */ - if (ctx == _mesa_get_current_context()) { - _mesa_make_current(NULL, NULL, NULL); - } - else { - /* unreference WinSysDraw/Read buffers */ - _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); - _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); - _mesa_unreference_framebuffer(&ctx->DrawBuffer); - _mesa_unreference_framebuffer(&ctx->ReadBuffer); + if (!_mesa_get_current_context()){ + /* No current context, but we may need one in order to delete + * texture objs, etc. So temporarily bind the context now. + */ + _mesa_make_current(ctx, NULL, NULL); } + /* unreference WinSysDraw/Read buffers */ + _mesa_unreference_framebuffer(&ctx->WinSysDrawBuffer); + _mesa_unreference_framebuffer(&ctx->WinSysReadBuffer); + _mesa_unreference_framebuffer(&ctx->DrawBuffer); + _mesa_unreference_framebuffer(&ctx->ReadBuffer); + _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); @@ -1233,6 +1240,11 @@ _mesa_free_context_data( GLcontext *ctx ) if (ctx->Extensions.String) _mesa_free((void *) ctx->Extensions.String); + + /* unbind the context if it's currently bound */ + if (ctx == _mesa_get_current_context()) { + _mesa_make_current(NULL, NULL, NULL); + } } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index ac70e5a22e..ea3328a047 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -287,7 +287,10 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, if (deleteFlag) { GET_CURRENT_CONTEXT(ctx); - ctx->Driver.DeleteTexture(ctx, oldTex); + if (ctx) + ctx->Driver.DeleteTexture(ctx, oldTex); + else + _mesa_problem(NULL, "Unable to delete texture, no context"); } *ptr = NULL; -- cgit v1.2.3 From 553f5759a6587d7fe77a62d4d1159ad786b336ee Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Aug 2007 16:46:27 +1000 Subject: nouveau: Lets only do private buffers. --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 52 ++++++++++++--------------- 1 file changed, 23 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 053680be8d..4d22ecc83e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -154,36 +154,30 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, nouveauSpanSetFunctions(nrb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa); - if (0 /* unified buffers if we choose to support them.. */) { - } else { - if (mesaVis->doubleBufferMode) { - nrb = nouveau_renderbuffer_new(color_format, NULL, - 0, 0, - NULL); - nouveauSpanSetFunctions(nrb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa); - } + if (mesaVis->doubleBufferMode) { + nrb = nouveau_renderbuffer_new(color_format, NULL, 0, 0, NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa); + } - if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { - nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL, - 0, 0, - NULL); - nouveauSpanSetFunctions(nrb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa); - } else if (mesaVis->depthBits == 24) { - nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24, NULL, - 0, 0, - NULL); - nouveauSpanSetFunctions(nrb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); - } else if (mesaVis->depthBits == 16) { - nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL, - 0, 0, - NULL); - nouveauSpanSetFunctions(nrb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); - } + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL, + 0, 0, NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa); + } else + if (mesaVis->depthBits == 24) { + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24, NULL, + 0, 0, NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); + } else + if (mesaVis->depthBits == 16) { + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL, + 0, 0, NULL); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); } _mesa_add_soft_renderbuffers(fb, -- cgit v1.2.3 From 386a70eeb5982976239a2d37b63cde307cfbc22c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Aug 2007 17:02:20 +1000 Subject: nouveau: reindent nouveau_buffers.c --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 673 +++++++++++++------------ 1 file changed, 339 insertions(+), 334 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index d498f616c9..5c5c7932bb 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -14,423 +14,428 @@ /* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */ GLboolean -nouveau_memformat_flat_emit(GLcontext *ctx, - nouveau_mem *dst, nouveau_mem *src, +nouveau_memformat_flat_emit(GLcontext * ctx, + nouveau_mem * dst, nouveau_mem * src, GLuint dst_offset, GLuint src_offset, GLuint size) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - uint32_t src_handle, dst_handle; - GLuint count; - - if (src_offset + size > src->size) { - MESSAGE("src out of nouveau_mem bounds\n"); - return GL_FALSE; - } - if (dst_offset + size > dst->size) { - MESSAGE("dst out of nouveau_mem bounds\n"); - return GL_FALSE; - } - - src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; - dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; - src_offset += nouveau_mem_gpu_offset_get(ctx, src); - dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); - - BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); - OUT_RING (src_handle); - OUT_RING (dst_handle); - - count = (size / MAX_MEMFMT_LENGTH) + ((size % MAX_MEMFMT_LENGTH) ? 1 : 0); - - while (count--) { - GLuint length = (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size; - - BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RING (src_offset); - OUT_RING (dst_offset); - OUT_RING (0); /* pitch in */ - OUT_RING (0); /* pitch out */ - OUT_RING (length); /* line length */ - OUT_RING (1); /* number of lines */ - OUT_RING ((1 << 8) /* dst_inc */ | (1 << 0) /* src_inc */); - OUT_RING (0); /* buffer notify? */ - FIRE_RING(); - - src_offset += length; - dst_offset += length; - size -= length; - } - - return GL_TRUE; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t src_handle, dst_handle; + GLuint count; + + if (src_offset + size > src->size) { + MESSAGE("src out of nouveau_mem bounds\n"); + return GL_FALSE; + } + if (dst_offset + size > dst->size) { + MESSAGE("dst out of nouveau_mem bounds\n"); + return GL_FALSE; + } + + src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; + dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; + src_offset += nouveau_mem_gpu_offset_get(ctx, src); + dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); + + BEGIN_RING_SIZE(NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); + OUT_RING(src_handle); + OUT_RING(dst_handle); + + count = (size / MAX_MEMFMT_LENGTH) + + ((size % MAX_MEMFMT_LENGTH) ? 1 : 0); + + while (count--) { + GLuint length = + (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size; + + BEGIN_RING_SIZE(NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RING(src_offset); + OUT_RING(dst_offset); + OUT_RING(0); /* pitch in */ + OUT_RING(0); /* pitch out */ + OUT_RING(length); /* line length */ + OUT_RING(1); /* number of lines */ + OUT_RING((1 << 8) /* dst_inc */ |(1 << 0) /* src_inc */ ); + OUT_RING(0); /* buffer notify? */ + FIRE_RING(); + + src_offset += length; + dst_offset += length; + size -= length; + } + + return GL_TRUE; } -void -nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem) +void nouveau_mem_free(GLcontext * ctx, nouveau_mem * mem) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct drm_nouveau_mem_free memf; - - if (NOUVEAU_DEBUG & DEBUG_MEM) { - fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n", - __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size); - } - - if (mem->map) - drmUnmap(mem->map, mem->size); - memf.flags = mem->type; - memf.offset = mem->offset; - drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, sizeof(memf)); - FREE(mem); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct drm_nouveau_mem_free memf; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint) mem->offset, + (GLuint) mem->size); + } + + if (mem->map) + drmUnmap(mem->map, mem->size); + memf.flags = mem->type; + memf.offset = mem->offset; + drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, + sizeof(memf)); + FREE(mem); } -nouveau_mem * -nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) +nouveau_mem *nouveau_mem_alloc(GLcontext * ctx, int type, GLuint size, + GLuint align) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct drm_nouveau_mem_alloc mema; - nouveau_mem *mem; - int ret; - - if (NOUVEAU_DEBUG & DEBUG_MEM) { - fprintf(stderr, "%s: requested: type=0x%x, size=0x%x, align=0x%x\n", - __func__, type, (GLuint)size, align); - } - - mem = CALLOC(sizeof(nouveau_mem)); - if (!mem) - return NULL; - - mema.flags = type; - mema.size = mem->size = size; - mema.alignment = align; - mem->map = NULL; - ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, - &mema, sizeof(mema)); - if (ret) { - FREE(mem); - return NULL; - } - mem->offset = mema.offset; - mem->type = mema.flags; - - if (NOUVEAU_DEBUG & DEBUG_MEM) { - fprintf(stderr, "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n", - __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size); - } - - if (type & NOUVEAU_MEM_MAPPED) - ret = drmMap(nmesa->driFd, mema.map_handle, mem->size, &mem->map); - if (ret) { - mem->map = NULL; - nouveau_mem_free(ctx, mem); - mem = NULL; - } - - return mem; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct drm_nouveau_mem_alloc mema; + nouveau_mem *mem; + int ret; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, + "%s: requested: type=0x%x, size=0x%x, align=0x%x\n", + __func__, type, (GLuint) size, align); + } + + mem = CALLOC(sizeof(nouveau_mem)); + if (!mem) + return NULL; + + mema.flags = type; + mema.size = mem->size = size; + mema.alignment = align; + mem->map = NULL; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, + &mema, sizeof(mema)); + if (ret) { + FREE(mem); + return NULL; + } + mem->offset = mema.offset; + mem->type = mema.flags; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, + "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint) mem->offset, + (GLuint) mem->size); + } + + if (type & NOUVEAU_MEM_MAPPED) + ret = + drmMap(nmesa->driFd, mema.map_handle, mem->size, + &mem->map); + if (ret) { + mem->map = NULL; + nouveau_mem_free(ctx, mem); + mem = NULL; + } + + return mem; } -uint32_t -nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem) +uint32_t nouveau_mem_gpu_offset_get(GLcontext * ctx, nouveau_mem * mem) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - return mem->offset; + return mem->offset; } static GLboolean -nouveau_renderbuffer_pixelformat(nouveau_renderbuffer *nrb, - GLenum internalFormat) +nouveau_renderbuffer_pixelformat(nouveau_renderbuffer * nrb, + GLenum internalFormat) { - nrb->mesa.InternalFormat = internalFormat; - - /*TODO: We probably want to extend this a bit, and maybe make - * card-specific? - */ - switch (internalFormat) { - case GL_RGBA: - case GL_RGBA8: - nrb->mesa._BaseFormat = GL_RGBA; - nrb->mesa._ActualFormat= GL_RGBA8; - nrb->mesa.DataType = GL_UNSIGNED_BYTE; - nrb->mesa.RedBits = 8; - nrb->mesa.GreenBits = 8; - nrb->mesa.BlueBits = 8; - nrb->mesa.AlphaBits = 8; - nrb->cpp = 4; - break; - case GL_RGB: - case GL_RGB5: - nrb->mesa._BaseFormat = GL_RGB; - nrb->mesa._ActualFormat= GL_RGB5; - nrb->mesa.DataType = GL_UNSIGNED_BYTE; - nrb->mesa.RedBits = 5; - nrb->mesa.GreenBits = 6; - nrb->mesa.BlueBits = 5; - nrb->mesa.AlphaBits = 0; - nrb->cpp = 2; - break; - case GL_DEPTH_COMPONENT16: - nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; - nrb->mesa._ActualFormat= GL_DEPTH_COMPONENT16; - nrb->mesa.DataType = GL_UNSIGNED_SHORT; - nrb->mesa.DepthBits = 16; - nrb->cpp = 2; - break; - case GL_DEPTH_COMPONENT24: - nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; - nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.DepthBits = 24; - nrb->cpp = 4; - break; - case GL_STENCIL_INDEX8_EXT: - nrb->mesa._BaseFormat = GL_STENCIL_INDEX; - nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.StencilBits = 8; - nrb->cpp = 4; - break; - case GL_DEPTH24_STENCIL8_EXT: - nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT; - nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.DepthBits = 24; - nrb->mesa.StencilBits = 8; - nrb->cpp = 4; - break; - default: - return GL_FALSE; - break; - } - - return GL_TRUE; + nrb->mesa.InternalFormat = internalFormat; + + /*TODO: We probably want to extend this a bit, and maybe make + * card-specific? + */ + switch (internalFormat) { + case GL_RGBA: + case GL_RGBA8: + nrb->mesa._BaseFormat = GL_RGBA; + nrb->mesa._ActualFormat = GL_RGBA8; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 8; + nrb->mesa.GreenBits = 8; + nrb->mesa.BlueBits = 8; + nrb->mesa.AlphaBits = 8; + nrb->cpp = 4; + break; + case GL_RGB: + case GL_RGB5: + nrb->mesa._BaseFormat = GL_RGB; + nrb->mesa._ActualFormat = GL_RGB5; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 5; + nrb->mesa.GreenBits = 6; + nrb->mesa.BlueBits = 5; + nrb->mesa.AlphaBits = 0; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT16: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat = GL_DEPTH_COMPONENT16; + nrb->mesa.DataType = GL_UNSIGNED_SHORT; + nrb->mesa.DepthBits = 16; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->cpp = 4; + break; + case GL_STENCIL_INDEX8_EXT: + nrb->mesa._BaseFormat = GL_STENCIL_INDEX; + nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + case GL_DEPTH24_STENCIL8_EXT: + nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT; + nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + default: + return GL_FALSE; + break; + } + + return GL_TRUE; } static GLboolean -nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, - GLuint height) +nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) { - nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb; - - if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { - fprintf(stderr, "%s: unknown internalFormat\n", __func__); - return GL_FALSE; - } - - /* If this buffer isn't statically alloc'd, we may need to ask the - * drm for more memory */ - if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) { - GLuint pitch; - - /* align pitches to 64 bytes */ - pitch = ((width * nrb->cpp) + 63) & ~63; - - if (nrb->mem) - nouveau_mem_free(ctx, nrb->mem); - nrb->mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, - pitch*height, - 0); - if (!nrb->mem) - return GL_FALSE; - - /* update nouveau_renderbuffer info */ - nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem); - nrb->pitch = pitch; - } - - rb->Width = width; - rb->Height = height; - rb->InternalFormat = internalFormat; - return GL_TRUE; + nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; + + if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { + fprintf(stderr, "%s: unknown internalFormat\n", __func__); + return GL_FALSE; + } + + /* If this buffer isn't statically alloc'd, we may need to ask the + * drm for more memory */ + if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) { + GLuint pitch; + + /* align pitches to 64 bytes */ + pitch = ((width * nrb->cpp) + 63) & ~63; + + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + nrb->mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_FB | + NOUVEAU_MEM_MAPPED, + pitch * height, 0); + if (!nrb->mem) + return GL_FALSE; + + /* update nouveau_renderbuffer info */ + nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem); + nrb->pitch = pitch; + } + + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + return GL_TRUE; } -static void -nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) +static void nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) { - GET_CURRENT_CONTEXT(ctx); - nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb; + GET_CURRENT_CONTEXT(ctx); + nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; - if (nrb->mem) - nouveau_mem_free(ctx, nrb->mem); - FREE(nrb); + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + FREE(nrb); } -nouveau_renderbuffer * -nouveau_renderbuffer_new(GLenum internalFormat, GLvoid *map, - GLuint offset, GLuint pitch, - __DRIdrawablePrivate *dPriv) +nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, + GLvoid * map, GLuint offset, + GLuint pitch, + __DRIdrawablePrivate * + dPriv) { - nouveau_renderbuffer *nrb; + nouveau_renderbuffer *nrb; - nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); - if (nrb) { - _mesa_init_renderbuffer(&nrb->mesa, 0); + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, 0); - nouveau_renderbuffer_pixelformat(nrb, internalFormat); + nouveau_renderbuffer_pixelformat(nrb, internalFormat); - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; - nrb->dPriv = dPriv; - nrb->offset = offset; - nrb->pitch = pitch; - nrb->map = map; - } + nrb->dPriv = dPriv; + nrb->offset = offset; + nrb->pitch = pitch; + nrb->map = map; + } - return nrb; + return nrb; } static void nouveau_cliprects_drawable_set(nouveauContextPtr nmesa, - nouveau_renderbuffer *nrb) + nouveau_renderbuffer * nrb) { - __DRIdrawablePrivate *dPriv = nrb->dPriv; - - nmesa->numClipRects = dPriv->numClipRects; - nmesa->pClipRects = dPriv->pClipRects; - nmesa->drawX = dPriv->x; - nmesa->drawY = dPriv->y; - nmesa->drawW = dPriv->w; - nmesa->drawH = dPriv->h; + __DRIdrawablePrivate *dPriv = nrb->dPriv; + + nmesa->numClipRects = dPriv->numClipRects; + nmesa->pClipRects = dPriv->pClipRects; + nmesa->drawX = dPriv->x; + nmesa->drawY = dPriv->y; + nmesa->drawW = dPriv->w; + nmesa->drawH = dPriv->h; } static void nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, - nouveau_renderbuffer *nrb) + nouveau_renderbuffer * nrb) { - nmesa->numClipRects = 1; - nmesa->pClipRects = &nmesa->osClipRect; - nmesa->osClipRect.x1 = 0; - nmesa->osClipRect.y1 = 0; - nmesa->osClipRect.x2 = nrb->mesa.Width; - nmesa->osClipRect.y2 = nrb->mesa.Height; - nmesa->drawX = 0; - nmesa->drawY = 0; - nmesa->drawW = nrb->mesa.Width; - nmesa->drawH = nrb->mesa.Height; + nmesa->numClipRects = 1; + nmesa->pClipRects = &nmesa->osClipRect; + nmesa->osClipRect.x1 = 0; + nmesa->osClipRect.y1 = 0; + nmesa->osClipRect.x2 = nrb->mesa.Width; + nmesa->osClipRect.y2 = nrb->mesa.Height; + nmesa->drawX = 0; + nmesa->drawY = 0; + nmesa->drawW = nrb->mesa.Width; + nmesa->drawH = nrb->mesa.Height; } -void -nouveau_window_moved(GLcontext *ctx) +void nouveau_window_moved(GLcontext * ctx) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer *nrb; - - nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0]; - if (!nrb) - return; - - if (!nrb->dPriv) - nouveau_cliprects_renderbuffer_set(nmesa, nrb); - else - nouveau_cliprects_drawable_set(nmesa, nrb); - - /* Viewport depends on window size/position, nouveauCalcViewport - * will take care of calling the hw-specific WindowMoved - */ - ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height); - /* Scissor depends on window position */ - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *nrb; + + nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + if (!nrb) + return; + + if (!nrb->dPriv) + nouveau_cliprects_renderbuffer_set(nmesa, nrb); + else + nouveau_cliprects_drawable_set(nmesa, nrb); + + /* Viewport depends on window size/position, nouveauCalcViewport + * will take care of calling the hw-specific WindowMoved + */ + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + /* Scissor depends on window position */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); } GLboolean -nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) +nouveau_build_framebuffer(GLcontext * ctx, struct gl_framebuffer *fb) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer *color[MAX_DRAW_BUFFERS]; - nouveau_renderbuffer *depth; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *color[MAX_DRAW_BUFFERS]; + nouveau_renderbuffer *depth; - _mesa_update_framebuffer(ctx); - _mesa_update_draw_buffer_bounds(ctx); + _mesa_update_framebuffer(ctx); + _mesa_update_draw_buffer_bounds(ctx); - color[0] = (nouveau_renderbuffer *)fb->_ColorDrawBuffers[0][0]; - if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) - depth = (nouveau_renderbuffer *)fb->_DepthBuffer->Wrapped; - else - depth = (nouveau_renderbuffer *)fb->_DepthBuffer; + color[0] = (nouveau_renderbuffer *) fb->_ColorDrawBuffers[0][0]; + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) + depth = (nouveau_renderbuffer *) fb->_DepthBuffer->Wrapped; + else + depth = (nouveau_renderbuffer *) fb->_DepthBuffer; - if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) - return GL_FALSE; - nouveau_window_moved(ctx); + if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) + return GL_FALSE; + nouveau_window_moved(ctx); - return GL_TRUE; + return GL_TRUE; } -static void -nouveauDrawBuffer(GLcontext *ctx, GLenum buffer) +static void nouveauDrawBuffer(GLcontext * ctx, GLenum buffer) { - nouveau_build_framebuffer(ctx, ctx->DrawBuffer); + nouveau_build_framebuffer(ctx, ctx->DrawBuffer); } -static struct gl_framebuffer * -nouveauNewFramebuffer(GLcontext *ctx, GLuint name) +static struct gl_framebuffer *nouveauNewFramebuffer(GLcontext * ctx, + GLuint name) { - return _mesa_new_framebuffer(ctx, name); + return _mesa_new_framebuffer(ctx, name); } -static struct gl_renderbuffer * -nouveauNewRenderbuffer(GLcontext *ctx, GLuint name) +static struct gl_renderbuffer *nouveauNewRenderbuffer(GLcontext * ctx, + GLuint name) { - nouveau_renderbuffer *nrb; + nouveau_renderbuffer *nrb; - nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); - if (nrb) { - _mesa_init_renderbuffer(&nrb->mesa, name); + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, name); - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; - } - return &nrb->mesa; + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; + } + return &nrb->mesa; } static void -nouveauBindFramebuffer(GLcontext *ctx, GLenum target, - struct gl_framebuffer *fb, struct gl_framebuffer *fbread) +nouveauBindFramebuffer(GLcontext * ctx, GLenum target, + struct gl_framebuffer *fb, + struct gl_framebuffer *fbread) { - if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { - nouveau_build_framebuffer(ctx, fb); - } + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + nouveau_build_framebuffer(ctx, fb); + } } static void -nouveauFramebufferRenderbuffer(GLcontext *ctx, - struct gl_framebuffer *fb, - GLenum attachment, +nouveauFramebufferRenderbuffer(GLcontext * ctx, + struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) { - _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); - nouveau_build_framebuffer(ctx, fb); + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + nouveau_build_framebuffer(ctx, fb); } static void -nouveauRenderTexture(GLcontext *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) +nouveauRenderTexture(GLcontext * ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) { } static void -nouveauFinishRenderTexture(GLcontext *ctx, - struct gl_renderbuffer_attachment *att) +nouveauFinishRenderTexture(GLcontext * ctx, + struct gl_renderbuffer_attachment *att) { } -void -nouveauInitBufferFuncs(struct dd_function_table *func) +void nouveauInitBufferFuncs(struct dd_function_table *func) { - func->DrawBuffer = nouveauDrawBuffer; - - func->NewFramebuffer = nouveauNewFramebuffer; - func->NewRenderbuffer = nouveauNewRenderbuffer; - func->BindFramebuffer = nouveauBindFramebuffer; - func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer; - func->RenderTexture = nouveauRenderTexture; - func->FinishRenderTexture = nouveauFinishRenderTexture; + func->DrawBuffer = nouveauDrawBuffer; + + func->NewFramebuffer = nouveauNewFramebuffer; + func->NewRenderbuffer = nouveauNewRenderbuffer; + func->BindFramebuffer = nouveauBindFramebuffer; + func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer; + func->RenderTexture = nouveauRenderTexture; + func->FinishRenderTexture = nouveauFinishRenderTexture; } - -- cgit v1.2.3 From 40e8ce700b0e1711e08e9f33c297d495c43598b1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Aug 2007 17:21:02 +1000 Subject: nouveau: reindent nouveau_buffers.h --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 15 ++++---- src/mesa/drivers/dri/nouveau/nouveau_buffers.h | 50 ++++++++++++++------------ 2 files changed, 34 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index 5c5c7932bb..7cf739fe47 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -89,7 +89,7 @@ void nouveau_mem_free(GLcontext * ctx, nouveau_mem * mem) FREE(mem); } -nouveau_mem *nouveau_mem_alloc(GLcontext * ctx, int type, GLuint size, +nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, uint32_t flags, GLuint size, GLuint align) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -99,15 +99,15 @@ nouveau_mem *nouveau_mem_alloc(GLcontext * ctx, int type, GLuint size, if (NOUVEAU_DEBUG & DEBUG_MEM) { fprintf(stderr, - "%s: requested: type=0x%x, size=0x%x, align=0x%x\n", - __func__, type, (GLuint) size, align); + "%s: requested: flags=0x%x, size=0x%x, align=0x%x\n", + __func__, flags, (GLuint) size, align); } mem = CALLOC(sizeof(nouveau_mem)); if (!mem) return NULL; - mema.flags = type; + mema.flags = flags; mema.size = mem->size = size; mema.alignment = align; mem->map = NULL; @@ -127,10 +127,9 @@ nouveau_mem *nouveau_mem_alloc(GLcontext * ctx, int type, GLuint size, (GLuint) mem->size); } - if (type & NOUVEAU_MEM_MAPPED) - ret = - drmMap(nmesa->driFd, mema.map_handle, mem->size, - &mem->map); + if (flags & NOUVEAU_MEM_MAPPED) + ret = drmMap(nmesa->driFd, mema.map_handle, mem->size, + &mem->map); if (ret) { mem->map = NULL; nouveau_mem_free(ctx, mem); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h index d86455184c..f0987d2aa7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h @@ -7,42 +7,46 @@ #include "renderbuffer.h" typedef struct nouveau_mem_t { - int type; - uint64_t offset; - uint64_t size; - void* map; + int type; + uint64_t offset; + uint64_t size; + void *map; } nouveau_mem; -extern nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, int type, - GLuint size, GLuint align); -extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem); -extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem); +extern nouveau_mem *nouveau_mem_alloc(GLcontext *, uint32_t flags, + GLuint size, GLuint align); +extern void nouveau_mem_free(GLcontext *, nouveau_mem *); +extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *, nouveau_mem *); -extern GLboolean nouveau_memformat_flat_emit(GLcontext *ctx, - nouveau_mem *dst, +extern GLboolean nouveau_memformat_flat_emit(GLcontext *, + nouveau_mem *dst, nouveau_mem *src, GLuint dst_offset, GLuint src_offset, GLuint size); typedef struct nouveau_renderbuffer_t { - struct gl_renderbuffer mesa; /* must be first! */ - __DRIdrawablePrivate *dPriv; + struct gl_renderbuffer mesa; /* must be first! */ + __DRIdrawablePrivate *dPriv; - nouveau_mem *mem; - void * map; + nouveau_mem *mem; + void *map; - int cpp; - uint32_t offset; - uint32_t pitch; + int cpp; + uint32_t offset; + uint32_t pitch; } nouveau_renderbuffer; extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, - GLvoid *map, GLuint offset, GLuint pitch, __DRIdrawablePrivate *dPriv); -extern void nouveau_window_moved(GLcontext *ctx); -extern GLboolean nouveau_build_framebuffer(GLcontext *, struct gl_framebuffer *); -extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *ctx); - -extern void nouveauInitBufferFuncs(struct dd_function_table *func); + GLvoid *map, + GLuint offset, + GLuint pitch, + __DRIdrawablePrivate *); +extern void nouveau_window_moved(GLcontext *); +extern GLboolean nouveau_build_framebuffer(GLcontext *, + struct gl_framebuffer *); +extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *); + +extern void nouveauInitBufferFuncs(struct dd_function_table *); #endif -- cgit v1.2.3 From b7c93de6d798d7ccfc7bfa12b9c8f474de955d55 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Aug 2007 20:02:04 +1000 Subject: nouveau: Split nouveau_buffers into nouveau_mem and nouveau_fbo --- src/mesa/drivers/dri/nouveau/Makefile | 3 +- src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c | 4 +- src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h | 2 +- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 440 ----------------------- src/mesa/drivers/dri/nouveau/nouveau_buffers.h | 52 --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 4 +- src/mesa/drivers/dri/nouveau/nouveau_fbo.c | 304 ++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_fbo.h | 35 ++ src/mesa/drivers/dri/nouveau/nouveau_mem.c | 144 ++++++++ src/mesa/drivers/dri/nouveau/nouveau_mem.h | 23 ++ src/mesa/drivers/dri/nouveau/nouveau_span.h | 2 +- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_sync.h | 2 - 13 files changed, 517 insertions(+), 504 deletions(-) delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_buffers.c delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_buffers.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_fbo.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_fbo.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_mem.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_mem.h (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 20d2de5eef..6ea4594f1e 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -9,12 +9,13 @@ MINIGLX_SOURCES = DRIVER_SOURCES = \ nouveau_bufferobj.c \ - nouveau_buffers.c \ nouveau_card.c \ nouveau_context.c \ nouveau_driver.c \ + nouveau_fbo.c \ nouveau_fifo.c \ nouveau_lock.c \ + nouveau_mem.c \ nouveau_object.c \ nouveau_screen.c \ nouveau_span.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c index fc14060c04..be6455a01e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -2,11 +2,11 @@ #include "enums.h" #include "nouveau_bufferobj.h" -#include "nouveau_buffers.h" #include "nouveau_context.h" #include "nouveau_drm.h" -#include "nouveau_object.h" +#include "nouveau_mem.h" #include "nouveau_msg.h" +#include "nouveau_object.h" #define NOUVEAU_MEM_FREE(mem) do { \ nouveau_mem_free(ctx, (mem)); \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h index 3439a35e7c..cbc89a151d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -2,7 +2,7 @@ #define __NOUVEAU_BUFFEROBJ_H__ #include "mtypes.h" -#include "nouveau_buffers.h" +#include "nouveau_mem.h" #define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE) #define NOUVEAU_BO_GART_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c deleted file mode 100644 index 7cf739fe47..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ /dev/null @@ -1,440 +0,0 @@ -#include "utils.h" -#include "framebuffer.h" -#include "renderbuffer.h" -#include "fbobject.h" - -#include "nouveau_context.h" -#include "nouveau_buffers.h" -#include "nouveau_object.h" -#include "nouveau_fifo.h" -#include "nouveau_reg.h" -#include "nouveau_msg.h" - -#define MAX_MEMFMT_LENGTH 32768 - -/* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */ -GLboolean -nouveau_memformat_flat_emit(GLcontext * ctx, - nouveau_mem * dst, nouveau_mem * src, - GLuint dst_offset, GLuint src_offset, - GLuint size) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - uint32_t src_handle, dst_handle; - GLuint count; - - if (src_offset + size > src->size) { - MESSAGE("src out of nouveau_mem bounds\n"); - return GL_FALSE; - } - if (dst_offset + size > dst->size) { - MESSAGE("dst out of nouveau_mem bounds\n"); - return GL_FALSE; - } - - src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; - dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; - src_offset += nouveau_mem_gpu_offset_get(ctx, src); - dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); - - BEGIN_RING_SIZE(NvSubMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); - OUT_RING(src_handle); - OUT_RING(dst_handle); - - count = (size / MAX_MEMFMT_LENGTH) + - ((size % MAX_MEMFMT_LENGTH) ? 1 : 0); - - while (count--) { - GLuint length = - (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size; - - BEGIN_RING_SIZE(NvSubMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - OUT_RING(src_offset); - OUT_RING(dst_offset); - OUT_RING(0); /* pitch in */ - OUT_RING(0); /* pitch out */ - OUT_RING(length); /* line length */ - OUT_RING(1); /* number of lines */ - OUT_RING((1 << 8) /* dst_inc */ |(1 << 0) /* src_inc */ ); - OUT_RING(0); /* buffer notify? */ - FIRE_RING(); - - src_offset += length; - dst_offset += length; - size -= length; - } - - return GL_TRUE; -} - -void nouveau_mem_free(GLcontext * ctx, nouveau_mem * mem) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct drm_nouveau_mem_free memf; - - if (NOUVEAU_DEBUG & DEBUG_MEM) { - fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n", - __func__, mem->type, (GLuint) mem->offset, - (GLuint) mem->size); - } - - if (mem->map) - drmUnmap(mem->map, mem->size); - memf.flags = mem->type; - memf.offset = mem->offset; - drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, - sizeof(memf)); - FREE(mem); -} - -nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, uint32_t flags, GLuint size, - GLuint align) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct drm_nouveau_mem_alloc mema; - nouveau_mem *mem; - int ret; - - if (NOUVEAU_DEBUG & DEBUG_MEM) { - fprintf(stderr, - "%s: requested: flags=0x%x, size=0x%x, align=0x%x\n", - __func__, flags, (GLuint) size, align); - } - - mem = CALLOC(sizeof(nouveau_mem)); - if (!mem) - return NULL; - - mema.flags = flags; - mema.size = mem->size = size; - mema.alignment = align; - mem->map = NULL; - ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, - &mema, sizeof(mema)); - if (ret) { - FREE(mem); - return NULL; - } - mem->offset = mema.offset; - mem->type = mema.flags; - - if (NOUVEAU_DEBUG & DEBUG_MEM) { - fprintf(stderr, - "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n", - __func__, mem->type, (GLuint) mem->offset, - (GLuint) mem->size); - } - - if (flags & NOUVEAU_MEM_MAPPED) - ret = drmMap(nmesa->driFd, mema.map_handle, mem->size, - &mem->map); - if (ret) { - mem->map = NULL; - nouveau_mem_free(ctx, mem); - mem = NULL; - } - - return mem; -} - -uint32_t nouveau_mem_gpu_offset_get(GLcontext * ctx, nouveau_mem * mem) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - return mem->offset; -} - -static GLboolean -nouveau_renderbuffer_pixelformat(nouveau_renderbuffer * nrb, - GLenum internalFormat) -{ - nrb->mesa.InternalFormat = internalFormat; - - /*TODO: We probably want to extend this a bit, and maybe make - * card-specific? - */ - switch (internalFormat) { - case GL_RGBA: - case GL_RGBA8: - nrb->mesa._BaseFormat = GL_RGBA; - nrb->mesa._ActualFormat = GL_RGBA8; - nrb->mesa.DataType = GL_UNSIGNED_BYTE; - nrb->mesa.RedBits = 8; - nrb->mesa.GreenBits = 8; - nrb->mesa.BlueBits = 8; - nrb->mesa.AlphaBits = 8; - nrb->cpp = 4; - break; - case GL_RGB: - case GL_RGB5: - nrb->mesa._BaseFormat = GL_RGB; - nrb->mesa._ActualFormat = GL_RGB5; - nrb->mesa.DataType = GL_UNSIGNED_BYTE; - nrb->mesa.RedBits = 5; - nrb->mesa.GreenBits = 6; - nrb->mesa.BlueBits = 5; - nrb->mesa.AlphaBits = 0; - nrb->cpp = 2; - break; - case GL_DEPTH_COMPONENT16: - nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; - nrb->mesa._ActualFormat = GL_DEPTH_COMPONENT16; - nrb->mesa.DataType = GL_UNSIGNED_SHORT; - nrb->mesa.DepthBits = 16; - nrb->cpp = 2; - break; - case GL_DEPTH_COMPONENT24: - nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; - nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.DepthBits = 24; - nrb->cpp = 4; - break; - case GL_STENCIL_INDEX8_EXT: - nrb->mesa._BaseFormat = GL_STENCIL_INDEX; - nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.StencilBits = 8; - nrb->cpp = 4; - break; - case GL_DEPTH24_STENCIL8_EXT: - nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT; - nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; - nrb->mesa.DepthBits = 24; - nrb->mesa.StencilBits = 8; - nrb->cpp = 4; - break; - default: - return GL_FALSE; - break; - } - - return GL_TRUE; -} - -static GLboolean -nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) -{ - nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; - - if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { - fprintf(stderr, "%s: unknown internalFormat\n", __func__); - return GL_FALSE; - } - - /* If this buffer isn't statically alloc'd, we may need to ask the - * drm for more memory */ - if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) { - GLuint pitch; - - /* align pitches to 64 bytes */ - pitch = ((width * nrb->cpp) + 63) & ~63; - - if (nrb->mem) - nouveau_mem_free(ctx, nrb->mem); - nrb->mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_FB | - NOUVEAU_MEM_MAPPED, - pitch * height, 0); - if (!nrb->mem) - return GL_FALSE; - - /* update nouveau_renderbuffer info */ - nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem); - nrb->pitch = pitch; - } - - rb->Width = width; - rb->Height = height; - rb->InternalFormat = internalFormat; - return GL_TRUE; -} - -static void nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) -{ - GET_CURRENT_CONTEXT(ctx); - nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; - - if (nrb->mem) - nouveau_mem_free(ctx, nrb->mem); - FREE(nrb); -} - -nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, - GLvoid * map, GLuint offset, - GLuint pitch, - __DRIdrawablePrivate * - dPriv) -{ - nouveau_renderbuffer *nrb; - - nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); - if (nrb) { - _mesa_init_renderbuffer(&nrb->mesa, 0); - - nouveau_renderbuffer_pixelformat(nrb, internalFormat); - - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; - - nrb->dPriv = dPriv; - nrb->offset = offset; - nrb->pitch = pitch; - nrb->map = map; - } - - return nrb; -} - -static void -nouveau_cliprects_drawable_set(nouveauContextPtr nmesa, - nouveau_renderbuffer * nrb) -{ - __DRIdrawablePrivate *dPriv = nrb->dPriv; - - nmesa->numClipRects = dPriv->numClipRects; - nmesa->pClipRects = dPriv->pClipRects; - nmesa->drawX = dPriv->x; - nmesa->drawY = dPriv->y; - nmesa->drawW = dPriv->w; - nmesa->drawH = dPriv->h; -} - -static void -nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, - nouveau_renderbuffer * nrb) -{ - nmesa->numClipRects = 1; - nmesa->pClipRects = &nmesa->osClipRect; - nmesa->osClipRect.x1 = 0; - nmesa->osClipRect.y1 = 0; - nmesa->osClipRect.x2 = nrb->mesa.Width; - nmesa->osClipRect.y2 = nrb->mesa.Height; - nmesa->drawX = 0; - nmesa->drawY = 0; - nmesa->drawW = nrb->mesa.Width; - nmesa->drawH = nrb->mesa.Height; -} - -void nouveau_window_moved(GLcontext * ctx) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer *nrb; - - nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0]; - if (!nrb) - return; - - if (!nrb->dPriv) - nouveau_cliprects_renderbuffer_set(nmesa, nrb); - else - nouveau_cliprects_drawable_set(nmesa, nrb); - - /* Viewport depends on window size/position, nouveauCalcViewport - * will take care of calling the hw-specific WindowMoved - */ - ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height); - /* Scissor depends on window position */ - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); -} - -GLboolean -nouveau_build_framebuffer(GLcontext * ctx, struct gl_framebuffer *fb) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer *color[MAX_DRAW_BUFFERS]; - nouveau_renderbuffer *depth; - - _mesa_update_framebuffer(ctx); - _mesa_update_draw_buffer_bounds(ctx); - - color[0] = (nouveau_renderbuffer *) fb->_ColorDrawBuffers[0][0]; - if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) - depth = (nouveau_renderbuffer *) fb->_DepthBuffer->Wrapped; - else - depth = (nouveau_renderbuffer *) fb->_DepthBuffer; - - if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) - return GL_FALSE; - nouveau_window_moved(ctx); - - return GL_TRUE; -} - -static void nouveauDrawBuffer(GLcontext * ctx, GLenum buffer) -{ - nouveau_build_framebuffer(ctx, ctx->DrawBuffer); -} - -static struct gl_framebuffer *nouveauNewFramebuffer(GLcontext * ctx, - GLuint name) -{ - return _mesa_new_framebuffer(ctx, name); -} - -static struct gl_renderbuffer *nouveauNewRenderbuffer(GLcontext * ctx, - GLuint name) -{ - nouveau_renderbuffer *nrb; - - nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); - if (nrb) { - _mesa_init_renderbuffer(&nrb->mesa, name); - - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; - } - return &nrb->mesa; -} - -static void -nouveauBindFramebuffer(GLcontext * ctx, GLenum target, - struct gl_framebuffer *fb, - struct gl_framebuffer *fbread) -{ - if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { - nouveau_build_framebuffer(ctx, fb); - } -} - -static void -nouveauFramebufferRenderbuffer(GLcontext * ctx, - struct gl_framebuffer *fb, - GLenum attachment, - struct gl_renderbuffer *rb) -{ - _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); - nouveau_build_framebuffer(ctx, fb); -} - -static void -nouveauRenderTexture(GLcontext * ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) -{ -} - -static void -nouveauFinishRenderTexture(GLcontext * ctx, - struct gl_renderbuffer_attachment *att) -{ -} - -void nouveauInitBufferFuncs(struct dd_function_table *func) -{ - func->DrawBuffer = nouveauDrawBuffer; - - func->NewFramebuffer = nouveauNewFramebuffer; - func->NewRenderbuffer = nouveauNewRenderbuffer; - func->BindFramebuffer = nouveauBindFramebuffer; - func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer; - func->RenderTexture = nouveauRenderTexture; - func->FinishRenderTexture = nouveauFinishRenderTexture; -} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h deleted file mode 100644 index f0987d2aa7..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __NOUVEAU_BUFFERS_H__ -#define __NOUVEAU_BUFFERS_H__ - -#include -#include "mtypes.h" -#include "utils.h" -#include "renderbuffer.h" - -typedef struct nouveau_mem_t { - int type; - uint64_t offset; - uint64_t size; - void *map; -} nouveau_mem; - -extern nouveau_mem *nouveau_mem_alloc(GLcontext *, uint32_t flags, - GLuint size, GLuint align); -extern void nouveau_mem_free(GLcontext *, nouveau_mem *); -extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *, nouveau_mem *); - -extern GLboolean nouveau_memformat_flat_emit(GLcontext *, - nouveau_mem *dst, - nouveau_mem *src, - GLuint dst_offset, - GLuint src_offset, - GLuint size); - -typedef struct nouveau_renderbuffer_t { - struct gl_renderbuffer mesa; /* must be first! */ - __DRIdrawablePrivate *dPriv; - - nouveau_mem *mem; - void *map; - - int cpp; - uint32_t offset; - uint32_t pitch; -} nouveau_renderbuffer; - -extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, - GLvoid *map, - GLuint offset, - GLuint pitch, - __DRIdrawablePrivate *); -extern void nouveau_window_moved(GLcontext *); -extern GLboolean nouveau_build_framebuffer(GLcontext *, - struct gl_framebuffer *); -extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *); - -extern void nouveauInitBufferFuncs(struct dd_function_table *); - -#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index fdbde51a72..03f778a13c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -36,10 +36,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "tnl/t_vertex.h" +#include "nouveau_fbo.h" #include "nouveau_screen.h" -#include "nouveau_state_cache.h" -#include "nouveau_buffers.h" #include "nouveau_shader.h" +#include "nouveau_state_cache.h" #include "nouveau_sync.h" #include "xmlconfig.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c new file mode 100644 index 0000000000..54c0c26d08 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -0,0 +1,304 @@ +#include "utils.h" +#include "framebuffer.h" +#include "renderbuffer.h" +#include "fbobject.h" + +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" + +static GLboolean +nouveau_renderbuffer_pixelformat(nouveau_renderbuffer * nrb, + GLenum internalFormat) +{ + nrb->mesa.InternalFormat = internalFormat; + + /*TODO: We probably want to extend this a bit, and maybe make + * card-specific? + */ + switch (internalFormat) { + case GL_RGBA: + case GL_RGBA8: + nrb->mesa._BaseFormat = GL_RGBA; + nrb->mesa._ActualFormat = GL_RGBA8; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 8; + nrb->mesa.GreenBits = 8; + nrb->mesa.BlueBits = 8; + nrb->mesa.AlphaBits = 8; + nrb->cpp = 4; + break; + case GL_RGB: + case GL_RGB5: + nrb->mesa._BaseFormat = GL_RGB; + nrb->mesa._ActualFormat = GL_RGB5; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 5; + nrb->mesa.GreenBits = 6; + nrb->mesa.BlueBits = 5; + nrb->mesa.AlphaBits = 0; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT16: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat = GL_DEPTH_COMPONENT16; + nrb->mesa.DataType = GL_UNSIGNED_SHORT; + nrb->mesa.DepthBits = 16; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->cpp = 4; + break; + case GL_STENCIL_INDEX8_EXT: + nrb->mesa._BaseFormat = GL_STENCIL_INDEX; + nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + case GL_DEPTH24_STENCIL8_EXT: + nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT; + nrb->mesa._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + default: + return GL_FALSE; + break; + } + + return GL_TRUE; +} + +static GLboolean +nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; + + if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { + fprintf(stderr, "%s: unknown internalFormat\n", __func__); + return GL_FALSE; + } + + /* If this buffer isn't statically alloc'd, we may need to ask the + * drm for more memory */ + if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) { + GLuint pitch; + + /* align pitches to 64 bytes */ + pitch = ((width * nrb->cpp) + 63) & ~63; + + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + nrb->mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_FB | + NOUVEAU_MEM_MAPPED, + pitch * height, 0); + if (!nrb->mem) + return GL_FALSE; + + /* update nouveau_renderbuffer info */ + nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem); + nrb->pitch = pitch; + } + + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + return GL_TRUE; +} + +static void nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) +{ + GET_CURRENT_CONTEXT(ctx); + nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; + + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + FREE(nrb); +} + +nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, + GLvoid * map, GLuint offset, + GLuint pitch, + __DRIdrawablePrivate * + dPriv) +{ + nouveau_renderbuffer *nrb; + + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, 0); + + nouveau_renderbuffer_pixelformat(nrb, internalFormat); + + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; + + nrb->dPriv = dPriv; + nrb->offset = offset; + nrb->pitch = pitch; + nrb->map = map; + } + + return nrb; +} + +static void +nouveau_cliprects_drawable_set(nouveauContextPtr nmesa, + nouveau_renderbuffer * nrb) +{ + __DRIdrawablePrivate *dPriv = nrb->dPriv; + + nmesa->numClipRects = dPriv->numClipRects; + nmesa->pClipRects = dPriv->pClipRects; + nmesa->drawX = dPriv->x; + nmesa->drawY = dPriv->y; + nmesa->drawW = dPriv->w; + nmesa->drawH = dPriv->h; +} + +static void +nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, + nouveau_renderbuffer * nrb) +{ + nmesa->numClipRects = 1; + nmesa->pClipRects = &nmesa->osClipRect; + nmesa->osClipRect.x1 = 0; + nmesa->osClipRect.y1 = 0; + nmesa->osClipRect.x2 = nrb->mesa.Width; + nmesa->osClipRect.y2 = nrb->mesa.Height; + nmesa->drawX = 0; + nmesa->drawY = 0; + nmesa->drawW = nrb->mesa.Width; + nmesa->drawH = nrb->mesa.Height; +} + +void nouveau_window_moved(GLcontext * ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *nrb; + + nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + if (!nrb) + return; + + if (!nrb->dPriv) + nouveau_cliprects_renderbuffer_set(nmesa, nrb); + else + nouveau_cliprects_drawable_set(nmesa, nrb); + + /* Viewport depends on window size/position, nouveauCalcViewport + * will take care of calling the hw-specific WindowMoved + */ + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + /* Scissor depends on window position */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + +GLboolean +nouveau_build_framebuffer(GLcontext * ctx, struct gl_framebuffer *fb) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *color[MAX_DRAW_BUFFERS]; + nouveau_renderbuffer *depth; + + _mesa_update_framebuffer(ctx); + _mesa_update_draw_buffer_bounds(ctx); + + color[0] = (nouveau_renderbuffer *) fb->_ColorDrawBuffers[0][0]; + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) + depth = (nouveau_renderbuffer *) fb->_DepthBuffer->Wrapped; + else + depth = (nouveau_renderbuffer *) fb->_DepthBuffer; + + if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) + return GL_FALSE; + nouveau_window_moved(ctx); + + return GL_TRUE; +} + +static void nouveauDrawBuffer(GLcontext * ctx, GLenum buffer) +{ + nouveau_build_framebuffer(ctx, ctx->DrawBuffer); +} + +static struct gl_framebuffer *nouveauNewFramebuffer(GLcontext * ctx, + GLuint name) +{ + return _mesa_new_framebuffer(ctx, name); +} + +static struct gl_renderbuffer *nouveauNewRenderbuffer(GLcontext * ctx, + GLuint name) +{ + nouveau_renderbuffer *nrb; + + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, name); + + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; + } + return &nrb->mesa; +} + +static void +nouveauBindFramebuffer(GLcontext * ctx, GLenum target, + struct gl_framebuffer *fb, + struct gl_framebuffer *fbread) +{ + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + nouveau_build_framebuffer(ctx, fb); + } +} + +static void +nouveauFramebufferRenderbuffer(GLcontext * ctx, + struct gl_framebuffer *fb, + GLenum attachment, + struct gl_renderbuffer *rb) +{ + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + nouveau_build_framebuffer(ctx, fb); +} + +static void +nouveauRenderTexture(GLcontext * ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ +} + +static void +nouveauFinishRenderTexture(GLcontext * ctx, + struct gl_renderbuffer_attachment *att) +{ +} + +void nouveauInitBufferFuncs(struct dd_function_table *func) +{ + func->DrawBuffer = nouveauDrawBuffer; + + func->NewFramebuffer = nouveauNewFramebuffer; + func->NewRenderbuffer = nouveauNewRenderbuffer; + func->BindFramebuffer = nouveauBindFramebuffer; + func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer; + func->RenderTexture = nouveauRenderTexture; + func->FinishRenderTexture = nouveauFinishRenderTexture; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.h b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h new file mode 100644 index 0000000000..757a784f8f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h @@ -0,0 +1,35 @@ +#ifndef __NOUVEAU_BUFFERS_H__ +#define __NOUVEAU_BUFFERS_H__ + +#include +#include "mtypes.h" +#include "utils.h" +#include "renderbuffer.h" + +#include "nouveau_mem.h" + +typedef struct nouveau_renderbuffer_t { + struct gl_renderbuffer mesa; /* must be first! */ + __DRIdrawablePrivate *dPriv; + + nouveau_mem *mem; + void *map; + + int cpp; + uint32_t offset; + uint32_t pitch; +} nouveau_renderbuffer; + +extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, + GLvoid *map, + GLuint offset, + GLuint pitch, + __DRIdrawablePrivate *); +extern void nouveau_window_moved(GLcontext *); +extern GLboolean nouveau_build_framebuffer(GLcontext *, + struct gl_framebuffer *); +extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *); + +extern void nouveauInitBufferFuncs(struct dd_function_table *); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_mem.c b/src/mesa/drivers/dri/nouveau/nouveau_mem.c new file mode 100644 index 0000000000..35c53268b0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_mem.c @@ -0,0 +1,144 @@ +#include "mtypes.h" + +#include "nouveau_context.h" +#include "nouveau_fifo.h" +#include "nouveau_mem.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" + +#define MAX_MEMFMT_LENGTH 32768 + +/* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */ +GLboolean +nouveau_memformat_flat_emit(GLcontext * ctx, + nouveau_mem * dst, nouveau_mem * src, + GLuint dst_offset, GLuint src_offset, + GLuint size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t src_handle, dst_handle; + GLuint count; + + if (src_offset + size > src->size) { + MESSAGE("src out of nouveau_mem bounds\n"); + return GL_FALSE; + } + if (dst_offset + size > dst->size) { + MESSAGE("dst out of nouveau_mem bounds\n"); + return GL_FALSE; + } + + src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; + dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaTT; + src_offset += nouveau_mem_gpu_offset_get(ctx, src); + dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); + + BEGIN_RING_SIZE(NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); + OUT_RING(src_handle); + OUT_RING(dst_handle); + + count = (size / MAX_MEMFMT_LENGTH) + + ((size % MAX_MEMFMT_LENGTH) ? 1 : 0); + + while (count--) { + GLuint length = + (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size; + + BEGIN_RING_SIZE(NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RING(src_offset); + OUT_RING(dst_offset); + OUT_RING(0); /* pitch in */ + OUT_RING(0); /* pitch out */ + OUT_RING(length); /* line length */ + OUT_RING(1); /* number of lines */ + OUT_RING((1 << 8) /* dst_inc */ |(1 << 0) /* src_inc */ ); + OUT_RING(0); /* buffer notify? */ + FIRE_RING(); + + src_offset += length; + dst_offset += length; + size -= length; + } + + return GL_TRUE; +} + +void nouveau_mem_free(GLcontext * ctx, nouveau_mem * mem) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct drm_nouveau_mem_free memf; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint) mem->offset, + (GLuint) mem->size); + } + + if (mem->map) + drmUnmap(mem->map, mem->size); + memf.flags = mem->type; + memf.offset = mem->offset; + drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, + sizeof(memf)); + FREE(mem); +} + +nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, uint32_t flags, GLuint size, + GLuint align) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct drm_nouveau_mem_alloc mema; + nouveau_mem *mem; + int ret; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, + "%s: requested: flags=0x%x, size=0x%x, align=0x%x\n", + __func__, flags, (GLuint) size, align); + } + + mem = CALLOC(sizeof(nouveau_mem)); + if (!mem) + return NULL; + + mema.flags = flags; + mema.size = mem->size = size; + mema.alignment = align; + mem->map = NULL; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, + &mema, sizeof(mema)); + if (ret) { + FREE(mem); + return NULL; + } + mem->offset = mema.offset; + mem->type = mema.flags; + + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, + "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint) mem->offset, + (GLuint) mem->size); + } + + if (flags & NOUVEAU_MEM_MAPPED) + ret = drmMap(nmesa->driFd, mema.map_handle, mem->size, + &mem->map); + if (ret) { + mem->map = NULL; + nouveau_mem_free(ctx, mem); + mem = NULL; + } + + return mem; +} + +uint32_t nouveau_mem_gpu_offset_get(GLcontext * ctx, nouveau_mem * mem) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + return mem->offset; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_mem.h b/src/mesa/drivers/dri/nouveau/nouveau_mem.h new file mode 100644 index 0000000000..6db73f4708 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_mem.h @@ -0,0 +1,23 @@ +#ifndef __NOUVEAU_MEM_H__ +#define __NOUVEAU_MEM_H__ + +typedef struct nouveau_mem_t { + int type; + uint64_t offset; + uint64_t size; + void *map; +} nouveau_mem; + +extern nouveau_mem *nouveau_mem_alloc(GLcontext *, uint32_t flags, + GLuint size, GLuint align); +extern void nouveau_mem_free(GLcontext *, nouveau_mem *); +extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *, nouveau_mem *); + +extern GLboolean nouveau_memformat_flat_emit(GLcontext *, + nouveau_mem *dst, + nouveau_mem *src, + GLuint dst_offset, + GLuint src_offset, + GLuint size); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.h b/src/mesa/drivers/dri/nouveau/nouveau_span.h index bc39ecd17b..c4142a10ef 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.h @@ -30,7 +30,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define __NOUVEAU_SPAN_H__ #include "drirenderbuffer.h" -#include "nouveau_buffers.h" +#include "nouveau_fbo.h" extern void nouveauSpanInitFunctions( GLcontext *ctx ); extern void nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 3f5f6d54e9..abb3088032 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -28,11 +28,11 @@ #include "vblank.h" /* for DO_USLEEP */ #include "nouveau_context.h" -#include "nouveau_buffers.h" -#include "nouveau_object.h" #include "nouveau_fifo.h" -#include "nouveau_reg.h" +#include "nouveau_mem.h" #include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" #include "nouveau_sync.h" #define NOTIFIER(__v) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index 1ff4eca325..fc37efbe6b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -28,8 +28,6 @@ #ifndef __NOUVEAU_SYNC_H__ #define __NOUVEAU_SYNC_H__ -#include "nouveau_buffers.h" - #define NV_NOTIFIER_SIZE 32 #define NV_NOTIFY_TIME_0 0x00000000 #define NV_NOTIFY_TIME_1 0x00000004 -- cgit v1.2.3 From fef3dcbee60b041df64a12511c8aa3c304a04652 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Aug 2007 20:38:10 +1000 Subject: nouveau: Always render offscreen, emulate front buffer rendering. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 25 +++-- src/mesa/drivers/dri/nouveau/nouveau_context.h | 7 +- src/mesa/drivers/dri/nouveau/nouveau_driver.c | 4 + src/mesa/drivers/dri/nouveau/nouveau_fbo.c | 126 +++++++++++-------------- src/mesa/drivers/dri/nouveau/nouveau_fbo.h | 13 +-- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 27 ++---- src/mesa/drivers/dri/nouveau/nouveau_span.c | 8 +- src/mesa/drivers/dri/nouveau/nouveau_span.h | 4 +- src/mesa/drivers/dri/nouveau/nv04_state.c | 4 +- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 +- src/mesa/drivers/dri/nouveau/nv20_state.c | 4 +- src/mesa/drivers/dri/nouveau/nv30_state.c | 6 +- src/mesa/drivers/dri/nouveau/nv50_state.c | 6 +- 13 files changed, 109 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 44392c0267..9b92f2001d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -315,19 +315,23 @@ GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv ) return GL_TRUE; } -static void nouveauDoSwapBuffers(nouveauContextPtr nmesa, - __DRIdrawablePrivate *dPriv) +void +nouveauDoSwapBuffers(nouveauContextPtr nmesa, __DRIdrawablePrivate *dPriv) { struct gl_framebuffer *fb; - nouveau_renderbuffer *src, *dst; + nouveauScreenPtr screen = dPriv->driScreenPriv->private; + nouveau_renderbuffer_t *src; drm_clip_rect_t *box; int nbox, i; fb = (struct gl_framebuffer *)dPriv->driverPrivate; - dst = (nouveau_renderbuffer*) - fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - src = (nouveau_renderbuffer*) - fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { + src = (nouveau_renderbuffer_t *) + fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + } else { + src = (nouveau_renderbuffer_t *) + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + } #ifdef ALLOW_MULTI_SUBCHANNEL LOCK_HARDWARE(nmesa); @@ -341,9 +345,10 @@ static void nouveauDoSwapBuffers(nouveauContextPtr nmesa, OUT_RING (6); /* X8R8G8B8 */ else OUT_RING (4); /* R5G6B5 */ - OUT_RING ((dst->pitch << 16) | src->pitch); - OUT_RING (src->offset); - OUT_RING (dst->offset); + OUT_RING(((screen->frontPitch * screen->fbFormat) << 16) | + src->pitch); + OUT_RING(src->offset); + OUT_RING(screen->frontOffset); } for (i=0; iDrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) + nouveauDoSwapBuffers(nmesa, nmesa->driDrawable); FIRE_RING(); } @@ -124,6 +127,7 @@ static void nouveauFlush( GLcontext *ctx ) static void nouveauFinish( GLcontext *ctx ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveauFlush( ctx ); nouveauWaitForIdle( nmesa ); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c index 54c0c26d08..cc3da8b9bd 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -11,7 +11,7 @@ #include "nouveau_reg.h" static GLboolean -nouveau_renderbuffer_pixelformat(nouveau_renderbuffer * nrb, +nouveau_renderbuffer_pixelformat(nouveau_renderbuffer_t * nrb, GLenum internalFormat) { nrb->mesa.InternalFormat = internalFormat; @@ -84,7 +84,7 @@ nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height) { - nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; + nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *) rb; if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { fprintf(stderr, "%s: unknown internalFormat\n", __func__); @@ -93,7 +93,7 @@ nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, /* If this buffer isn't statically alloc'd, we may need to ask the * drm for more memory */ - if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) { + if (rb->Width != width || rb->Height != height) { GLuint pitch; /* align pitches to 64 bytes */ @@ -116,62 +116,48 @@ nouveau_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, rb->Width = width; rb->Height = height; rb->InternalFormat = internalFormat; + + nouveauSpanSetFunctions(nrb); + return GL_TRUE; } -static void nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) +static void +nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) { GET_CURRENT_CONTEXT(ctx); - nouveau_renderbuffer *nrb = (nouveau_renderbuffer *) rb; + nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *) rb; if (nrb->mem) nouveau_mem_free(ctx, nrb->mem); FREE(nrb); } -nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, - GLvoid * map, GLuint offset, - GLuint pitch, - __DRIdrawablePrivate * - dPriv) +nouveau_renderbuffer_t * +nouveau_renderbuffer_new(GLenum internalFormat) { - nouveau_renderbuffer *nrb; + nouveau_renderbuffer_t *nrb; - nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); - if (nrb) { - _mesa_init_renderbuffer(&nrb->mesa, 0); - - nouveau_renderbuffer_pixelformat(nrb, internalFormat); + nrb = CALLOC_STRUCT(nouveau_renderbuffer); + if (!nrb) + return NULL; - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; + _mesa_init_renderbuffer(&nrb->mesa, 0); - nrb->dPriv = dPriv; - nrb->offset = offset; - nrb->pitch = pitch; - nrb->map = map; + if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { + fprintf(stderr, "%s: unknown internalFormat\n", __func__); + return GL_FALSE; } - return nrb; -} + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; -static void -nouveau_cliprects_drawable_set(nouveauContextPtr nmesa, - nouveau_renderbuffer * nrb) -{ - __DRIdrawablePrivate *dPriv = nrb->dPriv; - - nmesa->numClipRects = dPriv->numClipRects; - nmesa->pClipRects = dPriv->pClipRects; - nmesa->drawX = dPriv->x; - nmesa->drawY = dPriv->y; - nmesa->drawW = dPriv->w; - nmesa->drawH = dPriv->h; + return nrb; } static void nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, - nouveau_renderbuffer * nrb) + nouveau_renderbuffer_t * nrb) { nmesa->numClipRects = 1; nmesa->pClipRects = &nmesa->osClipRect; @@ -185,19 +171,18 @@ nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, nmesa->drawH = nrb->mesa.Height; } -void nouveau_window_moved(GLcontext * ctx) +void +nouveau_window_moved(GLcontext * ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer *nrb; + nouveau_renderbuffer_t *nrb; - nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + nrb = (nouveau_renderbuffer_t *) + ctx->DrawBuffer->_ColorDrawBuffers[0][0]; if (!nrb) return; - if (!nrb->dPriv) - nouveau_cliprects_renderbuffer_set(nmesa, nrb); - else - nouveau_cliprects_drawable_set(nmesa, nrb); + nouveau_cliprects_renderbuffer_set(nmesa, nrb); /* Viewport depends on window size/position, nouveauCalcViewport * will take care of calling the hw-specific WindowMoved @@ -210,20 +195,20 @@ void nouveau_window_moved(GLcontext * ctx) } GLboolean -nouveau_build_framebuffer(GLcontext * ctx, struct gl_framebuffer *fb) +nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer *color[MAX_DRAW_BUFFERS]; - nouveau_renderbuffer *depth; + nouveau_renderbuffer_t *color[MAX_DRAW_BUFFERS]; + nouveau_renderbuffer_t *depth; _mesa_update_framebuffer(ctx); _mesa_update_draw_buffer_bounds(ctx); - color[0] = (nouveau_renderbuffer *) fb->_ColorDrawBuffers[0][0]; + color[0] = (nouveau_renderbuffer_t *) fb->_ColorDrawBuffers[0][0]; if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) - depth = (nouveau_renderbuffer *) fb->_DepthBuffer->Wrapped; + depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer->Wrapped; else - depth = (nouveau_renderbuffer *) fb->_DepthBuffer; + depth = (nouveau_renderbuffer_t *) fb->_DepthBuffer; if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) return GL_FALSE; @@ -232,34 +217,36 @@ nouveau_build_framebuffer(GLcontext * ctx, struct gl_framebuffer *fb) return GL_TRUE; } -static void nouveauDrawBuffer(GLcontext * ctx, GLenum buffer) +static void +nouveauDrawBuffer(GLcontext *ctx, GLenum buffer) { nouveau_build_framebuffer(ctx, ctx->DrawBuffer); } -static struct gl_framebuffer *nouveauNewFramebuffer(GLcontext * ctx, - GLuint name) +static struct gl_framebuffer * +nouveauNewFramebuffer(GLcontext *ctx, GLuint name) { return _mesa_new_framebuffer(ctx, name); } -static struct gl_renderbuffer *nouveauNewRenderbuffer(GLcontext * ctx, - GLuint name) +static struct gl_renderbuffer * +nouveauNewRenderbuffer(GLcontext *ctx, GLuint name) { - nouveau_renderbuffer *nrb; + nouveau_renderbuffer_t *nrb; - nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); - if (nrb) { - _mesa_init_renderbuffer(&nrb->mesa, name); + nrb = CALLOC_STRUCT(nouveau_renderbuffer); + if (!nrb) + return NULL; - nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; - nrb->mesa.Delete = nouveau_renderbuffer_delete; - } + _mesa_init_renderbuffer(&nrb->mesa, name); + + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; return &nrb->mesa; } static void -nouveauBindFramebuffer(GLcontext * ctx, GLenum target, +nouveauBindFramebuffer(GLcontext *ctx, GLenum target, struct gl_framebuffer *fb, struct gl_framebuffer *fbread) { @@ -269,18 +256,15 @@ nouveauBindFramebuffer(GLcontext * ctx, GLenum target, } static void -nouveauFramebufferRenderbuffer(GLcontext * ctx, - struct gl_framebuffer *fb, - GLenum attachment, - struct gl_renderbuffer *rb) +nouveauFramebufferRenderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) { _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); nouveau_build_framebuffer(ctx, fb); } static void -nouveauRenderTexture(GLcontext * ctx, - struct gl_framebuffer *fb, +nouveauRenderTexture(GLcontext * ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { } @@ -291,7 +275,8 @@ nouveauFinishRenderTexture(GLcontext * ctx, { } -void nouveauInitBufferFuncs(struct dd_function_table *func) +void +nouveauInitBufferFuncs(struct dd_function_table *func) { func->DrawBuffer = nouveauDrawBuffer; @@ -302,3 +287,4 @@ void nouveauInitBufferFuncs(struct dd_function_table *func) func->RenderTexture = nouveauRenderTexture; func->FinishRenderTexture = nouveauFinishRenderTexture; } + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.h b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h index 757a784f8f..787af4e9e4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h @@ -8,9 +8,8 @@ #include "nouveau_mem.h" -typedef struct nouveau_renderbuffer_t { +typedef struct nouveau_renderbuffer { struct gl_renderbuffer mesa; /* must be first! */ - __DRIdrawablePrivate *dPriv; nouveau_mem *mem; void *map; @@ -18,17 +17,13 @@ typedef struct nouveau_renderbuffer_t { int cpp; uint32_t offset; uint32_t pitch; -} nouveau_renderbuffer; +} nouveau_renderbuffer_t; -extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, - GLvoid *map, - GLuint offset, - GLuint pitch, - __DRIdrawablePrivate *); +extern nouveau_renderbuffer_t *nouveau_renderbuffer_new(GLenum internalFormat); extern void nouveau_window_moved(GLcontext *); extern GLboolean nouveau_build_framebuffer(GLcontext *, struct gl_framebuffer *); -extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *); +extern nouveau_renderbuffer_t *nouveau_current_draw_buffer(GLcontext *); extern void nouveauInitBufferFuncs(struct dd_function_table *); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 4d22ecc83e..065aa81746 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -132,10 +132,11 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, GLboolean isPixmap) { nouveauScreenPtr screen = (nouveauScreenPtr) driScrnPriv->private; - nouveau_renderbuffer *nrb; + nouveau_renderbuffer_t *nrb; struct gl_framebuffer *fb; const GLboolean swAccum = mesaVis->accumRedBits > 0; - const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; + const GLboolean swStencil = (mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24); GLenum color_format = screen->fbFormat == 4 ? GL_RGBA8 : GL_RGB5; if (isPixmap) @@ -146,37 +147,25 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, return GL_FALSE; /* Front buffer */ - nrb = nouveau_renderbuffer_new(color_format, - driScrnPriv->pFB + screen->frontOffset, - screen->frontOffset, - screen->frontPitch * screen->fbFormat, - driDrawPriv); - nouveauSpanSetFunctions(nrb, mesaVis); + nrb = nouveau_renderbuffer_new(color_format); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa); if (mesaVis->doubleBufferMode) { - nrb = nouveau_renderbuffer_new(color_format, NULL, 0, 0, NULL); - nouveauSpanSetFunctions(nrb, mesaVis); + nrb = nouveau_renderbuffer_new(color_format); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa); } if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { - nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL, - 0, 0, NULL); - nouveauSpanSetFunctions(nrb, mesaVis); + nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa); } else if (mesaVis->depthBits == 24) { - nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24, NULL, - 0, 0, NULL); - nouveauSpanSetFunctions(nrb, mesaVis); + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); } else if (mesaVis->depthBits == 16) { - nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL, - 0, 0, NULL); - nouveauSpanSetFunctions(nrb, mesaVis); + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c index 6e3f9fadf4..453bc5f6c4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -37,8 +37,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define HAVE_HW_STENCIL_SPANS 0 #define HAVE_HW_STENCIL_PIXELS 0 -static char *fake_span[1280*1024*4]; - #define HW_CLIPLOOP() \ do { \ int _nc = nmesa->numClipRects; \ @@ -50,11 +48,10 @@ static char *fake_span[1280*1024*4]; #define LOCAL_VARS \ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ - nouveau_renderbuffer *nrb = (nouveau_renderbuffer *)rb; \ + nouveau_renderbuffer_t *nrb = (nouveau_renderbuffer_t *)rb; \ GLuint height = nrb->mesa.Height; \ GLubyte *map = (GLubyte *)(nrb->map ? nrb->map : nrb->mem->map) + \ (nmesa->drawY * nrb->pitch) + (nmesa->drawX * nrb->cpp); \ - map = fake_span; \ GLuint p; \ (void) p; @@ -119,10 +116,11 @@ void nouveauSpanInitFunctions( GLcontext *ctx ) * Plug in the Get/Put routines for the given driRenderbuffer. */ void -nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis) +nouveauSpanSetFunctions(nouveau_renderbuffer_t *nrb) { if (nrb->mesa._ActualFormat == GL_RGBA8) nouveauInitPointers_ARGB8888(&nrb->mesa); else // if (nrb->mesa._ActualFormat == GL_RGB5) nouveauInitPointers_RGB565(&nrb->mesa); } + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.h b/src/mesa/drivers/dri/nouveau/nouveau_span.h index c4142a10ef..d3f31c9cb2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.h @@ -32,8 +32,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drirenderbuffer.h" #include "nouveau_fbo.h" -extern void nouveauSpanInitFunctions( GLcontext *ctx ); -extern void nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis); +extern void nouveauSpanInitFunctions(GLcontext *ctx); +extern void nouveauSpanSetFunctions(nouveau_renderbuffer_t *nrb); #endif /* __NOUVEAU_SPAN_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c index 25df3d2a62..d3031aa5b1 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_state.c +++ b/src/mesa/drivers/dri/nouveau/nv04_state.c @@ -451,8 +451,8 @@ static GLboolean nv04InitCard(nouveauContextPtr nmesa) /* Update buffer offset/pitch/format */ static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) + nouveau_renderbuffer_t **color, + nouveau_renderbuffer_t *depth) { GLuint x, y, w, h; uint32_t depth_pitch=(depth?depth->pitch:0+15)&~15+16; diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 47c4b14ba6..0e1637015f 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -709,8 +709,8 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) /* Update buffer offset/pitch/format */ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) + nouveau_renderbuffer_t **color, + nouveau_renderbuffer_t *depth) { GLuint x, y, w, h; GLuint pitch, format, depth_pitch; diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index ccf2f6148b..6b583980a4 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -728,8 +728,8 @@ static GLboolean nv20InitCard(nouveauContextPtr nmesa) /* Update buffer offset/pitch/format */ static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) + nouveau_renderbuffer_t **color, + nouveau_renderbuffer_t *depth) { GLuint x, y, w, h; GLuint pitch, format, depth_pitch; diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9b010954b3..cd3ee98688 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -905,9 +905,9 @@ static GLboolean nv40InitCard(nouveauContextPtr nmesa) return GL_TRUE; } -static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) +static GLboolean +nv30BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer_t **color, nouveau_renderbuffer_t *depth) { GLuint x, y, w, h; diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c index 818e268615..a9236f093c 100644 --- a/src/mesa/drivers/dri/nouveau/nv50_state.c +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -584,9 +584,9 @@ static GLboolean nv50InitCard(nouveauContextPtr nmesa) return GL_FALSE; } -static GLboolean nv50BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) +static GLboolean +nv50BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer_t **color, nouveau_renderbuffer_t *depth) { return GL_FALSE; } -- cgit v1.2.3 From fcbd06d201754bf4f69a0262dcd04b4c287a173b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Aug 2007 22:05:15 +1000 Subject: nouveau: Remove ALLOW_MULTI_SUBCHANNEL hack Irrelevant, since we depend on working context switching now. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 -- src/mesa/drivers/dri/nouveau/nouveau_object.c | 2 -- src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 -- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 2 -- 4 files changed, 8 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 9b92f2001d..1e13324b98 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -333,7 +333,6 @@ nouveauDoSwapBuffers(nouveauContextPtr nmesa, __DRIdrawablePrivate *dPriv) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; } -#ifdef ALLOW_MULTI_SUBCHANNEL LOCK_HARDWARE(nmesa); nbox = dPriv->numClipRects; box = dPriv->pClipRects; @@ -362,7 +361,6 @@ nouveauDoSwapBuffers(nouveauContextPtr nmesa, __DRIdrawablePrivate *dPriv) FIRE_RING(); UNLOCK_HARDWARE(nmesa); -#endif } void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index a143488e8d..f6ff37848a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -45,7 +45,6 @@ void nouveauObjectInit(nouveauContextPtr nmesa) } nouveauCreateContextObject(nmesa, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT); -#ifdef ALLOW_MULTI_SUBCHANNEL nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D); BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0, 2); OUT_RING(NvDmaFB); @@ -58,7 +57,6 @@ void nouveauObjectInit(nouveauContextPtr nmesa) OUT_RING(3); /* SRCCOPY */ nouveauObjectOnSubchannel(nmesa, NvSubMemFormat, NvMemFormat); -#endif nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index 8c72d014da..730738ad34 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -3,8 +3,6 @@ #include "nouveau_context.h" -#define ALLOW_MULTI_SUBCHANNEL - void nouveauObjectInit(nouveauContextPtr nmesa); enum DMAObjects { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index abb3088032..e7abdd60ee 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -188,11 +188,9 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) */ BEGIN_RING_CACHE(NvSub3D, 0x180, 1); OUT_RING_CACHE (NvSyncNotify); -#ifdef ALLOW_MULTI_SUBCHANNEL BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); OUT_RING (NvSyncNotify); -#endif return GL_TRUE; } -- cgit v1.2.3 From 3cc4e9815d4962e5f5e7b23bae1cf9b82092bb52 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Aug 2007 23:12:04 +1000 Subject: nouveau: reindent nouveau_span.c --- src/mesa/drivers/dri/nouveau/nouveau_span.c | 45 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c index 453bc5f6c4..d62830ff53 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -67,7 +67,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Color buffers */ -/* RGB565 */ +/* RGB565 */ #define SPANTMP_PIXEL_FMT GL_RGB #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 @@ -86,41 +86,38 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp) #include "spantmp2.h" -static void -nouveauSpanRenderStart( GLcontext *ctx ) +static void nouveauSpanRenderStart(GLcontext * ctx) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - FIRE_RING(); - LOCK_HARDWARE(nmesa); - nouveauWaitForIdleLocked( nmesa ); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + FIRE_RING(); + LOCK_HARDWARE(nmesa); + nouveauWaitForIdleLocked(nmesa); } -static void -nouveauSpanRenderFinish( GLcontext *ctx ) +static void nouveauSpanRenderFinish(GLcontext * ctx) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - _swrast_flush( ctx ); - nouveauWaitForIdleLocked( nmesa ); - UNLOCK_HARDWARE( nmesa ); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + _swrast_flush(ctx); + nouveauWaitForIdleLocked(nmesa); + UNLOCK_HARDWARE(nmesa); } -void nouveauSpanInitFunctions( GLcontext *ctx ) +void nouveauSpanInitFunctions(GLcontext * ctx) { - struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); - swdd->SpanRenderStart = nouveauSpanRenderStart; - swdd->SpanRenderFinish = nouveauSpanRenderFinish; + struct swrast_device_driver *swdd = + _swrast_GetDeviceDriverReference(ctx); + swdd->SpanRenderStart = nouveauSpanRenderStart; + swdd->SpanRenderFinish = nouveauSpanRenderFinish; } /** * Plug in the Get/Put routines for the given driRenderbuffer. */ -void -nouveauSpanSetFunctions(nouveau_renderbuffer_t *nrb) +void nouveauSpanSetFunctions(nouveau_renderbuffer_t * nrb) { - if (nrb->mesa._ActualFormat == GL_RGBA8) - nouveauInitPointers_ARGB8888(&nrb->mesa); - else // if (nrb->mesa._ActualFormat == GL_RGB5) - nouveauInitPointers_RGB565(&nrb->mesa); + if (nrb->mesa._ActualFormat == GL_RGBA8) + nouveauInitPointers_ARGB8888(&nrb->mesa); + else // if (nrb->mesa._ActualFormat == GL_RGB5) + nouveauInitPointers_RGB565(&nrb->mesa); } - -- cgit v1.2.3 From ecfa3e4d0aa93ca597a19693c30532655795e9d8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 15 Aug 2007 14:26:15 +1000 Subject: nouveau: Keep drm channel alloc struct around. --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 29 ++++++++------------ src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 37 +++++++++++++------------- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 10 +++---- src/mesa/drivers/dri/nouveau/nouveau_object.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 5 ++-- 5 files changed, 39 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 37c8f40d09..dc904ad6b3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -44,17 +44,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xmlconfig.h" -typedef struct nouveau_fifo_t{ - int channel; - u_int32_t* buffer; - u_int32_t* mmio; - u_int32_t put_base; - u_int32_t current; - u_int32_t put; - u_int32_t free; - u_int32_t max; -} -nouveau_fifo; +typedef struct nouveau_fifo { + struct drm_nouveau_channel_alloc drm; + uint32_t *pushbuf; + uint32_t *mmio; + uint32_t *notifier_block; + uint32_t current; + uint32_t put; + uint32_t free; + uint32_t max; +} nouveau_fifo_t; #define TAG(x) nouveau##x #include "tnl_dd/t_dd_vertex.h" @@ -94,13 +93,7 @@ typedef struct nouveau_context { GLcontext *glCtx; /* The per-context fifo */ - nouveau_fifo fifo; - - /* The read-only regs */ - volatile unsigned char* mmio; - - /* The per-channel notifier block */ - volatile void *notifier_block; + nouveau_fifo_t fifo; /* Physical addresses of AGP/VRAM apertures */ uint64_t vram_phys; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 4208819d02..5dc94e0520 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -57,7 +57,8 @@ void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) if(nmesa->fifo.put >= fifo_get) { nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current; if(nmesa->fifo.free < size+1) { - OUT_RING(NV03_FIFO_CMD_JUMP | nmesa->fifo.put_base); + OUT_RING(NV03_FIFO_CMD_JUMP | + nmesa->fifo.drm.put_base); if(fifo_get <= RING_SKIPS) { if(nmesa->fifo.put <= RING_SKIPS) /* corner case - will be idle */ NV_FIFO_WRITE_PUT(RING_SKIPS + 1); @@ -98,54 +99,54 @@ void nouveauWaitForIdle(nouveauContextPtr nmesa) // here we call the fifo initialization ioctl and fill in stuff accordingly GLboolean nouveauFifoInit(nouveauContextPtr nmesa) { - struct drm_nouveau_channel_alloc fifo_init; int i, ret; #ifdef NOUVEAU_RING_DEBUG return GL_TRUE; #endif - fifo_init.fb_ctxdma_handle = NvDmaFB; - fifo_init.tt_ctxdma_handle = NvDmaTT; - ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_CHANNEL_ALLOC, &fifo_init, sizeof(fifo_init)); + nmesa->fifo.drm.fb_ctxdma_handle = NvDmaFB; + nmesa->fifo.drm.tt_ctxdma_handle = NvDmaTT; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_CHANNEL_ALLOC, + &nmesa->fifo.drm, sizeof(nmesa->fifo.drm)); if (ret) { - FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); + FATAL("Fifo initialization ioctl failed (returned %d)\n", ret); return GL_FALSE; } - ret = drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer); + ret = drmMap(nmesa->driFd, nmesa->fifo.drm.cmdbuf, + nmesa->fifo.drm.cmdbuf_size, &nmesa->fifo.pushbuf); if (ret) { - FATAL("Unable to map the fifo (returned %d)\n",ret); + FATAL("Unable to map the fifo (returned %d)\n", ret); return GL_FALSE; } - ret = drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio); + ret = drmMap(nmesa->driFd, nmesa->fifo.drm.ctrl, + nmesa->fifo.drm.ctrl_size, &nmesa->fifo.mmio); if (ret) { - FATAL("Unable to map the control regs (returned %d)\n",ret); + FATAL("Unable to map the control regs (returned %d)\n", ret); return GL_FALSE; } - ret = drmMap(nmesa->driFd, fifo_init.notifier, - fifo_init.notifier_size, - &nmesa->notifier_block); + ret = drmMap(nmesa->driFd, nmesa->fifo.drm.notifier, + nmesa->fifo.drm.notifier_size, + &nmesa->fifo.notifier_block); if (ret) { - FATAL("Unable to map the notifier block (returned %d)\n",ret); + FATAL("Unable to map the notifier block (returned %d)\n", ret); return GL_FALSE; } /* Setup our initial FIFO tracking params */ - nmesa->fifo.channel = fifo_init.channel; - nmesa->fifo.put_base = fifo_init.put_base; nmesa->fifo.current = 0; nmesa->fifo.put = 0; - nmesa->fifo.max = (fifo_init.cmdbuf_size >> 2) - 1; + nmesa->fifo.max = (nmesa->fifo.drm.cmdbuf_size >> 2) - 1; nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current; for (i=0; ififo.free -= RING_SKIPS; - MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); + MESSAGE("Fifo init ok. Using context %d\n", nmesa->fifo.drm.channel); return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 23325dcea5..956dd549dc 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -48,14 +48,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) #define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value; -#define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2) +#define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.drm.put_base) >> 2) #define NV_FIFO_WRITE_PUT(val) do { \ if (NOUVEAU_RING_TRACE) {\ printf("FIRE_RING : 0x%08x\n", nmesa->fifo.current << 2); \ fflush(stdout); \ sleep(1); \ } \ - NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base); \ + NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.drm.put_base); \ } while(0) /* @@ -110,20 +110,20 @@ nouveau_fifo_remaining-=sz; \ uint32_t* p=(uint32_t*)(ptr); \ int i; printf("OUT_RINGp: (size 0x%x dwords) (%s)\n",sz, __func__); for(i=0;ififo.current+i) << 2, *(p+i), *((float*)(p+i))); \ } \ - memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \ + memcpy(nmesa->fifo.pushbuf+nmesa->fifo.current,ptr,(sz)*4); \ nmesa->fifo.current+=(sz); \ }while(0) #define OUT_RING(n) do { \ if (NOUVEAU_RING_TRACE) \ printf("OUT_RINGn: [0x%08x] 0x%08x (%s)\n", nmesa->fifo.current << 2, n, __func__); \ -nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \ +nmesa->fifo.pushbuf[nmesa->fifo.current++]=(n); \ }while(0) #define OUT_RINGf(n) do { \ if (NOUVEAU_RING_TRACE) \ printf("OUT_RINGf: [0x%08x] %.04f (%s)\n", nmesa->fifo.current << 2, n, __func__); \ -*((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \ +*((float*)(nmesa->fifo.pushbuf+nmesa->fifo.current++))=(n); \ }while(0) #define BEGIN_RING_SIZE(subchannel,tag,size) do { \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index f6ff37848a..aff6954f06 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -10,7 +10,7 @@ GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, struct drm_nouveau_grobj_alloc cto; int ret; - cto.channel = nmesa->fifo.channel; + cto.channel = nmesa->fifo.drm.channel; cto.handle = handle; cto.class = class; ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_GROBJ_ALLOC, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index e7abdd60ee..2ca038f4f8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -37,7 +37,8 @@ #define NOTIFIER(__v) \ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ - volatile uint32_t *__v = (void*)nmesa->notifier_block + notifier->offset + volatile uint32_t *__v = (void*)nmesa->fifo.notifier_block + \ + notifier->offset struct drm_nouveau_notifierobj_alloc * nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) @@ -53,7 +54,7 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) if (!notifier) return NULL; - notifier->channel = nmesa->fifo.channel; + notifier->channel = nmesa->fifo.drm.channel; notifier->handle = handle; notifier->count = count; ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, -- cgit v1.2.3 From c2ac825e67f0c2da4385eadb3e01eeb295ccc8a2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 15 Aug 2007 14:27:46 +1000 Subject: nouveau: Use half the notifier block for query objects. --- src/mesa/drivers/dri/nouveau/nouveau_query.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c index 0154140069..e5c1750a8e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_query.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.c @@ -167,7 +167,8 @@ nouveauQueryInitFuncs(GLcontext *ctx) if (nmesa->screen->card->type < NV_20) return; - nmesa->query_object_max = (0x4000 / 32); + /* Reserve half the notifier block for use as query objects */ + nmesa->query_object_max = (nmesa->fifo.drm.notifier_size / 2) / 32; nmesa->queryNotifier = nouveau_notifier_new(ctx, NvQueryNotify, nmesa->query_object_max); -- cgit v1.2.3 From ab999608582534bb5187a786b2ea437167f2d8a4 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 15 Aug 2007 13:28:00 +0800 Subject: i965: use BRW_TEXCOORDMODE_CLAMP instead of BRW_TEXCOORDMODE_CLAMP_BORDER to implement GL_CLAMP --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 93d4cfc3a5..83a4b02e48 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -54,7 +54,7 @@ static GLuint translate_wrap_mode( GLenum wrap ) case GL_REPEAT: return BRW_TEXCOORDMODE_WRAP; case GL_CLAMP: - return BRW_TEXCOORDMODE_CLAMP_BORDER; /* conform likes it this way */ + return BRW_TEXCOORDMODE_CLAMP; case GL_CLAMP_TO_EDGE: return BRW_TEXCOORDMODE_CLAMP; /* conform likes it this way */ case GL_CLAMP_TO_BORDER: -- cgit v1.2.3 From a6d4dddb38e2342a6f80d7a241f23900b8b4c633 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 16 Aug 2007 02:41:03 +0200 Subject: suppress warning about ncon visuals (bug #6689) --- src/glx/x11/glxext.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index af3a5166dc..8fe10338a8 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -672,8 +672,11 @@ filter_modes( __GLcontextModes ** server_modes, if ( do_delete && (m->visualID != 0) ) { do_delete = GL_FALSE; - fprintf(stderr, "libGL warning: 3D driver claims to not support " - "visual 0x%02x\n", m->visualID); + /* don't warn for this visual (Novell #247471 / X.Org #6689) */ + if (m->visualRating != GLX_NON_CONFORMANT_CONFIG) { + fprintf(stderr, "libGL warning: 3D driver claims to not " + "support visual 0x%02x\n", m->visualID); + } } if ( do_delete ) { -- cgit v1.2.3 From 2193c4de83acfc3268ccca7b54b00543307e0baa Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 16 Aug 2007 08:45:16 +0200 Subject: i915tex: Unreference texture buffers on context destruction. Not doing this could cause the buffers to leak under some circumstances. --- src/mesa/drivers/dri/i915tex/i830_vtbl.c | 10 ++++++++++ src/mesa/drivers/dri/i915tex/i915_vtbl.c | 10 ++++++++++ 2 files changed, 20 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c index a3db6c0c0c..b2a1ba0ce3 100644 --- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -524,6 +524,16 @@ i830_emit_state(struct intel_context *intel) static void i830_destroy_context(struct intel_context *intel) { + GLuint i; + struct i830_context *i830 = i830_context(&intel->ctx); + + for (i = 0; i < I830_TEX_UNITS; i++) { + if (i830->state.tex_buffer[i] != NULL) { + driBOUnReference(i830->state.tex_buffer[i]); + i830->state.tex_buffer[i] = NULL; + } + } + _tnl_free_vertices(&intel->ctx); } diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index ff99721769..1d651a40d7 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -440,6 +440,16 @@ i915_emit_state(struct intel_context *intel) static void i915_destroy_context(struct intel_context *intel) { + GLuint i; + struct i915_context *i915 = i915_context(&intel->ctx); + + for (i = 0; i < I915_TEX_UNITS; i++) { + if (i915->state.tex_buffer[i] != NULL) { + driBOUnReference(i915->state.tex_buffer[i]); + i915->state.tex_buffer[i] = NULL; + } + } + _tnl_free_vertices(&intel->ctx); } -- cgit v1.2.3 From 145d762044f795bf9d68f28079cc5e5d3056920e Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 10:05:00 +0100 Subject: Bring over the texobj refcounting changes from mesa_7_0_branch --- src/mesa/main/attrib.c | 236 +++++++++++++++++++++++++++++++---------------- src/mesa/main/attrib.h | 20 ++-- src/mesa/main/context.c | 5 +- src/mesa/main/texobj.c | 20 +--- src/mesa/main/texstate.c | 46 +++++---- 5 files changed, 202 insertions(+), 125 deletions(-) (limited to 'src') diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 36e438a53c..52e3f22adc 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -51,6 +51,36 @@ #include "math/m_xform.h" +/** + * Special struct for saving/restoring texture state (GL_TEXTURE_BIT) + */ +struct texture_state +{ + struct gl_texture_attrib Texture; /**< The usual context state */ + + /** to save per texture object state (wrap modes, filters, etc): */ + struct gl_texture_object Saved1D[MAX_TEXTURE_UNITS]; + struct gl_texture_object Saved2D[MAX_TEXTURE_UNITS]; + struct gl_texture_object Saved3D[MAX_TEXTURE_UNITS]; + struct gl_texture_object SavedCube[MAX_TEXTURE_UNITS]; + struct gl_texture_object SavedRect[MAX_TEXTURE_UNITS]; + struct gl_texture_object Saved1DArray[MAX_TEXTURE_UNITS]; + struct gl_texture_object Saved2DArray[MAX_TEXTURE_UNITS]; + + /** + * To save references to texture objects (so they don't get accidentally + * deleted while saved in the attribute stack). + */ + struct gl_texture_object *SavedRef1D[MAX_TEXTURE_UNITS]; + struct gl_texture_object *SavedRef2D[MAX_TEXTURE_UNITS]; + struct gl_texture_object *SavedRef3D[MAX_TEXTURE_UNITS]; + struct gl_texture_object *SavedRefCube[MAX_TEXTURE_UNITS]; + struct gl_texture_object *SavedRefRect[MAX_TEXTURE_UNITS]; + struct gl_texture_object *SavedRef1DArray[MAX_TEXTURE_UNITS]; + struct gl_texture_object *SavedRef2DArray[MAX_TEXTURE_UNITS]; +}; + + /** * Allocate a new attribute state node. These nodes have a * "kind" value and a pointer to a struct of state data. @@ -339,47 +369,54 @@ _mesa_PushAttrib(GLbitfield mask) } if (mask & GL_TEXTURE_BIT) { - struct gl_texture_attrib *attr; + struct texture_state *texstate = CALLOC_STRUCT(texture_state); GLuint u; + if (!texstate) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)"); + goto end; + } + _mesa_lock_context_textures(ctx); - /* Bump the texture object reference counts so that they don't - * inadvertantly get deleted. + + /* copy/save the bulk of texture state here */ + _mesa_memcpy(&texstate->Texture, &ctx->Texture, sizeof(ctx->Texture)); + + /* Save references to the currently bound texture objects so they don't + * accidentally get deleted while referenced in the attribute stack. */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - ctx->Texture.Unit[u].Current1D->RefCount++; - ctx->Texture.Unit[u].Current2D->RefCount++; - ctx->Texture.Unit[u].Current3D->RefCount++; - ctx->Texture.Unit[u].CurrentCubeMap->RefCount++; - ctx->Texture.Unit[u].CurrentRect->RefCount++; - ctx->Texture.Unit[u].Current1DArray->RefCount++; - ctx->Texture.Unit[u].Current2DArray->RefCount++; + _mesa_reference_texobj(&texstate->SavedRef1D[u], ctx->Texture.Unit[u].Current1D); + _mesa_reference_texobj(&texstate->SavedRef2D[u], ctx->Texture.Unit[u].Current2D); + _mesa_reference_texobj(&texstate->SavedRef3D[u], ctx->Texture.Unit[u].Current3D); + _mesa_reference_texobj(&texstate->SavedRefCube[u], ctx->Texture.Unit[u].CurrentCubeMap); + _mesa_reference_texobj(&texstate->SavedRefRect[u], ctx->Texture.Unit[u].CurrentRect); + _mesa_reference_texobj(&texstate->SavedRef1DArray[u], ctx->Texture.Unit[u].Current1DArray); + _mesa_reference_texobj(&texstate->SavedRef2DArray[u], ctx->Texture.Unit[u].Current2DArray); } - attr = MALLOC_STRUCT( gl_texture_attrib ); - MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); - /* copy state of the currently bound texture objects */ + /* copy state/contents of the currently bound texture objects */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - _mesa_copy_texture_object(&attr->Unit[u].Saved1D, - attr->Unit[u].Current1D); - _mesa_copy_texture_object(&attr->Unit[u].Saved2D, - attr->Unit[u].Current2D); - _mesa_copy_texture_object(&attr->Unit[u].Saved3D, - attr->Unit[u].Current3D); - _mesa_copy_texture_object(&attr->Unit[u].SavedCubeMap, - attr->Unit[u].CurrentCubeMap); - _mesa_copy_texture_object(&attr->Unit[u].SavedRect, - attr->Unit[u].CurrentRect); - _mesa_copy_texture_object(&attr->Unit[u].Saved1DArray, - attr->Unit[u].Current1DArray); - _mesa_copy_texture_object(&attr->Unit[u].Saved2DArray, - attr->Unit[u].Current2DArray); + _mesa_copy_texture_object(&texstate->Saved1D[u], + ctx->Texture.Unit[u].Current1D); + _mesa_copy_texture_object(&texstate->Saved2D[u], + ctx->Texture.Unit[u].Current2D); + _mesa_copy_texture_object(&texstate->Saved3D[u], + ctx->Texture.Unit[u].Current3D); + _mesa_copy_texture_object(&texstate->SavedCube[u], + ctx->Texture.Unit[u].CurrentCubeMap); + _mesa_copy_texture_object(&texstate->SavedRect[u], + ctx->Texture.Unit[u].CurrentRect); + _mesa_copy_texture_object(&texstate->Saved1DArray[u], + ctx->Texture.Unit[u].Current1DArray); + _mesa_copy_texture_object(&texstate->Saved2DArray[u], + ctx->Texture.Unit[u].Current2DArray); } _mesa_unlock_context_textures(ctx); newnode = new_attrib_node( GL_TEXTURE_BIT ); - newnode->data = attr; + newnode->data = texstate; newnode->next = head; head = newnode; } @@ -415,6 +452,7 @@ _mesa_PushAttrib(GLbitfield mask) head = newnode; } +end: ctx->AttribStack[ctx->AttribStackDepth] = head; ctx->AttribStackDepth++; } @@ -624,14 +662,19 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) } +/** + * Pop/restore texture attribute/group state. + */ static void -pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) +pop_texture_group(GLcontext *ctx, struct texture_state *texstate) { GLuint u; + _mesa_lock_context_textures(ctx); + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - const struct gl_texture_unit *unit = &texAttrib->Unit[u]; - GLuint i; + const struct gl_texture_unit *unit = &texstate->Texture.Unit[u]; + GLuint tgt; _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u); _mesa_set_enable(ctx, GL_TEXTURE_1D, @@ -724,53 +767,56 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) 1 << unit->Combine.ScaleShiftA); } - /* Restore texture object state */ - for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { - GLenum target = 0; + /* Restore texture object state for each target */ + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { const struct gl_texture_object *obj = NULL; GLfloat bordColor[4]; + GLenum target; - switch (i) { - case 0: - target = GL_TEXTURE_1D; - obj = &unit->Saved1D; + switch (tgt) { + case TEXTURE_1D_INDEX: + obj = &texstate->Saved1D[u]; + ASSERT(obj->Target == GL_TEXTURE_1D); break; - case 1: - target = GL_TEXTURE_2D; - obj = &unit->Saved2D; + case TEXTURE_2D_INDEX: + obj = &texstate->Saved2D[u]; + ASSERT(obj->Target == GL_TEXTURE_2D); break; - case 2: - target = GL_TEXTURE_3D; - obj = &unit->Saved3D; + case TEXTURE_3D_INDEX: + obj = &texstate->Saved3D[u]; + ASSERT(obj->Target == GL_TEXTURE_3D); break; - case 3: + case TEXTURE_CUBE_INDEX: if (!ctx->Extensions.ARB_texture_cube_map) continue; - target = GL_TEXTURE_CUBE_MAP_ARB; - obj = &unit->SavedCubeMap; + obj = &texstate->SavedCube[u]; + ASSERT(obj->Target == GL_TEXTURE_CUBE_MAP_ARB); break; - case 4: + case TEXTURE_RECT_INDEX: if (!ctx->Extensions.NV_texture_rectangle) continue; - target = GL_TEXTURE_RECTANGLE_NV; - obj = &unit->SavedRect; + obj = &texstate->SavedRect[u]; + ASSERT(obj->Target == GL_TEXTURE_RECTANGLE_NV); break; - case 5: + case TEXTURE_1D_ARRAY_INDEX: if (!ctx->Extensions.MESA_texture_array) continue; - target = GL_TEXTURE_1D_ARRAY_EXT; - obj = &unit->Saved1DArray; + obj = &texstate->Saved1DArray[u]; + ASSERT(obj->Target == GL_TEXTURE_1D_ARRAY_EXT); break; - case 6: + case TEXTURE_2D_ARRAY_INDEX: if (!ctx->Extensions.MESA_texture_array) continue; - target = GL_TEXTURE_2D_ARRAY_EXT; - obj = &unit->Saved2DArray; + obj = &texstate->Saved2DArray[u]; + ASSERT(obj->Target == GL_TEXTURE_2D_ARRAY_EXT); break; default: - ; /* silence warnings */ + _mesa_problem(ctx, "bad texture index in pop_texture_group"); + continue; } + target = obj->Target; + _mesa_BindTexture(target, obj->Name); bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]); @@ -778,8 +824,8 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]); bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]); - _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority); _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor); + _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority); _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS); _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT); _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR); @@ -805,25 +851,21 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX, obj->ShadowAmbient); } - } - } - _mesa_ActiveTextureARB(GL_TEXTURE0_ARB - + texAttrib->CurrentUnit); - /* "un-bump" the texture object reference counts. We did that so they - * wouldn't inadvertantly get deleted while they were still referenced - * inside the attribute state stack. - */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - ctx->Texture.Unit[u].Current1D->RefCount--; - ctx->Texture.Unit[u].Current2D->RefCount--; - ctx->Texture.Unit[u].Current3D->RefCount--; - ctx->Texture.Unit[u].CurrentCubeMap->RefCount--; - ctx->Texture.Unit[u].CurrentRect->RefCount--; - ctx->Texture.Unit[u].Current1DArray->RefCount--; - ctx->Texture.Unit[u].Current2DArray->RefCount--; + /* remove saved references to the texture objects */ + _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL); + _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL); + _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef1DArray[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef2DArray[u], NULL); } + + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit); + + _mesa_unlock_context_textures(ctx); } @@ -1202,9 +1244,9 @@ _mesa_PopAttrib(void) case GL_TEXTURE_BIT: /* Take care of texture object reference counters */ { - const struct gl_texture_attrib *texture; - texture = (const struct gl_texture_attrib *) attr->data; - pop_texture_group(ctx, texture); + struct texture_state *texstate + = (struct texture_state *) attr->data; + pop_texture_group(ctx, texstate); ctx->NewState |= _NEW_TEXTURE; } break; @@ -1426,6 +1468,46 @@ _mesa_PopClientAttrib(void) } +/** + * Free any attribute state data that might be attached to the context. + */ +void +_mesa_free_attrib_data(GLcontext *ctx) +{ + while (ctx->AttribStackDepth > 0) { + struct gl_attrib_node *attr, *next; + + ctx->AttribStackDepth--; + attr = ctx->AttribStack[ctx->AttribStackDepth]; + + while (attr) { + if (attr->kind == GL_TEXTURE_BIT) { + struct texture_state *texstate = (struct texture_state*)attr->data; + GLuint u; + /* clear references to the saved texture objects */ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL); + _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL); + _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef1DArray[u], NULL); + _mesa_reference_texobj(&texstate->SavedRef2DArray[u], NULL); + } + } + else { + /* any other chunks of state that requires special handling? */ + } + + next = attr->next; + _mesa_free(attr->data); + _mesa_free(attr); + attr = next; + } + } +} + + void _mesa_init_attrib( GLcontext *ctx ) { /* Renderer and client attribute stacks */ diff --git a/src/mesa/main/attrib.h b/src/mesa/main/attrib.h index 09d75196b2..2cf8fe6934 100644 --- a/src/mesa/main/attrib.h +++ b/src/mesa/main/attrib.h @@ -1,18 +1,8 @@ -/** - * \file attrib.h - * Attribute stacks. - * - * \if subset - * (No-op) - * - * \endif - */ - /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 7.1 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -32,8 +22,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - - #ifndef ATTRIB_H #define ATTRIB_H @@ -58,10 +46,14 @@ _mesa_PopClientAttrib( void ); extern void _mesa_init_attrib( GLcontext *ctx ); +extern void +_mesa_free_attrib_data( GLcontext *ctx ); + #else /** No-op */ #define _mesa_init_attrib( c ) ((void)0) +#define _mesa_free_attrib_data( c ) ((void)0) #endif diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 37a14d3004..f3141fe63e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -6,9 +6,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -1209,6 +1209,7 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_unreference_framebuffer(&ctx->DrawBuffer); _mesa_unreference_framebuffer(&ctx->ReadBuffer); + _mesa_free_attrib_data(ctx); _mesa_free_lighting_data( ctx ); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index ea3328a047..3e017c1eda 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -152,10 +152,6 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) { GLuint i, face; - /* - printf("TEX DELETE %p (%u)\n", (void*) texObj, texObj->Name); - */ - (void) ctx; /* Set Target to an invalid value. With some assertions elsewhere @@ -195,6 +191,7 @@ void _mesa_copy_texture_object( struct gl_texture_object *dest, const struct gl_texture_object *src ) { + dest->Target = src->Target; dest->Name = src->Name; dest->Priority = src->Priority; dest->BorderColor[0] = src->BorderColor[0]; @@ -278,10 +275,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, _glthread_LOCK_MUTEX(oldTex->Mutex); ASSERT(oldTex->RefCount > 0); oldTex->RefCount--; - /* - printf("TEX DECR %p (%u) to %d\n", - (void*) oldTex, oldTex->Name, oldTex->RefCount); - */ + deleteFlag = (oldTex->RefCount == 0); _glthread_UNLOCK_MUTEX(oldTex->Mutex); @@ -309,10 +303,6 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, } else { tex->RefCount++; - /* - printf("TEX INCR %p (%u) to %d\n", - (void*) tex, tex->Name, tex->RefCount); - */ *ptr = tex; } _glthread_UNLOCK_MUTEX(tex->Mutex); @@ -805,7 +795,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - /* Unrefernce the texobj. If refcount hits zero, the texture + /* Unreference the texobj. If refcount hits zero, the texture * will be deleted. */ _mesa_reference_texobj(&delObj, NULL); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 08d083d201..91ee6513dc 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -119,20 +119,20 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) /* copy texture object bindings, not contents of texture objects */ _mesa_lock_context_textures(dst); - _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D, - src->Texture.Unit[i].Current1D); - _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D, - src->Texture.Unit[i].Current2D); - _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D, - src->Texture.Unit[i].Current3D); - _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap, - src->Texture.Unit[i].CurrentCubeMap); - _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect, - src->Texture.Unit[i].CurrentRect); - _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray, - src->Texture.Unit[i].Current1DArray); - _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray, - src->Texture.Unit[i].Current2DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D, + src->Texture.Unit[i].Current1D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D, + src->Texture.Unit[i].Current2D); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D, + src->Texture.Unit[i].Current3D); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap, + src->Texture.Unit[i].CurrentCubeMap); + _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect, + src->Texture.Unit[i].CurrentRect); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current1DArray, + src->Texture.Unit[i].Current1DArray); + _mesa_reference_texobj(&dst->Texture.Unit[i].Current2DArray, + src->Texture.Unit[i].Current2DArray); _mesa_unlock_context_textures(dst); } @@ -3201,7 +3201,19 @@ _mesa_init_texture(GLcontext *ctx) void _mesa_free_texture_data(GLcontext *ctx) { - GLuint i; + GLuint u; + + /* unreference current textures */ + for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { + struct gl_texture_unit *unit = ctx->Texture.Unit + u; + _mesa_reference_texobj(&unit->Current1D, NULL); + _mesa_reference_texobj(&unit->Current2D, NULL); + _mesa_reference_texobj(&unit->Current3D, NULL); + _mesa_reference_texobj(&unit->CurrentCubeMap, NULL); + _mesa_reference_texobj(&unit->CurrentRect, NULL); + _mesa_reference_texobj(&unit->Current1DArray, NULL); + _mesa_reference_texobj(&unit->Current2DArray, NULL); + } /* Free proxy texture objects */ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); @@ -3212,8 +3224,8 @@ _mesa_free_texture_data(GLcontext *ctx) (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray ); (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray ); - for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) - _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable ); + for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) + _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable ); _mesa_TexEnvProgramCacheDestroy( ctx ); } -- cgit v1.2.3 From b3e3e72e25247a48c4f154e2971eff48ecb9d9ef Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 10:27:24 +0100 Subject: remove old Saved1D/2D/etc fields --- src/mesa/main/mtypes.h | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 989d199a10..0f578c5616 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1536,17 +1536,6 @@ struct gl_texture_unit struct gl_texture_object *_Current; /**< Points to really enabled tex obj */ - /** These are used for glPush/PopAttrib */ - /*@{*/ - struct gl_texture_object Saved1D; - struct gl_texture_object Saved2D; - struct gl_texture_object Saved3D; - struct gl_texture_object SavedCubeMap; - struct gl_texture_object SavedRect; - struct gl_texture_object Saved1DArray; - struct gl_texture_object Saved2DArray; - /*@}*/ - /** GL_SGI_texture_color_table */ /*@{*/ struct gl_color_table ColorTable; -- cgit v1.2.3 From 0135ff512d25b221d1a4cf9a5d344420d4ad3341 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 10:28:23 +0100 Subject: replace separate 1D/2D/etc fields with an array indexed by texture target --- src/mesa/main/attrib.c | 128 ++++++++++++++++++------------------------------- 1 file changed, 46 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 52e3f22adc..3199c9b426 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -59,25 +59,13 @@ struct texture_state struct gl_texture_attrib Texture; /**< The usual context state */ /** to save per texture object state (wrap modes, filters, etc): */ - struct gl_texture_object Saved1D[MAX_TEXTURE_UNITS]; - struct gl_texture_object Saved2D[MAX_TEXTURE_UNITS]; - struct gl_texture_object Saved3D[MAX_TEXTURE_UNITS]; - struct gl_texture_object SavedCube[MAX_TEXTURE_UNITS]; - struct gl_texture_object SavedRect[MAX_TEXTURE_UNITS]; - struct gl_texture_object Saved1DArray[MAX_TEXTURE_UNITS]; - struct gl_texture_object Saved2DArray[MAX_TEXTURE_UNITS]; + struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; /** * To save references to texture objects (so they don't get accidentally * deleted while saved in the attribute stack). */ - struct gl_texture_object *SavedRef1D[MAX_TEXTURE_UNITS]; - struct gl_texture_object *SavedRef2D[MAX_TEXTURE_UNITS]; - struct gl_texture_object *SavedRef3D[MAX_TEXTURE_UNITS]; - struct gl_texture_object *SavedRefCube[MAX_TEXTURE_UNITS]; - struct gl_texture_object *SavedRefRect[MAX_TEXTURE_UNITS]; - struct gl_texture_object *SavedRef1DArray[MAX_TEXTURE_UNITS]; - struct gl_texture_object *SavedRef2DArray[MAX_TEXTURE_UNITS]; + struct gl_texture_object *SavedTexRef[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; }; @@ -386,30 +374,37 @@ _mesa_PushAttrib(GLbitfield mask) * accidentally get deleted while referenced in the attribute stack. */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - _mesa_reference_texobj(&texstate->SavedRef1D[u], ctx->Texture.Unit[u].Current1D); - _mesa_reference_texobj(&texstate->SavedRef2D[u], ctx->Texture.Unit[u].Current2D); - _mesa_reference_texobj(&texstate->SavedRef3D[u], ctx->Texture.Unit[u].Current3D); - _mesa_reference_texobj(&texstate->SavedRefCube[u], ctx->Texture.Unit[u].CurrentCubeMap); - _mesa_reference_texobj(&texstate->SavedRefRect[u], ctx->Texture.Unit[u].CurrentRect); - _mesa_reference_texobj(&texstate->SavedRef1DArray[u], ctx->Texture.Unit[u].Current1DArray); - _mesa_reference_texobj(&texstate->SavedRef2DArray[u], ctx->Texture.Unit[u].Current2DArray); + _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_1D_INDEX], + ctx->Texture.Unit[u].Current1D); + _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_2D_INDEX], + ctx->Texture.Unit[u].Current2D); + _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_3D_INDEX], + ctx->Texture.Unit[u].Current3D); + _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_CUBE_INDEX], + ctx->Texture.Unit[u].CurrentCubeMap); + _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_RECT_INDEX], + ctx->Texture.Unit[u].CurrentRect); + _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_1D_ARRAY_INDEX], + ctx->Texture.Unit[u].Current1DArray); + _mesa_reference_texobj(&texstate->SavedTexRef[u][TEXTURE_2D_ARRAY_INDEX], + ctx->Texture.Unit[u].Current2DArray); } /* copy state/contents of the currently bound texture objects */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - _mesa_copy_texture_object(&texstate->Saved1D[u], + _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_1D_INDEX], ctx->Texture.Unit[u].Current1D); - _mesa_copy_texture_object(&texstate->Saved2D[u], + _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_2D_INDEX], ctx->Texture.Unit[u].Current2D); - _mesa_copy_texture_object(&texstate->Saved3D[u], + _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_3D_INDEX], ctx->Texture.Unit[u].Current3D); - _mesa_copy_texture_object(&texstate->SavedCube[u], + _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_CUBE_INDEX], ctx->Texture.Unit[u].CurrentCubeMap); - _mesa_copy_texture_object(&texstate->SavedRect[u], + _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_RECT_INDEX], ctx->Texture.Unit[u].CurrentRect); - _mesa_copy_texture_object(&texstate->Saved1DArray[u], + _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_1D_ARRAY_INDEX], ctx->Texture.Unit[u].Current1DArray); - _mesa_copy_texture_object(&texstate->Saved2DArray[u], + _mesa_copy_texture_object(&texstate->SavedObj[u][TEXTURE_2D_ARRAY_INDEX], ctx->Texture.Unit[u].Current2DArray); } @@ -773,45 +768,22 @@ pop_texture_group(GLcontext *ctx, struct texture_state *texstate) GLfloat bordColor[4]; GLenum target; - switch (tgt) { - case TEXTURE_1D_INDEX: - obj = &texstate->Saved1D[u]; - ASSERT(obj->Target == GL_TEXTURE_1D); - break; - case TEXTURE_2D_INDEX: - obj = &texstate->Saved2D[u]; - ASSERT(obj->Target == GL_TEXTURE_2D); - break; - case TEXTURE_3D_INDEX: - obj = &texstate->Saved3D[u]; - ASSERT(obj->Target == GL_TEXTURE_3D); - break; - case TEXTURE_CUBE_INDEX: - if (!ctx->Extensions.ARB_texture_cube_map) - continue; - obj = &texstate->SavedCube[u]; - ASSERT(obj->Target == GL_TEXTURE_CUBE_MAP_ARB); - break; - case TEXTURE_RECT_INDEX: - if (!ctx->Extensions.NV_texture_rectangle) - continue; - obj = &texstate->SavedRect[u]; - ASSERT(obj->Target == GL_TEXTURE_RECTANGLE_NV); - break; - case TEXTURE_1D_ARRAY_INDEX: - if (!ctx->Extensions.MESA_texture_array) - continue; - obj = &texstate->Saved1DArray[u]; - ASSERT(obj->Target == GL_TEXTURE_1D_ARRAY_EXT); - break; - case TEXTURE_2D_ARRAY_INDEX: - if (!ctx->Extensions.MESA_texture_array) - continue; - obj = &texstate->Saved2DArray[u]; - ASSERT(obj->Target == GL_TEXTURE_2D_ARRAY_EXT); - break; - default: - _mesa_problem(ctx, "bad texture index in pop_texture_group"); + obj = &texstate->SavedObj[u][tgt]; + + /* don't restore state for unsupported targets to prevent + * raising GL errors. + */ + if (obj->Target == GL_TEXTURE_CUBE_MAP_ARB && + !ctx->Extensions.ARB_texture_cube_map) { + continue; + } + else if (obj->Target == GL_TEXTURE_RECTANGLE_NV && + !ctx->Extensions.NV_texture_rectangle) { + continue; + } + else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT || + obj->Target == GL_TEXTURE_2D_ARRAY_EXT) && + !ctx->Extensions.MESA_texture_array) { continue; } @@ -854,13 +826,9 @@ pop_texture_group(GLcontext *ctx, struct texture_state *texstate) } /* remove saved references to the texture objects */ - _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL); - _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL); - _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef1DArray[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef2DArray[u], NULL); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { + _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL); + } } _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + texstate->Texture.CurrentUnit); @@ -1483,16 +1451,12 @@ _mesa_free_attrib_data(GLcontext *ctx) while (attr) { if (attr->kind == GL_TEXTURE_BIT) { struct texture_state *texstate = (struct texture_state*)attr->data; - GLuint u; + GLuint u, tgt; /* clear references to the saved texture objects */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - _mesa_reference_texobj(&texstate->SavedRef1D[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef2D[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef3D[u], NULL); - _mesa_reference_texobj(&texstate->SavedRefCube[u], NULL); - _mesa_reference_texobj(&texstate->SavedRefRect[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef1DArray[u], NULL); - _mesa_reference_texobj(&texstate->SavedRef2DArray[u], NULL); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { + _mesa_reference_texobj(&texstate->SavedTexRef[u][tgt], NULL); + } } } else { -- cgit v1.2.3 From fe469007037d9d5cdbe1677d8ff7368b276e9e7c Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 11:06:13 +0100 Subject: Replace Proxy1D/2D/etc with ProxyTex[] indexed by TEXTURE_x_INDEX. Simplification in colortab.c too. --- src/mesa/drivers/dri/tdfx/tdfx_tex.c | 2 +- src/mesa/main/colortab.c | 306 +++++++++++------------------------ src/mesa/main/mtypes.h | 4 + src/mesa/main/teximage.c | 58 +++---- src/mesa/main/texstate.c | 81 ++++------ 5 files changed, 154 insertions(+), 297 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index 89865d9637..64946385b6 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -1822,7 +1822,7 @@ tdfxTestProxyTexImage(GLcontext *ctx, GLenum target, tdfxTexInfo *ti; int memNeeded; - tObj = ctx->Texture.Proxy2D; + tObj = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; if (!tObj->DriverData) tObj->DriverData = fxAllocTexObjData(fxMesa); ti = TDFX_TEXTURE_DATA(tObj); diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c index 610acba306..97120398f9 100644 --- a/src/mesa/main/colortab.c +++ b/src/mesa/main/colortab.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -30,6 +30,7 @@ #include "image.h" #include "macros.h" #include "state.h" +#include "teximage.h" /** @@ -305,49 +306,6 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ switch (target) { - case GL_TEXTURE_1D: - texObj = texUnit->Current1D; - table = &texObj->Palette; - break; - case GL_TEXTURE_2D: - texObj = texUnit->Current2D; - table = &texObj->Palette; - break; - case GL_TEXTURE_3D: - texObj = texUnit->Current3D; - table = &texObj->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; - } - texObj = texUnit->CurrentCubeMap; - table = &texObj->Palette; - break; - case GL_PROXY_TEXTURE_1D: - texObj = ctx->Texture.Proxy1D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_2D: - texObj = ctx->Texture.Proxy2D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_3D: - texObj = ctx->Texture.Proxy3D; - table = &texObj->Palette; - proxy = GL_TRUE; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; - } - texObj = ctx->Texture.ProxyCubeMap; - table = &texObj->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -396,8 +354,19 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat, proxy = GL_TRUE; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + proxy = _mesa_is_proxy_texture(target); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); + return; + } + } } assert(table); @@ -499,26 +468,6 @@ _mesa_ColorSubTable( GLenum target, GLsizei start, ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { - case GL_TEXTURE_1D: - texObj = texUnit->Current1D; - table = &texObj->Palette; - break; - case GL_TEXTURE_2D: - texObj = texUnit->Current2D; - table = &texObj->Palette; - break; - case GL_TEXTURE_3D: - texObj = texUnit->Current3D; - table = &texObj->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); - return; - } - texObj = texUnit->CurrentCubeMap; - table = &texObj->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -547,8 +496,15 @@ _mesa_ColorSubTable( GLenum target, GLsizei start, bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); - return; + /* try texture targets */ + texObj = _mesa_select_tex_object(ctx, texUnit, target); + if (texObj && !_mesa_is_proxy_texture(target)) { + table = &texObj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); + return; + } } assert(table); @@ -636,22 +592,6 @@ _mesa_GetColorTable( GLenum target, GLenum format, } switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -672,8 +612,18 @@ _mesa_GetColorTable( GLenum target, GLenum format, table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj && !_mesa_is_proxy_texture(target)) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); + return; + } + } } ASSERT(table); @@ -781,65 +731,41 @@ _mesa_GetColorTable( GLenum target, GLenum format, void GLAPIENTRY _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) { + GLfloat *scale, *bias; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); switch (target) { - case GL_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_TEXTURE_COLOR_TABLE_SGI: - if (!ctx->Extensions.SGI_texture_color_table) { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); - return; - } - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.TextureColorTableScale, params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.TextureColorTableBias, params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: - if (pname == GL_COLOR_TABLE_SCALE_SGI) { - COPY_4V(ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX], params); - } - else if (pname == GL_COLOR_TABLE_BIAS_SGI) { - COPY_4V(ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX], params); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); - return; - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); - return; + case GL_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; + break; + case GL_TEXTURE_COLOR_TABLE_SGI: + scale = ctx->Pixel.TextureColorTableScale; + bias = ctx->Pixel.TextureColorTableBias; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; + bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); + return; + } + + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + COPY_4V(scale, params); + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + COPY_4V(bias, params); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); + return; } ctx->NewState |= _NEW_PIXEL; @@ -879,40 +805,6 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameterfv(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; - case GL_PROXY_TEXTURE_1D: - table = &ctx->Texture.Proxy1D->Palette; - break; - case GL_PROXY_TEXTURE_2D: - table = &ctx->Texture.Proxy2D->Palette; - break; - case GL_PROXY_TEXTURE_3D: - table = &ctx->Texture.Proxy3D->Palette; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameterfv(target)"); - return; - } - table = &ctx->Texture.ProxyCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -981,8 +873,19 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)"); - return; + /* try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetColorTableParameterfv(target)"); + return; + } + } } assert(table); @@ -1029,40 +932,6 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) ASSERT_OUTSIDE_BEGIN_END(ctx); switch (target) { - case GL_TEXTURE_1D: - table = &texUnit->Current1D->Palette; - break; - case GL_TEXTURE_2D: - table = &texUnit->Current2D->Palette; - break; - case GL_TEXTURE_3D: - table = &texUnit->Current3D->Palette; - break; - case GL_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameteriv(target)"); - return; - } - table = &texUnit->CurrentCubeMap->Palette; - break; - case GL_PROXY_TEXTURE_1D: - table = &ctx->Texture.Proxy1D->Palette; - break; - case GL_PROXY_TEXTURE_2D: - table = &ctx->Texture.Proxy2D->Palette; - break; - case GL_PROXY_TEXTURE_3D: - table = &ctx->Texture.Proxy3D->Palette; - break; - case GL_PROXY_TEXTURE_CUBE_MAP_ARB: - if (!ctx->Extensions.ARB_texture_cube_map) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetColorTableParameteriv(target)"); - return; - } - table = &ctx->Texture.ProxyCubeMap->Palette; - break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; @@ -1161,8 +1030,19 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)"); - return; + /* Try texture targets */ + { + struct gl_texture_object *texobj + = _mesa_select_tex_object(ctx, texUnit, target); + if (texobj) { + table = &texobj->Palette; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetColorTableParameteriv(target)"); + return; + } + } } assert(table); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 0f578c5616..a04815a021 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1576,6 +1576,7 @@ struct gl_texture_attrib struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; +#if 0 struct gl_texture_object *Proxy1D; struct gl_texture_object *Proxy2D; struct gl_texture_object *Proxy3D; @@ -1583,6 +1584,9 @@ struct gl_texture_attrib struct gl_texture_object *ProxyRect; struct gl_texture_object *Proxy1DArray; struct gl_texture_object *Proxy2DArray; +#else + struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; +#endif /** GL_EXT_shared_texture_palette */ GLboolean SharedPalette; diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 3420d8e2ba..56322f87af 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -760,15 +760,15 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, case GL_TEXTURE_1D: return texUnit->Current1D; case GL_PROXY_TEXTURE_1D: - return ctx->Texture.Proxy1D; + return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; case GL_TEXTURE_2D: return texUnit->Current2D; case GL_PROXY_TEXTURE_2D: - return ctx->Texture.Proxy2D; + return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; case GL_TEXTURE_3D: return texUnit->Current3D; case GL_PROXY_TEXTURE_3D: - return ctx->Texture.Proxy3D; + return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: @@ -780,25 +780,25 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, ? texUnit->CurrentCubeMap : NULL; case GL_PROXY_TEXTURE_CUBE_MAP_ARB: return ctx->Extensions.ARB_texture_cube_map - ? ctx->Texture.ProxyCubeMap : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; case GL_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle ? texUnit->CurrentRect : NULL; case GL_PROXY_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle - ? ctx->Texture.ProxyRect : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; case GL_TEXTURE_1D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array ? texUnit->Current1DArray : NULL; case GL_PROXY_TEXTURE_1D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array - ? ctx->Texture.Proxy1DArray : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; case GL_TEXTURE_2D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array ? texUnit->Current2DArray : NULL; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: return ctx->Extensions.MESA_texture_array - ? ctx->Texture.Proxy2DArray : NULL; + ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; default: _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); return NULL; @@ -924,106 +924,106 @@ _mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level) case GL_PROXY_TEXTURE_1D: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy1D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy1D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy1D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_2D: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy2D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy2D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy2D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_3D: if (level >= ctx->Const.Max3DTextureLevels) return NULL; - texImage = ctx->Texture.Proxy3D->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy3D->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy3D; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; } return texImage; case GL_PROXY_TEXTURE_CUBE_MAP: if (level >= ctx->Const.MaxCubeTextureLevels) return NULL; - texImage = ctx->Texture.ProxyCubeMap->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.ProxyCubeMap->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.ProxyCubeMap; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]; } return texImage; case GL_PROXY_TEXTURE_RECTANGLE_NV: if (level > 0) return NULL; - texImage = ctx->Texture.ProxyRect->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.ProxyRect->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.ProxyRect; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX]; } return texImage; case GL_PROXY_TEXTURE_1D_ARRAY_EXT: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy1DArray->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy1DArray->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy1DArray; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX]; } return texImage; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: if (level >= ctx->Const.MaxTextureLevels) return NULL; - texImage = ctx->Texture.Proxy2DArray->Image[0][level]; + texImage = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level]; if (!texImage) { texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; } - ctx->Texture.Proxy2DArray->Image[0][level] = texImage; + ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]->Image[0][level] = texImage; /* Set the 'back' pointer */ - texImage->TexObject = ctx->Texture.Proxy2DArray; + texImage->TexObject = ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX]; } return texImage; default: @@ -2591,7 +2591,7 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 1, border)) { /* when error, clear all proxy texture image parameters */ if (texImage) - clear_teximage_fields(ctx->Texture.Proxy2D->Image[0][level]); + clear_teximage_fields(ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]->Image[0][level]); } else { /* no error, set the tex image parameters */ diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 91ee6513dc..020e3eef4c 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -3060,54 +3060,32 @@ _mesa_update_texture( GLcontext *ctx, GLuint new_state ) static GLboolean alloc_proxy_textures( GLcontext *ctx ) { - ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); - if (!ctx->Texture.Proxy1D) - goto cleanup; - - ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D); - if (!ctx->Texture.Proxy2D) - goto cleanup; - - ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D); - if (!ctx->Texture.Proxy3D) - goto cleanup; - - ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB); - if (!ctx->Texture.ProxyCubeMap) - goto cleanup; - - ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV); - if (!ctx->Texture.ProxyRect) - goto cleanup; - - ctx->Texture.Proxy1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT); - if (!ctx->Texture.Proxy1DArray) - goto cleanup; - - ctx->Texture.Proxy2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT); - if (!ctx->Texture.Proxy2DArray) - goto cleanup; - - assert(ctx->Texture.Proxy1D->RefCount == 1); + static const GLenum targets[] = { + GL_TEXTURE_1D, + GL_TEXTURE_2D, + GL_TEXTURE_3D, + GL_TEXTURE_CUBE_MAP_ARB, + GL_TEXTURE_RECTANGLE_NV, + GL_TEXTURE_1D_ARRAY_EXT, + GL_TEXTURE_2D_ARRAY_EXT + }; + GLint tgt; + + ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS); + + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { + if (!(ctx->Texture.ProxyTex[tgt] + = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) { + /* out of memory, free what we did allocate */ + while (--tgt >= 0) { + ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); + } + return GL_FALSE; + } + } + assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */ return GL_TRUE; - - cleanup: - if (ctx->Texture.Proxy1D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D); - if (ctx->Texture.Proxy2D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D); - if (ctx->Texture.Proxy3D) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D); - if (ctx->Texture.ProxyCubeMap) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap); - if (ctx->Texture.ProxyRect) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect); - if (ctx->Texture.Proxy1DArray) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray); - if (ctx->Texture.Proxy2DArray) - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray); - return GL_FALSE; } @@ -3201,7 +3179,7 @@ _mesa_init_texture(GLcontext *ctx) void _mesa_free_texture_data(GLcontext *ctx) { - GLuint u; + GLuint u, tgt; /* unreference current textures */ for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { @@ -3216,13 +3194,8 @@ _mesa_free_texture_data(GLcontext *ctx) } /* Free proxy texture objects */ - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray ); - (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray ); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) + ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable ); -- cgit v1.2.3 From 09867b53a9add9c1a392ad46f850d40d50bbc536 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 11:06:39 +0100 Subject: replace Proxy1D/2D/etc fields with ProxyTex[] array --- src/mesa/main/mtypes.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'src') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index a04815a021..1145f361b1 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1576,17 +1576,8 @@ struct gl_texture_attrib struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; -#if 0 - struct gl_texture_object *Proxy1D; - struct gl_texture_object *Proxy2D; - struct gl_texture_object *Proxy3D; - struct gl_texture_object *ProxyCubeMap; - struct gl_texture_object *ProxyRect; - struct gl_texture_object *Proxy1DArray; - struct gl_texture_object *Proxy2DArray; -#else + /** Proxy texture objects */ struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS]; -#endif /** GL_EXT_shared_texture_palette */ GLboolean SharedPalette; -- cgit v1.2.3 From c5a5d12743b4921ab9c01ee69fa6a06b6b4d716a Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 16:43:31 +0100 Subject: remove reference to ctx->Color.DrawBuffer --- src/mesa/swrast/s_span.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index cfc65bee87..bbde0025f4 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -873,7 +873,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) #endif /* we have to wait until after occlusion to do this test */ - if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) { + if (ctx->Color.IndexMask == 0) { /* write no pixels */ span->arrayMask = origArrayMask; return; -- cgit v1.2.3 From c033ccc36d08c669dcdfbfc1cf89e472e8211c5f Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 16:49:35 +0100 Subject: update comments, etc related to Read/DrawBuffer state --- src/mesa/main/buffers.c | 7 +++++-- src/mesa/main/framebuffer.c | 46 +++++++++++++++++++++++++++------------------ 2 files changed, 33 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 0e6ca8ea1c..82dd059e4b 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -479,9 +479,12 @@ set_color_output(GLcontext *ctx, GLuint output, GLenum buffer, /* not really needed, will be set later */ fb->_NumColorDrawBuffers[output] = 0; - if (fb->Name == 0) - /* Set traditional state var */ + if (fb->Name == 0) { + /* Only set the per-context DrawBuffer state if we're currently + * drawing to a window system framebuffer. + */ ctx->Color.DrawBuffer[output] = buffer; + } } diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 0a6de12fb8..72d85f6f89 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -138,7 +138,7 @@ _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) /* save the visual */ fb->Visual = *visual; - /* Init glRead/DrawBuffer state */ + /* Init read/draw renderbuffer state */ if (visual->doubleBufferMode) { fb->ColorDrawBuffer[0] = GL_BACK; fb->_ColorDrawBufferMask[0] = BUFFER_BIT_BACK_LEFT; @@ -649,6 +649,22 @@ update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb) } +/** + * Update a gl_framebuffer's derived state. + * + * Specifically, update these framebuffer fields: + * _ColorDrawBuffers + * _NumColorDrawBuffers + * _ColorReadBuffer + * _DepthBuffer + * _StencilBuffer + * + * If the framebuffer is user-created, make sure it's complete. + * + * The following functions (at least) can effect framebuffer state: + * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT, + * glRenderbufferStorageEXT. + */ static void update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) { @@ -660,8 +676,11 @@ update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) _mesa_update_framebuffer_visual(fb); } - /* update_color_draw/read_buffers not needed for - read/draw only fb, but shouldn't hurt ??? */ + /* Strictly speaking, we don't need to update the draw-state + * if this FB is bound as ctx->ReadBuffer (and conversely, the + * read-state if this FB is bound as ctx->DrawBuffer), but no + * harm. + */ update_color_draw_buffers(ctx, fb); update_color_read_buffer(ctx, fb); _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); @@ -670,28 +689,19 @@ update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) compute_depth_max(fb); } + /** * Update state related to the current draw/read framebuffers. - * Specifically, update these framebuffer fields: - * _ColorDrawBuffers - * _NumColorDrawBuffers - * _ColorReadBuffer - * _DepthBuffer - * _StencilBuffer - * If the current framebuffer is user-created, make sure it's complete. - * The following functions can effect this state: glReadBuffer, - * glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT, - * glRenderbufferStorageEXT. */ void _mesa_update_framebuffer(GLcontext *ctx) { - struct gl_framebuffer *fb = ctx->DrawBuffer; - struct gl_framebuffer *fbread = ctx->ReadBuffer; + struct gl_framebuffer *drawFb = ctx->DrawBuffer; + struct gl_framebuffer *readFb = ctx->ReadBuffer; - update_framebuffer(ctx, fb); - if (fbread != fb) - update_framebuffer(ctx, fbread); + update_framebuffer(ctx, drawFb); + if (readFb != drawFb) + update_framebuffer(ctx, readFb); } -- cgit v1.2.3 From 32d86eb28aedd01a03ceab746214a8db2a4cbbab Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 16 Aug 2007 18:52:48 +0100 Subject: Rework the GL_READ_BUFFER, GL_DRAW_BUFFER state repairs that Roland previously did. Basically, in update_framebuffer() (which should be called after an FBO is bound with MakeCurrent or BindFramebuffer) we check if the FBO is a window-system FBO. If it is, update the FBO's GL_READ/DRAW_BUFFER state according to the context state. Old code still in place but disabled with #if 0 / #endif. --- src/mesa/main/buffers.c | 86 ++++++++++++++++++++++++++++++++++++++++++--- src/mesa/main/buffers.h | 9 +++-- src/mesa/main/context.c | 7 ++++ src/mesa/main/fbobject.c | 21 ++++++++--- src/mesa/main/framebuffer.c | 26 ++++++++++---- 5 files changed, 131 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 82dd059e4b..94b4be54d5 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -336,6 +336,20 @@ read_buffer_enum_to_index(GLenum buffer) * \sa _mesa_DrawBuffersARB * * \param buffer buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc. + * + * Note that the behaviour of this function depends on whether the + * current ctx->DrawBuffer is a window-system framebuffer (Name=0) or + * a user-created framebuffer object (Name!=0). + * In the former case, we update the per-context ctx->Color.DrawBuffer + * state var _and_ the FB's ColorDrawBuffer state. + * In the later case, we update the FB's ColorDrawBuffer state only. + * + * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the + * new FB is a window system FB, we need to re-update the FB's + * ColorDrawBuffer state to match the context. This is handled in + * _mesa_update_framebuffer(). + * + * See the GL_EXT_framebuffer_object spec for more info. */ void GLAPIENTRY _mesa_DrawBuffer(GLenum buffer) @@ -489,10 +503,12 @@ set_color_output(GLcontext *ctx, GLuint output, GLenum buffer, /** - * Helper routine used by _mesa_DrawBuffer, _mesa_DrawBuffersARB and - * other places (window fbo fixup) to set fbo (and the old ctx) fields. + * Helper function to set the GL_DRAW_BUFFER state in the context and + * current FBO. + * * All error checking will have been done prior to calling this function * so nothing should go wrong at this point. + * * \param ctx current context * \param n number of color outputs to set * \param buffers array[n] of colorbuffer names, like GL_LEFT. @@ -532,6 +548,7 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, } +#if 0 GLboolean _mesa_readbuffer_update_fields(GLcontext *ctx, GLenum buffer) { @@ -563,13 +580,45 @@ _mesa_readbuffer_update_fields(GLcontext *ctx, GLenum buffer) } if (fb->Name == 0) { + /* Only update the per-context GL_READ_BUFFER state if we're bound to + * a window-system framebuffer. + */ ctx->Pixel.ReadBuffer = buffer; } + + /* Set the FBO's GL_READ_BUFFER state */ fb->ColorReadBuffer = buffer; fb->_ColorReadBufferIndex = srcBuffer; return GL_TRUE; } +#endif + + +/** + * Like \sa _mesa_drawbuffers(), this is a helper function for setting + * GL_READ_BUFFER state in the context and current FBO. + * \param ctx the rendering context + * \param buffer GL_FRONT, GL_BACK, GL_COLOR_ATTACHMENT0, etc. + * \param bufferIndex the numerical index corresponding to 'buffer' + */ +void +_mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex) +{ + struct gl_framebuffer *fb = ctx->ReadBuffer; + + if (fb->Name == 0) { + /* Only update the per-context READ_BUFFER state if we're bound to + * a window-system framebuffer. + */ + ctx->Pixel.ReadBuffer = buffer; + } + + fb->ColorReadBuffer = buffer; + fb->_ColorReadBufferIndex = bufferIndex; + + ctx->NewState |= _NEW_PIXEL; +} @@ -580,16 +629,43 @@ _mesa_readbuffer_update_fields(GLcontext *ctx, GLenum buffer) void GLAPIENTRY _mesa_ReadBuffer(GLenum buffer) { + struct gl_framebuffer *fb; + GLbitfield supportedMask; + GLint srcBuffer; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); - if (!_mesa_readbuffer_update_fields(ctx, buffer)) - return; + fb = ctx->ReadBuffer; - ctx->NewState |= _NEW_PIXEL; + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); + + if (fb->Name > 0 && buffer == GL_NONE) { + /* This is legal for user-created framebuffer objects */ + srcBuffer = -1; + } + else { + /* general case / window-system framebuffer */ + srcBuffer = read_buffer_enum_to_index(buffer); + if (srcBuffer == -1) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glReadBuffer(buffer=0x%x)", buffer); + return; + } + supportedMask = supported_buffer_bitmask(ctx, fb); + if (((1 << srcBuffer) & supportedMask) == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glReadBuffer(buffer=0x%x)", buffer); + return; + } + } + + /* OK, all error checking has been completed now */ + + _mesa_readbuffer(ctx, buffer, srcBuffer); /* * Call device driver function. diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h index 208e7af2b9..e7228a6da6 100644 --- a/src/mesa/main/buffers.h +++ b/src/mesa/main/buffers.h @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -56,8 +56,13 @@ extern void _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, const GLbitfield *destMask); +extern void +_mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex); + +#if 0 extern GLboolean _mesa_readbuffer_update_fields(GLcontext *ctx, GLenum buffer); +#endif extern void GLAPIENTRY _mesa_ReadBuffer( GLenum mode ); diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index f3141fe63e..9ee7b4bec7 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1530,6 +1530,7 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, */ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); +#if 000 /* fix up the fb fields - these will end up wrong otherwise if the DRIdrawable changes, and everything relies on them. This is a bit messy (same as needed in _mesa_BindFramebufferEXT) */ @@ -1539,12 +1540,18 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, buffers[i] = newCtx->Color.DrawBuffer[i]; } _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers, buffers, NULL); +#endif } if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); +#if 00 _mesa_readbuffer_update_fields(newCtx, newCtx->Pixel.ReadBuffer); +#endif } + /* XXX only set this flag if we're really changing the draw/read + * framebuffer bindings. + */ newCtx->NewState |= _NEW_BUFFERS; #if 1 diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index fcb620b39d..5cd18d0287 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -962,9 +962,11 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) } FLUSH_VERTICES(ctx, _NEW_BUFFERS); + if (ctx->Driver.Flush) { ctx->Driver.Flush(ctx); } + if (framebuffer) { /* Binding a user-created framebuffer object */ newFb = _mesa_lookup_framebuffer(ctx, framebuffer); @@ -998,34 +1000,43 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) * XXX check if re-binding same buffer and skip some of this code. */ +#if 000 /* for window-framebuffers, re-initialize the fbo values, as they could be wrong (makecurrent with a new drawable while still a fbo was bound will lead to default init fbo values). note that therefore the context ReadBuffer/DrawBuffer values are not valid while fbo's are bound!!! */ +#endif if (bindReadBuf) { _mesa_reference_framebuffer(&ctx->ReadBuffer, newFbread); +#if 000 if (!newFbread->Name) { _mesa_readbuffer_update_fields(ctx, ctx->Pixel.ReadBuffer); } +#endif } if (bindDrawBuf) { /* check if old FB had any texture attachments */ check_end_texture_render(ctx, ctx->DrawBuffer); + /* check if time to delete this framebuffer */ _mesa_reference_framebuffer(&ctx->DrawBuffer, newFb); - if (!newFb->Name) { + + if (newFb->Name != 0) { + /* check if newly bound framebuffer has any texture attachments */ + check_begin_texture_render(ctx, newFb); + } + else { + /* XXX try to remove this: */ +#if 000 GLuint i; GLenum buffers[MAX_DRAW_BUFFERS]; for(i = 0; i < ctx->Const.MaxDrawBuffers; i++) { buffers[i] = ctx->Color.DrawBuffer[i]; } _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL); - } - else { - /* check if newly bound framebuffer has any texture attachments */ - check_begin_texture_render(ctx, newFb); +#endif } } diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 72d85f6f89..3e36197d88 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -32,6 +32,7 @@ #include "glheader.h" #include "imports.h" +#include "buffers.h" #include "context.h" #include "depthstencil.h" #include "mtypes.h" @@ -583,7 +584,7 @@ _mesa_update_stencil_buffer(GLcontext *ctx, /** - * Update the list of color drawing renderbuffer pointers. + * Update the (derived) list of color drawing renderbuffer pointers. * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers * writing colors. */ @@ -627,7 +628,7 @@ update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb) /** - * Update the color read renderbuffer pointer. + * Update the (derived) color read renderbuffer pointer. * Unlike the DrawBuffer, we can only read from one (or zero) color buffers. */ static void @@ -668,10 +669,23 @@ update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb) static void update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) { - /* Completeness only matters for user-created framebuffers */ - if (fb->Name != 0) { - /* XXX: EXT_framebuffer_blit: - framebuffer must still be complete wrt read/draw? */ + if (fb->Name == 0) { + /* This is a window-system framebuffer */ + /* Need to update the FB's GL_DRAW_BUFFER state to match the + * context state (GL_READ_BUFFER too). + */ + if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) { + _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, + ctx->Color.DrawBuffer, NULL); + } + if (fb->ColorReadBuffer != ctx->Pixel.ReadBuffer) { + + } + } + else { + /* This is a user-created framebuffer. + * Completeness only matters for user-created framebuffers. + */ _mesa_test_framebuffer_completeness(ctx, fb); _mesa_update_framebuffer_visual(fb); } -- cgit v1.2.3 From f5ed049655d214a8828d5ce68651741c3dff0c66 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 16 Aug 2007 20:53:29 +0200 Subject: nouveau: nv10: create objects needed to clear buffer --- src/mesa/drivers/dri/nouveau/nouveau_object.c | 33 +++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_object.h | 6 +++++ 2 files changed, 39 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index aff6954f06..4169530be6 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -43,6 +43,11 @@ void nouveauObjectInit(nouveauContextPtr nmesa) } else { nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT); } + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->typescreen->card->type>=NV_10) && (nmesa->screen->card->type Date: Thu, 16 Aug 2007 21:28:40 +0200 Subject: nouveau: store render buffer pointers in context, to access them when clearing buffer --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 4 ++++ src/mesa/drivers/dri/nouveau/nv10_state.c | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index dc904ad6b3..65ecf21cab 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -123,6 +123,10 @@ typedef struct nouveau_context { struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; + /* Color and depth renderbuffers */ + nouveau_renderbuffer_t *color_buffer[2]; + nouveau_renderbuffer_t *depth_buffer; + /* Color buffer clear value */ uint32_t clear_color_value; diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 0e1637015f..2183fc1577 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -715,6 +715,11 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, GLuint x, y, w, h; GLuint pitch, format, depth_pitch; + /* Store buffer pointers in context */ + nmesa->color_buffer[0] = color[0]; + nmesa->color_buffer[1] = color[1]; + nmesa->depth_buffer = depth; + w = color[0]->mesa.Width; h = color[0]->mesa.Height; x = nmesa->drawX; -- cgit v1.2.3 From a60695ebafcdf048ce13d5195e74f8b7d1fff8d8 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 16 Aug 2007 21:31:30 +0200 Subject: nouveau: nv10: add function to clear a buffer --- src/mesa/drivers/dri/nouveau/nv10_state.c | 32 ++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 2183fc1577..0c746325c6 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -111,11 +111,41 @@ static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac OUT_RING_CACHE(dfactorRGB); } -static void nv10Clear(GLcontext *ctx, GLbitfield mask) +static void nv10ClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer, int fill, int mask) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (!buffer) { + return; + } + /* TODO */ } +static void nv10Clear(GLcontext *ctx, GLbitfield mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (mask & (BUFFER_BIT_FRONT_LEFT)) { + nv10ClearBuffer(ctx, nmesa->color_buffer[0], + nmesa->clear_color_value, 0xffffffff); + } + if (mask & (BUFFER_BIT_BACK_LEFT)) { + nv10ClearBuffer(ctx, nmesa->color_buffer[1], + nmesa->clear_color_value, 0xffffffff); + } + /* FIXME: check depth bits */ + if (mask & (BUFFER_BIT_DEPTH)) { + nv10ClearBuffer(ctx, nmesa->depth_buffer, + nmesa->clear_value, 0xffffff00); + } + /* FIXME: check about stencil? */ + if (mask & (BUFFER_BIT_STENCIL)) { + nv10ClearBuffer(ctx, nmesa->depth_buffer, + nmesa->clear_value, 0x000000ff); + } +} + static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); -- cgit v1.2.3 From b902a223c461c804cee5cabd6440a934835803bd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 16 Aug 2007 21:50:34 +0200 Subject: nouveau: nv10: clear a buffer --- src/mesa/drivers/dri/nouveau/nv10_state.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 0c746325c6..4a3646ea4f 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -114,12 +114,35 @@ static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac static void nv10ClearBuffer(GLcontext *ctx, nouveau_renderbuffer_t *buffer, int fill, int mask) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int dimensions; if (!buffer) { return; } - /* TODO */ + /* Surface that we will work on */ + nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D); + + BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING(0x0b); /* Y32 color format */ + OUT_RING((buffer->pitch<<16)|buffer->pitch); + OUT_RING(buffer->offset); + OUT_RING(buffer->offset); + + /* Now clear a rectangle */ + dimensions = ((buffer->mesa.Height)<<16) | (buffer->mesa.Width); + + nouveauObjectOnSubchannel(nmesa, NvSubGdiRectText, NvGdiRectText); + + BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING(3); /* SRCCOPY */ + + BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL, 5); + OUT_RING(0); /* top left */ + OUT_RING(dimensions); /* bottom right */ + OUT_RING(fill); + OUT_RING(0); /* top left */ + OUT_RING(dimensions); /* bottom right */ } static void nv10Clear(GLcontext *ctx, GLbitfield mask) -- cgit v1.2.3 From 327e6551197e6069150200878b4e6e7a595e2bee Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:28:12 -0700 Subject: Add decode for XY_COLOR_BLT and XY_SRC_COPY_BLT. --- src/mesa/drivers/dri/i915tex/i915_disasm.c | 87 +++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_disasm.c b/src/mesa/drivers/dri/i915tex/i915_disasm.c index 6ac34a1480..292b6e3a3b 100644 --- a/src/mesa/drivers/dri/i915tex/i915_disasm.c +++ b/src/mesa/drivers/dri/i915tex/i915_disasm.c @@ -134,7 +134,8 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) static int decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) { - unsigned int opcode; + unsigned int opcode, len; + char *format; struct { uint32_t opcode; @@ -169,11 +170,93 @@ decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, }; + switch ((data[0] & 0x1fc00000) >> 22) { + case 0x50: + instr_out(data, hw_offset, 0, + "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 6) + fprintf(out, "Bad count in XY_COLOR_BLT\n"); + if (count < 6) + BUFFER_FAIL(count, len, "XY_COLOR_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "color\n"); + return len; + case 0x53: + instr_out(data, hw_offset, 0, + "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 8) + fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); + if (count < 8) + BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "src (%d,%d)\n", + data[5] & 0xffff, data[5] >> 16); + instr_out(data, hw_offset, 6, "src pitch %d\n", + data[6] & 0xffff); + instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); + return len; + } + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); opcode++) { if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { - unsigned int len = 1, i; + unsigned int i; + len = 1; instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); if (opcodes_2d[opcode].max_len > 1) { len = (data[0] & 0x000000ff) + 2; -- cgit v1.2.3 From 2b77a8696b14bc36be359bf858189ade5fab8511 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:34:24 -0700 Subject: Don't forget to update buffer offset after validation. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 6e29199cd8..7f1e10fbc8 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -262,6 +262,8 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) /* XXX: add to fence list for sanity checking */ } + buf->offset = ttm_buf->drm_bo.offset; + return err; } -- cgit v1.2.3 From 64297acf9e96353fe724362248246acaf0be8cb8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:35:06 -0700 Subject: Fix bad printf on TTM fence_wait failure. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 7f1e10fbc8..2d4f518b31 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -339,7 +339,7 @@ dri_ttm_fence_wait(dri_fence *fence) _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); if (ret != 0) { _mesa_printf("%s:%d: Error %d waiting for fence %s.\n", - __FILE__, __LINE__, fence_ttm->name); + __FILE__, __LINE__, ret, fence_ttm->name); abort(); } } -- cgit v1.2.3 From b6ad5e7de8dc84ee42eeeb62d2112f096413b335 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:36:35 -0700 Subject: Move i915_disasm to later so we can use the hardware offset. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 1edbb618d3..5aabef96ae 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -27,6 +27,7 @@ #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "i915_disasm.h" /* Relocations in kernel space: * - pass dma buffer seperately @@ -144,9 +145,6 @@ do_flush_locked(struct intel_batchbuffer *batch, dri_bo_unreference(r->buf); } - if (INTEL_DEBUG & DEBUG_BATCH) - i915_disasm(ptr, used / 4, 0); - dri_bo_unmap(batch->buf); batch->map = NULL; batch->ptr = NULL; @@ -196,6 +194,12 @@ do_flush_locked(struct intel_batchbuffer *batch, } intel->vtbl.lost_hardware(intel); } + + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + i915_disasm(ptr, used / 4, batch->buf->offset); + dri_bo_unmap(batch->buf); + } } -- cgit v1.2.3 From 3e168a0ec840af65863e197f4a884aae905b213e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 16 Aug 2007 14:32:53 -0700 Subject: Convert TTM code to require the server provide buffers for front/back/depth. This removes the use of fake buffers from the driver, such that it could probably be removed from the interface. It also should assist in proper synchronization of access. --- src/mesa/drivers/dri/common/dri_bufmgr.h | 2 + src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 46 ++++----- src/mesa/drivers/dri/i915tex/intel_regions.c | 32 +++++-- src/mesa/drivers/dri/i915tex/intel_regions.h | 2 + src/mesa/drivers/dri/i915tex/intel_screen.c | 110 +++++++++++++--------- src/mesa/drivers/dri/i915tex/intel_screen.h | 1 + src/mesa/drivers/dri/i915tex/server/i830_common.h | 9 ++ 7 files changed, 121 insertions(+), 81 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h index 0f8e27923b..3be342926f 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr.h +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -192,5 +192,7 @@ dri_bufmgr *dri_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, unsigned int cookie), void *driver_priv); void dri_bufmgr_destroy(dri_bufmgr *bufmgr); +dri_bo *dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, + unsigned int handle); #endif diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 2d4f518b31..5128d95370 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -131,15 +131,30 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, return &ttm_buf->bo; } +/* Our TTM backend doesn't allow creation of static buffers, as that requires + * privelege for the non-fake case, and the lock in the fake case where we were + * working around the X Server not creating buffers and passing handles to us. + */ static dri_bo * dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, unsigned long offset, unsigned long size, void *virtual, unsigned int location_mask) +{ + return NULL; +} + +/** Returns a dri_bo wrapping the given buffer object handle. + * + * This can be used when one application needs to pass a buffer object + * to another. + */ +dri_bo * +dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, + unsigned int handle) { dri_bufmgr_ttm *ttm_bufmgr; dri_bo_ttm *ttm_buf; int ret; - unsigned int flags, hint; ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr; @@ -147,25 +162,14 @@ dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name, if (!ttm_buf) return NULL; - /* The mask argument doesn't do anything for us that we want other than - * determine which pool (TTM or local) the buffer is allocated into, so just - * pass all of the allocation class flags. - */ - flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | - DRM_BO_FLAG_EXE | DRM_BO_FLAG_NO_MOVE; - /* No hints we want to use. */ - hint = 0; - - ret = drmBOCreate(ttm_bufmgr->fd, offset, size, 0, - NULL, drm_bo_type_fake, - flags, hint, &ttm_buf->drm_bo); + ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo); if (ret != 0) { free(ttm_buf); return NULL; } ttm_buf->bo.size = ttm_buf->drm_bo.size; ttm_buf->bo.offset = ttm_buf->drm_bo.offset; - ttm_buf->bo.virtual = virtual; + ttm_buf->bo.virtual = NULL; ttm_buf->bo.bufmgr = bufmgr; ttm_buf->name = name; ttm_buf->refcount = 1; @@ -367,7 +371,6 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, unsigned int fence_type_flush) { dri_bufmgr_ttm *bufmgr_ttm; - dri_bo *test_alloc; bufmgr_ttm = malloc(sizeof(*bufmgr_ttm)); bufmgr_ttm->fd = fd; @@ -388,18 +391,5 @@ dri_bufmgr_ttm_init(int fd, unsigned int fence_type, bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait; bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy; - /* Attempt an allocation to make sure that the DRM was actually set up for - * TTM. - */ - test_alloc = dri_bo_alloc((dri_bufmgr *)bufmgr_ttm, "test allocation", - 4096, 4096, DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_MEM_TT); - if (test_alloc == NULL) { - fprintf(stderr, "TTM test allocation failed\n"); - _glthread_DESTROY_MUTEX(bufmgr_ttm->mutex); - free(bufmgr_ttm); - return NULL; - } - dri_bo_unreference(test_alloc); - return &bufmgr_ttm->bufmgr; } diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c index 4e3cea5e05..4eac859a13 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -147,6 +147,7 @@ intel_region_release(struct intel_region **region) struct intel_region * intel_region_create_static(intelScreenPrivate *intelScreen, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, GLuint pitch, GLuint height) @@ -159,9 +160,18 @@ intel_region_create_static(intelScreenPrivate *intelScreen, region->height = height; /* needed? */ region->refcount = 1; - region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", - offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT); + if (intelScreen->ttm) { + assert(bo_handle != -1); + region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, + "static region", + bo_handle); + } else { + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, + "static region", + offset, pitch * cpp * height, + virtual, + DRM_BO_FLAG_MEM_TT); + } return region; } @@ -172,6 +182,7 @@ void intel_region_update_static(intelScreenPrivate *intelScreen, struct intel_region *region, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, GLuint pitch, GLuint height) @@ -188,9 +199,18 @@ intel_region_update_static(intelScreenPrivate *intelScreen, */ dri_bo_unreference(region->buffer); - region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, "static region", - offset, pitch * cpp * height, virtual, - DRM_BO_FLAG_MEM_TT); + if (intelScreen->ttm) { + assert(bo_handle != -1); + region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, + "static region", + bo_handle); + } else { + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, + "static region", + offset, pitch * cpp * height, + virtual, + DRM_BO_FLAG_MEM_TT); + } } diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h index 9623cf7bd5..42d7b17711 100644 --- a/src/mesa/drivers/dri/i915tex/intel_regions.h +++ b/src/mesa/drivers/dri/i915tex/intel_regions.h @@ -73,6 +73,7 @@ void intel_region_release(struct intel_region **ib); extern struct intel_region *intel_region_create_static(intelScreenPrivate *intelScreen, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, @@ -81,6 +82,7 @@ extern void intel_region_update_static(intelScreenPrivate *intelScreen, struct intel_region *region, GLuint mem_type, + unsigned int bo_handle, GLuint offset, void *virtual, GLuint cpp, GLuint pitch, GLuint height); diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index a0471019e4..2721a90094 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -170,18 +170,26 @@ intel_fence_wait(void *private, unsigned int cookie) static struct intel_region * intel_recreate_static(intelScreenPrivate *intelScreen, struct intel_region *region, - GLuint mem_type, - GLuint offset, - void *virtual, - GLuint cpp, GLuint pitch, GLuint height) + intelRegion *region_desc, + GLuint mem_type) { if (region) { - intel_region_update_static(intelScreen, region, mem_type, offset, - virtual, cpp, pitch, height); + intel_region_update_static(intelScreen, region, mem_type, + region_desc->bo_handle, region_desc->offset, + region_desc->map, intelScreen->cpp, + region_desc->pitch / intelScreen->cpp, + intelScreen->height); } else { - region = intel_region_create_static(intelScreen, mem_type, offset, - virtual, cpp, pitch, height); + region = intel_region_create_static(intelScreen, mem_type, + region_desc->bo_handle, + region_desc->offset, + region_desc->map, intelScreen->cpp, + region_desc->pitch / intelScreen->cpp, + intelScreen->height); } + + assert(region->buffer != NULL); + return region; } @@ -203,57 +211,42 @@ intel_recreate_static_regions(intelScreenPrivate *intelScreen) intelScreen->front_region = intel_recreate_static(intelScreen, intelScreen->front_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->front.offset, - intelScreen->front.map, - intelScreen->cpp, - intelScreen->front.pitch / intelScreen->cpp, - intelScreen->height); - - intelScreen->rotated_region = - intel_recreate_static(intelScreen, - intelScreen->rotated_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->rotated.offset, - intelScreen->rotated.map, - intelScreen->cpp, - intelScreen->rotated.pitch / - intelScreen->cpp, intelScreen->height); + &intelScreen->front, + DRM_BO_FLAG_MEM_TT); + /* The rotated region is only used for old DDXes that didn't handle rotation +\ * on their own. + */ + if (intelScreen->driScrnPriv->ddxMinor < 8) { + intelScreen->rotated_region = + intel_recreate_static(intelScreen, + intelScreen->rotated_region, + &intelScreen->rotated, + DRM_BO_FLAG_MEM_TT); + } intelScreen->back_region = intel_recreate_static(intelScreen, intelScreen->back_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->back.offset, - intelScreen->back.map, - intelScreen->cpp, - intelScreen->back.pitch / intelScreen->cpp, - intelScreen->height); + &intelScreen->back, + DRM_BO_FLAG_MEM_TT); if (intelScreen->third.handle) { intelScreen->third_region = intel_recreate_static(intelScreen, intelScreen->third_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->third.offset, - intelScreen->third.map, - intelScreen->cpp, - intelScreen->third.pitch / intelScreen->cpp, - intelScreen->height); + &intelScreen->third, + DRM_BO_FLAG_MEM_TT); } - /* Still assuming front.cpp == depth.cpp + /* Still assumes front.cpp == depth.cpp. We can kill this when we move to + * private buffers. */ intelScreen->depth_region = intel_recreate_static(intelScreen, intelScreen->depth_region, - DRM_BO_FLAG_MEM_TT, - intelScreen->depth.offset, - intelScreen->depth.map, - intelScreen->cpp, - intelScreen->depth.pitch / intelScreen->cpp, - intelScreen->height); + &intelScreen->depth, + DRM_BO_FLAG_MEM_TT); } /** @@ -396,6 +389,18 @@ intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, intelScreen->depth.handle = sarea->depth_handle; intelScreen->depth.size = sarea->depth_size; + if (intelScreen->driScrnPriv->ddxMinor >= 9) { + intelScreen->front.bo_handle = sarea->front_bo_handle; + intelScreen->back.bo_handle = sarea->back_bo_handle; + intelScreen->third.bo_handle = sarea->third_bo_handle; + intelScreen->depth.bo_handle = sarea->depth_bo_handle; + } else { + intelScreen->front.bo_handle = -1; + intelScreen->back.bo_handle = -1; + intelScreen->third.bo_handle = -1; + intelScreen->depth.bo_handle = -1; + } + intelScreen->tex.offset = sarea->tex_offset; intelScreen->logTextureGranularity = sarea->log_tex_granularity; intelScreen->tex.handle = sarea->tex_handle; @@ -526,10 +531,21 @@ intelInitDriver(__DRIscreenPrivate * sPriv) (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); } - intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, - DRM_FENCE_TYPE_EXE, - DRM_FENCE_TYPE_EXE | - DRM_I915_FENCE_TYPE_RW); + /* If we've got a new enough DDX that's initializing TTM and giving us + * object handles for the shared buffers, use that. + */ + intelScreen->ttm = GL_FALSE; + if (getenv("INTEL_NO_TTM") == NULL && + intelScreen->driScrnPriv->ddxMinor >= 9 && + intelScreen->front.bo_handle != -1) { + intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW); + if (intelScreen->bufmgr != NULL) + intelScreen->ttm = GL_TRUE; + } + /* Otherwise, use the classic buffer manager. */ if (intelScreen->bufmgr == NULL) { if (intelScreen->tex.size == 0) { fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h index 168793d05a..aa0ef2c509 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.h +++ b/src/mesa/drivers/dri/i915tex/intel_screen.h @@ -45,6 +45,7 @@ typedef struct char *map; /* memory map */ int offset; /* from start of video mem, in bytes */ int pitch; /* row stride, in bytes */ + unsigned int bo_handle; /* buffer object id if available, or -1 */ } intelRegion; typedef struct diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h index 7a76957c6a..bd2bec3eae 100644 --- a/src/mesa/drivers/dri/i915tex/server/i830_common.h +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -136,6 +136,15 @@ typedef struct { int third_offset; int third_size; unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; } drmI830Sarea; /* Flags for perf_boxes -- cgit v1.2.3 From 00b86ecf6f2f936bad6d628622ea5546c780ab8d Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 17 Aug 2007 12:42:52 -0400 Subject: i965: align width/height for volume texture --- src/mesa/drivers/dri/i965/brw_tex_layout.c | 46 +++++++++++++++++++-------- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 1 + 2 files changed, 34 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index af1ad0f1ef..2094a1c8ad 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -37,6 +37,7 @@ #include "intel_tex_layout.h" #include "macros.h" +#define ALIGN(value, alignment) ((value + alignment - 1) & ~(alignment - 1)) GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) { @@ -53,11 +54,20 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) GLuint pack_x_pitch, pack_x_nr; GLuint pack_y_pitch; GLuint level; + GLuint align_h = 2; + GLuint align_w = 4; - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; mt->total_height = 0; + + if (mt->compressed) { + align_w = intel_compressed_alignment(mt->internal_format); + mt->pitch = ALIGN(width, align_w); + pack_y_pitch = (height + 3) / 4; + } else { + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + pack_y_pitch = ALIGN(mt->height0, align_h); + } - pack_y_pitch = MAX2(mt->height0, 2); pack_x_pitch = mt->pitch; pack_x_nr = 1; @@ -83,20 +93,30 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) mt->total_height += y; - - if (pack_x_pitch > 4) { - pack_x_pitch >>= 1; - pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); - } - - if (pack_y_pitch > 2) { - pack_y_pitch >>= 1; - } - width = minify(width); height = minify(height); depth = minify(depth); + + if (mt->compressed) { + pack_y_pitch = (height + 3) / 4; + + if (pack_x_pitch > ALIGN(width, align_w)) { + pack_x_pitch = ALIGN(width, align_w); + pack_x_nr <<= 1; + } + } else { + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= mt->pitch); + } + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; + pack_y_pitch = ALIGN(pack_y_pitch, align_h); + } + } + } break; } diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index f24f234682..0fb33e27f4 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -233,6 +233,7 @@ GLboolean intel_miptree_image_data(struct intel_context *intel, if (dst->compressed) { alignment = intel_compressed_alignment(dst->internal_format); + src_row_pitch = ((src_row_pitch + alignment - 1) & ~(alignment - 1)); width = ((width + alignment - 1) & ~(alignment - 1)); height = (height + 3) / 4; } -- cgit v1.2.3 From dcfdb63b9fde8134562cb3a4e779a36e0abb4ae5 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 17 Aug 2007 13:36:13 -0400 Subject: Brian's fix for bug9829 --- src/mesa/main/texenvprogram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 72b54b27d9..9c84da985e 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -38,7 +38,7 @@ * According to Glean's texCombine test, no more than 21 instructions * are needed. Allow a few extra just in case. */ -#define MAX_INSTRUCTIONS 24 +#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 6) + 10) /* see bug 9829 */ #define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) -- cgit v1.2.3 From 95e84a09ce3f35f59465be28026e83c1bc40ae8a Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 18 Aug 2007 16:10:25 +0100 Subject: remove dead code left over after fixing GL_READ/DRAW_BUFFER state issues --- src/mesa/main/buffers.c | 47 ----------------------------------------------- src/mesa/main/buffers.h | 5 ----- src/mesa/main/context.c | 14 -------------- src/mesa/main/fbobject.c | 23 ----------------------- 4 files changed, 89 deletions(-) (limited to 'src') diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 94b4be54d5..cbbe3e8698 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -548,53 +548,6 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, } -#if 0 -GLboolean -_mesa_readbuffer_update_fields(GLcontext *ctx, GLenum buffer) -{ - struct gl_framebuffer *fb; - GLbitfield supportedMask; - GLint srcBuffer; - - fb = ctx->ReadBuffer; - - if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); - - if (fb->Name > 0 && buffer == GL_NONE) { - /* This is legal for user-created framebuffer objects */ - srcBuffer = -1; - } - else { - /* general case / window-system framebuffer */ - srcBuffer = read_buffer_enum_to_index(buffer); - if (srcBuffer == -1) { - _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(buffer=0x%x)", buffer); - return GL_FALSE; - } - supportedMask = supported_buffer_bitmask(ctx, fb); - if (((1 << srcBuffer) & supportedMask) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(buffer=0x%x)", buffer); - return GL_FALSE; - } - } - - if (fb->Name == 0) { - /* Only update the per-context GL_READ_BUFFER state if we're bound to - * a window-system framebuffer. - */ - ctx->Pixel.ReadBuffer = buffer; - } - - /* Set the FBO's GL_READ_BUFFER state */ - fb->ColorReadBuffer = buffer; - fb->_ColorReadBufferIndex = srcBuffer; - - return GL_TRUE; -} -#endif - - /** * Like \sa _mesa_drawbuffers(), this is a helper function for setting * GL_READ_BUFFER state in the context and current FBO. diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h index e7228a6da6..9c0070e00f 100644 --- a/src/mesa/main/buffers.h +++ b/src/mesa/main/buffers.h @@ -59,11 +59,6 @@ _mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, extern void _mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex); -#if 0 -extern GLboolean -_mesa_readbuffer_update_fields(GLcontext *ctx, GLenum buffer); -#endif - extern void GLAPIENTRY _mesa_ReadBuffer( GLenum mode ); diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 9ee7b4bec7..bb48109317 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1530,23 +1530,9 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, */ if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) { _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer); -#if 000 - /* fix up the fb fields - these will end up wrong otherwise - if the DRIdrawable changes, and everything relies on them. - This is a bit messy (same as needed in _mesa_BindFramebufferEXT) */ - int i; - GLenum buffers[MAX_DRAW_BUFFERS]; - for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) { - buffers[i] = newCtx->Color.DrawBuffer[i]; - } - _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers, buffers, NULL); -#endif } if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); -#if 00 - _mesa_readbuffer_update_fields(newCtx, newCtx->Pixel.ReadBuffer); -#endif } /* XXX only set this flag if we're really changing the draw/read diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 5cd18d0287..db04c785de 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -1000,20 +1000,8 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) * XXX check if re-binding same buffer and skip some of this code. */ -#if 000 - /* for window-framebuffers, re-initialize the fbo values, as they - could be wrong (makecurrent with a new drawable while still a fbo - was bound will lead to default init fbo values). - note that therefore the context ReadBuffer/DrawBuffer values are not - valid while fbo's are bound!!! */ -#endif if (bindReadBuf) { _mesa_reference_framebuffer(&ctx->ReadBuffer, newFbread); -#if 000 - if (!newFbread->Name) { - _mesa_readbuffer_update_fields(ctx, ctx->Pixel.ReadBuffer); - } -#endif } if (bindDrawBuf) { @@ -1027,17 +1015,6 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) /* check if newly bound framebuffer has any texture attachments */ check_begin_texture_render(ctx, newFb); } - else { - /* XXX try to remove this: */ -#if 000 - GLuint i; - GLenum buffers[MAX_DRAW_BUFFERS]; - for(i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - buffers[i] = ctx->Color.DrawBuffer[i]; - } - _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL); -#endif - } } if (ctx->Driver.BindFramebuffer) { -- cgit v1.2.3 From 53cf87be1b93c760228e6a9af8115d2a9ff99337 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 18 Aug 2007 16:25:16 +0100 Subject: some fixes for compressed cube maps (bug 11986) --- src/mesa/main/mipmap.c | 7 ++++--- src/mesa/main/teximage.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 9f3db22b75..a9260c847b 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -957,7 +957,8 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, GLint components, size; GLchan *dst; - assert(texObj->Target == GL_TEXTURE_2D); + assert(texObj->Target == GL_TEXTURE_2D || + texObj->Target == GL_TEXTURE_CUBE_MAP_ARB); if (srcImage->_BaseFormat == GL_RGB) { convertFormat = &_mesa_texformat_rgb; diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 56322f87af..1bc52d220a 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1998,7 +1998,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, } if (is_compressed_format(ctx, internalFormat)) { - if (target != GL_TEXTURE_2D) { + if (!target_can_be_compressed(ctx, target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%d(target)", dimensions); return GL_TRUE; @@ -2181,7 +2181,7 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, } if (teximage->IsCompressed) { - if (target != GL_TEXTURE_2D) { + if (!target_can_be_compressed(ctx, target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%d(target)", dimensions); return GL_TRUE; -- cgit v1.2.3 From ef71a0fd4536363e578c49a05b6f1161f907c150 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 19 Aug 2007 20:12:26 +0200 Subject: nouveau: nv10: only one color buffer atm --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 2 +- src/mesa/drivers/dri/nouveau/nv10_state.c | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 65ecf21cab..778c4401e4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -124,7 +124,7 @@ typedef struct nouveau_context { GLuint vertex_attr_count; /* Color and depth renderbuffers */ - nouveau_renderbuffer_t *color_buffer[2]; + nouveau_renderbuffer_t *color_buffer; nouveau_renderbuffer_t *depth_buffer; /* Color buffer clear value */ diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 4a3646ea4f..0e48784084 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -149,12 +149,8 @@ static void nv10Clear(GLcontext *ctx, GLbitfield mask) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - if (mask & (BUFFER_BIT_FRONT_LEFT)) { - nv10ClearBuffer(ctx, nmesa->color_buffer[0], - nmesa->clear_color_value, 0xffffffff); - } - if (mask & (BUFFER_BIT_BACK_LEFT)) { - nv10ClearBuffer(ctx, nmesa->color_buffer[1], + if (mask & (BUFFER_BIT_FRONT_LEFT|BUFFER_BIT_BACK_LEFT)) { + nv10ClearBuffer(ctx, nmesa->color_buffer, nmesa->clear_color_value, 0xffffffff); } /* FIXME: check depth bits */ @@ -769,8 +765,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, GLuint pitch, format, depth_pitch; /* Store buffer pointers in context */ - nmesa->color_buffer[0] = color[0]; - nmesa->color_buffer[1] = color[1]; + nmesa->color_buffer = color[0]; nmesa->depth_buffer = depth; w = color[0]->mesa.Width; -- cgit v1.2.3 From a3c3bc9ece7e7c55c8832dbc8c50ab1c34f5bfe9 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 20 Aug 2007 12:55:34 +0100 Subject: don't map buffer in _mesa_validate_DrawElements() unless needed --- src/mesa/main/api_validate.c | 51 +++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 18dead61c3..ab8c3e19ba 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 7.0.1 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -35,7 +35,6 @@ _mesa_validate_DrawElements(GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { - GLboolean mapped = GL_FALSE; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (count <= 0) { @@ -68,19 +67,14 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { GLuint indexBytes; - const GLvoid *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_READ_ONLY, - ctx->Array.ElementArrayBufferObj); /* use indices in the buffer object */ - if (!map) { - _mesa_warning(ctx, "DrawElements with empty vertex elements buffer!"); + if (!ctx->Array.ElementArrayBufferObj->Size) { + _mesa_warning(ctx, + "glDrawElements called with empty array elements buffer"); return GL_FALSE; } - mapped = GL_TRUE; - /* make sure count doesn't go outside buffer bounds */ if (type == GL_UNSIGNED_INT) { indexBytes = count * sizeof(GLuint); @@ -93,19 +87,10 @@ _mesa_validate_DrawElements(GLcontext *ctx, indexBytes = count * sizeof(GLushort); } - if (ADD_POINTERS(map, indices) + indexBytes > - (GLubyte *)map + ctx->Array.ElementArrayBufferObj->Size) { + if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); return GL_FALSE; } - - /* Actual address is the sum of pointers. Indices may be used below. */ - if (ctx->Const.CheckArrayBounds) { - indices = ADD_POINTERS(map, indices); - } } else { /* not using a VBO */ @@ -115,8 +100,18 @@ _mesa_validate_DrawElements(GLcontext *ctx, if (ctx->Const.CheckArrayBounds) { /* find max array index */ + const GLubyte *map; GLuint max = 0; GLint i; + + map = ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + GL_READ_ONLY, + ctx->Array.ElementArrayBufferObj); + + /* Actual address is the sum of pointers */ + indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); + if (type == GL_UNSIGNED_INT) { for (i = 0; i < count; i++) if (((GLuint *) indices)[i] > max) @@ -134,24 +129,16 @@ _mesa_validate_DrawElements(GLcontext *ctx, max = ((GLubyte *) indices)[i]; } + ctx->Driver.UnmapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + ctx->Array.ElementArrayBufferObj); + if (max >= ctx->Array._MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ - if (mapped) { - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); - } - return GL_FALSE; } } - if (mapped) { - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); - } - return GL_TRUE; } -- cgit v1.2.3 From d8c6719f95b1543296ac954f95d13b048ae48634 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 20 Aug 2007 13:12:20 +0100 Subject: refactor bounds checking code --- src/mesa/main/api_validate.c | 148 +++++++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index ab8c3e19ba..3e4fe46b1d 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -30,6 +30,55 @@ #include "state.h" +/** + * Find the max index in the given element/index buffer + */ +static GLuint +max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, + const void *indices, + struct gl_buffer_object *elementBuf) +{ + const GLubyte *map = NULL; + GLuint max = 0; + GLint i; + + if (elementBuf->Name) { + /* elements are in a user-defined buffer object. need to map it */ + map = ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + GL_READ_ONLY, + elementBuf); + /* Actual address is the sum of pointers */ + indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); + } + + if (type == GL_UNSIGNED_INT) { + for (i = 0; i < count; i++) + if (((GLuint *) indices)[i] > max) + max = ((GLuint *) indices)[i]; + } + else if (type == GL_UNSIGNED_SHORT) { + for (i = 0; i < count; i++) + if (((GLushort *) indices)[i] > max) + max = ((GLushort *) indices)[i]; + } + else { + ASSERT(type == GL_UNSIGNED_BYTE); + for (i = 0; i < count; i++) + if (((GLubyte *) indices)[i] > max) + max = ((GLubyte *) indices)[i]; + } + + if (map) { + ctx->Driver.UnmapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + ctx->Array.ElementArrayBufferObj); + } + + return max; +} + + GLboolean _mesa_validate_DrawElements(GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, @@ -61,21 +110,15 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* Always need vertex positions */ if (!ctx->Array.ArrayObj->Vertex.Enabled - && !(ctx->VertexProgram._Enabled && ctx->Array.ArrayObj->VertexAttrib[0].Enabled)) + && !(ctx->VertexProgram._Enabled + && ctx->Array.ArrayObj->VertexAttrib[0].Enabled)) return GL_FALSE; /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { - GLuint indexBytes; - /* use indices in the buffer object */ - if (!ctx->Array.ElementArrayBufferObj->Size) { - _mesa_warning(ctx, - "glDrawElements called with empty array elements buffer"); - return GL_FALSE; - } + GLuint indexBytes; - /* make sure count doesn't go outside buffer bounds */ if (type == GL_UNSIGNED_INT) { indexBytes = count * sizeof(GLuint); } @@ -87,6 +130,7 @@ _mesa_validate_DrawElements(GLcontext *ctx, indexBytes = count * sizeof(GLushort); } + /* make sure count doesn't go outside buffer bounds */ if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); return GL_FALSE; @@ -100,39 +144,8 @@ _mesa_validate_DrawElements(GLcontext *ctx, if (ctx->Const.CheckArrayBounds) { /* find max array index */ - const GLubyte *map; - GLuint max = 0; - GLint i; - - map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_READ_ONLY, - ctx->Array.ElementArrayBufferObj); - - /* Actual address is the sum of pointers */ - indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); - - if (type == GL_UNSIGNED_INT) { - for (i = 0; i < count; i++) - if (((GLuint *) indices)[i] > max) - max = ((GLuint *) indices)[i]; - } - else if (type == GL_UNSIGNED_SHORT) { - for (i = 0; i < count; i++) - if (((GLushort *) indices)[i] > max) - max = ((GLushort *) indices)[i]; - } - else { - ASSERT(type == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) - if (((GLubyte *) indices)[i] > max) - max = ((GLubyte *) indices)[i]; - } - - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); - + GLuint max = max_buffer_index(ctx, count, type, indices, + ctx->Array.ElementArrayBufferObj); if (max >= ctx->Array._MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ return GL_FALSE; @@ -179,41 +192,41 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /* Always need vertex positions */ if (!ctx->Array.ArrayObj->Vertex.Enabled - && !(ctx->VertexProgram._Enabled && ctx->Array.ArrayObj->VertexAttrib[0].Enabled)) + && !(ctx->VertexProgram._Enabled + && ctx->Array.ArrayObj->VertexAttrib[0].Enabled)) return GL_FALSE; /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { - /* XXX re-use code from above? */ + /* use indices in the buffer object */ + GLuint indexBytes; + + if (type == GL_UNSIGNED_INT) { + indexBytes = count * sizeof(GLuint); + } + else if (type == GL_UNSIGNED_BYTE) { + indexBytes = count * sizeof(GLubyte); + } + else { + ASSERT(type == GL_UNSIGNED_SHORT); + indexBytes = count * sizeof(GLushort); + } + + /* make sure count doesn't go outside buffer bounds */ + if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) { + _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); + return GL_FALSE; + } } else { - /* not using VBO */ + /* not using a VBO */ if (!indices) return GL_FALSE; } if (ctx->Const.CheckArrayBounds) { - /* Find max array index. - * We don't trust the user's start and end values. - */ - GLuint max = 0; - GLint i; - if (type == GL_UNSIGNED_INT) { - for (i = 0; i < count; i++) - if (((GLuint *) indices)[i] > max) - max = ((GLuint *) indices)[i]; - } - else if (type == GL_UNSIGNED_SHORT) { - for (i = 0; i < count; i++) - if (((GLushort *) indices)[i] > max) - max = ((GLushort *) indices)[i]; - } - else { - ASSERT(type == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) - if (((GLubyte *) indices)[i] > max) - max = ((GLubyte *) indices)[i]; - } + GLuint max = max_buffer_index(ctx, count, type, indices, + ctx->Array.ElementArrayBufferObj); if (max >= ctx->Array._MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ return GL_FALSE; @@ -248,7 +261,8 @@ _mesa_validate_DrawArrays(GLcontext *ctx, _mesa_update_state(ctx); /* Always need vertex positions */ - if (!ctx->Array.ArrayObj->Vertex.Enabled && !ctx->Array.ArrayObj->VertexAttrib[0].Enabled) + if (!ctx->Array.ArrayObj->Vertex.Enabled + && !ctx->Array.ArrayObj->VertexAttrib[0].Enabled) return GL_FALSE; if (ctx->Const.CheckArrayBounds) { -- cgit v1.2.3 From 07b7e97fb49585d18beaacc12063127501e5407b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 20 Aug 2007 19:35:31 +0200 Subject: Use correct object for GART --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 0e48784084..62911d40f3 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -736,7 +736,7 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2); OUT_RING(NvDmaFB); /* 184 dma_in_memory0 */ - OUT_RING(NvDmaFB); /* 188 dma_in_memory1 */ + OUT_RING(NvDmaTT); /* 188 dma_in_memory1 */ BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2); OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */ OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */ -- cgit v1.2.3 From c6e729377cd1b1e7b5a1a22c40cee80b15a799f7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Aug 2007 16:52:10 +0200 Subject: nouveau: nv10: Remove commented, unsupported by hw command --- src/mesa/drivers/dri/nouveau/nv10_state.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 62911d40f3..8bfe20c6c0 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -790,13 +790,6 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, OUT_RING_CACHE(color[0]->offset); OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); - /* Always set to bottom left of buffer */ - /*BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); - OUT_RING_CACHEf (0.0); - OUT_RING_CACHEf ((GLfloat) h); - OUT_RING_CACHEf (0.0); - OUT_RING_CACHEf (0.0);*/ - return GL_TRUE; } -- cgit v1.2.3 From a6d35694c4570368f718f78bd85a21a626b7cdc9 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Aug 2007 16:53:13 +0200 Subject: nouveau: Use proper notifier object --- src/mesa/drivers/dri/nouveau/nouveau_object.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 4169530be6..83867574d3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -73,12 +73,12 @@ void nouveauObjectInit(nouveauContextPtr nmesa) nouveauObjectOnSubchannel(nmesa, NvSubRasterOp, NvRasterOp); BEGIN_RING_SIZE(NvSubRasterOp, NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY, 1); - OUT_RING(NvDmaFB); + OUT_RING(NvSyncNotify); nouveauObjectOnSubchannel(nmesa, NvSubGdiRectText, NvGdiRectText); BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY, 1); - OUT_RING(NvDmaFB); + OUT_RING(NvSyncNotify); BEGIN_RING_SIZE(NvSubGdiRectText, NV04_GDI_RECTANGLE_TEXT_PATTERN, 2); OUT_RING(NvPattern); OUT_RING(NvRasterOp); -- cgit v1.2.3 From 3d508a5d7bd67c915f9f9403570189d1a60ded5f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Aug 2007 16:55:42 +0200 Subject: nouveau: nv10: Move some initialization stuff --- src/mesa/drivers/dri/nouveau/nv10_state.c | 36 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 8bfe20c6c0..d246daea87 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -701,30 +701,17 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) GLuint h = ctx->Viewport.Height; GLuint x = ctx->Viewport.X + nmesa->drawX; GLuint y = ctx->Viewport.Y + nmesa->drawY; - int i; BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); OUT_RING_CACHE((w << 16) | x); OUT_RING_CACHE((h << 16) | y); - /* something to do with clears, possibly doesn't belong here */ - BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); - OUT_RING(0); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); - for (i=1; i<8; i++) { - BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); - OUT_RING_CACHE(0); - BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); - OUT_RING_CACHE(0); - } nv10ViewportScale(nmesa); } @@ -732,6 +719,8 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) /* Initialise any card-specific non-GL related state */ static GLboolean nv10InitCard(nouveauContextPtr nmesa) { + int i; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2); @@ -741,6 +730,27 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */ OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */ + /* 0x0 viewport size */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING(0); + OUT_RING(0); + + /* Clipping regions */ + BEGIN_RING_SIZE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(0x07ff0800); + BEGIN_RING_SIZE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(0x07ff0800); + for (i=1; i<8; i++) { + BEGIN_RING_SIZE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING(0); + } + BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); OUT_RING(0x00100001); BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); -- cgit v1.2.3 From 24746d0e3219b333fdbbb0026191fc735036ac8c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 22 Aug 2007 10:28:13 +0200 Subject: nouveau: nv10: initialize more of nv10 tcl engine --- src/mesa/drivers/dri/nouveau/nv10_state.c | 102 ++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index d246daea87..1d2994e510 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -720,6 +720,7 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) static GLboolean nv10InitCard(nouveauContextPtr nmesa) { int i; + GLfloat projection[16]; nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); @@ -736,6 +737,8 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) OUT_RING(0); /* Clipping regions */ + BEGIN_RING_SIZE(NvSub3D, 0x2b4, 1); /* clip_mode */ + OUT_RING (0); BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); OUT_RING(0x07ff0800); @@ -761,8 +764,106 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) OUT_RING(0); OUT_RING(1); OUT_RING(2); + + BEGIN_RING_SIZE(NvSubImageBlit, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); } + /* Set state for stuff not initialized in nouveau_state.c */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(0), 2); + OUT_RING (0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(0), 12); + OUT_RING (0x30141010); + OUT_RING (0); + OUT_RING (0x20040000); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0x00000c00); + OUT_RING (0); + OUT_RING (0x00000c00); + OUT_RING (0x18000000); + OUT_RING (0x300e0300); + OUT_RING (0x0c091c80); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE, 1); + OUT_RING (0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL, 1); + OUT_RING (0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL, 1); + OUT_RING (0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING (8); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE, 1); + OUT_RING (0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING (8); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(0), 8); + for (i=0;i<8;i++) { + OUT_RING (0); + } + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf (-1.50); + OUT_RINGf (-0.09); + OUT_RINGf ( 0.00); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 2); + OUT_RING (0x802); + OUT_RING (2); + + /* Projection matrix */ + memset(projection, 0, sizeof(projection)); + projection[0*4+0] = 1.0; + projection[1*4+1] = 1.0; + projection[2*4+2] = 1.0; + projection[3*4+3] = 1.0; + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE, 1); + OUT_RING (6); /* enable projection and modelview0 matrix */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); + for (i=0; i<16; i++) { + OUT_RINGf (projection[i]); + } + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + + /* Set per-vertex component */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R, 4); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X, 3); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S, 4); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S, 4); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F, 1); + OUT_RINGf (0.0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE, 1); + OUT_RING (1); + return GL_TRUE; } @@ -800,6 +901,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, OUT_RING_CACHE(color[0]->offset); OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + nv10ViewportScale(nmesa); return GL_TRUE; } -- cgit v1.2.3 From a3750c989b7330cc08942c9e0959ebfcdfcb9306 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 22 Aug 2007 11:01:59 +0200 Subject: nouveau: nv10: set projection matrix from viewport size --- src/mesa/drivers/dri/nouveau/nv10_state.c | 51 ++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 1d2994e510..5d512b13c4 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -37,29 +37,43 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. static void nv10ViewportScale(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; - GLuint w = ctx->Viewport.Width; - GLuint h = ctx->Viewport.Height; - + GLuint w = ((GLfloat) ctx->Viewport.Width) * 0.5; + GLuint h = ((GLfloat) ctx->Viewport.Height) * 0.5; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; -/* if (ctx->DrawBuffer) { - switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { - case 16: - max_depth *= 32767.0; - break; - case 24: - max_depth *= 16777215.0; - break; - } - } else {*/ - /* Default to 24 bits range */ - max_depth *= 16777215.0; -/* }*/ + GLfloat projection[16]; + int i; + + if (!ctx->DrawBuffer) { + return; + } + if (!ctx->DrawBuffer->_DepthBuffer) { + return; + } + + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); - OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); - OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); + OUT_RING_CACHEf (w - 2048.0); + OUT_RING_CACHEf (h - 2048.0); OUT_RING_CACHEf (max_depth); OUT_RING_CACHEf (0.0); + + memset(projection, 0, sizeof(projection)); + projection[0*4+0] = w; + projection[1*4+1] = h; + projection[2*4+2] = max_depth; + projection[3*4+3] = 1.0; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); + for (i=0; i<16; i++) { + OUT_RING_CACHEf (projection[i]); + } } static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) @@ -774,6 +788,7 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) /* Set state for stuff not initialized in nouveau_state.c */ BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_TX_ENABLE(0), 2); OUT_RING (0); + OUT_RING (0); BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(0), 12); OUT_RING (0x30141010); OUT_RING (0); -- cgit v1.2.3 From dbef6158c6c19a28dc96a96357c9ed9bd9422b88 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 23 Aug 2007 08:16:52 +0100 Subject: remove unneeded CallStack array --- src/mesa/main/dlist.c | 4 ---- src/mesa/main/mtypes.h | 1 - 2 files changed, 5 deletions(-) (limited to 'src') diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index be2f438a94..5b9391096a 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -5737,8 +5737,6 @@ execute_list(GLcontext *ctx, GLuint list) if (!dlist) return; - ctx->ListState.CallStack[ctx->ListState.CallDepth++] = dlist; - if (ctx->Driver.BeginCallList) ctx->Driver.BeginCallList(ctx, dlist); @@ -6625,8 +6623,6 @@ execute_list(GLcontext *ctx, GLuint list) if (ctx->Driver.EndCallList) ctx->Driver.EndCallList(ctx); - - ctx->ListState.CallStack[ctx->ListState.CallDepth--] = NULL; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 1145f361b1..f5a8c970e4 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2866,7 +2866,6 @@ struct mesa_display_list */ struct gl_dlist_state { - struct mesa_display_list *CallStack[MAX_LIST_NESTING]; GLuint CallDepth; /**< Current recursion calling depth */ struct mesa_display_list *CurrentList; -- cgit v1.2.3 From 4b654d41da08b3b5475144c027e97a3ae7ab5696 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 23 Aug 2007 08:53:43 +0100 Subject: For _mesa_share_state(), update the context's references to the new share group's objects (Shane Blackett) --- src/mesa/drivers/windows/gdi/wgl.c | 4 +- src/mesa/drivers/windows/gdi/wmesa.c | 5 ++ src/mesa/main/bufferobj.c | 170 ++++++++++++++++++++--------------- src/mesa/main/bufferobj.h | 3 + src/mesa/main/context.c | 36 +++++++- src/mesa/main/texstate.c | 24 +++++ src/mesa/main/texstate.h | 3 + src/mesa/shader/program.c | 43 +++++++++ src/mesa/shader/program.h | 3 + 9 files changed, 214 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/windows/gdi/wgl.c b/src/mesa/drivers/windows/gdi/wgl.c index dad3dc1160..17eed1dc32 100644 --- a/src/mesa/drivers/windows/gdi/wgl.c +++ b/src/mesa/drivers/windows/gdi/wgl.c @@ -601,8 +601,8 @@ WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, HGLRC hglrc2) { - (void) hglrc1; (void) hglrc2; - return(TRUE); + WMesaShareLists(hglrc1, hglrc2); + return(TRUE); } diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c index 5b67439f0f..ea3f1780d3 100644 --- a/src/mesa/drivers/windows/gdi/wmesa.c +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -1401,6 +1401,11 @@ void WMesaSwapBuffers( HDC hdc ) } } +void WMesaShareLists(WMesaContext ctx_to_share, WMesaContext ctx) +{ + _mesa_share_state(&ctx->gl_ctx, &ctx_to_share->gl_ctx); +} + /* This is hopefully a temporary hack to define some needed dispatch * table entries. Hopefully, I'll find a better solution. The * dispatch table generation scripts ought to be making these dummy diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 009055a6ab..9ad2dccc12 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -409,6 +409,101 @@ _mesa_init_buffer_objects( GLcontext *ctx ) ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj; } +/** + * Bind the specified target to buffer for the specified context. + */ +static void +bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer) +{ + struct gl_buffer_object *oldBufObj; + struct gl_buffer_object *newBufObj = NULL; + struct gl_buffer_object **bindTarget = NULL; + + switch (target) { + case GL_ARRAY_BUFFER_ARB: + bindTarget = &ctx->Array.ArrayBufferObj; + break; + case GL_ELEMENT_ARRAY_BUFFER_ARB: + bindTarget = &ctx->Array.ElementArrayBufferObj; + break; + case GL_PIXEL_PACK_BUFFER_EXT: + bindTarget = &ctx->Pack.BufferObj; + break; + case GL_PIXEL_UNPACK_BUFFER_EXT: + bindTarget = &ctx->Unpack.BufferObj; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target)"); + return; + } + + /* Get pointer to old buffer object (to be unbound) */ + oldBufObj = get_buffer(ctx, target); + if (oldBufObj && oldBufObj->Name == buffer) + return; /* rebinding the same buffer object- no change */ + + /* + * Get pointer to new buffer object (newBufObj) + */ + if (buffer == 0) { + /* The spec says there's not a buffer object named 0, but we use + * one internally because it simplifies things. + */ + newBufObj = ctx->Array.NullBufferObj; + } + else { + /* non-default buffer object */ + newBufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!newBufObj) { + /* if this is a new buffer object id, allocate a buffer object now */ + ASSERT(ctx->Driver.NewBufferObject); + newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target); + if (!newBufObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB"); + return; + } + _mesa_save_buffer_object(ctx, newBufObj); + } + } + + /* Make new binding */ + *bindTarget = newBufObj; + newBufObj->RefCount++; + + /* Pass BindBuffer call to device driver */ + if (ctx->Driver.BindBuffer && newBufObj) + ctx->Driver.BindBuffer( ctx, target, newBufObj ); + + /* decr ref count on old buffer obj, delete if needed */ + if (oldBufObj) { + oldBufObj->RefCount--; + assert(oldBufObj->RefCount >= 0); + if (oldBufObj->RefCount == 0) { + assert(oldBufObj->Name != 0); + ASSERT(ctx->Driver.DeleteBuffer); + ctx->Driver.DeleteBuffer( ctx, oldBufObj ); + } + } +} + + +/** + * Update the default buffer objects in the given context to reference those + * specified in the shared state and release those referencing the old + * shared state. + */ +void +_mesa_update_default_objects_buffer_objects(GLcontext *ctx) +{ + /* Bind the NullBufferObj to remove references to those + * in the shared context hash table. + */ + bind_buffer_object( ctx, GL_ARRAY_BUFFER_ARB, 0); + bind_buffer_object( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + bind_buffer_object( ctx, GL_PIXEL_PACK_BUFFER_ARB, 0); + bind_buffer_object( ctx, GL_PIXEL_UNPACK_BUFFER_ARB, 0); +} + /** * When we're about to read pixel data out of a PBO (via glDrawPixels, @@ -493,76 +588,9 @@ void GLAPIENTRY _mesa_BindBufferARB(GLenum target, GLuint buffer) { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object *oldBufObj; - struct gl_buffer_object *newBufObj = NULL; - struct gl_buffer_object **bindTarget = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); - switch (target) { - case GL_ARRAY_BUFFER_ARB: - bindTarget = &ctx->Array.ArrayBufferObj; - break; - case GL_ELEMENT_ARRAY_BUFFER_ARB: - bindTarget = &ctx->Array.ElementArrayBufferObj; - break; - case GL_PIXEL_PACK_BUFFER_EXT: - bindTarget = &ctx->Pack.BufferObj; - break; - case GL_PIXEL_UNPACK_BUFFER_EXT: - bindTarget = &ctx->Unpack.BufferObj; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target)"); - return; - } - - /* Get pointer to old buffer object (to be unbound) */ - oldBufObj = get_buffer(ctx, target); - if (oldBufObj && oldBufObj->Name == buffer) - return; /* rebinding the same buffer object- no change */ - - /* - * Get pointer to new buffer object (newBufObj) - */ - if (buffer == 0) { - /* The spec says there's not a buffer object named 0, but we use - * one internally because it simplifies things. - */ - newBufObj = ctx->Array.NullBufferObj; - } - else { - /* non-default buffer object */ - newBufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!newBufObj) { - /* if this is a new buffer object id, allocate a buffer object now */ - ASSERT(ctx->Driver.NewBufferObject); - newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target); - if (!newBufObj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB"); - return; - } - _mesa_save_buffer_object(ctx, newBufObj); - } - } - - /* Make new binding */ - *bindTarget = newBufObj; - newBufObj->RefCount++; - - /* Pass BindBuffer call to device driver */ - if (ctx->Driver.BindBuffer && newBufObj) - ctx->Driver.BindBuffer( ctx, target, newBufObj ); - - /* decr ref count on old buffer obj, delete if needed */ - if (oldBufObj) { - oldBufObj->RefCount--; - assert(oldBufObj->RefCount >= 0); - if (oldBufObj->RefCount == 0) { - assert(oldBufObj->Name != 0); - ASSERT(ctx->Driver.DeleteBuffer); - ctx->Driver.DeleteBuffer( ctx, oldBufObj ); - } - } + bind_buffer_object(ctx, target, buffer); } @@ -658,9 +686,9 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids) _mesa_BindBufferARB( GL_PIXEL_UNPACK_BUFFER_EXT, 0 ); } - /* The ID is immediately freed for re-use */ - _mesa_remove_buffer_object(ctx, bufObj); - _mesa_unbind_buffer_object(ctx, bufObj); + /* The ID is immediately freed for re-use */ + _mesa_remove_buffer_object(ctx, bufObj); + _mesa_unbind_buffer_object(ctx, bufObj); } } diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index f54f9e9ff0..1d2715da84 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -38,6 +38,9 @@ extern void _mesa_init_buffer_objects( GLcontext *ctx ); +extern void +_mesa_update_default_objects_buffer_objects(GLcontext *ctx); + extern struct gl_buffer_object * _mesa_new_buffer_object( GLcontext *ctx, GLuint name, GLenum target ); diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index bb48109317..d988ef2d21 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -998,6 +998,28 @@ init_attrib_groups(GLcontext *ctx) } +/** + * Update default objects in a GL context with respect to shared state. + * + * \param ctx GL context. + * + * Removes references to old default objects, (texture objects, program + * objects, etc.) and changes to reference those from the current shared + * state. + */ +static GLboolean +update_default_objects(GLcontext *ctx) +{ + assert(ctx); + + _mesa_update_default_objects_program(ctx); + _mesa_update_default_objects_texture(ctx); + _mesa_update_default_objects_buffer_objects(ctx); + + return GL_TRUE; +} + + /** * This is the default function we plug into all dispatch table slots * This helps prevents a segfault when someone calls a GL function without @@ -1605,12 +1627,18 @@ GLboolean _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { - ctx->Shared->RefCount--; - if (ctx->Shared->RefCount == 0) { - free_shared_state(ctx, ctx->Shared); - } + struct gl_shared_state *oldSharedState = ctx->Shared; + ctx->Shared = ctxToShare->Shared; ctx->Shared->RefCount++; + + update_default_objects(ctx); + + oldSharedState->RefCount--; + if (oldSharedState->RefCount == 0) { + free_shared_state(ctx, oldSharedState); + } + return GL_TRUE; } else { diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 020e3eef4c..288b334eaf 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -3202,3 +3202,27 @@ _mesa_free_texture_data(GLcontext *ctx) _mesa_TexEnvProgramCacheDestroy( ctx ); } + + +/** + * Update the default texture objects in the given context to reference those + * specified in the shared state and release those referencing the old + * shared state. + */ +void +_mesa_update_default_objects_texture(GLcontext *ctx) +{ + GLuint i; + + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + + _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D); + _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D); + _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D); + _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap); + _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect); + _mesa_reference_texobj(&texUnit->Current1DArray, ctx->Shared->Default1DArray); + _mesa_reference_texobj(&texUnit->Current2DArray, ctx->Shared->Default2DArray); + } +} diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h index 60145691b8..b978654116 100644 --- a/src/mesa/main/texstate.h +++ b/src/mesa/main/texstate.h @@ -148,6 +148,9 @@ _mesa_init_texture( GLcontext *ctx ); extern void _mesa_free_texture_data( GLcontext *ctx ); +extern void +_mesa_update_default_objects_texture(GLcontext *ctx); + /*@}*/ #endif diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 1f227390af..2097c39591 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -118,6 +118,49 @@ _mesa_free_program_data(GLcontext *ctx) } +/** + * Update the default program objects in the given context to reference those + * specified in the shared state and release those referencing the old + * shared state. + */ +void +_mesa_update_default_objects_program(GLcontext *ctx) +{ +#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program + if (ctx->VertexProgram.Current) { + ctx->VertexProgram.Current->Base.RefCount--; + if (ctx->VertexProgram.Current->Base.RefCount <= 0) + ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base)); + } + ctx->VertexProgram.Current = (struct gl_vertex_program *) ctx->Shared->DefaultVertexProgram; + assert(ctx->VertexProgram.Current); + ctx->VertexProgram.Current->Base.RefCount++; +#endif + +#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program + if (ctx->FragmentProgram.Current) { + ctx->FragmentProgram.Current->Base.RefCount--; + if (ctx->FragmentProgram.Current->Base.RefCount <= 0) + ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base)); + } + ctx->FragmentProgram.Current = (struct gl_fragment_program *) ctx->Shared->DefaultFragmentProgram; + assert(ctx->FragmentProgram.Current); + ctx->FragmentProgram.Current->Base.RefCount++; +#endif + + /* XXX probably move this stuff */ +#if FEATURE_ATI_fragment_shader + if (ctx->ATIFragmentShader.Current) { + ctx->ATIFragmentShader.Current->RefCount--; + if (ctx->ATIFragmentShader.Current->RefCount <= 0) { + _mesa_free(ctx->ATIFragmentShader.Current); + } + } + ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader; + assert(ctx->ATIFragmentShader.Current); + ctx->ATIFragmentShader.Current->RefCount++; +#endif +} /** diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 52704856ab..ea2c8c3050 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -56,6 +56,9 @@ _mesa_init_program(GLcontext *ctx); extern void _mesa_free_program_data(GLcontext *ctx); +extern void +_mesa_update_default_objects_program(GLcontext *ctx); + extern void _mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string); -- cgit v1.2.3 From f8e4cf716a3656faa08086ee80d04b36a5266d65 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 24 Aug 2007 08:43:58 +0100 Subject: remove CallDepth++/-- accidentally removed in prev commit --- src/mesa/main/dlist.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 5b9391096a..b881b12ff3 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -5737,6 +5737,8 @@ execute_list(GLcontext *ctx, GLuint list) if (!dlist) return; + ctx->ListState.CallDepth++; + if (ctx->Driver.BeginCallList) ctx->Driver.BeginCallList(ctx, dlist); @@ -6623,6 +6625,8 @@ execute_list(GLcontext *ctx, GLuint list) if (ctx->Driver.EndCallList) ctx->Driver.EndCallList(ctx); + + ctx->ListState.CallDepth--; } -- cgit v1.2.3 From 1a911aad0a31b2d043a524e5d6f766fbb38142d7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 25 Aug 2007 11:39:04 +0200 Subject: nouveau: nv10: properly set viewport and projection --- src/mesa/drivers/dri/nouveau/nv10_state.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 5d512b13c4..6d9ddd55d4 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -37,8 +37,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. static void nv10ViewportScale(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; - GLuint w = ((GLfloat) ctx->Viewport.Width) * 0.5; - GLuint h = ((GLfloat) ctx->Viewport.Height) * 0.5; + GLfloat w = ((GLfloat) ctx->Viewport.Width) * 0.5; + GLfloat h = ((GLfloat) ctx->Viewport.Height) * 0.5; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; GLfloat projection[16]; int i; @@ -67,7 +67,7 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) memset(projection, 0, sizeof(projection)); projection[0*4+0] = w; - projection[1*4+1] = h; + projection[1*4+1] = -h; projection[2*4+2] = max_depth; projection[3*4+3] = 1.0; BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); -- cgit v1.2.3 From 40ecc4a359fb587627fee44a13192a0c20b03b8e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 25 Aug 2007 12:36:03 +0200 Subject: nouveau: nv10: add a scissor func, do not cache viewport settings --- src/mesa/drivers/dri/nouveau/nv10_state.c | 96 ++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 6d9ddd55d4..d3331ac970 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -59,20 +59,21 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) break; } - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); - OUT_RING_CACHEf (w - 2048.0); - OUT_RING_CACHEf (h - 2048.0); - OUT_RING_CACHEf (max_depth); - OUT_RING_CACHEf (0.0); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); + OUT_RINGf (w - 2048.0); + OUT_RINGf (h - 2048.0); + OUT_RINGf (max_depth); + OUT_RINGf (0.0); + /* FIXME: should multiply by gl projection and modelview ? */ memset(projection, 0, sizeof(projection)); projection[0*4+0] = w; projection[1*4+1] = -h; projection[2*4+2] = max_depth; projection[3*4+3] = 1.0; - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); for (i=0; i<16; i++) { - OUT_RING_CACHEf (projection[i]); + OUT_RINGf (projection[i]); } } @@ -637,9 +638,52 @@ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ void (*RenderMode)(GLcontext *ctx, GLenum mode ); +/* Translate GL coords to window coords, clamping w/h to the + * dimensions of the window. + */ +static void nv10WindowCoords(nouveauContextPtr nmesa, + GLuint x, GLuint y, GLuint w, GLuint h, + GLuint *wX, GLuint *wY, GLuint *wW, GLuint *wH) +{ + if ((x+w) > nmesa->drawW) + w = nmesa->drawW - x; + (*wX) = x + nmesa->drawX; + (*wW) = w; + + if ((y+h) > nmesa->drawH) + h = nmesa->drawH - y; + (*wY) = (nmesa->drawH - y) - h + nmesa->drawY; + (*wH) = h; +} + /** Define the scissor box */ static void nv10Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLuint wX, wY, wW, wH; + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + wX = nmesa->drawX; + wY = nmesa->drawY; + wW = nmesa->drawW; + wH = nmesa->drawH; + } else { + nv10WindowCoords(nmesa, x, y, w, h, &wX, &wY, &wW, &wH); + } + + if (!wW || !wH) { + return; + } + + BEGIN_RING_SIZE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(((wW+wX-1) << 16) | wX | 0x08000800); + BEGIN_RING_SIZE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(((wH+wY-1) << 16) | wY | 0x08000800); } /** Select flat or smooth shading */ @@ -711,23 +755,20 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; GLfloat *v = nmesa->viewport.m; - GLuint w = ctx->Viewport.Width; - GLuint h = ctx->Viewport.Height; - GLuint x = ctx->Viewport.X + nmesa->drawX; - GLuint y = ctx->Viewport.Y + nmesa->drawY; + GLuint wX, wY, wW, wH; - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); + nv10WindowCoords(nmesa, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height, + &wX, &wY, &wW, &wH); - BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); - OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); - BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); - OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING((wW << 16) | wX); + OUT_RING((wH << 16) | wY); nv10ViewportScale(nmesa); + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); } /* Initialise any card-specific non-GL related state */ @@ -902,21 +943,20 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, if (num_color != 1) return GL_FALSE; - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); + OUT_RING((w << 16) | x); + OUT_RING((h << 16) | y); depth_pitch = (depth ? depth->pitch : color[0]->pitch); pitch = (depth_pitch<<16) | color[0]->pitch; format = 0x108; if (color[0]->mesa._ActualFormat != GL_RGBA8) { format = 0x103; /* R5G6B5 color buffer */ } - OUT_RING_CACHE(format); - OUT_RING_CACHE(pitch); - OUT_RING_CACHE(color[0]->offset); - OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + OUT_RING(format); + OUT_RING(pitch); + OUT_RING(color[0]->offset); + OUT_RING(depth ? depth->offset : color[0]->offset); - nv10ViewportScale(nmesa); return GL_TRUE; } -- cgit v1.2.3 From 24967c8646b496b0e6f2735374528fe93ac3e0a4 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 25 Aug 2007 17:46:53 +0200 Subject: nouveau: nv10: also set modelview0 matrix to identity --- src/mesa/drivers/dri/nouveau/nv10_state.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index d3331ac970..79d567b25d 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -869,7 +869,7 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) OUT_RING (0x802); OUT_RING (2); - /* Projection matrix */ + /* Projection and modelview matrix */ memset(projection, 0, sizeof(projection)); projection[0*4+0] = 1.0; projection[1*4+1] = 1.0; @@ -882,6 +882,10 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) for (i=0; i<16; i++) { OUT_RINGf (projection[i]); } + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_MODELVIEW0_MATRIX(0), 16); + for (i=0; i<16; i++) { + OUT_RINGf (projection[i]); + } BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); OUT_RINGf (0.0); OUT_RINGf (1.0); -- cgit v1.2.3 From c28ea5573d1e0249083c90d53890c2ec4e61f08c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 27 Aug 2007 11:45:30 +0200 Subject: nouveau: nv10: set total stride of vertex array for POS attribute --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 611469b6e4..e31faf21a7 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -455,27 +455,33 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) * Tell the hardware about the vertex format */ if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) { - int size; + int total_stride = 0; #define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2 #define NV10_SET_VERTEX_ATTRIB(i,j) \ do { \ + int size; \ + int stride = attr_size[j] << 2; \ + if (i==0) { \ + stride += total_stride; \ + } \ size = attr_size[j] << 4; \ - size |= (attr_size[j]*4) << 8; \ + size |= stride << 8; \ size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \ OUT_RING_CACHE(size); \ + total_stride += stride; \ } while (0) - NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS); - NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0); - NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1); - NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0); - NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1); - NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL); - NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG); + NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); + NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL); + NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1); + NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0); + NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1); + NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0); + NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1); OUT_RING_CACHE(0); -- cgit v1.2.3 From f0a036bad91d5f281f8007e8cddefb3f648f1684 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 27 Aug 2007 10:36:11 -0600 Subject: new __gluInvertMatrix() function (Mesa bug 6748) --- src/glu/sgi/libutil/project.c | 115 ++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/glu/sgi/libutil/project.c b/src/glu/sgi/libutil/project.c index 2b20ad4fb3..d22989c385 100644 --- a/src/glu/sgi/libutil/project.c +++ b/src/glu/sgi/libutil/project.c @@ -168,74 +168,57 @@ static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4], } /* -** inverse = invert(src) -** New, faster implementation by Shan Hao Bo, April 2006. +** Invert 4x4 matrix. +** Contributed by David Moore (See Mesa bug #6748) */ -static int __gluInvertMatrixd(const GLdouble src[16], GLdouble inverse[16]) +static int __gluInvertMatrixd(const GLdouble m[16], GLdouble inv[16]) { - int i, j, k; - double t; - GLdouble temp[4][4]; - - for (i=0; i<4; i++) { - for (j=0; j<4; j++) { - temp[i][j] = src[i*4+j]; - } - } - __gluMakeIdentityd(inverse); - - for (i = 0; i < 4; i++) { - if (temp[i][i] == 0.0f) { - /* - ** Look for non-zero element in column - */ - for (j = i + 1; j < 4; j++) { - if (temp[j][i] != 0.0f) { - break; - } - } - - if (j != 4) { - /* - ** Swap rows. - */ - for (k = 0; k < 4; k++) { - t = temp[i][k]; - temp[i][k] = temp[j][k]; - temp[j][k] = t; - - t = inverse[i*4+k]; - inverse[i*4+k] = inverse[j*4+k]; - inverse[j*4+k] = t; - } - } - else { - /* - ** No non-zero pivot. The matrix is singular, -which shouldn't - ** happen. This means the user gave us a bad -matrix. - */ - return GL_FALSE; - } - } - - t = 1.0f / temp[i][i]; - for (k = 0; k < 4; k++) { - temp[i][k] *= t; - inverse[i*4+k] *= t; - } - for (j = 0; j < 4; j++) { - if (j != i) { - t = temp[j][i]; - for (k = 0; k < 4; k++) { - temp[j][k] -= temp[i][k]*t; - inverse[j*4+k] -= inverse[i*4+k]*t; - } - } - } - } - return GL_TRUE; + double det; + int i; + + inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15] + + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10]; + inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15] + - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10]; + inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15] + + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9]; + inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14] + - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9]; + inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15] + - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10]; + inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15] + + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10]; + inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15] + - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9]; + inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14] + + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9]; + inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15] + + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6]; + inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15] + - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6]; + inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15] + + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5]; + inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14] + - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5]; + inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11] + - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6]; + inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11] + + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6]; + inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11] + - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5]; + inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10] + + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5]; + + det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12]; + if (det == 0) + return GL_FALSE; + + det = 1.0 / det; + + for (i = 0; i < 16; i++) + inv[i] *= det; + + return GL_TRUE; } static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16], -- cgit v1.2.3 From d62be3d4cac4228a74fd93a5588717b8b8468cc6 Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Mon, 27 Aug 2007 10:47:32 -0600 Subject: fixed problem with big glDrawArrays (see bug 12141) --- src/glx/x11/indirect_vertex_array.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/x11/indirect_vertex_array.c index 90ec277c41..120fd826c3 100644 --- a/src/glx/x11/indirect_vertex_array.c +++ b/src/glx/x11/indirect_vertex_array.c @@ -527,7 +527,7 @@ static GLubyte * emit_DrawArrays_header_old( __GLXcontext * gc, struct array_state_vector * arrays, size_t * elements_per_request, - size_t * total_requests, + unsigned int * total_requests, GLenum mode, GLsizei count ) { size_t command_size; @@ -640,7 +640,7 @@ emit_DrawArrays_old( GLenum mode, GLint first, GLsizei count ) GLubyte * pc; size_t elements_per_request; - size_t total_requests = 0; + unsigned total_requests = 0; unsigned i; size_t total_sent = 0; @@ -770,9 +770,10 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, GLubyte * pc; size_t elements_per_request; - size_t total_requests = 0; + unsigned total_requests = 0; unsigned i; unsigned req; + unsigned req_element=0; pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request, @@ -790,7 +791,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, switch( type ) { case GL_UNSIGNED_INT: { - const GLuint * ui_ptr = (const GLuint *) indices; + const GLuint * ui_ptr = (const GLuint *) indices + req_element; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(ui_ptr++); @@ -799,7 +800,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, break; } case GL_UNSIGNED_SHORT: { - const GLushort * us_ptr = (const GLushort *) indices; + const GLushort * us_ptr = (const GLushort *) indices + req_element; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(us_ptr++); @@ -808,7 +809,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, break; } case GL_UNSIGNED_BYTE: { - const GLubyte * ub_ptr = (const GLubyte *) indices; + const GLubyte * ub_ptr = (const GLubyte *) indices + req_element; for ( i = 0 ; i < elements_per_request ; i++ ) { const GLint index = (GLint) *(ub_ptr++); @@ -826,6 +827,7 @@ emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type, } count -= elements_per_request; + req_element += elements_per_request; } -- cgit v1.2.3 From c235cc71a296e63f65cafcc95839119cf3cf2a63 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 28 Aug 2007 11:35:52 -0400 Subject: i965: flush batch buffer when getting the maximum. This makes some 3D programs such as pymol work well. --- src/mesa/drivers/dri/i965/brw_draw.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 0c64d7e756..5ca9b2f549 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -331,6 +331,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, else { /* Otherwise, explicitly do the cliprects at this point: */ + GLuint nprims = 0; for (j = 0; j < brw->intel.numClipRects; j++) { brw_emit_cliprect(brw, &brw->intel.pClipRects[j]); @@ -338,6 +339,11 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, */ for (i = 0; i < nr_prims; i++) { brw_emit_prim(brw, &prim[i]); + + if (++nprims == VBO_MAX_PRIM) { + intel_batchbuffer_flush(brw->intel.batch); + nprims = 0; + } } } } -- cgit v1.2.3 From 500193dca8cee7d8b609bd20cb60d20c96d77de3 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 28 Aug 2007 12:27:51 -0700 Subject: Add register defines for hw binning --- src/mesa/drivers/dri/i915tex/i915_reg.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_reg.h b/src/mesa/drivers/dri/i915tex/i915_reg.h index 34c6821405..a9fa56e8a6 100644 --- a/src/mesa/drivers/dri/i915tex/i915_reg.h +++ b/src/mesa/drivers/dri/i915tex/i915_reg.h @@ -112,6 +112,20 @@ /* 3DSTATE_CHROMA_KEY */ /* 3DSTATE_CLEAR_PARAMETERS, p150 */ +/* + * Sets the color, depth and stencil clear values used by the + * CLEAR_RECT and ZONE_INIT primitive types, respectively. These + * primitives set override most 3d state and only take a minimal x/y + * vertex. The color/z/stencil information is supplied here and + * therefore cannot vary per vertex. + */ +#define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) +/* Dword 1 */ +#define CLEARPARAM_CLEAR_RECT (1 << 16) +#define CLEARPARAM_ZONE_INIT (0 << 16) +#define CLEARPARAM_WRITE_COLOR (1 << 2) +#define CLEARPARAM_WRITE_DEPTH (1 << 1) +#define CLEARPARAM_WRITE_STENCIL (1 << 0) /* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ #define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) @@ -424,6 +438,17 @@ #define S7_DEPTH_OFFSET_CONST_MASK ~0 + +/* Helper macros for blend factors + */ +#define DST_BLND_FACT(f) ((f)< Date: Wed, 29 Aug 2007 10:13:10 -0400 Subject: i965: samplers group in fours in WM_STATE. fix bug#9415 --- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index ff5cb31bdd..5b4f2abd0e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -117,7 +117,7 @@ static void upload_wm_unit(struct brw_context *brw ) wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754; /* CACHE_NEW_SAMPLER */ - wm.wm4.sampler_count = brw->wm.sampler_count; + wm.wm4.sampler_count = (brw->wm.sampler_count + 1) / 4; wm.wm4.sampler_state_pointer = brw->wm.sampler_gs_offset >> 5; /* BRW_NEW_FRAGMENT_PROGRAM */ -- cgit v1.2.3 From f6a89e1884535a6136900febc163ee930c1d2179 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 29 Aug 2007 13:03:34 -0400 Subject: i965: check NULL pointer. fix bug#12193 --- src/mesa/drivers/dri/i965/intel_pixel_bitmap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index f3f062e651..23f381fe91 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -174,6 +174,8 @@ do_blit_bitmap( GLcontext *ctx, GLubyte ub[4]; } color; + if (!dst) + return GL_FALSE; if (unpack->BufferObj->Name) { bitmap = map_pbo(ctx, width, height, unpack, bitmap); -- cgit v1.2.3 From bad6e175cf59cce630c37d73f6e71f3a4de50ae6 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 29 Aug 2007 15:11:10 -0400 Subject: i965: store read drawable info in intel_context. Some OpenGL operations are based on read drawable. fix bug#10136. --- src/mesa/drivers/dri/i965/intel_context.c | 4 ++++ src/mesa/drivers/dri/i965/intel_context.h | 1 + src/mesa/drivers/dri/i965/intel_pixel_copy.c | 5 +++-- 3 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index eafe809d3a..1fbf571184 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -576,6 +576,10 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if (driContextPriv) { struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; + if (intel->driReadDrawable != driReadPriv) { + intel->driReadDrawable = driReadPriv; + } + if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 406f8483dc..ae25592908 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -234,6 +234,7 @@ struct intel_context int driFd; __DRIdrawablePrivate *driDrawable; + __DRIdrawablePrivate *driReadDrawable; __DRIscreenPrivate *driScreen; intelScreenPrivate *intelScreen; volatile drmI830Sarea *sarea; diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c index 58dc49505f..3bdf2fb479 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c @@ -231,6 +231,7 @@ do_blit_copypixels(GLcontext * ctx, if (intel->driDrawable->numClipRects) { __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIdrawablePrivate *dReadPriv = intel->driReadDrawable; drm_clip_rect_t *box = dPriv->pClipRects; drm_clip_rect_t dest_rect; GLint nbox = dPriv->numClipRects; @@ -262,8 +263,8 @@ do_blit_copypixels(GLcontext * ctx, srcy = dPriv->h - srcy - height; dstx += dPriv->x; dsty += dPriv->y; - srcx += dPriv->x; - srcy += dPriv->y; + srcx += dReadPriv->x; + srcy += dReadPriv->y; /* Clip against the source region. This is the only source * clipping we do. Dst is clipped with cliprects below. -- cgit v1.2.3 From 3b7df51eb5f5e2f980248f5e8c547869ea93ac78 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 30 Aug 2007 08:41:38 -0600 Subject: s/movaps/movups/ (see bug 12216) --- src/mesa/x86-64/xform4.S | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/x86-64/xform4.S b/src/mesa/x86-64/xform4.S index 65328f6666..4f7f914eea 100644 --- a/src/mesa/x86-64/xform4.S +++ b/src/mesa/x86-64/xform4.S @@ -1,10 +1,8 @@ -/* $Id: xform4.S,v 1.2 2006/04/17 18:58:24 krh Exp $ */ - /* * Mesa 3-D graphics library - * Version: 3.5 + * Version: 7.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -64,7 +62,7 @@ _mesa_x86_64_transform_points4_general: p4_general_loop: - movaps (%rdx), %xmm8 /* ox | oy | oz | ow */ + movups (%rdx), %xmm8 /* ox | oy | oz | ow */ prefetchw 16(%rdi) pshufd $0x00, %xmm8, %xmm0 /* ox | ox | ox | ox */ -- cgit v1.2.3 From 74e1d0996d109ce6426507f9ca64cf38d3b83acf Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 30 Aug 2007 18:04:49 +0200 Subject: fix another occurence of movaps which might not be aligned --- src/mesa/x86-64/xform4.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/x86-64/xform4.S b/src/mesa/x86-64/xform4.S index 4f7f914eea..3f9c9d56ab 100644 --- a/src/mesa/x86-64/xform4.S +++ b/src/mesa/x86-64/xform4.S @@ -147,7 +147,7 @@ _mesa_x86_64_transform_points4_3d: p4_3d_loop: - movaps (%rdx), %xmm8 /* ox | oy | oz | ow */ + movups (%rdx), %xmm8 /* ox | oy | oz | ow */ prefetchw 16(%rdi) pshufd $0x00, %xmm8, %xmm0 /* ox | ox | ox | ox */ -- cgit v1.2.3 From 1dd94a63ace0c6133f80191ba3b3e5f56f86c8fe Mon Sep 17 00:00:00 2001 From: David Moore Date: Thu, 30 Aug 2007 14:43:30 -0700 Subject: Bug #10571: Fix 965 line clipping when neither vertex needs clipping. --- src/mesa/drivers/dri/i965/brw_clip_line.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 83182270ea..0103be4345 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -130,6 +130,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) struct brw_instruction *plane_loop; struct brw_instruction *plane_active; struct brw_instruction *is_negative; + struct brw_instruction *is_neg2; struct brw_instruction *not_culled; struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD); @@ -183,13 +184,20 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) /* Coming back in. We know that both cannot be negative * because the line would have been culled in that case. */ - brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); - brw_math_invert(p, c->reg.t, c->reg.t); - brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); - brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); - brw_MOV(p, c->reg.t0, c->reg.t); - brw_set_predicate_control(p, BRW_PREDICATE_NONE); + /* If both are positive, do nothing */ + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0)); + is_neg2 = brw_IF(p, BRW_EXECUTE_1); + { + brw_ADD(p, c->reg.t, c->reg.dp0, negate(c->reg.dp1)); + brw_math_invert(p, c->reg.t, c->reg.t); + brw_MUL(p, c->reg.t, c->reg.t, c->reg.dp0); + + brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_G, c->reg.t, c->reg.t0 ); + brw_MOV(p, c->reg.t0, c->reg.t); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + } + brw_ENDIF(p, is_neg2); } brw_ENDIF(p, is_negative); } -- cgit v1.2.3 From 22bc3cdd49eb81d48ad4b8f06be0b9a9de624c91 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 31 Aug 2007 12:51:36 +0800 Subject: i965: Take the upper limitation on LOD into account. --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 83a4b02e48..81fc9ef2f0 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -192,8 +192,8 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, */ sampler->ss0.base_level = U_FIXED(0, 1); - sampler->ss1.max_lod = U_FIXED(MAX2(texObj->MaxLod, 0), 6); - sampler->ss1.min_lod = U_FIXED(MAX2(texObj->MinLod, 0), 6); + sampler->ss1.max_lod = U_FIXED(MIN2(MAX2(texObj->MaxLod, 0), 13), 6); + sampler->ss1.min_lod = U_FIXED(MIN2(MAX2(texObj->MinLod, 0), 13), 6); sampler->ss2.default_color_pointer = sdc_gs_offset >> 5; } -- cgit v1.2.3 From b47c9f8c915ae4ca8c7fa5ee3b6b64f17c38b569 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 31 Aug 2007 13:42:20 +0800 Subject: optimize 965 clip 1. increase clip thread number to 2 2. do cliptest for -rhw --- src/mesa/drivers/dri/i965/brw_clip_line.c | 7 ++ src/mesa/drivers/dri/i965/brw_clip_state.c | 2 +- src/mesa/drivers/dri/i965/brw_clip_tri.c | 107 +++++++++++++++++++++++++++-- src/mesa/drivers/dri/i965/brw_clip_util.c | 12 +--- 4 files changed, 113 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 0103be4345..9ad00676d4 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -147,6 +147,13 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_clip_init_planes(c); brw_clip_init_clipmask(c); + /* -ve rhw workaround */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), + brw_imm_ud(1<<20)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + plane_loop = brw_DO(p, BRW_EXECUTE_1); { /* if (planemask & 1) diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index 1e6d6fa176..ae46d7a86e 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -55,7 +55,7 @@ static void upload_clip_unit( struct brw_context *brw ) /* BRW_NEW_URB_FENCE */ clip.thread4.nr_urb_entries = brw->urb.nr_clip_entries; clip.thread4.urb_entry_allocation_size = brw->urb.vsize - 1; - clip.thread4.max_threads = 0; /* Hmm, maybe the max is 1 or 2 threads */ + clip.thread4.max_threads = 1; /* 2 threads */ if (INTEL_DEBUG & DEBUG_STATS) clip.thread4.stats_enable = 1; diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index f62b02cedf..506ab3712d 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -42,6 +42,20 @@ #include "brw_util.h" #include "brw_clip.h" +static struct brw_reg get_tmp( struct brw_clip_compile *c ) +{ + struct brw_reg tmp = brw_vec4_grf(c->last_tmp, 0); + + if (++c->last_tmp > c->prog_data.total_grf) + c->prog_data.total_grf = c->last_tmp; + + return tmp; +} + +static void release_tmps( struct brw_clip_compile *c ) +{ + c->last_tmp = c->first_tmp; +} void brw_clip_tri_alloc_regs( struct brw_clip_compile *c, @@ -435,15 +449,103 @@ static void maybe_do_clip_tri( struct brw_clip_compile *c ) brw_ENDIF(p, do_clip); } - +static void brw_clip_test( struct brw_clip_compile *c ) +{ + struct brw_reg t = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t2 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + struct brw_reg t3 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); + + struct brw_reg v0 = get_tmp(c); + struct brw_reg v1 = get_tmp(c); + struct brw_reg v2 = get_tmp(c); + + struct brw_indirect vt0 = brw_indirect(0, 0); + struct brw_indirect vt1 = brw_indirect(1, 0); + struct brw_indirect vt2 = brw_indirect(2, 0); + + struct brw_compile *p = &c->func; + + brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0])); + brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1])); + brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2])); + brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS])); + brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS])); + brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS])); + brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f)); + + /* test nearz, xmin, ymin plane */ + brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t2, BRW_CONDITIONAL_LE, negate(v1), get_element(v1, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t3, BRW_CONDITIONAL_LE, negate(v2), get_element(v2, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_XOR(p, t, t1, t2); + brw_XOR(p, t1, t2, t3); + brw_OR(p, t, t, t1); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 0), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<5))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 1), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<3))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 2), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<1))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + /* test farz, xmax, ymax plane */ + brw_CMP(p, t1, BRW_CONDITIONAL_L, v0, get_element(v0, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t2, BRW_CONDITIONAL_L, v1, get_element(v1, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, t3, BRW_CONDITIONAL_L, v2, get_element(v2, 3)); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + brw_XOR(p, t, t1, t2); + brw_XOR(p, t1, t2, t3); + brw_OR(p, t, t, t1); + + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 0), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<4))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 1), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<2))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_NZ, + get_element(t, 2), brw_imm_ud(0)); + brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud((1<<0))); + brw_set_predicate_control(p, BRW_PREDICATE_NONE); + + release_tmps(c); +} void brw_emit_tri_clip( struct brw_clip_compile *c ) { + struct brw_instruction *neg_rhw; + struct brw_compile *p = &c->func; brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6); brw_clip_tri_init_vertices(c); brw_clip_init_clipmask(c); + /* if -ve rhw workaround bit is set, + do cliptest */ + brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); + brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), + brw_imm_ud(1<<20)); + neg_rhw = brw_IF(p, BRW_EXECUTE_1); + { + brw_clip_test(c); + } + brw_ENDIF(p, neg_rhw); + /* Can't push into do_clip_tri because with polygon (or quad) * flatshading, need to apply the flatshade here because we don't * respect the PV when converting to trifan for emit: @@ -462,6 +564,3 @@ void brw_emit_tri_clip( struct brw_clip_compile *c ) */ brw_clip_kill_thread(c); } - - - diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c index 19bef19801..c37bfeb1ce 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_util.c +++ b/src/mesa/drivers/dri/i965/brw_clip_util.c @@ -272,6 +272,7 @@ void brw_clip_kill_thread(struct brw_clip_compile *c) + struct brw_reg brw_clip_plane0_address( struct brw_clip_compile *c ) { return brw_address(c->reg.fixed_planes); @@ -327,8 +328,7 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c ) /* Shift so that lowest outcode bit is rightmost: */ - brw_MOV(p, c->reg.planemask, incoming); - brw_SHR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(26)); + brw_SHR(p, c->reg.planemask, incoming, brw_imm_ud(26)); if (c->key.nr_userclip) { struct brw_reg tmp = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UD); @@ -342,13 +342,5 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c ) release_tmp(c, tmp); } - - /* Test for -ve rhw workaround - */ - brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); - brw_AND(p, vec1(brw_null_reg()), incoming, brw_imm_ud(1<<20)); - brw_OR(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(0x3f)); - brw_set_predicate_control(p, BRW_PREDICATE_NONE); - } -- cgit v1.2.3 From 214347fdb4c30dc8bac5d4b9a823458709bc53ea Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 31 Aug 2007 16:50:48 +0800 Subject: i965: Calculate the positional light in homogeneous coordinates. fix bug#11009 --- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 5 +++++ src/mesa/tnl/t_vp_build.c | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index b69be350a9..339a330448 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1003,6 +1003,11 @@ static void build_lighting( struct tnl_program *p ) VPpli = get_temp(p); half = get_temp(p); + + /* In homogeneous object coordinates + */ + emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); + emit_op2(p, OPCODE_MUL, Ppli, 0, Ppli, dist); /* Calulate VPpli vector */ diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index ee1a2498b3..336f3c7a2a 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -960,6 +960,11 @@ static void build_lighting( struct tnl_program *p ) VPpli = get_temp(p); half = get_temp(p); + /* In homogeneous object coordinates + */ + emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); + emit_op2(p, OPCODE_MUL, Ppli, 0, Ppli, dist); + /* Calulate VPpli vector */ emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); -- cgit v1.2.3 From b0a1e81887a831f72ffbec4fe005e1837c81018c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 31 Aug 2007 19:43:16 +0200 Subject: nouveau: add hw-dependent function to update modelview*projection matrix --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 6 ++++ src/mesa/drivers/dri/nouveau/nouveau_state.c | 17 ++++++++++ src/mesa/drivers/dri/nouveau/nv10_state.c | 46 ++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv20_state.c | 5 +++ src/mesa/drivers/dri/nouveau/nv30_state.c | 5 +++ src/mesa/drivers/dri/nouveau/nv50_state.c | 5 +++ 7 files changed, 85 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 1e13324b98..ae0a6d5c9e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -210,6 +210,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, _swsetup_CreateContext( ctx ); _math_matrix_ctr(&nmesa->viewport); + _math_matrix_ctr(&nmesa->model_proj); nouveauDDInitStateFuncs( ctx ); nouveauSpanInitFunctions( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 778c4401e4..94d729daef 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -86,6 +86,9 @@ typedef struct nouveau_hw_func_t { nouveau_renderbuffer_t *depth); /* Update anything that depends on the window position/size */ void (*WindowMoved)(struct nouveau_context *); + + /* Update projection matrix */ + void (*UpdateModelProjMatrix)(struct nouveau_context *); } nouveau_hw_func; typedef struct nouveau_context { @@ -117,6 +120,9 @@ typedef struct nouveau_context { GLuint color_offset; GLuint specular_offset; + /* Projection*modelview matrix */ + GLmatrix model_proj; + /* Vertex state */ GLuint vertex_size; GLubyte *verts; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index f618dcfc99..6c63b12c46 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -100,6 +100,16 @@ static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far) nouveauCalcViewport(ctx); } +static void nouveauUpdateModelProjMatrix(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + _math_matrix_mul_matrix(&(nmesa->model_proj), &(ctx->_ModelProjectMatrix), + ctx->ModelviewMatrixStack.Top); + + nmesa->hw_func.UpdateModelProjMatrix(nmesa); +} + static void nouveauDDUpdateHWState(GLcontext *ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -141,6 +151,13 @@ static void nouveauDDUpdateHWState(GLcontext *ctx) static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state) { + if ( new_state & _NEW_PROJECTION ) { + nouveauUpdateModelProjMatrix(ctx); + } + if ( new_state & _NEW_MODELVIEW ) { + nouveauUpdateModelProjMatrix(ctx); + } + _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _vbo_InvalidateState( ctx, new_state ); diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 79d567b25d..9c63bd118a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -750,6 +750,51 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } +static void nv10UpdateModelProjMatrix(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat w = ((GLfloat) ctx->Viewport.Width) * 0.5; + GLfloat h = ((GLfloat) ctx->Viewport.Height) * 0.5; + GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; + GLfloat projection[16]; + int i; + + if (ctx->DrawBuffer) { + if (ctx->DrawBuffer->_DepthBuffer) { + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } + } + } + + /* Rescale for viewport */ + for (i=0; i<4; i++) { + projection[i] = w * nmesa->model_proj.m[i]; + } + for (i=0; i<4; i++) { + projection[i+4] = -h * nmesa->model_proj.m[i+4]; + } + for (i=0; i<4; i++) { + projection[i+8] = max_depth * nmesa->model_proj.m[i+8]; + } + for (i=0; i<4; i++) { + projection[i+12] = nmesa->model_proj.m[i+12]; + } + + for (i=0; i<16; i++) { + printf("%d\t%.3f\t%.3f\n", i, + nmesa->model_proj.m[i], projection[i]); + } + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); + OUT_RINGp(projection, 16); +} + /* Update anything that depends on the window position/size */ static void nv10WindowMoved(nouveauContextPtr nmesa) { @@ -1011,4 +1056,5 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv10InitCard; nmesa->hw_func.BindBuffers = nv10BindBuffers; nmesa->hw_func.WindowMoved = nv10WindowMoved; + nmesa->hw_func.UpdateModelProjMatrix = nv10UpdateModelProjMatrix; } diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 6b583980a4..c6efa6b72c 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -636,6 +636,10 @@ static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } +static void nv20UpdateModelProjMatrix(nouveauContextPtr nmesa) +{ +} + /* Update anything that depends on the window position/size */ static void nv20WindowMoved(nouveauContextPtr nmesa) { @@ -820,5 +824,6 @@ void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv20InitCard; nmesa->hw_func.BindBuffers = nv20BindBuffers; nmesa->hw_func.WindowMoved = nv20WindowMoved; + nmesa->hw_func.UpdateModelProjMatrix = nv20UpdateModelProjMatrix; } diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index cd3ee98688..ebd9e1c514 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -767,6 +767,10 @@ static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) } } +static void nv30UpdateModelProjMatrix(nouveauContextPtr nmesa) +{ +} + static void nv30WindowMoved(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; @@ -998,5 +1002,6 @@ void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv30InitCard; nmesa->hw_func.BindBuffers = nv30BindBuffers; nmesa->hw_func.WindowMoved = nv30WindowMoved; + nmesa->hw_func.UpdateModelProjMatrix = nv30UpdateModelProjMatrix; } diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c index a9236f093c..66a18c4a15 100644 --- a/src/mesa/drivers/dri/nouveau/nv50_state.c +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -520,6 +520,10 @@ static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) /* Only with shaders */ } +static void nv50UpdateModelProjMatrix(nouveauContextPtr nmesa) +{ +} + static void nv50WindowMoved(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; @@ -638,4 +642,5 @@ void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv50InitCard; nmesa->hw_func.BindBuffers = nv50BindBuffers; nmesa->hw_func.WindowMoved = nv50WindowMoved; + nmesa->hw_func.UpdateModelProjMatrix = nv50UpdateModelProjMatrix; } -- cgit v1.2.3 From 47768ce0e59a76cbe367fe3b66be4150cd4ea3a8 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 31 Aug 2007 19:45:14 +0200 Subject: nouveau: nv10: remove setting projection matrix when scaling viewport --- src/mesa/drivers/dri/nouveau/nv10_state.c | 41 +++++++++---------------------- 1 file changed, 11 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 9c63bd118a..bdfc75b875 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -43,20 +43,17 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) GLfloat projection[16]; int i; - if (!ctx->DrawBuffer) { - return; - } - if (!ctx->DrawBuffer->_DepthBuffer) { - return; - } - - switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { - case 16: - max_depth *= 32767.0; - break; - case 24: - max_depth *= 16777215.0; - break; + if (ctx->DrawBuffer) { + if (ctx->DrawBuffer->_DepthBuffer) { + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } + } } BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); @@ -64,17 +61,6 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) OUT_RINGf (h - 2048.0); OUT_RINGf (max_depth); OUT_RINGf (0.0); - - /* FIXME: should multiply by gl projection and modelview ? */ - memset(projection, 0, sizeof(projection)); - projection[0*4+0] = w; - projection[1*4+1] = -h; - projection[2*4+2] = max_depth; - projection[3*4+3] = 1.0; - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); - for (i=0; i<16; i++) { - OUT_RINGf (projection[i]); - } } static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) @@ -786,11 +772,6 @@ static void nv10UpdateModelProjMatrix(nouveauContextPtr nmesa) projection[i+12] = nmesa->model_proj.m[i+12]; } - for (i=0; i<16; i++) { - printf("%d\t%.3f\t%.3f\n", i, - nmesa->model_proj.m[i], projection[i]); - } - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); OUT_RINGp(projection, 16); } -- cgit v1.2.3 From 6dd98e9853a6984150aa47467112e016c40a4ab4 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 31 Aug 2007 16:42:05 -0600 Subject: Fix problem introduced in previous commit in which a state variable (uniform) is written to. (see bug 12239) Also, added some assertions to the emit_arg() and emit_dst() functions to catch this kind of error in the future. --- src/mesa/tnl/t_vp_build.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 336f3c7a2a..63f7890205 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 2006 Tungsten Graphics All Rights Reserved. + * Copyright (C) 2007 Tungsten Graphics 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"), @@ -457,9 +457,13 @@ static void register_matrix_param5( struct tnl_program *p, } +/** + * Convert a ureg source register to a prog_src_register. + */ static void emit_arg( struct prog_src_register *src, struct ureg reg ) { + assert(reg.file != PROGRAM_OUTPUT); src->File = reg.file; src->Index = reg.idx; src->Swizzle = reg.swz; @@ -469,9 +473,18 @@ static void emit_arg( struct prog_src_register *src, src->RelAddr = 0; } +/** + * Convert a ureg dest register to a prog_dst_register. + */ static void emit_dst( struct prog_dst_register *dst, struct ureg reg, GLuint mask ) { + /* Check for legal output register type. UNDEFINED will occur in + * instruction that don't produce a result (like END). + */ + assert(reg.file == PROGRAM_TEMPORARY || + reg.file == PROGRAM_OUTPUT || + reg.file == PROGRAM_UNDEFINED); dst->File = reg.file; dst->Index = reg.idx; /* allow zero as a shorthand for xyzw */ @@ -956,18 +969,19 @@ static void build_lighting( struct tnl_program *p ) STATE_POSITION); struct ureg V = get_eye_position(p); struct ureg dist = get_temp(p); + struct ureg tmpPpli = get_temp(p); VPpli = get_temp(p); half = get_temp(p); - /* In homogeneous object coordinates - */ - emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); - emit_op2(p, OPCODE_MUL, Ppli, 0, Ppli, dist); + /* In homogeneous object coordinates + */ + emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); + emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist); - /* Calulate VPpli vector + /* Calculate VPpli vector */ - emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); + emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V); /* Normalize VPpli. The dist value also used in * attenuation below. @@ -999,6 +1013,7 @@ static void build_lighting( struct tnl_program *p ) emit_normalize_vec3(p, half, half); release_temp(p, dist); + release_temp(p, tmpPpli); } /* Calculate dot products: -- cgit v1.2.3 From cb7da3f09655f9c66eabb6a38f581c9176980cd2 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Sat, 1 Sep 2007 15:43:15 +0800 Subject: i965: Correct build_lighting in i965 driver according to commit 6dd98e9853a6984150aa47467112e016c40a4ab4. --- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 339a330448..2ed80dc36e 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1000,6 +1000,7 @@ static void build_lighting( struct tnl_program *p ) STATE_POSITION); struct ureg V = get_eye_position(p); struct ureg dist = get_temp(p); + struct ureg tmpPpli = get_temp(p); VPpli = get_temp(p); half = get_temp(p); @@ -1007,11 +1008,11 @@ static void build_lighting( struct tnl_program *p ) /* In homogeneous object coordinates */ emit_op1(p, OPCODE_RCP, dist, 0, swizzle1(Ppli, W)); - emit_op2(p, OPCODE_MUL, Ppli, 0, Ppli, dist); + emit_op2(p, OPCODE_MUL, tmpPpli, 0, Ppli, dist); /* Calulate VPpli vector */ - emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); + emit_op2(p, OPCODE_SUB, VPpli, 0, tmpPpli, V); /* Normalize VPpli. The dist value also used in * attenuation below. @@ -1043,6 +1044,7 @@ static void build_lighting( struct tnl_program *p ) emit_normalize_vec3(p, half, half); release_temp(p, dist); + release_temp(p, tmpPpli); } /* Calculate dot products: -- cgit v1.2.3 From c45bb05b3c0b65981b6ddeaf1bb043b9a6f7f3fc Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 3 Sep 2007 23:08:57 +0200 Subject: nouveau: separate modelview and projection matrix updates --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_context.h | 9 ++++++--- src/mesa/drivers/dri/nouveau/nouveau_state.c | 22 ++++++++++++++-------- src/mesa/drivers/dri/nouveau/nv10_state.c | 18 +++++++++++------- src/mesa/drivers/dri/nouveau/nv20_state.c | 5 ----- src/mesa/drivers/dri/nouveau/nv30_state.c | 5 ----- src/mesa/drivers/dri/nouveau/nv50_state.c | 5 ----- 7 files changed, 32 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index ae0a6d5c9e..0f7bd4aa07 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -210,7 +210,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, _swsetup_CreateContext( ctx ); _math_matrix_ctr(&nmesa->viewport); - _math_matrix_ctr(&nmesa->model_proj); + _math_matrix_ctr(&nmesa->projection); nouveauDDInitStateFuncs( ctx ); nouveauSpanInitFunctions( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 94d729daef..51666ef91c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -88,7 +88,10 @@ typedef struct nouveau_hw_func_t { void (*WindowMoved)(struct nouveau_context *); /* Update projection matrix */ - void (*UpdateModelProjMatrix)(struct nouveau_context *); + void (*UpdateProjectionMatrix)(GLcontext *); + + /* Update modelview matrix (used for lighting and vertex weight) */ + void (*UpdateModelviewMatrix)(GLcontext *); } nouveau_hw_func; typedef struct nouveau_context { @@ -120,8 +123,8 @@ typedef struct nouveau_context { GLuint color_offset; GLuint specular_offset; - /* Projection*modelview matrix */ - GLmatrix model_proj; + /* Projection matrix */ + GLmatrix projection; /* Vertex state */ GLuint vertex_size; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 6c63b12c46..9e64a7010e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -100,14 +100,12 @@ static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far) nouveauCalcViewport(ctx); } -static void nouveauUpdateModelProjMatrix(GLcontext *ctx) +static void nouveauUpdateProjectionMatrix(GLcontext *ctx) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - _math_matrix_mul_matrix(&(nmesa->model_proj), &(ctx->_ModelProjectMatrix), - ctx->ModelviewMatrixStack.Top); +} - nmesa->hw_func.UpdateModelProjMatrix(nmesa); +static void nouveauUpdateModelviewMatrix(GLcontext *ctx) +{ } static void nouveauDDUpdateHWState(GLcontext *ctx) @@ -151,11 +149,13 @@ static void nouveauDDUpdateHWState(GLcontext *ctx) static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + if ( new_state & _NEW_PROJECTION ) { - nouveauUpdateModelProjMatrix(ctx); + nmesa->hw_func.UpdateProjectionMatrix(ctx); } if ( new_state & _NEW_MODELVIEW ) { - nouveauUpdateModelProjMatrix(ctx); + nmesa->hw_func.UpdateModelviewMatrix(ctx); } _swrast_InvalidateState( ctx, new_state ); @@ -203,6 +203,8 @@ void nouveauDDInitState(nouveauContextPtr nmesa) /* Initialize the driver's state functions */ void nouveauDDInitStateFuncs(GLcontext *ctx) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + ctx->Driver.UpdateState = nouveauDDInvalidateState; ctx->Driver.ClearIndex = NULL; @@ -253,6 +255,10 @@ void nouveauDDInitStateFuncs(GLcontext *ctx) ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + /* Matrix updates */ + nmesa->hw_func.UpdateProjectionMatrix = nouveauUpdateProjectionMatrix; + nmesa->hw_func.UpdateModelviewMatrix = nouveauUpdateModelviewMatrix; } #define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index bdfc75b875..f9a8356772 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -736,9 +736,9 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } -static void nv10UpdateModelProjMatrix(nouveauContextPtr nmesa) +static void nv10UpdateProjectionMatrix(GLcontext *ctx) { - GLcontext *ctx = nmesa->glCtx; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLfloat w = ((GLfloat) ctx->Viewport.Width) * 0.5; GLfloat h = ((GLfloat) ctx->Viewport.Height) * 0.5; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; @@ -758,18 +758,22 @@ static void nv10UpdateModelProjMatrix(nouveauContextPtr nmesa) } } + /* Calc projection * modelview */ + _math_matrix_mul_matrix(&(nmesa->projection), &(ctx->_ModelProjectMatrix), + ctx->ModelviewMatrixStack.Top); + /* Rescale for viewport */ for (i=0; i<4; i++) { - projection[i] = w * nmesa->model_proj.m[i]; + projection[i] = w * nmesa->projection.m[i]; } for (i=0; i<4; i++) { - projection[i+4] = -h * nmesa->model_proj.m[i+4]; + projection[i+4] = -h * nmesa->projection.m[i+4]; } for (i=0; i<4; i++) { - projection[i+8] = max_depth * nmesa->model_proj.m[i+8]; + projection[i+8] = max_depth * nmesa->projection.m[i+8]; } for (i=0; i<4; i++) { - projection[i+12] = nmesa->model_proj.m[i+12]; + projection[i+12] = nmesa->projection.m[i+12]; } BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); @@ -1037,5 +1041,5 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv10InitCard; nmesa->hw_func.BindBuffers = nv10BindBuffers; nmesa->hw_func.WindowMoved = nv10WindowMoved; - nmesa->hw_func.UpdateModelProjMatrix = nv10UpdateModelProjMatrix; + nmesa->hw_func.UpdateProjectionMatrix = nv10UpdateProjectionMatrix; } diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index c6efa6b72c..6b583980a4 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -636,10 +636,6 @@ static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } -static void nv20UpdateModelProjMatrix(nouveauContextPtr nmesa) -{ -} - /* Update anything that depends on the window position/size */ static void nv20WindowMoved(nouveauContextPtr nmesa) { @@ -824,6 +820,5 @@ void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv20InitCard; nmesa->hw_func.BindBuffers = nv20BindBuffers; nmesa->hw_func.WindowMoved = nv20WindowMoved; - nmesa->hw_func.UpdateModelProjMatrix = nv20UpdateModelProjMatrix; } diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index ebd9e1c514..cd3ee98688 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -767,10 +767,6 @@ static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) } } -static void nv30UpdateModelProjMatrix(nouveauContextPtr nmesa) -{ -} - static void nv30WindowMoved(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; @@ -1002,6 +998,5 @@ void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv30InitCard; nmesa->hw_func.BindBuffers = nv30BindBuffers; nmesa->hw_func.WindowMoved = nv30WindowMoved; - nmesa->hw_func.UpdateModelProjMatrix = nv30UpdateModelProjMatrix; } diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c index 66a18c4a15..a9236f093c 100644 --- a/src/mesa/drivers/dri/nouveau/nv50_state.c +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -520,10 +520,6 @@ static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) /* Only with shaders */ } -static void nv50UpdateModelProjMatrix(nouveauContextPtr nmesa) -{ -} - static void nv50WindowMoved(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; @@ -642,5 +638,4 @@ void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.InitCard = nv50InitCard; nmesa->hw_func.BindBuffers = nv50BindBuffers; nmesa->hw_func.WindowMoved = nv50WindowMoved; - nmesa->hw_func.UpdateModelProjMatrix = nv50UpdateModelProjMatrix; } -- cgit v1.2.3 From 2f8ff58c0e8fbb60974be9c2412db8610b2152e2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Mon, 3 Sep 2007 23:42:33 +0200 Subject: nouveau: nv10: forgot function to set modelview matrix --- src/mesa/drivers/dri/nouveau/nv10_state.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index f9a8356772..93fc4ff936 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -40,7 +40,6 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) GLfloat w = ((GLfloat) ctx->Viewport.Width) * 0.5; GLfloat h = ((GLfloat) ctx->Viewport.Height) * 0.5; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; - GLfloat projection[16]; int i; if (ctx->DrawBuffer) { @@ -780,6 +779,16 @@ static void nv10UpdateProjectionMatrix(GLcontext *ctx) OUT_RINGp(projection, 16); } +static void nv10UpdateModelviewMatrix(GLcontext *ctx) +{ + /* TODO update modelview if lighting or vertex weight enabled + update inverse modelview if lighting enabled + or update projection if lighting and vertex weight disabled + */ + + nv10UpdateProjectionMatrix(ctx); +} + /* Update anything that depends on the window position/size */ static void nv10WindowMoved(nouveauContextPtr nmesa) { @@ -1042,4 +1051,5 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) nmesa->hw_func.BindBuffers = nv10BindBuffers; nmesa->hw_func.WindowMoved = nv10WindowMoved; nmesa->hw_func.UpdateProjectionMatrix = nv10UpdateProjectionMatrix; + nmesa->hw_func.UpdateModelviewMatrix = nv10UpdateModelviewMatrix; } -- cgit v1.2.3 From c2e1ee08b083638a7306e15ca48e9ea516d42dc4 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 3 Sep 2007 16:20:05 -0600 Subject: Use temporary matrix in __gluInvertMatrixd() to fix aliasing problem (see bugs 12269, 6748) --- src/glu/sgi/libutil/project.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/glu/sgi/libutil/project.c b/src/glu/sgi/libutil/project.c index d22989c385..356b46b899 100644 --- a/src/glu/sgi/libutil/project.c +++ b/src/glu/sgi/libutil/project.c @@ -171,9 +171,9 @@ static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4], ** Invert 4x4 matrix. ** Contributed by David Moore (See Mesa bug #6748) */ -static int __gluInvertMatrixd(const GLdouble m[16], GLdouble inv[16]) +static int __gluInvertMatrixd(const GLdouble m[16], GLdouble invOut[16]) { - double det; + double inv[16], det; int i; inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15] @@ -216,7 +216,7 @@ static int __gluInvertMatrixd(const GLdouble m[16], GLdouble inv[16]) det = 1.0 / det; for (i = 0; i < 16; i++) - inv[i] *= det; + invOut[i] = inv[i] * det; return GL_TRUE; } -- cgit v1.2.3 From ece08b7fd9af5ba67afa0a5d8e0a11f688ab4b0f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 4 Sep 2007 19:13:07 +0200 Subject: nouveau: nv10: need to transpose mesa model+proj matrix for hw --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 1 - src/mesa/drivers/dri/nouveau/nouveau_context.h | 3 --- src/mesa/drivers/dri/nouveau/nv10_state.c | 15 +++++---------- 3 files changed, 5 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 0f7bd4aa07..1e13324b98 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -210,7 +210,6 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, _swsetup_CreateContext( ctx ); _math_matrix_ctr(&nmesa->viewport); - _math_matrix_ctr(&nmesa->projection); nouveauDDInitStateFuncs( ctx ); nouveauSpanInitFunctions( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 51666ef91c..77fe13a9cd 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -123,9 +123,6 @@ typedef struct nouveau_context { GLuint color_offset; GLuint specular_offset; - /* Projection matrix */ - GLmatrix projection; - /* Vertex state */ GLuint vertex_size; GLubyte *verts; diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 93fc4ff936..94525ba2a8 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -40,7 +40,6 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) GLfloat w = ((GLfloat) ctx->Viewport.Width) * 0.5; GLfloat h = ((GLfloat) ctx->Viewport.Height) * 0.5; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; - int i; if (ctx->DrawBuffer) { if (ctx->DrawBuffer->_DepthBuffer) { @@ -757,22 +756,18 @@ static void nv10UpdateProjectionMatrix(GLcontext *ctx) } } - /* Calc projection * modelview */ - _math_matrix_mul_matrix(&(nmesa->projection), &(ctx->_ModelProjectMatrix), - ctx->ModelviewMatrixStack.Top); - - /* Rescale for viewport */ + /* Transpose and rescale for viewport */ for (i=0; i<4; i++) { - projection[i] = w * nmesa->projection.m[i]; + projection[i] = w * ctx->_ModelProjectMatrix.m[i*4]; } for (i=0; i<4; i++) { - projection[i+4] = -h * nmesa->projection.m[i+4]; + projection[i+4] = -h * ctx->_ModelProjectMatrix.m[i*4+1]; } for (i=0; i<4; i++) { - projection[i+8] = max_depth * nmesa->projection.m[i+8]; + projection[i+8] = max_depth * ctx->_ModelProjectMatrix.m[i*4+2]; } for (i=0; i<4; i++) { - projection[i+12] = nmesa->projection.m[i+12]; + projection[i+12] = ctx->_ModelProjectMatrix.m[i*4+3]; } BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); -- cgit v1.2.3 From 8752a20decab59de4dd5feb9672b8299126eb7eb Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 4 Sep 2007 23:21:21 +0200 Subject: nouveau: who needs nv03 ? --- src/mesa/drivers/dri/nouveau/nouveau_card_list.h | 7 ------- src/mesa/drivers/dri/nouveau/nouveau_context.c | 3 --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 3 --- 3 files changed, 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h index 8ec5c4a188..c2600bc532 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h @@ -1,7 +1,4 @@ static nouveau_card nouveau_card_list[]={ -{0x0008, "EDGE 3D", 0, NV_03, 0}, -{0x0009, "EDGE 3D", 0, NV_03, 0}, -{0x0010, "Mutara V08", 0, NV_03, 0}, {0x0020, "RIVA TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x0029, "RIVA TNT2 Ultra", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, @@ -220,10 +217,6 @@ static nouveau_card nouveau_card_list[]={ {0x03D1, "GeForce 6100 nForce 405", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x03D2, "GeForce 6100 nForce 400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x03D5, "GeForce 6100 nForce 420", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, -{0x0008, "NV1", 0, NV_03, 0}, -{0x0009, "DAC64", 0, NV_03, 0}, -{0x0018, "Riva128", 0, NV_03, 0}, -{0x0019, "Riva128ZX", 0, NV_03, 0}, {0x0020, "TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x0028, "TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x0029, "UTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 1e13324b98..f9f33eceeb 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -216,9 +216,6 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nouveauDDInitState( nmesa ); switch(nmesa->screen->card->type) { - case NV_03: - //nv03TriInitFunctions( ctx ); - break; case NV_04: case NV_05: nv04TriInitFunctions( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 9e64a7010e..1cfcc31486 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -171,9 +171,6 @@ void nouveauDDInitState(nouveauContextPtr nmesa) uint32_t type = nmesa->screen->card->type; switch(type) { - case NV_03: - /* Unimplemented */ - break; case NV_04: case NV_05: nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); -- cgit v1.2.3 From 1a15b2169ba6cb100627eb525a20a00537cfb6f0 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 5 Sep 2007 13:31:01 +0800 Subject: i965: only take non-varying attribute into account when compiling sf_prog. fix bug#11378 (which is introduced by commit d619cceea47dc3070ebb7f7ea4f8b6b31a672d38) --- src/mesa/drivers/dri/i965/brw_sf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index 73232b3c7c..a655b010fd 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -43,7 +43,7 @@ #include "brw_sf.h" #include "brw_state.h" -#define DO_SETUP_BITS ((1< Date: Wed, 5 Sep 2007 23:35:52 +0200 Subject: nouveau: nv10: emit vertex data in proper order for nv1x hw --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 78 ++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index e31faf21a7..be351df8f6 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -417,31 +417,65 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) /* * Tell t_vertex about the vertex format */ - for(i=0;i<16;i++) - { - if (RENDERINPUTS_TEST(index, i)) + if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) { + +#define NV10_EMIT_VERTEX_ATTRIB(i) \ + do { \ + if (RENDERINPUTS_TEST(index, i)) { \ + switch(attr_size[i]) \ + { \ + case 1: \ + EMIT_ATTR(i,EMIT_1F); \ + break; \ + case 2: \ + EMIT_ATTR(i,EMIT_2F); \ + break; \ + case 3: \ + EMIT_ATTR(i,EMIT_3F); \ + break; \ + case 4: \ + EMIT_ATTR(i,EMIT_4F); \ + break; \ + } \ + total_size+=attr_size[i]; \ + } \ + } while (0) + + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_FOG); + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_WEIGHT); + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_NORMAL); + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_TEX1); + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_TEX0); + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_COLOR1); + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_COLOR0); + NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_POS); + } else { + for(i=0;i<16;i++) { - slots=i+1; - switch(attr_size[i]) + if (RENDERINPUTS_TEST(index, i)) { - case 1: - EMIT_ATTR(i,EMIT_1F); - break; - case 2: - EMIT_ATTR(i,EMIT_2F); - break; - case 3: - EMIT_ATTR(i,EMIT_3F); - break; - case 4: - EMIT_ATTR(i,EMIT_4F); - break; + slots=i+1; + switch(attr_size[i]) + { + case 1: + EMIT_ATTR(i,EMIT_1F); + break; + case 2: + EMIT_ATTR(i,EMIT_2F); + break; + case 3: + EMIT_ATTR(i,EMIT_3F); + break; + case 4: + EMIT_ATTR(i,EMIT_4F); + break; + } + if (i==_TNL_ATTRIB_COLOR0) + nmesa->color_offset=total_size; + if (i==_TNL_ATTRIB_COLOR1) + nmesa->specular_offset=total_size; + total_size+=attr_size[i]; } - if (i==_TNL_ATTRIB_COLOR0) - nmesa->color_offset=total_size; - if (i==_TNL_ATTRIB_COLOR1) - nmesa->specular_offset=total_size; - total_size+=attr_size[i]; } } -- cgit v1.2.3 From a956184f70733bd22e2bbee515386da12302963f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 6 Sep 2007 19:12:58 +0200 Subject: Disable an assert for hw that do not emit POS as first vertex attrib, like nv1x --- src/mesa/tnl/t_vertex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c index a6728c318f..da32be9a17 100644 --- a/src/mesa/tnl/t_vertex.c +++ b/src/mesa/tnl/t_vertex.c @@ -294,7 +294,7 @@ GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map, GLuint i, j; assert(nr < _TNL_ATTRIB_MAX); - assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS); +/* assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS);*/ vtx->new_inputs = ~0; vtx->need_viewport = GL_FALSE; -- cgit v1.2.3 From 8f9b9ac387b1ffcecdca749b22d59eef5604bc6f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 6 Sep 2007 19:58:59 +0200 Subject: nouveau: need parenthesis around macro params, generator should be fixed --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 8758b538c8..b5e40dd6c6 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -502,7 +502,7 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000ce0 # define NV10_TCL_PRIMITIVE_3D_VERTEX_WGH_1F 0x00000ce4 # define NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE 0x00000cec -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + d * 0x0008) /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + ((d) * 0x0008)) /* Parameters: stride fields type */ # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE 0x00000cf0 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_POS 0x00000d00 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_POS 0x00000d04 /* Parameters: stride fields type */ -- cgit v1.2.3 From 7307ff80c9141aa9730c17f500e99d3d983840b8 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 6 Sep 2007 20:00:25 +0200 Subject: nouveau: nv10: replace macros by loop to set vertex attributes --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 95 +++++++++++++------------------ 1 file changed, 41 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index be351df8f6..a9bcc5df17 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -389,6 +389,12 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) struct vertex_buffer *VB = &tnl->vb; int attr_size[16]; int default_attr_size[8]={3,3,3,4,3,1,4,4}; + const int nv10_vtx_attribs[8]={ + _TNL_ATTRIB_FOG, _TNL_ATTRIB_WEIGHT, + _TNL_ATTRIB_NORMAL, _TNL_ATTRIB_TEX1, + _TNL_ATTRIB_TEX0, _TNL_ATTRIB_COLOR1, + _TNL_ATTRIB_COLOR0, _TNL_ATTRIB_POS + }; int i; int slots=0; int total_size=0; @@ -418,37 +424,27 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) * Tell t_vertex about the vertex format */ if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) { - -#define NV10_EMIT_VERTEX_ATTRIB(i) \ - do { \ - if (RENDERINPUTS_TEST(index, i)) { \ - switch(attr_size[i]) \ - { \ - case 1: \ - EMIT_ATTR(i,EMIT_1F); \ - break; \ - case 2: \ - EMIT_ATTR(i,EMIT_2F); \ - break; \ - case 3: \ - EMIT_ATTR(i,EMIT_3F); \ - break; \ - case 4: \ - EMIT_ATTR(i,EMIT_4F); \ - break; \ - } \ - total_size+=attr_size[i]; \ - } \ - } while (0) - - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_FOG); - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_WEIGHT); - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_NORMAL); - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_TEX1); - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_TEX0); - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_COLOR1); - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_COLOR0); - NV10_EMIT_VERTEX_ATTRIB(_TNL_ATTRIB_POS); + for(i=0;i<8;i++) { + int j = nv10_vtx_attribs[i]; + if (RENDERINPUTS_TEST(index, j)) { + switch(attr_size[j]) + { + case 1: + EMIT_ATTR(j,EMIT_1F); + break; + case 2: + EMIT_ATTR(j,EMIT_2F); + break; + case 3: + EMIT_ATTR(j,EMIT_3F); + break; + case 4: + EMIT_ATTR(j,EMIT_4F); + break; + } + total_size+=attr_size[j]; + } + } } else { for(i=0;i<16;i++) { @@ -493,29 +489,20 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) #define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2 -#define NV10_SET_VERTEX_ATTRIB(i,j) \ - do { \ - int size; \ - int stride = attr_size[j] << 2; \ - if (i==0) { \ - stride += total_stride; \ - } \ - size = attr_size[j] << 4; \ - size |= stride << 8; \ - size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \ - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \ - OUT_RING_CACHE(size); \ - total_stride += stride; \ - } while (0) - - NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG); - NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); - NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL); - NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1); - NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0); - NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1); - NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0); - NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS); + for(i=0;i<8;i++) { + int j = nv10_vtx_attribs[i]; + int size; + int stride = attr_size[j] << 2; + if (j==_TNL_ATTRIB_POS) { + stride += total_stride; + } + size = attr_size[j] << 4; + size |= stride << 8; + size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR((7-i)),1); + OUT_RING_CACHE(size); + total_stride += stride; + } BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1); OUT_RING_CACHE(0); -- cgit v1.2.3 From 15a6bf9118937e1e705e64e36fbceafbb3ad70ed Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 6 Sep 2007 22:33:22 +0200 Subject: nouveau: init depth range --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 1cfcc31486..e2f9fb869a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -296,6 +296,7 @@ void nouveauInitState(GLcontext *ctx) STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode ); STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func ); STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask ); + STATE_INIT(DepthRange)( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled ); -- cgit v1.2.3 From 249ca55555beea76c63a5f5dd09d35aa45efa180 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 6 Sep 2007 22:36:12 +0200 Subject: nouveau: nv10: check NULL pointers --- src/mesa/drivers/dri/nouveau/nv10_state.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 94525ba2a8..b63893d05c 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -253,8 +253,12 @@ static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLfloat depth_scale = 16777216.0; - if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 16) { - depth_scale = 32768.0; + if (ctx->DrawBuffer) { + if (ctx->DrawBuffer->_DepthBuffer) { + if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 16) { + depth_scale = 32768.0; + } + } } BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); -- cgit v1.2.3 From 241b7bc0a3e6277e15bb45887ad5533ffe692428 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 11 Sep 2007 16:49:02 +0800 Subject: i965: limit on LOD Bias, fix#11987 --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 81fc9ef2f0..8afefdd435 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -178,7 +178,7 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, /* Set LOD bias: */ - sampler->ss0.lod_bias = S_FIXED(texUnit->LodBias + texObj->LodBias, 6); + sampler->ss0.lod_bias = S_FIXED(CLAMP(texUnit->LodBias + texObj->LodBias, -16, 15), 6); sampler->ss0.lod_preclamp = 1; /* OpenGL mode */ sampler->ss0.default_color_mode = 0; /* OpenGL/DX10 mode */ -- cgit v1.2.3 From 0aedb9a2042bef9c13358500f93acaf8459a74cb Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 11 Sep 2007 16:57:07 +0800 Subject: i965: take the secondary color into account when drawing bitmap. fix#10688 --- src/mesa/drivers/dri/i965/intel_pixel_bitmap.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c index 23f381fe91..79c1fee9c0 100644 --- a/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/i965/intel_pixel_bitmap.c @@ -168,7 +168,8 @@ do_blit_bitmap( GLcontext *ctx, { struct intel_context *intel = intel_context(ctx); struct intel_region *dst = intel_drawbuf_region(intel); - + GLfloat tmpColor[4]; + union { GLuint ui; GLubyte ub[4]; @@ -183,10 +184,16 @@ do_blit_bitmap( GLcontext *ctx, return GL_TRUE; /* even though this is an error, we're done */ } - UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], ctx->Current.RasterColor[2]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], ctx->Current.RasterColor[1]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], ctx->Current.RasterColor[0]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], ctx->Current.RasterColor[3]); + COPY_4V(tmpColor, ctx->Current.RasterColor); + + if (NEED_SECONDARY_COLOR(ctx)) { + ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor); + } + + UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], tmpColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], tmpColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], tmpColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], tmpColor[3]); /* Does zoom apply to bitmaps? */ -- cgit v1.2.3 From 78b7e49c846c535f6907c18a9982d07c9e9feabb Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 11 Sep 2007 03:54:34 -0700 Subject: intel: disentangle planes & pipes This is the Mesa portion of the pipe & plane disambiguation. Mesa needs to use the new assumptions about plane vs. pipe mappings and should use the new SAREA field names to avoid confusion. --- src/mesa/drivers/dri/i915/intel_context.c | 20 ++++----- src/mesa/drivers/dri/i915/server/i830_common.h | 19 ++++---- src/mesa/drivers/dri/i915tex/intel_buffers.c | 54 +++++++++++------------ src/mesa/drivers/dri/i915tex/intel_fbo.h | 2 +- src/mesa/drivers/dri/i915tex/server/i830_common.h | 19 ++++---- 5 files changed, 60 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 11c23f24a1..07bee4ef9f 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -564,16 +564,16 @@ void intelWindowMoved( intelContextPtr intel ) drmI830Sarea *sarea = intel->sarea; drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; - drm_clip_rect_t pipeA_rect = { .x1 = sarea->pipeA_x, - .x2 = sarea->pipeA_x + sarea->pipeA_w, - .y1 = sarea->pipeA_y, - .y2 = sarea->pipeA_y + sarea->pipeA_h }; - drm_clip_rect_t pipeB_rect = { .x1 = sarea->pipeB_x, - .x2 = sarea->pipeB_x + sarea->pipeB_w, - .y1 = sarea->pipeB_y, - .y2 = sarea->pipeB_y + sarea->pipeB_h }; - GLint areaA = driIntersectArea( drw_rect, pipeA_rect ); - GLint areaB = driIntersectArea( drw_rect, pipeB_rect ); + drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, + .x2 = sarea->planeA_x + sarea->planeA_w, + .y1 = sarea->planeA_y, + .y2 = sarea->planeA_y + sarea->planeA_h }; + drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, + .x2 = sarea->planeB_x + sarea->planeB_w, + .y1 = sarea->planeB_y, + .y2 = sarea->planeB_y + sarea->planeB_h }; + GLint areaA = driIntersectArea( drw_rect, planeA_rect ); + GLint areaB = driIntersectArea( drw_rect, planeB_rect ); GLuint flags = intel->vblank_flags; if (areaB > areaA || (areaA == areaB && areaB > 0)) { diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/i915/server/i830_common.h index fb6ceaa52d..a5d2598849 100644 --- a/src/mesa/drivers/dri/i915/server/i830_common.h +++ b/src/mesa/drivers/dri/i915/server/i830_common.h @@ -119,14 +119,17 @@ typedef struct { unsigned int rotated_tiled; unsigned int rotated2_tiled; - int pipeA_x; - int pipeA_y; - int pipeA_w; - int pipeA_h; - int pipeB_x; - int pipeB_y; - int pipeB_w; - int pipeB_h; + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; + + int planeA_pipe; + int planeB_pipe; } drmI830Sarea; /* Flags for perf_boxes diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c index 15d02f8e2c..40f93dac91 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -50,7 +50,7 @@ #define DRM_VBLANK_FLIP 0x8000000 typedef struct drm_i915_flip { - int pipes; + int planes; } drm_i915_flip_t; #undef DRM_IOCTL_I915_FLIP @@ -235,34 +235,34 @@ intelWindowMoved(struct intel_context *intel) drmI830Sarea *sarea = intel->sarea; drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; - drm_clip_rect_t pipeA_rect = { .x1 = sarea->pipeA_x, .y1 = sarea->pipeA_y, - .x2 = sarea->pipeA_x + sarea->pipeA_w, - .y2 = sarea->pipeA_y + sarea->pipeA_h }; - drm_clip_rect_t pipeB_rect = { .x1 = sarea->pipeB_x, .y1 = sarea->pipeB_y, - .x2 = sarea->pipeB_x + sarea->pipeB_w, - .y2 = sarea->pipeB_y + sarea->pipeB_h }; - GLint areaA = driIntersectArea( drw_rect, pipeA_rect ); - GLint areaB = driIntersectArea( drw_rect, pipeB_rect ); + drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, + .x2 = sarea->planeA_x + sarea->planeA_w, + .y2 = sarea->planeA_y + sarea->planeA_h }; + drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, + .x2 = sarea->planeB_x + sarea->planeB_w, + .y2 = sarea->planeB_y + sarea->planeB_h }; + GLint areaA = driIntersectArea( drw_rect, planeA_rect ); + GLint areaB = driIntersectArea( drw_rect, planeB_rect ); GLuint flags = intel_fb->vblank_flags; GLboolean pf_active; - GLint pf_pipes; + GLint pf_planes; /* Update page flipping info */ - pf_pipes = 0; + pf_planes = 0; if (areaA > 0) - pf_pipes |= 1; + pf_planes |= 1; if (areaB > 0) - pf_pipes |= 2; + pf_planes |= 2; intel_fb->pf_current_page = (intel->sarea->pf_current_page >> - (intel_fb->pf_pipes & 0x2)) & 0x3; + (intel_fb->pf_planes & 0x2)) & 0x3; intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2; - pf_active = pf_pipes && (pf_pipes & intel->sarea->pf_active) == pf_pipes; + pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes; if (INTEL_DEBUG & DEBUG_LOCK) if (pf_active != intel_fb->pf_active) @@ -270,8 +270,8 @@ intelWindowMoved(struct intel_context *intel) pf_active ? "" : "in"); if (pf_active) { - /* Sync pages between pipes if we're flipping on both at the same time */ - if (pf_pipes == 0x3 && pf_pipes != intel_fb->pf_pipes && + /* Sync pages between planes if flipping on both at the same time */ + if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes && (intel->sarea->pf_current_page & 0x3) != (((intel->sarea->pf_current_page) >> 2) & 0x3)) { drm_i915_flip_t flip; @@ -287,7 +287,7 @@ intelWindowMoved(struct intel_context *intel) ((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % intel_fb->pf_num_pages) << 2; - flip.pipes = 0x2; + flip.planes = 0x2; } else { intel->sarea->pf_current_page = intel->sarea->pf_current_page & (0x3 << 2); @@ -295,13 +295,13 @@ intelWindowMoved(struct intel_context *intel) (intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % intel_fb->pf_num_pages; - flip.pipes = 0x1; + flip.planes = 0x1; } drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); } - intel_fb->pf_pipes = pf_pipes; + intel_fb->pf_planes = pf_planes; } intel_fb->pf_active = pf_active; @@ -715,14 +715,14 @@ intel_wait_flips(struct intel_context *intel, GLuint batch_flags) BUFFER_BACK_LEFT); if (intel_fb->Base.Name == 0 && intel_rb->pf_pending == intel_fb->pf_seq) { - GLint pf_pipes = intel_fb->pf_pipes; + GLint pf_planes = intel_fb->pf_planes; BATCH_LOCALS; /* Wait for pending flips to take effect */ BEGIN_BATCH(2, batch_flags); - OUT_BATCH(pf_pipes & 0x1 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP) + OUT_BATCH(pf_planes & 0x1 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP) : 0); - OUT_BATCH(pf_pipes & 0x2 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_B_FLIP) + OUT_BATCH(pf_planes & 0x2 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_B_FLIP) : 0); ADVANCE_BATCH(); @@ -761,7 +761,7 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv) if (dPriv->numClipRects && intel_fb->pf_active) { drm_i915_flip_t flip; - flip.pipes = intel_fb->pf_pipes; + flip.planes = intel_fb->pf_planes; ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); } @@ -776,7 +776,7 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv) } intel_fb->pf_current_page = (intel->sarea->pf_current_page >> - (intel_fb->pf_pipes & 0x2)) & 0x3; + (intel_fb->pf_planes & 0x2)) & 0x3; if (dPriv->numClipRects != 0) { intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->pf_pending = @@ -860,7 +860,7 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) swap.seqtype |= DRM_VBLANK_FLIP; intel_fb->pf_current_page = (((intel->sarea->pf_current_page >> - (intel_fb->pf_pipes & 0x2)) & 0x3) + 1) % + (intel_fb->pf_planes & 0x2)) & 0x3) + 1) % intel_fb->pf_num_pages; } @@ -884,7 +884,7 @@ intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) } else { if (swap.seqtype & DRM_VBLANK_FLIP) { intel_fb->pf_current_page = ((intel->sarea->pf_current_page >> - (intel_fb->pf_pipes & 0x2)) & 0x3) % + (intel_fb->pf_planes & 0x2)) & 0x3) % intel_fb->pf_num_pages; } diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.h b/src/mesa/drivers/dri/i915tex/intel_fbo.h index 963f5e706f..411d634231 100644 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.h +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.h @@ -44,7 +44,7 @@ struct intel_framebuffer /* Drawable page flipping state */ GLboolean pf_active; GLuint pf_seq; - GLint pf_pipes; + GLint pf_planes; GLint pf_current_page; GLint pf_num_pages; diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h index d4d58886ce..07cc63f663 100644 --- a/src/mesa/drivers/dri/i915tex/server/i830_common.h +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -121,14 +121,17 @@ typedef struct { unsigned int rotated_tiled; unsigned int rotated2_tiled; - int pipeA_x; - int pipeA_y; - int pipeA_w; - int pipeA_h; - int pipeB_x; - int pipeB_y; - int pipeB_w; - int pipeB_h; + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; + + int planeA_pipe; + int planeB_pipe; /* Triple buffering */ drm_handle_t third_handle; -- cgit v1.2.3 From 0c43ab6fbcd43f611170885f2068dd3a06bc6cea Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Sep 2007 09:20:48 -0600 Subject: fix comment --- src/mesa/drivers/dri/i915tex/i915_metaops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c index 3ab62bc806..397ff75b6f 100644 --- a/src/mesa/drivers/dri/i915tex/i915_metaops.c +++ b/src/mesa/drivers/dri/i915tex/i915_metaops.c @@ -95,7 +95,7 @@ meta_depth_replace(struct intel_context *intel) i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | S6_DEPTH_WRITE_ENABLE); - /* ctx->Driver.DepthFunc( ctx, GL_REPLACE ) + /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) */ i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; i915->meta.Ctx[I915_CTXREG_LIS6] |= -- cgit v1.2.3 From 995e01a6bcfe280149a2a076b5ea66ee94d0721c Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Sep 2007 09:21:34 -0600 Subject: Update depth test state when binding new framebuffer object --- src/mesa/drivers/dri/i915tex/intel_buffers.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c index 40f93dac91..cb151ab94d 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -1124,6 +1124,15 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); } + /* + * Update depth test state + */ + if (ctx->Depth.Test && fb->Visual.depthBits > 0) { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); + } + else { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); + } /** ** Release old regions, reference new regions -- cgit v1.2.3 From a614877592e8526d997242ce336fb455dd3f5bdb Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Sep 2007 10:56:35 -0600 Subject: In _mesa_make_current(), don't unbind FBOs from the old context. This fixes the X server crash reported by KeithP on Aug 29. The old context's FBOs will be unreferenced during context destruction so there's no memleak with this change. --- src/mesa/main/context.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index d988ef2d21..08db12b1b6 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1499,8 +1499,6 @@ void _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, GLframebuffer *readBuffer ) { - GET_CURRENT_CONTEXT(oldCtx); - if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(newCtx, "_mesa_make_current()\n"); @@ -1525,13 +1523,6 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, _glapi_set_context((void *) newCtx); ASSERT(_mesa_get_current_context() == newCtx); - if (oldCtx) { - _mesa_unreference_framebuffer(&oldCtx->WinSysDrawBuffer); - _mesa_unreference_framebuffer(&oldCtx->WinSysReadBuffer); - _mesa_unreference_framebuffer(&oldCtx->DrawBuffer); - _mesa_unreference_framebuffer(&oldCtx->ReadBuffer); - } - if (!newCtx) { _glapi_set_dispatch(NULL); /* none current */ } -- cgit v1.2.3 From acfeb3b6ea93bcb5b18e6f51a0727e39da608d76 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 11 Sep 2007 10:57:37 -0600 Subject: Fix-up #includes to remove some -I options. eg: #include "shader/program.h" and remove -I$(TOP)/src/mesa/program --- src/mesa/drivers/dri/Makefile.template | 5 ----- src/mesa/drivers/dri/i915/i915_fragprog.c | 11 ++++++----- src/mesa/drivers/dri/i915tex/i915_fragprog.c | 11 ++++++----- src/mesa/drivers/dri/i965/brw_program.c | 10 +++++----- src/mesa/drivers/dri/i965/brw_sf.h | 2 +- src/mesa/drivers/dri/i965/brw_vs.h | 2 +- src/mesa/drivers/dri/i965/brw_vs_emit.c | 4 ++-- src/mesa/drivers/dri/i965/brw_wm.h | 2 +- src/mesa/drivers/dri/r200/r200_fragshader.c | 10 +++++----- src/mesa/drivers/dri/r200/r200_vertprog.c | 8 ++++---- src/mesa/drivers/dri/r300/r300_shader.c | 7 +++---- src/mesa/drivers/dri/r300/r300_swtcl.c | 1 + src/mesa/drivers/dri/r300/r300_vertprog.c | 8 ++++---- src/mesa/drivers/dri/radeon/radeon_context.c | 17 +++++++++-------- 14 files changed, 48 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 6f2314ee8c..adf30ef41e 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -49,11 +49,6 @@ SHARED_INCLUDES = \ -I$(TOP)/src/mesa \ -I$(TOP)/src/mesa/main \ -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/math \ - -I$(TOP)/src/mesa/transform \ - -I$(TOP)/src/mesa/shader \ - -I$(TOP)/src/mesa/swrast \ - -I$(TOP)/src/mesa/swrast_setup \ -I$(TOP)/src/egl/main \ -I$(TOP)/src/egl/drivers/dri \ $(LIBDRM_CFLAGS) diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index abca0bbffe..c839bbdea5 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -29,19 +29,20 @@ #include "macros.h" #include "enums.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/program.h" +#include "shader/programopt.h" + #include "tnl/tnl.h" #include "tnl/t_context.h" + #include "intel_batchbuffer.h" #include "i915_reg.h" #include "i915_context.h" #include "i915_program.h" -#include "prog_instruction.h" -#include "prog_parameter.h" -#include "program.h" -#include "programopt.h" - /* 1, -1/3!, 1/5!, -1/7! */ diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c index 95ec50490a..4c3f2236e5 100644 --- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c @@ -29,19 +29,20 @@ #include "macros.h" #include "enums.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/program.h" +#include "shader/programopt.h" + #include "tnl/tnl.h" #include "tnl/t_context.h" + #include "intel_batchbuffer.h" #include "i915_reg.h" #include "i915_context.h" #include "i915_program.h" -#include "prog_instruction.h" -#include "prog_parameter.h" -#include "program.h" -#include "programopt.h" - /* 1, -1/3!, 1/5!, -1/7! */ diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 752fe49bcb..f7b1d31810 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -29,15 +29,15 @@ * Keith Whitwell */ +#include "main/imports.h" +#include "main/enums.h" #include "shader/prog_parameter.h" +#include "shader/program.h" +#include "tnl/tnl.h" + #include "brw_context.h" #include "brw_aub.h" #include "brw_util.h" -#include "program.h" -#include "imports.h" -#include "enums.h" -#include "tnl/tnl.h" - static void brwBindProgram( GLcontext *ctx, GLenum target, diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index e374e372bb..e8946511dd 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -34,9 +34,9 @@ #define BRW_SF_H +#include "shader/program.h" #include "brw_context.h" #include "brw_eu.h" -#include "program.h" #define SF_POINTS 0 diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h index fdb5785d67..8843f816f9 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.h +++ b/src/mesa/drivers/dri/i965/brw_vs.h @@ -36,7 +36,7 @@ #include "brw_context.h" #include "brw_eu.h" -#include "program.h" +#include "shader/program.h" struct brw_vs_prog_key { diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index d00f0c71a8..8733b470c2 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -30,8 +30,8 @@ */ -#include "program.h" -#include "macros.h" +#include "main/macros.h" +#include "shader/program.h" #include "shader/prog_parameter.h" #include "shader/prog_print.h" #include "brw_context.h" diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index f5fddfdb68..6dcf4732a9 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -34,9 +34,9 @@ #define BRW_WM_H +#include "shader/prog_instruction.h" #include "brw_context.h" #include "brw_eu.h" -#include "prog_instruction.h" /* A big lookup table is used to figure out which and how many * additional regs will inserted before the main payload in the WM diff --git a/src/mesa/drivers/dri/r200/r200_fragshader.c b/src/mesa/drivers/dri/r200/r200_fragshader.c index 5dd3adaef6..d514b28219 100644 --- a/src/mesa/drivers/dri/r200/r200_fragshader.c +++ b/src/mesa/drivers/dri/r200/r200_fragshader.c @@ -24,13 +24,13 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **************************************************************************/ -#include "glheader.h" -#include "macros.h" -#include "enums.h" +#include "main/glheader.h" +#include "main/macros.h" +#include "main/enums.h" #include "tnl/t_context.h" -#include "atifragshader.h" -#include "program.h" +#include "shader/atifragshader.h" +#include "shader/program.h" #include "r200_context.h" #include "r200_ioctl.h" #include "r200_tex.h" diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 6089d617c6..604b9c6cae 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -30,10 +30,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Aapo Tahkola * Roland Scheidegger */ -#include "glheader.h" -#include "macros.h" -#include "enums.h" -#include "program.h" +#include "main/glheader.h" +#include "main/macros.h" +#include "main/enums.h" +#include "shader/program.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" #include "shader/prog_statevars.h" diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 5f5ac7c4c7..77abf86a8e 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -1,8 +1,7 @@ -#include "glheader.h" -#include "macros.h" -#include "enums.h" -#include "program.h" +#include "main/glheader.h" + +#include "shader/program.h" #include "tnl/tnl.h" #include "r300_context.h" #include "r300_fragprog.h" diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index c949f33bf3..a732bdb559 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -40,6 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "image.h" #include "imports.h" +#include "light.h" #include "macros.h" #include "swrast/s_context.h" diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 7d4e8c9511..4dd3fd6a67 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -35,10 +35,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * For a description of the vertex program instruction set see r300_reg.h. */ -#include "glheader.h" -#include "macros.h" -#include "enums.h" -#include "program.h" +#include "main/glheader.h" +#include "main/macros.h" +#include "main/enums.h" +#include "shader/program.h" #include "shader/prog_instruction.h" #include "shader/prog_parameter.h" #include "shader/prog_statevars.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index 9451ec4aa5..b302275c71 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -35,14 +35,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Keith Whitwell */ -#include "glheader.h" -#include "api_arrayelt.h" -#include "context.h" -#include "simple_list.h" -#include "imports.h" -#include "matrix.h" -#include "extensions.h" -#include "framebuffer.h" +#include "main/glheader.h" +#include "main/api_arrayelt.h" +#include "main/context.h" +#include "main/simple_list.h" +#include "main/imports.h" +#include "main/matrix.h" +#include "main/extensions.h" +#include "main/framebuffer.h" +#include "main/state.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -- cgit v1.2.3 From 9944174abc546fe1845c26ce496edd747ad34347 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 11 Sep 2007 15:24:43 -0600 Subject: prefix some include filenames with shader/ --- src/mesa/drivers/common/driverfuncs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 9b1c3f1e06..1e7c279875 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -25,11 +25,10 @@ #include "glheader.h" #include "imports.h" +#include "arrayobj.h" #include "buffers.h" #include "context.h" #include "framebuffer.h" -#include "program.h" -#include "prog_execute.h" #include "queryobj.h" #include "renderbuffer.h" #include "texcompress.h" @@ -44,9 +43,10 @@ #include "fbobject.h" #include "texrender.h" #endif -#include "shader_api.h" -#include "arrayobj.h" +#include "shader/program.h" +#include "shader/prog_execute.h" +#include "shader/shader_api.h" #include "driverfuncs.h" #include "tnl/tnl.h" #include "swrast/swrast.h" -- cgit v1.2.3 From ae078e1a0abae58e325ed3ebcb1884867847826b Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 12 Sep 2007 15:13:06 +0800 Subject: i965: revert commit 1a15b2169ba6cb100627eb525a20a00537cfb6f0, and keep the instruction state unchanged after calling brw_emit_tri_setup/brw_emit_line_setup when building setup thread for SF_UNFILLED_TRIS. --- src/mesa/drivers/dri/i965/brw_sf.c | 2 +- src/mesa/drivers/dri/i965/brw_sf_emit.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index a655b010fd..738ceb0552 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -43,7 +43,7 @@ #include "brw_sf.h" #include "brw_state.h" -#define DO_SETUP_BITS ((1<<(FRAG_ATTRIB_MAX - MAX_VARYING))-1) +#define DO_SETUP_BITS ((1<<(FRAG_ATTRIB_MAX)) - 1) static void compile_sf_prog( struct brw_context *brw, struct brw_sf_prog_key *key ) diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index 22911a4649..5e86e428fa 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -663,7 +663,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) (1<<_3DPRIM_TRIFAN_NOSTIPPLE))); jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); { + brw_push_insn_state(p); brw_emit_tri_setup( c ); + brw_pop_insn_state(p); /* note - thread killed in subroutine */ } brw_land_fwd_jump(p, jmp); @@ -677,7 +679,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) (1<<_3DPRIM_LINESTRIP_CONT_BF))); jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); { + brw_push_insn_state(p); brw_emit_line_setup( c ); + brw_pop_insn_state(p); /* note - thread killed in subroutine */ } brw_land_fwd_jump(p, jmp); @@ -686,7 +690,9 @@ void brw_emit_anyprim_setup( struct brw_sf_compile *c ) brw_AND(p, v1_null_ud, payload_attr, brw_imm_ud(1< Date: Wed, 12 Sep 2007 16:51:45 +0800 Subject: i965: translate shadow compare function into correct internal function to match the EXT_shadow_funs spec. fix bug#11925 --- src/mesa/drivers/dri/i965/brw_wm_sampler_state.c | 2 +- src/mesa/drivers/dri/i965/intel_context.h | 2 +- src/mesa/drivers/dri/i965/intel_state.c | 25 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c index 8afefdd435..3c0952acf0 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c @@ -173,7 +173,7 @@ static void brw_update_sampler_state( struct gl_texture_unit *texUnit, * message (sample_c). So need to recompile WM program when * shadow comparison is enabled on each/any texture unit. */ - sampler->ss0.shadow_function = intel_translate_compare_func(texObj->CompareFunc); + sampler->ss0.shadow_function = intel_translate_shadow_compare_func(texObj->CompareFunc); } /* Set LOD bias: diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index ae25592908..053d93a82b 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -464,7 +464,7 @@ extern void intelInitStateFuncs( struct dd_function_table *functions ); #define BLENDFACT_INV_CONST_ALPHA 0x0f #define BLENDFACT_MASK 0x0f - +extern int intel_translate_shadow_compare_func( GLenum func ); extern int intel_translate_compare_func( GLenum func ); extern int intel_translate_stencil_op( GLenum op ); extern int intel_translate_blend_factor( GLenum factor ); diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c index 2e442db619..2f5467a4e4 100644 --- a/src/mesa/drivers/dri/i965/intel_state.c +++ b/src/mesa/drivers/dri/i965/intel_state.c @@ -38,6 +38,31 @@ #include "intel_regions.h" #include "swrast/swrast.h" +int intel_translate_shadow_compare_func( GLenum func ) +{ + switch(func) { + case GL_NEVER: + return COMPAREFUNC_ALWAYS; + case GL_LESS: + return COMPAREFUNC_LEQUAL; + case GL_LEQUAL: + return COMPAREFUNC_LESS; + case GL_GREATER: + return COMPAREFUNC_GEQUAL; + case GL_GEQUAL: + return COMPAREFUNC_GREATER; + case GL_NOTEQUAL: + return COMPAREFUNC_EQUAL; + case GL_EQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_ALWAYS: + return COMPAREFUNC_NEVER; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_NEVER; +} + int intel_translate_compare_func( GLenum func ) { switch(func) { -- cgit v1.2.3 From f5557c3a528fbad3750aaa18595dc3548b600609 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Wed, 12 Sep 2007 09:57:53 -0600 Subject: DESTDIR support. --- docs/install.html | 10 +++++++++- src/glu/Makefile | 4 ++-- src/glut/fbdev/Makefile | 8 ++++---- src/glut/glx/Makefile | 8 ++++---- src/glw/Makefile | 8 ++++---- src/mesa/Makefile | 14 +++++++------- src/mesa/drivers/dri/Makefile.template | 4 ++-- 7 files changed, 32 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/docs/install.html b/docs/install.html index 804dee59b5..0a36143069 100644 --- a/docs/install.html +++ b/docs/install.html @@ -287,7 +287,15 @@ already installed, you'll have to choose different directories, like To install Mesa's headers and libraries, run make install. But first, check the Mesa/configs/default file and examine the values of the INSTALL_DIR and DRI_DRIVER_INSTALL_DIR variables. -Change them if needed, then run make install +Change them if needed, then run make install. +

+ +

+The variable +DESTDIR may also be used to install the contents to a temporary +staging directory. +This can be useful for package management. +For example: make install DESTDIR=/somepath/

diff --git a/src/glu/Makefile b/src/glu/Makefile index 5ddc50946a..b8c55db6d0 100644 --- a/src/glu/Makefile +++ b/src/glu/Makefile @@ -14,8 +14,8 @@ default: $(TOP)/configs/current done install: - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) $(TOP)/$(LIB_DIR)/libGLU.* $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) $(TOP)/$(LIB_DIR)/libGLU.* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) clean: @for dir in $(SUBDIRS) ; do \ diff --git a/src/glut/fbdev/Makefile b/src/glut/fbdev/Makefile index 254ff8c098..d84d52ec48 100644 --- a/src/glut/fbdev/Makefile +++ b/src/glut/fbdev/Makefile @@ -69,10 +69,10 @@ $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) $(MKLIB_OPTIONS) $(OBJECTS) install: - $(INSTALL) -d $(INSTALL_DIR)/include/GL - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) -m 644 $(TOP)/include/GL/glut.h $(INSTALL_DIR)/include/GL - $(INSTALL) $(TOP)/$(LIB_DIR)/libglut* $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 $(TOP)/include/GL/glut.h $(DESTDIR)$(INSTALL_DIR)/include/GL + $(INSTALL) $(TOP)/$(LIB_DIR)/libglut* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) # Run 'make -f Makefile.solo dep' to update the dependencies if you change # what's included by any source file. diff --git a/src/glut/glx/Makefile b/src/glut/glx/Makefile index 7e1d56b327..b236c6fad3 100644 --- a/src/glut/glx/Makefile +++ b/src/glut/glx/Makefile @@ -97,10 +97,10 @@ $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) install: - $(INSTALL) -d $(INSTALL_DIR)/include/GL - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) -m 644 $(TOP)/include/GL/glut.h $(INSTALL_DIR)/include/GL - $(INSTALL) $(TOP)/$(LIB_DIR)/libglut* $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 $(TOP)/include/GL/glut.h $(DESTDIR)$(INSTALL_DIR)/include/GL + $(INSTALL) $(TOP)/$(LIB_DIR)/libglut* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) clean: diff --git a/src/glw/Makefile b/src/glw/Makefile index 5228cbbb72..778ffb0218 100644 --- a/src/glw/Makefile +++ b/src/glw/Makefile @@ -26,10 +26,10 @@ OBJECTS = $(GLW_SOURCES:.c=.o) default: $(TOP)/$(LIB_DIR)/$(GLW_LIB_NAME) install: - $(INSTALL) -d $(INSTALL_DIR)/include/GL - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) -m 644 *.h $(INSTALL_DIR)/include/GL - $(INSTALL) $(TOP)/$(LIB_DIR)/libGLw.* $(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 *.h $(DESTDIR)$(INSTALL_DIR)/include/GL + $(INSTALL) $(TOP)/$(LIB_DIR)/libGLw.* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) clean: -rm depend depend.bak diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 6943219036..a50e826701 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -149,22 +149,22 @@ subdirs: install: default - $(INSTALL) -d $(INSTALL_DIR)/include/GL - $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR) - $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ - $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \ + $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \ fi @if [ -e $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) ]; then \ - $(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(INSTALL_DIR)/$(LIB_DIR); \ + $(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \ fi @if [ "${DRIVER_DIRS}" = "dri" ] ; then \ cd drivers/dri ; $(MAKE) install ; \ fi ## NOT INSTALLED YET: -## $(INSTALL) -d $(INSTALL_DIR)/include/GLES -## $(INSTALL) -m 644 include/GLES/*.h $(INSTALL_DIR)/include/GLES +## $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES +## $(INSTALL) -m 644 include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES # Emacs tags diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index adf30ef41e..3576d0bac8 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -95,8 +95,8 @@ clean: install: $(LIBNAME) - $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR) - $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + $(INSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) include depend -- cgit v1.2.3 From 94617bc6d505b056b028dc0978ef4a94ee47fa7d Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Wed, 12 Sep 2007 10:03:05 -0600 Subject: pkg-config support --- .gitignore | 1 + src/glu/Makefile | 12 +++++++++++- src/glu/glu.pc.in | 11 +++++++++++ src/glut/glx/Makefile | 12 +++++++++++- src/glut/glx/glut.pc.in | 11 +++++++++++ src/glw/Makefile | 12 +++++++++++- src/glw/glw.pc.in | 11 +++++++++++ src/mesa/Makefile | 13 ++++++++++++- src/mesa/gl.pc.in | 11 +++++++++++ 9 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 src/glu/glu.pc.in create mode 100644 src/glut/glx/glut.pc.in create mode 100644 src/glw/glw.pc.in create mode 100644 src/mesa/gl.pc.in (limited to 'src') diff --git a/.gitignore b/.gitignore index 033e6e10bd..c128ba8609 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.o *.so *.sw[a-z] +*.pc *~ depend depend.bak diff --git a/src/glu/Makefile b/src/glu/Makefile index b8c55db6d0..836baa684c 100644 --- a/src/glu/Makefile +++ b/src/glu/Makefile @@ -13,9 +13,19 @@ default: $(TOP)/configs/current (cd $$dir ; $(MAKE)) ; \ done -install: +# GLU pkg-config file +pcedit = sed \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ + -e 's,@LIB_DIR@,$(LIB_DIR),' \ + -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' +glu.pc: glu.pc.in + $(pcedit) $< > $@ + +install: glu.pc $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig $(INSTALL) $(TOP)/$(LIB_DIR)/libGLU.* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 glu.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig clean: @for dir in $(SUBDIRS) ; do \ diff --git a/src/glu/glu.pc.in b/src/glu/glu.pc.in new file mode 100644 index 0000000000..5d6e52a75e --- /dev/null +++ b/src/glu/glu.pc.in @@ -0,0 +1,11 @@ +prefix=@INSTALL_DIR@ +exec_prefix=${prefix} +libdir=${exec_prefix}/@LIB_DIR@ +includedir=${prefix}/include + +Name: glu +Description: Mesa OpenGL Utility library +Requires: gl +Version: @VERSION@ +Libs: -L${libdir} -lGLU +Cflags: -I${includedir} diff --git a/src/glut/glx/Makefile b/src/glut/glx/Makefile index b236c6fad3..5a224c9af5 100644 --- a/src/glut/glx/Makefile +++ b/src/glut/glx/Makefile @@ -96,11 +96,21 @@ $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) $(GLUT_LIB_DEPS) $(OBJECTS) -install: +# glut pkgconfig file +pcedit = sed \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ + -e 's,@LIB_DIR@,$(LIB_DIR),' \ + -e 's,@VERSION@,$(GLUT_MAJOR).$(GLUT_MINOR).$(GLUT_TINY),' +glut.pc: glut.pc.in + $(pcedit) $< > $@ + +install: glut.pc $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig $(INSTALL) -m 644 $(TOP)/include/GL/glut.h $(DESTDIR)$(INSTALL_DIR)/include/GL $(INSTALL) $(TOP)/$(LIB_DIR)/libglut* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 glut.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig clean: diff --git a/src/glut/glx/glut.pc.in b/src/glut/glx/glut.pc.in new file mode 100644 index 0000000000..f732f2990d --- /dev/null +++ b/src/glut/glx/glut.pc.in @@ -0,0 +1,11 @@ +prefix=@INSTALL_DIR@ +exec_prefix=${prefix} +libdir=${exec_prefix}/@LIB_DIR@ +includedir=${prefix}/include + +Name: glut +Description: Mesa OpenGL Utility Toolkit library +Requires: gl glu +Version: @VERSION@ +Libs: -L${libdir} -lglut +Cflags: -I${includedir} diff --git a/src/glw/Makefile b/src/glw/Makefile index 778ffb0218..c32fc0ccad 100644 --- a/src/glw/Makefile +++ b/src/glw/Makefile @@ -25,11 +25,21 @@ OBJECTS = $(GLW_SOURCES:.c=.o) default: $(TOP)/$(LIB_DIR)/$(GLW_LIB_NAME) -install: +# GLU pkg-config file +pcedit = sed \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ + -e 's,@LIB_DIR@,$(LIB_DIR),' \ + -e 's,@VERSION@,$(MAJOR).$(MINOR).$(TINY),' +glw.pc: glw.pc.in + $(pcedit) $< > $@ + +install: glw.pc $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig $(INSTALL) -m 644 *.h $(DESTDIR)$(INSTALL_DIR)/include/GL $(INSTALL) $(TOP)/$(LIB_DIR)/libGLw.* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -m 644 glw.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig clean: -rm depend depend.bak diff --git a/src/glw/glw.pc.in b/src/glw/glw.pc.in new file mode 100644 index 0000000000..951e2dc2af --- /dev/null +++ b/src/glw/glw.pc.in @@ -0,0 +1,11 @@ +prefix=@INSTALL_DIR@ +exec_prefix=${prefix} +libdir=${exec_prefix}/@LIB_DIR@ +includedir=${prefix}/include + +Name: glw +Description: Mesa OpenGL widget library +Requires: gl +Version: @VERSION@ +Libs: -L${libdir} -lGLU +Cflags: -I${includedir} diff --git a/src/mesa/Makefile b/src/mesa/Makefile index a50e826701..c05b195957 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -133,6 +133,15 @@ $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECT fi +###################################################################### +# libGL pkg-config file +pcedit = sed \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ + -e 's,@LIB_DIR@,$(LIB_DIR),' \ + -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' +gl.pc: gl.pc.in + $(pcedit) $< > $@ + ###################################################################### # Generic stuff @@ -148,13 +157,15 @@ subdirs: @ (cd x86-64 ; $(MAKE)) -install: default +install: default gl.pc $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR) + $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \ $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \ fi + $(INSTALL) -m 644 gl.pc $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)/pkgconfig @if [ -e $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) ]; then \ $(INSTALL) $(TOP)/$(LIB_DIR)/libOSMesa* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \ fi diff --git a/src/mesa/gl.pc.in b/src/mesa/gl.pc.in new file mode 100644 index 0000000000..4b144ffa4b --- /dev/null +++ b/src/mesa/gl.pc.in @@ -0,0 +1,11 @@ +prefix=@INSTALL_DIR@ +exec_prefix=${prefix} +libdir=${exec_prefix}/@LIB_DIR@ +includedir=${prefix}/include + +Name: gl +Description: Mesa OpenGL library +Requires: +Version: @VERSION@ +Libs: -L${libdir} -lGL +Cflags: -I${includedir} -- cgit v1.2.3 From ba5290e836d5fd6e80dc460f75f6b032e2510382 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 12 Sep 2007 09:03:44 -0700 Subject: Remove unused plane->pipe mapping fields from SAREA private. --- src/mesa/drivers/dri/i915/server/i830_common.h | 3 --- src/mesa/drivers/dri/i915tex/server/i830_common.h | 3 --- 2 files changed, 6 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/i915/server/i830_common.h index a5d2598849..2962ecc68a 100644 --- a/src/mesa/drivers/dri/i915/server/i830_common.h +++ b/src/mesa/drivers/dri/i915/server/i830_common.h @@ -127,9 +127,6 @@ typedef struct { int planeB_y; int planeB_w; int planeB_h; - - int planeA_pipe; - int planeB_pipe; } drmI830Sarea; /* Flags for perf_boxes diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h index 07cc63f663..8735f93d14 100644 --- a/src/mesa/drivers/dri/i915tex/server/i830_common.h +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -130,9 +130,6 @@ typedef struct { int planeB_w; int planeB_h; - int planeA_pipe; - int planeB_pipe; - /* Triple buffering */ drm_handle_t third_handle; int third_offset; -- cgit v1.2.3 From 642267b2d8c9848c5c1a11ba2b598dc313a2737a Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 12 Sep 2007 13:37:10 -0600 Subject: Rename. "fcb" = fortran call back --- src/glut/glx/glut_fcb.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/glut/glx/glut_fcb.c (limited to 'src') diff --git a/src/glut/glx/glut_fcb.c b/src/glut/glx/glut_fcb.c new file mode 100644 index 0000000000..e93188b862 --- /dev/null +++ b/src/glut/glx/glut_fcb.c @@ -0,0 +1,164 @@ + +/* Copyright (c) Mark J. Kilgard, 1998. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +/* I appreciate the guidance from William Mitchell + (mitchell@cam.nist.gov) in developing this friend interface + for use by the f90gl package. See ../../README.fortran */ + +#include "glutint.h" + +/* FCB stands for Fortran CallBack. */ + +/* There is only one idleFunc, menuStateFunc, and menuStatusFunc, so they + can be saved in the wrappers for Fortran rather than the C structures. */ + +/* Set a Fortran callback function. */ + +void APIENTRY +__glutSetFCB(int which, void *func) +{ +#ifdef SUPPORT_FORTRAN + switch (which) { + case GLUT_FCB_DISPLAY: + __glutCurrentWindow->fdisplay = (GLUTdisplayFCB) func; + break; + case GLUT_FCB_RESHAPE: + __glutCurrentWindow->freshape = (GLUTreshapeFCB) func; + break; + case GLUT_FCB_MOUSE: + __glutCurrentWindow->fmouse = (GLUTmouseFCB) func; + break; + case GLUT_FCB_MOTION: + __glutCurrentWindow->fmotion = (GLUTmotionFCB) func; + break; + case GLUT_FCB_PASSIVE: + __glutCurrentWindow->fpassive = (GLUTpassiveFCB) func; + break; + case GLUT_FCB_ENTRY: + __glutCurrentWindow->fentry = (GLUTentryFCB) func; + break; + case GLUT_FCB_KEYBOARD: + __glutCurrentWindow->fkeyboard = (GLUTkeyboardFCB) func; + break; + case GLUT_FCB_KEYBOARD_UP: + __glutCurrentWindow->fkeyboardUp = (GLUTkeyboardFCB) func; + break; + case GLUT_FCB_WINDOW_STATUS: + __glutCurrentWindow->fwindowStatus = (GLUTwindowStatusFCB) func; + break; + case GLUT_FCB_VISIBILITY: + __glutCurrentWindow->fvisibility = (GLUTvisibilityFCB) func; + break; + case GLUT_FCB_SPECIAL: + __glutCurrentWindow->fspecial = (GLUTspecialFCB) func; + break; + case GLUT_FCB_SPECIAL_UP: + __glutCurrentWindow->fspecialUp = (GLUTspecialFCB) func; + break; + case GLUT_FCB_BUTTON_BOX: + __glutCurrentWindow->fbuttonBox = (GLUTbuttonBoxFCB) func; + break; + case GLUT_FCB_DIALS: + __glutCurrentWindow->fdials = (GLUTdialsFCB) func; + break; + case GLUT_FCB_SPACE_MOTION: + __glutCurrentWindow->fspaceMotion = (GLUTspaceMotionFCB) func; + break; + case GLUT_FCB_SPACE_ROTATE: + __glutCurrentWindow->fspaceRotate = (GLUTspaceRotateFCB) func; + break; + case GLUT_FCB_SPACE_BUTTON: + __glutCurrentWindow->fspaceButton = (GLUTspaceButtonFCB) func; + break; + case GLUT_FCB_TABLET_MOTION: + __glutCurrentWindow->ftabletMotion = (GLUTtabletMotionFCB) func; + break; + case GLUT_FCB_TABLET_BUTTON: + __glutCurrentWindow->ftabletButton = (GLUTtabletButtonFCB) func; + break; +#ifdef _WIN32 + case GLUT_FCB_JOYSTICK: + __glutCurrentWindow->fjoystick = (GLUTjoystickFCB) func; + break; +#endif + case GLUT_FCB_OVERLAY_DISPLAY: + __glutCurrentWindow->overlay->fdisplay = (GLUTdisplayFCB) func; + break; + case GLUT_FCB_SELECT: + __glutCurrentMenu->fselect = (GLUTselectFCB) func; + break; + case GLUT_FCB_TIMER: + __glutNewTimer->ffunc = (GLUTtimerFCB) func; + break; + } +#endif +} + +/* Get a Fortran callback function. */ + +void* APIENTRY +__glutGetFCB(int which) +{ +#ifdef SUPPORT_FORTRAN + switch (which) { + case GLUT_FCB_DISPLAY: + return (void *) __glutCurrentWindow->fdisplay; + case GLUT_FCB_RESHAPE: + return (void *) __glutCurrentWindow->freshape; + case GLUT_FCB_MOUSE: + return (void *) __glutCurrentWindow->fmouse; + case GLUT_FCB_MOTION: + return (void *) __glutCurrentWindow->fmotion; + case GLUT_FCB_PASSIVE: + return (void *) __glutCurrentWindow->fpassive; + case GLUT_FCB_ENTRY: + return (void *) __glutCurrentWindow->fentry; + case GLUT_FCB_KEYBOARD: + return (void *) __glutCurrentWindow->fkeyboard; + case GLUT_FCB_KEYBOARD_UP: + return (void *) __glutCurrentWindow->fkeyboardUp; + case GLUT_FCB_WINDOW_STATUS: + return (void *) __glutCurrentWindow->fwindowStatus; + case GLUT_FCB_VISIBILITY: + return (void *) __glutCurrentWindow->fvisibility; + case GLUT_FCB_SPECIAL: + return (void *) __glutCurrentWindow->fspecial; + case GLUT_FCB_SPECIAL_UP: + return (void *) __glutCurrentWindow->fspecialUp; + case GLUT_FCB_BUTTON_BOX: + return (void *) __glutCurrentWindow->fbuttonBox; + case GLUT_FCB_DIALS: + return (void *) __glutCurrentWindow->fdials; + case GLUT_FCB_SPACE_MOTION: + return (void *) __glutCurrentWindow->fspaceMotion; + case GLUT_FCB_SPACE_ROTATE: + return (void *) __glutCurrentWindow->fspaceRotate; + case GLUT_FCB_SPACE_BUTTON: + return (void *) __glutCurrentWindow->fspaceButton; + case GLUT_FCB_TABLET_MOTION: + return (void *) __glutCurrentWindow->ftabletMotion; + case GLUT_FCB_TABLET_BUTTON: + return (void *) __glutCurrentWindow->ftabletButton; + case GLUT_FCB_JOYSTICK: +#ifdef _WIN32 + return (void *) __glutCurrentWindow->fjoystick; +#else + return NULL; +#endif + case GLUT_FCB_OVERLAY_DISPLAY: + return (void *) __glutCurrentWindow->overlay->fdisplay; + case GLUT_FCB_SELECT: + return (void *) __glutCurrentMenu->fselect; + case GLUT_FCB_TIMER: + return (void *) __glutTimerList->ffunc; + default: + return NULL; + } +#else + return NULL; +#endif +} -- cgit v1.2.3 From ae0dd620fec580b77b0901ed1376e6a6b2569c7e Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 12 Sep 2007 13:40:15 -0600 Subject: Add glut_fcb.c to the build and update to fix warnings (see bug 12405) --- include/GL/glutf90.h | 4 ++-- src/glut/glx/Makefile | 1 + src/glut/glx/glut_fcb.c | 50 ++++++++++++++++++++++++------------------------- 3 files changed, 28 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/include/GL/glutf90.h b/include/GL/glutf90.h index 7ba3e19ef9..8a3a86727c 100644 --- a/include/GL/glutf90.h +++ b/include/GL/glutf90.h @@ -75,7 +75,7 @@ typedef void (GLUTCALLBACK *GLUTmenuStatusFCB) (int *, int *, int *); typedef void (GLUTCALLBACK *GLUTidleFCB) (void); /* Functions that set and return Fortran callback functions. */ -GLUTAPI void* APIENTRY __glutGetFCB(int which); -GLUTAPI void APIENTRY __glutSetFCB(int which, void *func); +GLUTAPI GLUTproc APIENTRY __glutGetFCB(int which); +GLUTAPI void APIENTRY __glutSetFCB(int which, GLUTproc func); #endif /* __glutf90_h__ */ diff --git a/src/glut/glx/Makefile b/src/glut/glx/Makefile index 5a224c9af5..f73158ad38 100644 --- a/src/glut/glx/Makefile +++ b/src/glut/glx/Makefile @@ -36,6 +36,7 @@ SOURCES = \ glut_dstr.c \ glut_event.c \ glut_ext.c \ + glut_fcb.c \ glut_fullscrn.c \ glut_gamemode.c \ glut_get.c \ diff --git a/src/glut/glx/glut_fcb.c b/src/glut/glx/glut_fcb.c index e93188b862..b272d0e227 100644 --- a/src/glut/glx/glut_fcb.c +++ b/src/glut/glx/glut_fcb.c @@ -19,7 +19,7 @@ /* Set a Fortran callback function. */ void APIENTRY -__glutSetFCB(int which, void *func) +__glutSetFCB(int which, GLUTproc func) { #ifdef SUPPORT_FORTRAN switch (which) { @@ -100,61 +100,61 @@ __glutSetFCB(int which, void *func) /* Get a Fortran callback function. */ -void* APIENTRY +GLUTproc APIENTRY __glutGetFCB(int which) { #ifdef SUPPORT_FORTRAN switch (which) { case GLUT_FCB_DISPLAY: - return (void *) __glutCurrentWindow->fdisplay; + return __glutCurrentWindow->fdisplay; case GLUT_FCB_RESHAPE: - return (void *) __glutCurrentWindow->freshape; + return __glutCurrentWindow->freshape; case GLUT_FCB_MOUSE: - return (void *) __glutCurrentWindow->fmouse; + return __glutCurrentWindow->fmouse; case GLUT_FCB_MOTION: - return (void *) __glutCurrentWindow->fmotion; + return __glutCurrentWindow->fmotion; case GLUT_FCB_PASSIVE: - return (void *) __glutCurrentWindow->fpassive; + return __glutCurrentWindow->fpassive; case GLUT_FCB_ENTRY: - return (void *) __glutCurrentWindow->fentry; + return __glutCurrentWindow->fentry; case GLUT_FCB_KEYBOARD: - return (void *) __glutCurrentWindow->fkeyboard; + return __glutCurrentWindow->fkeyboard; case GLUT_FCB_KEYBOARD_UP: - return (void *) __glutCurrentWindow->fkeyboardUp; + return __glutCurrentWindow->fkeyboardUp; case GLUT_FCB_WINDOW_STATUS: - return (void *) __glutCurrentWindow->fwindowStatus; + return __glutCurrentWindow->fwindowStatus; case GLUT_FCB_VISIBILITY: - return (void *) __glutCurrentWindow->fvisibility; + return __glutCurrentWindow->fvisibility; case GLUT_FCB_SPECIAL: - return (void *) __glutCurrentWindow->fspecial; + return __glutCurrentWindow->fspecial; case GLUT_FCB_SPECIAL_UP: - return (void *) __glutCurrentWindow->fspecialUp; + return __glutCurrentWindow->fspecialUp; case GLUT_FCB_BUTTON_BOX: - return (void *) __glutCurrentWindow->fbuttonBox; + return __glutCurrentWindow->fbuttonBox; case GLUT_FCB_DIALS: - return (void *) __glutCurrentWindow->fdials; + return __glutCurrentWindow->fdials; case GLUT_FCB_SPACE_MOTION: - return (void *) __glutCurrentWindow->fspaceMotion; + return __glutCurrentWindow->fspaceMotion; case GLUT_FCB_SPACE_ROTATE: - return (void *) __glutCurrentWindow->fspaceRotate; + return __glutCurrentWindow->fspaceRotate; case GLUT_FCB_SPACE_BUTTON: - return (void *) __glutCurrentWindow->fspaceButton; + return __glutCurrentWindow->fspaceButton; case GLUT_FCB_TABLET_MOTION: - return (void *) __glutCurrentWindow->ftabletMotion; + return __glutCurrentWindow->ftabletMotion; case GLUT_FCB_TABLET_BUTTON: - return (void *) __glutCurrentWindow->ftabletButton; + return __glutCurrentWindow->ftabletButton; case GLUT_FCB_JOYSTICK: #ifdef _WIN32 - return (void *) __glutCurrentWindow->fjoystick; + return __glutCurrentWindow->fjoystick; #else return NULL; #endif case GLUT_FCB_OVERLAY_DISPLAY: - return (void *) __glutCurrentWindow->overlay->fdisplay; + return __glutCurrentWindow->overlay->fdisplay; case GLUT_FCB_SELECT: - return (void *) __glutCurrentMenu->fselect; + return __glutCurrentMenu->fselect; case GLUT_FCB_TIMER: - return (void *) __glutTimerList->ffunc; + return __glutTimerList->ffunc; default: return NULL; } -- cgit v1.2.3 From 5fdeb52e5d21bfb7feff2253c7d9e18e6b3cb252 Mon Sep 17 00:00:00 2001 From: Jonathan Bestien-Filiatrault Date: Wed, 12 Sep 2007 16:21:13 -0600 Subject: check return value of invert_matrix() --- src/glu/mesa/Makefile | 2 +- src/glu/mesa/project.c | 6 ++++-- src/glu/mini/project.c | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/glu/mesa/Makefile b/src/glu/mesa/Makefile index 47f95ef024..611d7a630c 100644 --- a/src/glu/mesa/Makefile +++ b/src/glu/mesa/Makefile @@ -23,7 +23,7 @@ C_SOURCES = \ OBJECTS = $(C_SOURCES:.c=.o) -INCLUDES = -I. -I- -I$(TOP)/include +INCLUDES = -I. -I$(TOP)/include ##### RULES ##### diff --git a/src/glu/mesa/project.c b/src/glu/mesa/project.c index 6fa03267e5..2e79cdf084 100644 --- a/src/glu/mesa/project.c +++ b/src/glu/mesa/project.c @@ -346,7 +346,8 @@ gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, /* calcul transformation inverse */ matmul(A, proj, model); - invert_matrix(A, m); + if (!invert_matrix(A, m)) + return GL_FALSE; /* d'ou les coordonnees objets */ transform_point(out, m, in); @@ -386,7 +387,8 @@ gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw, /* calcul transformation inverse */ matmul(A, projMatrix, modelMatrix); - invert_matrix(A, m); + if (!invert_matrix(A, m)) + return GL_FALSE; /* d'ou les coordonnees objets */ transform_point(out, m, in); diff --git a/src/glu/mini/project.c b/src/glu/mini/project.c index a2747de55f..71279947cf 100644 --- a/src/glu/mini/project.c +++ b/src/glu/mini/project.c @@ -347,7 +347,8 @@ gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, /* calcul transformation inverse */ matmul(A, proj, model); - invert_matrix(A, m); + if (!invert_matrix(A, m)) + return GL_FALSE; /* d'ou les coordonnees objets */ transform_point(out, m, in); @@ -387,7 +388,8 @@ gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw, /* calcul transformation inverse */ matmul(A, projMatrix, modelMatrix); - invert_matrix(A, m); + if (!invert_matrix(A, m)) + return GL_FALSE; /* d'ou les coordonnees objets */ transform_point(out, m, in); -- cgit v1.2.3 From 20b331c2f6fa4e16f0c473f27914644e2bcd2b39 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Sep 2007 09:26:27 -0600 Subject: added null ptr check --- src/glut/glx/glut_fcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/glut/glx/glut_fcb.c b/src/glut/glx/glut_fcb.c index b272d0e227..c8a3422b36 100644 --- a/src/glut/glx/glut_fcb.c +++ b/src/glut/glx/glut_fcb.c @@ -154,7 +154,7 @@ __glutGetFCB(int which) case GLUT_FCB_SELECT: return __glutCurrentMenu->fselect; case GLUT_FCB_TIMER: - return __glutTimerList->ffunc; + return __glutTimerList ? __glutTimerList->ffunc : NULL; default: return NULL; } -- cgit v1.2.3 From d799b7a7ecbe3e773decfcc2ebd1b23f53fc48a7 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Sep 2007 11:29:00 -0600 Subject: Fix state.texgen parsing error (bug 12313). Replace *(*inst++) with *(*inst)++ in a few places. --- src/mesa/shader/arbprogparse.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 9a5290d920..737194d3b6 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1226,10 +1226,10 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, state_tokens[1] = coord; /* EYE or OBJECT */ - type = *(*inst++); + type = *(*inst)++; /* 0 - s, 1 - t, 2 - r, 3 - q */ - coord = *(*inst++); + coord = *(*inst)++; if (type == TEX_GEN_EYE) { switch (coord) { @@ -1245,6 +1245,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_EYE_Q; break; + default: + _mesa_problem(ctx, "bad texgen component in " + "parse_state_single_item()"); } } else { @@ -1261,6 +1264,9 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, case COMPONENT_W: state_tokens[2] = STATE_TEXGEN_OBJECT_Q; break; + default: + _mesa_problem(ctx, "bad texgen component in " + "parse_state_single_item()"); } } } @@ -1283,7 +1289,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, break; case STATE_POINT: - switch (*(*inst++)) { + switch (*(*inst)++) { case POINT_SIZE: state_tokens[0] = STATE_POINT_SIZE; break; @@ -2454,8 +2460,9 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, Program->Position = parse_position (inst); if (!found) { - program_error(ctx, Program->Position, - "2: Undefined variable"); /* src->name */ + char s[1000]; + sprintf(s, "Undefined variable: %s", src->name); + program_error(ctx, Program->Position, s); return 1; } -- cgit v1.2.3 From ab31a3a7647ca1b1567dbc58c6093c523173c988 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Sep 2007 11:41:49 -0600 Subject: added program_error2() function for better error reporting --- src/mesa/shader/arbprogparse.c | 107 +++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 737194d3b6..3360fef585 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -633,6 +633,41 @@ program_error(GLcontext *ctx, GLint position, const char *descrip) } +/** + * As above, but with an extra string parameter for more info. + */ +static void +program_error2(GLcontext *ctx, GLint position, const char *descrip, + const char *var) +{ + if (descrip) { + const char *prefix = "glProgramString(", *suffix = ")"; + char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + + _mesa_strlen(": ") + + _mesa_strlen(var) + + _mesa_strlen(prefix) + + _mesa_strlen(suffix) + 1); + if (str) { + _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix); + _mesa_error(ctx, GL_INVALID_OPERATION, str); + _mesa_free(str); + } + } + { + char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) + + _mesa_strlen(": ") + + _mesa_strlen(var) + 1); + if (str) { + _mesa_sprintf(str, "%s: %s", descrip, var); + } + _mesa_set_program_error(ctx, position, str); + if (str) { + _mesa_free(str); + } + } +} + + /** * constructs an integer from 4 GLubytes in LE format @@ -1693,18 +1728,14 @@ parse_attrib (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head struct arb_program *Program) { GLuint found; - char *error_msg; struct var_cache *attrib_var; attrib_var = parse_string (inst, vc_head, Program, &found); Program->Position = parse_position (inst); if (found) { - error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - attrib_var->name); - program_error(ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) attrib_var->name); return 1; } @@ -1882,12 +1913,9 @@ parse_param (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - param_var->name); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) param_var->name); return 1; } @@ -1982,12 +2010,9 @@ parse_temp (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, temp_var = parse_string (inst, vc_head, Program, &found); Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - temp_var->name); - program_error(ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) temp_var->name); return 1; } @@ -2028,12 +2053,9 @@ parse_output (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head output_var = parse_string (inst, vc_head, Program, &found); Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - output_var->name); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) output_var->name); return 1; } @@ -2059,12 +2081,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - temp_var->name); - program_error(ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) temp_var->name); return 1; } @@ -2074,12 +2093,9 @@ parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head, if (!found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); - _mesa_sprintf (error_msg, "Alias value %s is not defined", - temp_var->alias_binding->name); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Undefined alias value", + (char *) temp_var->alias_binding->name); return 1; } @@ -2102,12 +2118,9 @@ parse_address (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_hea temp_var = parse_string (inst, vc_head, Program, &found); Program->Position = parse_position (inst); if (found) { - char *error_msg = (char *) - _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); - _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", - temp_var->name); - program_error (ctx, Program->Position, error_msg); - _mesa_free (error_msg); + program_error2(ctx, Program->Position, + "Duplicate variable declaration", + (char *) temp_var->name); return 1; } @@ -2460,9 +2473,9 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst, Program->Position = parse_position (inst); if (!found) { - char s[1000]; - sprintf(s, "Undefined variable: %s", src->name); - program_error(ctx, Program->Position, s); + program_error2(ctx, Program->Position, + "Undefined variable", + (char *) src->name); return 1; } -- cgit v1.2.3 From 3a2559a1e9989655591b7faf93ea6bfa21dbff1b Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Thu, 13 Sep 2007 22:13:39 +0200 Subject: nouveau : diable broken light enable on nv10 --- src/mesa/drivers/dri/nouveau/nv10_state.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index b63893d05c..154ba3cce1 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -323,6 +323,11 @@ static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; // case GL_HISTOGRAM: // case GL_INDEX_LOGIC_OP: +#if 0 + /* light is broken, the hardware seem to only allow to use light + * in order : ie GL_LIGHT0 & GL_LIGHT2 is invalid + * In this case the blob remap GL_LIGHT2 to hw light 1 + */ case GL_LIGHT0: case GL_LIGHT1: case GL_LIGHT2: @@ -333,7 +338,11 @@ static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_LIGHT7: { uint32_t mask=1<<(2*(cap-GL_LIGHT0)); - nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); + if (state) + nmesa->enabled_lights |= mask; + else + nmesa->enabled_lights &= ~mask; + if (nmesa->lighting_enabled) { BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); @@ -349,6 +358,7 @@ static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) else OUT_RING_CACHE(0x0); break; +#endif case GL_LINE_SMOOTH: BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); OUT_RING_CACHE(state); -- cgit v1.2.3 From 885a95f4fa6d8adba2bfc1839b99f404b473f646 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 13 Sep 2007 14:42:23 -0600 Subject: Fix timer problem when using Fortran bindings (submitted by Bill Mitchell) Also, add some comments about what's going on. --- src/glut/glx/glut_event.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/glut/glx/glut_event.c b/src/glut/glx/glut_event.c index 0a96e8cf71..b5df7b2311 100644 --- a/src/glut/glx/glut_event.c +++ b/src/glut/glx/glut_event.c @@ -172,10 +172,14 @@ handleTimeouts(void) GETTIMEOFDAY(&now); while (IS_AT_OR_AFTER(__glutTimerList->timeout, now)) { timer = __glutTimerList; - __glutTimerList = timer->next; + /* call the timer function */ timer->func(timer->value); + /* remove from the linked list */ + __glutTimerList = timer->next; + /* put this timer on the "free" list */ timer->next = freeTimerList; freeTimerList = timer; + if (!__glutTimerList) break; } -- cgit v1.2.3 From ea07a0df9a2f689b8f5acaf92c40bbbd602cab3c Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 14 Sep 2007 11:10:23 +0800 Subject: i965: align the address of the first element within the index buffer. (fix#11910) --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 6150cac4aa..dc289ca9ae 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -593,6 +593,28 @@ void brw_upload_indices( struct brw_context *brw, ib_size, index_buffer->ptr, bufferobj); + } else { + if (((1 << get_index_type(index_buffer->type)) - 1) & offset) { + struct gl_buffer_object *vbo; + GLuint voffset; + GLubyte *map = ctx->Driver.MapBuffer(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + GL_DYNAMIC_DRAW_ARB, + bufferobj); + map += offset; + get_space(brw, ib_size, &vbo, &voffset); + + ctx->Driver.BufferSubData(ctx, + GL_ELEMENT_ARRAY_BUFFER_ARB, + voffset, + ib_size, + map, + vbo); + ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, bufferobj); + + bufferobj = vbo; + offset = voffset; + } } /* Emit the indexbuffer packet: -- cgit v1.2.3 From e04c58e06842e5157231f1bd4ba79ccbbaad8f1c Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Fri, 14 Sep 2007 16:26:56 +0800 Subject: mesa: bind VBO_ATTRIB_XXX to correct input array when executing a display list. fix #10604 --- src/mesa/vbo/vbo_save_draw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 3c6f0fccd9..da7bc765b7 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -132,9 +132,11 @@ static void vbo_bind_vertex_list( GLcontext *ctx, } for (attr = 0; attr < VBO_ATTRIB_MAX; attr++) { - if (node->attrsz[attr]) { + GLuint src = map[attr]; + + if (node->attrsz[src]) { arrays[attr].Ptr = (const GLubyte *)data; - arrays[attr].Size = node->attrsz[attr]; + arrays[attr].Size = node->attrsz[src]; arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); arrays[attr].Stride = node->vertex_size * sizeof(GLfloat); arrays[attr].Type = GL_FLOAT; -- cgit v1.2.3 From 032707eeca2e6a0fd931ebd9ef4831bf30baf183 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 14 Sep 2007 09:57:57 -0600 Subject: fix copypixels overlap test bug (#12417) --- src/mesa/swrast/s_copypix.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index bbe1081860..218a3b5590 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -71,13 +71,20 @@ regions_overlap(GLint srcx, GLint srcy, } else { /* add one pixel of slop when zooming, just to be safe */ - if ((srcx > dstx + (width * zoomX) + 1) || (srcx + width + 1 < dstx)) { + if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) { + /* src is completely right of dest */ + return GL_FALSE; + } + else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) { + /* src is completely left of dest */ return GL_FALSE; } else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) { + /* src is completely below dest */ return GL_FALSE; } else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) { + /* src is completely above dest */ return GL_FALSE; } else { -- cgit v1.2.3 From 63147344e422aa2b00b6b22d76fdea801c38b2ea Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Fri, 14 Sep 2007 22:07:34 +0200 Subject: nouveau : fix NV10_TCL_PRIMITIVE_3D_CLIP_PLANE --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 4 ++-- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index b5e40dd6c6..e08a5e4f7b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -393,7 +393,7 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_A 0x000003b4 # define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ # define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ -# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + (d) * 0x0004) # define NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE 0x000003e8 /* Parameters: projection modelview0 modelview1 */ # define NV10_TCL_PRIMITIVE_3D_POINT_SIZE 0x000003ec # define NV10_TCL_PRIMITIVE_3D_MODELVIEW0_MATRIX( d) (0x00000400 + d * 0x0004) @@ -401,7 +401,7 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW0_MATRIX( d) (0x00000480 + d * 0x0004) # define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW1_MATRIX( d) (0x000004c0 + d * 0x0004) # define NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000500 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000600 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000600 + (d) * 0x0010) # define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000604 + d * 0x0010) # define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000608 + d * 0x0010) # define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000060c + d * 0x0010) diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 154ba3cce1..2ba5d79684 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -200,7 +200,7 @@ static void nv10ClearStencil(GLcontext *ctx, GLint s) static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane - GL_CLIP_PLANE0), 4); OUT_RING_CACHEf(equation[0]); OUT_RING_CACHEf(equation[1]); OUT_RING_CACHEf(equation[2]); -- cgit v1.2.3 From 5e7835625912e5b64c1c0f76c7614367bec40039 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Fri, 14 Sep 2007 22:13:52 +0200 Subject: nouveau : check for nmesa->state_cache.atoms overflow --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 956dd549dc..0805882025 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -149,6 +149,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); #define BEGIN_RING_CACHE(subchannel,tag,size) do { \ nmesa->state_cache.dirty=1; \ nmesa->state_cache.current_pos=((tag)/4); \ + assert(nmesa->state_cache.current_pos + size <= NOUVEAU_STATE_CACHE_ENTRIES); \ }while(0) #define OUT_RING_CACHE(n) do { \ -- cgit v1.2.3 From 8d9d990cb2d20074e188df4ddaa8e4e235e87b0e Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sat, 15 Sep 2007 00:25:09 +0200 Subject: nouveau : use new nouveau_reg.h with correct Bracket in macro --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_object.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 4219 ++++++++++++++++++++++-- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 4 +- 5 files changed, 3863 insertions(+), 370 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index f9f33eceeb..f36483a3d4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -348,7 +348,7 @@ nouveauDoSwapBuffers(nouveauContextPtr nmesa, __DRIdrawablePrivate *dPriv) } for (i=0; iy1 - dPriv->y) << 16) | (box->x1 - dPriv->x)); OUT_RING ((box->y1 << 16) | box->x1); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 83867574d3..8f33093f1a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -39,7 +39,7 @@ void nouveauObjectInit(nouveauContextPtr nmesa) nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D); } if (nmesa->screen->card->type>=NV_11) { - nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT); + nouveauCreateContextObject(nmesa, NvImageBlit, NV11_IMAGE_BLIT); } else { nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT); } @@ -56,9 +56,9 @@ void nouveauObjectInit(nouveauContextPtr nmesa) OUT_RING(NvDmaFB); nouveauObjectOnSubchannel(nmesa, NvSubImageBlit, NvImageBlit); - BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D, 1); + BEGIN_RING_SIZE(NvSubImageBlit, NV_IMAGE_BLIT_SET_SURFACES_2D, 1); OUT_RING(NvCtxSurf2D); - BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_OPERATION, 1); + BEGIN_RING_SIZE(NvSubImageBlit, NV_IMAGE_BLIT_OPERATION, 1); OUT_RING(3); /* SRCCOPY */ if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->typescreen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); @@ -516,7 +516,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) } else { BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1); OUT_RING(0); - BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots); + BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR8_TX0,slots); for(i=0;i Date: Sun, 16 Sep 2007 16:13:55 +0200 Subject: nouveau : nv1x pos vertex attribute need to be the first in mesa. Swap it latter in order it match hw format. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 72 +++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 0a42acefd6..22144b6611 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -54,6 +54,50 @@ static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim ); static void nv10ResetLineStipple( GLcontext *ctx ); +static const int default_attr_size[8]={3,3,3,4,3,1,4,4}; + +/* Mesa requires us to put pos attribute as the first attribute of the + * vertex, but on NV10 it is the last attribute. + * To fix that we put the pos attribute first, and we swap the pos + * attribute before sending it to the card. + * Speed cost of the swap seems negligeable + */ +#if 0 +/* old stuff where pos attribute isn't put first for mesa. + * Usefull for speed comparaison + */ +#define INV_VERT(i) i +#define OUT_RING_VERTp(nmesa, ptr,sz, vertex_size) OUT_RINGp(ptr,sz) +#define OUT_RING_VERT(nmesa, ptr, vertex_size) OUT_RINGp(ptr,vertex_size) +#else + +#define INV_VERT(i) (i==0?7:i-1) + +#define OUT_RING_VERT_RAW(ptr,vertex_size) do{ \ + /* if the vertex size is not null, we have at least pos attribute */ \ + OUT_RINGp((ptr) + default_attr_size[_TNL_ATTRIB_POS], (vertex_size) - default_attr_size[_TNL_ATTRIB_POS]); \ + OUT_RINGp((ptr), default_attr_size[_TNL_ATTRIB_POS]); \ +}while(0) + +#define OUT_RING_VERT(nmesa,ptr,vertex_size) do{ \ + if (nmesa->screen->card->type>=NV_20) \ + OUT_RINGp(ptr, vertex_size); \ + else \ + OUT_RING_VERT_RAW(ptr, vertex_size); \ +}while(0) + + +#define OUT_RING_VERTp(nmesa, ptr,sz, vertex_size) do{ \ + int nb_vert; \ + if (nmesa->screen->card->type>=NV_20) \ + OUT_RINGp(ptr, sz); \ + else \ + for (nb_vert = 0; nb_vert < (sz)/(vertex_size); nb_vert++) { \ + OUT_RING_VERT_RAW((uint32_t*)(ptr)+nb_vert*(vertex_size), vertex_size); \ + } \ +}while(0) + +#endif static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) @@ -109,7 +153,7 @@ static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint sta nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); - OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize)),size_dword); + OUT_RING_VERTp(nmesa, (nouveauVertex*)(vertptr+(start*vertsize)),size_dword, (vertsize/4)); nv10FinishPrimitive(nmesa); } @@ -198,7 +242,7 @@ static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint star nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); for (j=start; jvb; int attr_size[16]; - int default_attr_size[8]={3,3,3,4,3,1,4,4}; const int nv10_vtx_attribs[8]={ _TNL_ATTRIB_FOG, _TNL_ATTRIB_WEIGHT, _TNL_ATTRIB_NORMAL, _TNL_ATTRIB_TEX1, @@ -425,7 +469,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) */ if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) { for(i=0;i<8;i++) { - int j = nv10_vtx_attribs[i]; + int j = nv10_vtx_attribs[INV_VERT(i)]; if (RENDERINPUTS_TEST(index, j)) { switch(attr_size[j]) { -- cgit v1.2.3 From 3d17cdf55acc2b452b9f2b57a9823595615c4806 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 16 Sep 2007 16:15:13 +0200 Subject: revert a956184f70733bd22e2bbee515386da12302963f --- src/mesa/tnl/t_vertex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/tnl/t_vertex.c b/src/mesa/tnl/t_vertex.c index da32be9a17..a6728c318f 100644 --- a/src/mesa/tnl/t_vertex.c +++ b/src/mesa/tnl/t_vertex.c @@ -294,7 +294,7 @@ GLuint _tnl_install_attrs( GLcontext *ctx, const struct tnl_attr_map *map, GLuint i, j; assert(nr < _TNL_ATTRIB_MAX); -/* assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS);*/ + assert(nr == 0 || map[0].attrib == VERT_ATTRIB_POS); vtx->new_inputs = ~0; vtx->need_viewport = GL_FALSE; -- cgit v1.2.3 From e605f2828fb2e5d38a1f68ed78300f441c86dfa5 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 16 Sep 2007 18:57:03 +0200 Subject: nouveau : opps I introduce a bug when cleaning vertex pos attribute swap patch --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 22144b6611..545600af64 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -75,8 +75,8 @@ static const int default_attr_size[8]={3,3,3,4,3,1,4,4}; #define OUT_RING_VERT_RAW(ptr,vertex_size) do{ \ /* if the vertex size is not null, we have at least pos attribute */ \ - OUT_RINGp((ptr) + default_attr_size[_TNL_ATTRIB_POS], (vertex_size) - default_attr_size[_TNL_ATTRIB_POS]); \ - OUT_RINGp((ptr), default_attr_size[_TNL_ATTRIB_POS]); \ + OUT_RINGp((uint32_t *)(ptr) + default_attr_size[_TNL_ATTRIB_POS], (vertex_size) - default_attr_size[_TNL_ATTRIB_POS]); \ + OUT_RINGp((uint32_t *)(ptr), default_attr_size[_TNL_ATTRIB_POS]); \ }while(0) #define OUT_RING_VERT(nmesa,ptr,vertex_size) do{ \ -- cgit v1.2.3 From 2616b206895d0e4e3ba1a5b981708ce3d37670ef Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 16 Sep 2007 19:37:27 +0200 Subject: nouveau : fix nv10_render functions use _tnl_RenderClipped helper functions that will call the right driver callback clean nv10_render_generic_primitive_elts to match nv10_render style --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 52 +++++++++---------------------- 1 file changed, 15 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 545600af64..4172afbb16 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -233,16 +233,16 @@ static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *, static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; - GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(count-start)/4; + uint32_t *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size / 4; + GLuint size_dword = vertsize*(count-start); const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; GLuint j; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); for (j=start; jvertex_attr_count++; \ } while (0) -static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) -{ - /* FIXME do something here */ - WARN_ONCE("Unimplemented %s\n", __func__); -} - -static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint *tmp = VB->Elts; - VB->Elts = (GLuint *)elts; - nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON ); - VB->Elts = tmp; -} - static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) { WARN_ONCE("Unimplemented\n"); @@ -356,12 +340,10 @@ static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; - GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(2)/4; - + uint32_t *vertptr = (GLubyte *)nmesa->verts; /* OUT_RINGp wants size in DWORDS */ - vertsize >>= 2; + GLuint vertsize = nmesa->vertex_size / 4; + GLuint size_dword = vertsize*2; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,GL_LINES+1,size_dword); @@ -373,12 +355,10 @@ static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; - GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(3)/4; - + uint32_t *vertptr = (GLubyte *)nmesa->verts; /* OUT_RINGp wants size in DWORDS */ - vertsize >>= 2; + GLuint vertsize = nmesa->vertex_size / 4; + GLuint size_dword = vertsize*3; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword); @@ -391,12 +371,10 @@ static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuin static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; - GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(4)/4; - + uint32_t *vertptr = (GLubyte *)nmesa->verts; /* OUT_RINGp wants size in DWORDS */ - vertsize >>= 2; + GLuint vertsize = nmesa->vertex_size / 4; + GLuint size_dword = vertsize*4; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword); @@ -416,8 +394,8 @@ static void nv10ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; - tnl->Driver.Render.ClippedLine = nv10_render_clipped_line; - tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; tnl->Driver.Render.Points = nv10_render_points; tnl->Driver.Render.Line = nv10_render_line; tnl->Driver.Render.Triangle = nv10_render_triangle; -- cgit v1.2.3 From 7356dac1b69ca76706439bb7c51ef37fee6588a2 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 16 Sep 2007 23:01:56 +0200 Subject: nouveau : implement nv10_render_points --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 4172afbb16..14c1351aa1 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -332,9 +332,36 @@ do { \ nmesa->vertex_attr_count++; \ } while (0) +static inline void nv10_render_point(GLcontext *ctx, GLubyte *vertptr) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLuint vertsize = nmesa->vertex_size / 4; + GLuint size_dword = vertsize; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_POINTS+1,size_dword); + OUT_RING_VERT(nmesa, (nouveauVertex*)(vertptr),vertsize); + nv10FinishPrimitive(nmesa); +} + static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) { - WARN_ONCE("Unimplemented\n"); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size / 4; + GLuint i; + + if (VB->Elts) { + for (i = first; i < last; i++) + if (VB->ClipMask[VB->Elts[i]] == 0) + nv10_render_point(ctx, vertptr + (VB->Elts[i]*vertsize)); + } + else { + for (i = first; i < last; i++) + if (VB->ClipMask[i] == 0) + nv10_render_point(ctx, vertptr + (i*vertsize)); + } } static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) -- cgit v1.2.3 From 7cc4d31ed9ff0e7f428b9ab05fc69b4e037c0a3a Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 16 Sep 2007 23:19:22 +0200 Subject: nouveau : use GLfloat instead of uint32_t. After all, our vertex attributes are float. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 14c1351aa1..e3f869d1f7 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -75,8 +75,8 @@ static const int default_attr_size[8]={3,3,3,4,3,1,4,4}; #define OUT_RING_VERT_RAW(ptr,vertex_size) do{ \ /* if the vertex size is not null, we have at least pos attribute */ \ - OUT_RINGp((uint32_t *)(ptr) + default_attr_size[_TNL_ATTRIB_POS], (vertex_size) - default_attr_size[_TNL_ATTRIB_POS]); \ - OUT_RINGp((uint32_t *)(ptr), default_attr_size[_TNL_ATTRIB_POS]); \ + OUT_RINGp((GLfloat *)(ptr) + default_attr_size[_TNL_ATTRIB_POS], (vertex_size) - default_attr_size[_TNL_ATTRIB_POS]); \ + OUT_RINGp((GLfloat *)(ptr), default_attr_size[_TNL_ATTRIB_POS]); \ }while(0) #define OUT_RING_VERT(nmesa,ptr,vertex_size) do{ \ @@ -93,14 +93,14 @@ static const int default_attr_size[8]={3,3,3,4,3,1,4,4}; OUT_RINGp(ptr, sz); \ else \ for (nb_vert = 0; nb_vert < (sz)/(vertex_size); nb_vert++) { \ - OUT_RING_VERT_RAW((uint32_t*)(ptr)+nb_vert*(vertex_size), vertex_size); \ + OUT_RING_VERT_RAW((GLfloat*)(ptr)+nb_vert*(vertex_size), vertex_size); \ } \ }while(0) #endif -static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) +static inline void nv10StartPrimitive(struct nouveau_context* nmesa,GLuint primitive,GLuint size) { if ((nmesa->screen->card->type>=NV_10) && (nmesa->screen->card->type<=NV_17)) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); @@ -233,7 +233,7 @@ static void (*nv10_render_tab_verts[GL_POLYGON+2])(GLcontext *, static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - uint32_t *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size / 4; GLuint size_dword = vertsize*(count-start); const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; @@ -332,7 +332,7 @@ do { \ nmesa->vertex_attr_count++; \ } while (0) -static inline void nv10_render_point(GLcontext *ctx, GLubyte *vertptr) +static inline void nv10_render_point(GLcontext *ctx, GLfloat *vertptr) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLuint vertsize = nmesa->vertex_size / 4; @@ -348,7 +348,7 @@ static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - uint32_t *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size / 4; GLuint i; @@ -367,7 +367,7 @@ static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - uint32_t *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; /* OUT_RINGp wants size in DWORDS */ GLuint vertsize = nmesa->vertex_size / 4; GLuint size_dword = vertsize*2; @@ -382,7 +382,7 @@ static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - uint32_t *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; /* OUT_RINGp wants size in DWORDS */ GLuint vertsize = nmesa->vertex_size / 4; GLuint size_dword = vertsize*3; @@ -398,7 +398,7 @@ static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuin static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - uint32_t *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; /* OUT_RINGp wants size in DWORDS */ GLuint vertsize = nmesa->vertex_size / 4; GLuint size_dword = vertsize*4; -- cgit v1.2.3 From c29886718ac8389b526b3eb5947c286b7fe00a88 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 16 Sep 2007 23:33:10 +0200 Subject: nouveau : avoid vertex_size / 4 for each vertex ops --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index e3f869d1f7..42b3d666fb 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -147,13 +147,13 @@ static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size) static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLfloat *vertptr = (GLfloat *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(count-start)/4; + GLuint size_dword = vertsize*(count-start); nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); - OUT_RING_VERTp(nmesa, (nouveauVertex*)(vertptr+(start*vertsize)),size_dword, (vertsize/4)); + OUT_RING_VERTp(nmesa, (nouveauVertex*)(vertptr+(start*vertsize)),size_dword, vertsize); nv10FinishPrimitive(nmesa); } @@ -234,7 +234,7 @@ static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint star { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLfloat *vertptr = (GLfloat *)nmesa->verts; - GLuint vertsize = nmesa->vertex_size / 4; + GLuint vertsize = nmesa->vertex_size; GLuint size_dword = vertsize*(count-start); const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; GLuint j; @@ -335,7 +335,7 @@ do { \ static inline void nv10_render_point(GLcontext *ctx, GLfloat *vertptr) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLuint vertsize = nmesa->vertex_size / 4; + GLuint vertsize = nmesa->vertex_size; GLuint size_dword = vertsize; nv10ExtendPrimitive(nmesa, size_dword); @@ -349,7 +349,7 @@ static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLfloat *vertptr = (GLfloat *)nmesa->verts; - GLuint vertsize = nmesa->vertex_size / 4; + GLuint vertsize = nmesa->vertex_size; GLuint i; if (VB->Elts) { @@ -368,8 +368,7 @@ static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLfloat *vertptr = (GLfloat *)nmesa->verts; - /* OUT_RINGp wants size in DWORDS */ - GLuint vertsize = nmesa->vertex_size / 4; + GLuint vertsize = nmesa->vertex_size; GLuint size_dword = vertsize*2; nv10ExtendPrimitive(nmesa, size_dword); @@ -383,8 +382,7 @@ static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuin { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLfloat *vertptr = (GLfloat *)nmesa->verts; - /* OUT_RINGp wants size in DWORDS */ - GLuint vertsize = nmesa->vertex_size / 4; + GLuint vertsize = nmesa->vertex_size; GLuint size_dword = vertsize*3; nv10ExtendPrimitive(nmesa, size_dword); @@ -399,8 +397,7 @@ static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3 { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLfloat *vertptr = (GLfloat *)nmesa->verts; - /* OUT_RINGp wants size in DWORDS */ - GLuint vertsize = nmesa->vertex_size / 4; + GLuint vertsize = nmesa->vertex_size; GLuint size_dword = vertsize*4; nv10ExtendPrimitive(nmesa, size_dword); @@ -528,7 +525,9 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) nmesa->vertex_attrs, nmesa->vertex_attr_count, NULL, 0 ); - assert(nmesa->vertex_size==total_size*4); + /* OUT_RINGp wants size in DWORDS */ + nmesa->vertex_size = nmesa->vertex_size / 4; + assert(nmesa->vertex_size==total_size); /* * Tell the hardware about the vertex format -- cgit v1.2.3 From e21d2c6ef300c7661f49c50b4c68b4f205795f4a Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 18 Sep 2007 09:32:44 +0800 Subject: mesa: Always use the original mask to update stencil buffer in stencil_and_ztest_pixels. fix #12263 --- src/mesa/swrast/s_stencil.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c index d0cbdd6917..cae1e09929 100644 --- a/src/mesa/swrast/s_stencil.c +++ b/src/mesa/swrast/s_stencil.c @@ -923,6 +923,8 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face ) ASSERT(rb->DataType == GL_UNSIGNED_BYTE); _swrast_get_values(ctx, rb, n, x, y, stencil, sizeof(GLubyte)); + _mesa_memcpy(origMask, mask, n * sizeof(GLubyte)); + (void) do_stencil_test(ctx, face, n, stencil, mask); if (ctx->Depth.Test == GL_FALSE) { @@ -930,11 +932,12 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face ) n, stencil, mask); } else { - _mesa_memcpy(origMask, mask, n * sizeof(GLubyte)); + GLubyte tmpMask[MAX_WIDTH]; + _mesa_memcpy(tmpMask, mask, n * sizeof(GLubyte)); _swrast_depth_test_span(ctx, span); - compute_pass_fail_masks(n, origMask, mask, passMask, failMask); + compute_pass_fail_masks(n, tmpMask, mask, passMask, failMask); if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) { apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face, -- cgit v1.2.3 From e3745dac59602a9d21b49d602646de5aef95075f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 18 Sep 2007 15:46:16 -0700 Subject: Add some error reporting and a couple of assertions to TTM bufmgr. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 5128d95370..8c36502b85 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -220,6 +220,8 @@ dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable) if (write_enable) flags |= DRM_BO_FLAG_WRITE; + assert(buf->virtual == NULL); + return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual); } @@ -234,6 +236,8 @@ dri_ttm_bo_unmap(dri_bo *buf) bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr; + assert(buf->virtual != NULL); + buf->virtual = NULL; return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo); @@ -264,6 +268,9 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) if (err == 0) { /* XXX: add to fence list for sanity checking */ + } else { + fprintf(stderr, "failed to validate buffer (%s): %s\n", + ttm_buf->name, strerror(err)); } buf->offset = ttm_buf->drm_bo.offset; @@ -294,6 +301,7 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->fence.bufmgr = bufmgr; ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); if (ret) { + fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(ret)); free(fence_ttm); return NULL; } -- cgit v1.2.3 From 3800599bd4f6185c1eefc5d44794525ec4a3e406 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 19 Sep 2007 19:08:56 +0200 Subject: nouveau: nv10: color logic op only for nv11+ --- src/mesa/drivers/dri/nouveau/nv10_state.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 148f9fdd5e..36084f3554 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -297,8 +297,10 @@ static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING_CACHE(state); break; case GL_COLOR_LOGIC_OP: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); - OUT_RING_CACHE(state); + if (nmesa->screen->card->type >= NV_11) { + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); + } break; // case GL_COLOR_MATERIAL: // case GL_COLOR_SUM_EXT: @@ -583,6 +585,10 @@ static void nv10LineWidth(GLcontext *ctx, GLfloat width) static void nv10LogicOpcode(GLcontext *ctx, GLenum opcode) { + if (nmesa->screen->card->type < NV_11) { + return; + } + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); OUT_RING_CACHE(opcode); -- cgit v1.2.3 From 9070e6b9970a6aeabfff07b259e0e1660980cc59 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 19 Jun 2007 15:15:40 -0700 Subject: i915: Quiet valgrind by initializing the seq value the kernel writes into. Also, add a couple of comments to the wait/emit IRQ functions. --- src/mesa/drivers/dri/i915/intel_ioctl.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c index ede3b6378f..ddd92782db 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915/intel_ioctl.c @@ -53,6 +53,10 @@ u_int32_t intelGetLastFrame (intelContextPtr intel) return frame; } +/** + * Emits a marker in the command stream, numbered from 0x00000001 to + * 0x7fffffff. + */ int intelEmitIrqLocked( intelContextPtr intel ) { drmI830IrqEmit ie; @@ -61,6 +65,10 @@ int intelEmitIrqLocked( intelContextPtr intel ) assert(((*(int *)intel->driHwLock) & ~DRM_LOCK_CONT) == (DRM_LOCK_HELD|intel->hHWContext)); + /* Valgrind can't tell that the kernel will have copyout()ed onto this + * value, so initialize it now to prevent false positives. + */ + seq = 0; ie.irq_seq = &seq; ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT, @@ -76,6 +84,7 @@ int intelEmitIrqLocked( intelContextPtr intel ) return seq; } +/** Blocks on a marker returned by intelEitIrqLocked(). */ void intelWaitIrq( intelContextPtr intel, int seq ) { int ret; -- cgit v1.2.3 From f843dcb844c4b1000f3b98a85f622b6929c19eea Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 19 Sep 2007 09:02:24 -0700 Subject: Enable building the debug (env INTEL_DEBUG=list) code by default. --- src/mesa/drivers/dri/i915tex/intel_context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index ddd1439b00..3bb34796b1 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -354,7 +354,7 @@ __memcpy(void *to, const void *from, size_t n) /* ================================================================ * Debugging: */ -#define DO_DEBUG 0 +#define DO_DEBUG 1 #if DO_DEBUG extern int INTEL_DEBUG; #else -- cgit v1.2.3 From b91791a85c1098e7a0210d7b9f186db20106ba3b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 19 Sep 2007 09:56:43 -0700 Subject: Replace i915tex batchbuffer printout with a pretty-printed version. --- src/mesa/drivers/dri/i915tex/Makefile | 1 + src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 18 +- src/mesa/drivers/dri/i915tex/intel_decode.c | 832 +++++++++++++++++++++++ src/mesa/drivers/dri/i915tex/intel_decode.h | 29 + 4 files changed, 865 insertions(+), 15 deletions(-) create mode 100644 src/mesa/drivers/dri/i915tex/intel_decode.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_decode.h (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index 445327f243..ed8483a028 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -44,6 +44,7 @@ DRIVER_SOURCES = \ i915_state.c \ i915_vtbl.c \ intel_context.c \ + intel_decode.c \ intel_ioctl.c \ intel_rotate.c \ intel_screen.c \ diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 6665629d03..c740c3d7f6 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -27,6 +27,7 @@ #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "intel_decode.h" #include "i915_debug.h" /* Relocations in kernel space: @@ -67,16 +68,6 @@ * modifying cliprects ??? */ -static void -intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); - for (i = 0; i < count / 4; i += 1) - fprintf(stderr, "\t0x%08x\n", ptr[i]); - fprintf(stderr, "END BATCH\n\n\n"); -} - void intel_batchbuffer_reset(struct intel_batchbuffer *batch) { @@ -186,11 +177,8 @@ do_flush_locked(struct intel_batchbuffer *batch, ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; } - if (INTEL_DEBUG & DEBUG_BATCH) { - if (0) i915_dump_batchbuffer(ptr, ptr + used/4); - intel_dump_batchbuffer(0, ptr, used); - } - + if (INTEL_DEBUG & DEBUG_BATCH) + intel_decode(ptr, used / 4, 0); driBOUnmap(batch->buffer); batch->map = NULL; diff --git a/src/mesa/drivers/dri/i915tex/intel_decode.c b/src/mesa/drivers/dri/i915tex/intel_decode.c new file mode 100644 index 0000000000..6fc02c999c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_decode.c @@ -0,0 +1,832 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +/** @file intel_decode.c + * This file contains code to print out batchbuffer contents in a + * human-readable format. + * + * The current version only supports i915 packets, and only pretty-prints a + * subset of them. The intention is for it to make just a best attempt to + * decode, but never crash in the process. + */ + +#include +#include +#include + +#include "intel_decode.h" +#include "i915_reg.h" + +#define BUFFER_FAIL(_count, _len, _name) do { \ + fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ + (_name), (_count), (_len)); \ + (*failures)++; \ + return count; \ +} while (0) + +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; + +static float +int_as_float(uint32_t intval) +{ + union intfloat { + uint32_t i; + float f; + } uval; + + uval.i = intval; + return uval.f; +} + +static void +instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, + char *fmt, ...) +{ + va_list va; + + fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); + va_start(va, fmt); + vfprintf(out, fmt, va); + va_end(va); +} + + +static int +decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_mi[] = { + { 0x08, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 1, 1, "MI_FLUSH" }, + { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 1, 1, "MI_NOOP" }, + { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, + }; + + + for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); + opcode++) { + if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); + if (opcodes_mi[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_mi[opcode].min_len || + len > opcodes_mi[opcode].max_len) + { + fprintf(out, "Bad length in %s\n", + opcodes_mi[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_mi[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode, len; + char *format; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_2d[] = { + { 0x40, 5, 5, "COLOR_BLT" }, + { 0x43, 6, 6, "SRC_COPY_BLT" }, + { 0x01, 8, 8, "XY_SETUP_BLT" }, + { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, + { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, + { 0x24, 2, 2, "XY_PIXEL_BLT" }, + { 0x25, 3, 3, "XY_SCANLINES_BLT" }, + { 0x26, 4, 4, "Y_TEXT_BLT" }, + { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, + { 0x50, 6, 6, "XY_COLOR_BLT" }, + { 0x51, 6, 6, "XY_PAT_BLT" }, + { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, + { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, + { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, + { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, + { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, + { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, + { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, + { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, + { 0x55, 9, 9, "XY_FULL_BLT" }, + { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, + { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, + { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, + { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, + { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, + }; + + switch ((data[0] & 0x1fc00000) >> 22) { + case 0x50: + instr_out(data, hw_offset, 0, + "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 6) + fprintf(out, "Bad count in XY_COLOR_BLT\n"); + if (count < 6) + BUFFER_FAIL(count, len, "XY_COLOR_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "color\n"); + return len; + case 0x53: + instr_out(data, hw_offset, 0, + "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 8) + fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); + if (count < 8) + BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "src (%d,%d)\n", + data[5] & 0xffff, data[5] >> 16); + instr_out(data, hw_offset, 6, "src pitch %d\n", + data[6] & 0xffff); + instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); + opcode++) { + if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { + unsigned int i; + + len = 1; + instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); + if (opcodes_2d[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_2d[opcode].min_len || + len > opcodes_2d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_2d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + switch ((data[0] & 0x00f80000) >> 19) { + case 0x11: + instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); + return 1; + case 0x10: + instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); + return 1; + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int len, i, c, opcode, word, map, sampler, instr; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d_1d[] = { + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, + { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, + { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, + { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, + { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, + { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, + { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, + { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, + { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, + { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, + { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, + { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, + { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, + { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, + }; + + switch ((data[0] & 0x00ff0000) >> 16) { + case 0x07: + /* This instruction is unusual. A 0 length means just 1 DWORD instead of + * 2. The 0 length is specified in one place to be unsupported, but + * stated to be required in another, and 0 length LOAD_INDIRECTs appear + * to cause no harm at least. + */ + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); + len = (data[0] & 0x000000ff) + 1; + i = 1; + if (data[0] & (0x01 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SIS.0\n"); + instr_out(data, hw_offset, i++, "SIS.1\n"); + } + if (data[0] & (0x02 << 8)) { + if (i + 1 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "DIS.0\n"); + } + if (data[0] & (0x04 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SSB.0\n"); + instr_out(data, hw_offset, i++, "SSB.1\n"); + } + if (data[0] & (0x08 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "MSB.0\n"); + instr_out(data, hw_offset, i++, "MSB.1\n"); + } + if (data[0] & (0x10 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSP.0\n"); + instr_out(data, hw_offset, i++, "PSP.1\n"); + } + if (data[0] & (0x20 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSC.0\n"); + instr_out(data, hw_offset, i++, "PSC.1\n"); + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + return len; + } + return len; + case 0x04: + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); + len = (data[0] & 0x0000000f) + 2; + i = 1; + for (word = 0; word <= 7; word++) { + if (data[0] & (1 << (4 + word))) { + if (i >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + + /* save vertex state for decode */ + if (word == 2) { + saved_s2_set = 1; + saved_s2 = data[i]; + } + if (word == 4) { + saved_s4_set = 1; + saved_s4 = data[i]; + } + + instr_out(data, hw_offset, i++, "S%d\n", word); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + } + return len; + case 0x00: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + + i = 1; + for (map = 0; map <= 15; map++) { + if (data[1] & (1 << map)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "map %d MS2\n", map); + instr_out(data, hw_offset, i++, "map %d MS3\n", map); + instr_out(data, hw_offset, i++, "map %d MS4\n", map); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + return len; + } + return len; + case 0x06: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + len = (data[0] & 0x000000ff) + 2; + + i = 1; + for (c = 0; c <= 31; c++) { + if (data[1] & (1 << c)) { + if (i + 4 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); + instr_out(data, hw_offset, i, "C%d.X = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Y = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Z = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.W = %f\n", + c, int_as_float(data[i])); + i++; + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + } + return len; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); + len = (data[0] & 0x000000ff) + 2; + if ((len - 1) % 3 != 0 || len > 370) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); + (*failures)++; + } + i = 1; + for (instr = 0; instr < (len - 1) / 3; instr++) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + } + return len; + case 0x01: + instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + i = 1; + for (sampler = 0; sampler <= 15; sampler++) { + if (data[1] & (1 << sampler)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); + instr_out(data, hw_offset, i++, "sampler %d SS2\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS3\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS4\n", + sampler); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); + (*failures)++; + } + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); + opcode++) + { + if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); + if (opcodes_3d_1d[opcode].max_len > 1) { + len = (data[0] & 0x0000ffff) + 2; + if (len < opcodes_3d_1d[opcode].min_len || + len > opcodes_3d_1d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", + opcodes_3d_1d[opcode].name); + (*failures)++; + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, + int *failures) +{ + char immediate = (data[0] & (1 << 23)) == 0; + unsigned int len, i; + char *primtype; + + switch ((data[0] >> 18) & 0xf) { + case 0x0: primtype = "TRILIST"; break; + case 0x1: primtype = "TRISTRIP"; break; + case 0x2: primtype = "TRISTRIP_REVERSE"; break; + case 0x3: primtype = "TRIFAN"; break; + case 0x4: primtype = "POLYGON"; break; + case 0x5: primtype = "LINELIST"; break; + case 0x6: primtype = "LINESTRIP"; break; + case 0x7: primtype = "RECTLIST"; break; + case 0x8: primtype = "POINTLIST"; break; + case 0x9: primtype = "DIB"; break; + case 0xa: primtype = "CLEAR_RECT"; break; + default: primtype = "unknown"; break; + } + + /* XXX: 3DPRIM_DIB not supported */ + if (immediate) { + len = (data[0] & 0x0003ffff) + 2; + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); + if (!saved_s2_set || !saved_s4_set) { + fprintf(out, "unknown vertex format\n"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + unsigned int vertex = 0; + for (i = 1; i < len;) { + unsigned int tc; + +#define VERTEX_OUT(fmt, ...) do { \ + if (i < len) \ + instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ + else \ + fprintf(out, " missing data in V%d\n", vertex); \ + i++; \ +} while (0) + + VERTEX_OUT("X = %f", int_as_float(data[i])); + VERTEX_OUT("Y = %f", int_as_float(data[i])); + switch (saved_s4 >> 6 & 0x7) { + case 0x1: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + case 0x3: + break; + case 0x4: + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + default: + fprintf(out, "bad S4 position mask\n"); + } + + if (saved_s4 & (1 << 10)) { + VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 11)) { + VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 12)) + VERTEX_OUT("width = 0x%08x)", data[i]); + + for (tc = 0; tc <= 7; tc++) { + switch ((saved_s2 >> (tc * 4)) & 0xf) { + case 0x0: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + break; + case 0x1: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); + break; + case 0x3: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + break; + case 0x4: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + break; + case 0x5: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); + break; + case 0xf: + break; + default: + fprintf(out, "bad S2.T%d format\n", tc); + } + } + vertex++; + } + } + } else { + /* indirect vertices */ + len = data[0] & 0x0000ffff; /* index count */ + if (data[0] & (1 << 17)) { + /* random vertex access */ + if (count < (len + 1) / 2 + 1) { + BUFFER_FAIL(count, (len + 1) / 2 + 1, + "3DPRIMITIVE random indirect"); + } + instr_out(data, hw_offset, 0, + "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); + if (len == 0) { + /* vertex indices continue until 0xffff is found */ + for (i = 1; i < count; i++) { + if ((data[i] & 0xffff) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: (terminator)\n"); + return i; + } else if ((data[i] >> 16) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: 0x%04x, " + "(terminator)\n", + data[i] & 0xffff); + return i; + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + fprintf(out, + "3DPRIMITIVE: no terminator found in index buffer\n"); + (*failures)++; + return count; + } else { + /* fixed size vertex index buffer */ + for (i = 0; i < len; i += 2) { + if (i * 2 == len - 1) { + instr_out(data, hw_offset, i, + " indices: 0x%04x\n", + data[i] & 0xffff); + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + } + return (len + 1) / 2 + 1; + } else { + /* sequential vertex access */ + if (count < 2) + BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); + instr_out(data, hw_offset, 0, + "3DPRIMITIVE sequential indirect %s, %d starting from " + "%d\n", primtype, len, data[1] & 0xffff); + instr_out(data, hw_offset, 1, " start\n"); + return 2; + } + } + + return len; +} + +static int +decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, + { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, + { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, + { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, + { 0x0d, 1, 1, "3DSTATE_MODES_4" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** + * Decodes an i830-i915 batch buffer, writing the output to stdout. + * + * \param data batch buffer contents + * \param count number of DWORDs to decode in the batch buffer + * \param hw_offset hardware address for the buffer + */ +int +intel_decode(uint32_t *data, int count, uint32_t hw_offset) +{ + int index = 0; + int failures = 0; + + out = stdout; + + while (index < count) { + switch ((data[index] & 0xe0000000) >> 29) { + case 0x0: + index += decode_mi(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x2: + index += decode_2d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x3: + index += decode_3d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + default: + instr_out(data, hw_offset, index, "UNKNOWN\n"); + failures++; + index++; + break; + } + fflush(out); + } + + return failures; +} + +void intel_disasm_context_reset() +{ + saved_s2_set = 0; + saved_s4_set = 1; +} + diff --git a/src/mesa/drivers/dri/i915tex/intel_decode.h b/src/mesa/drivers/dri/i915tex/intel_decode.h new file mode 100644 index 0000000000..ef0cba153c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_decode.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +int intel_decode(uint32_t *data, int count, uint32_t hw_offset); +void intel_decode_context_reset(); -- cgit v1.2.3 From 1310f02dee336048a0d3f94a9b34575c3f6e00a6 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Wed, 19 Sep 2007 19:57:55 +0200 Subject: nouveau : add GL_FOG_COLOR + fix a compil error --- src/mesa/drivers/dri/nouveau/nv10_state.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 36084f3554..99975c3d8b 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -430,11 +430,21 @@ static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte cf[4]; switch(pname) { case GL_FOG_MODE: - //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); - //OUT_RING_CACHE (params); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); + OUT_RING_CACHE (ctx->Fog.Mode); /* can we extract it from params ??? */ + break; + case GL_FOG_COLOR: + CLAMPED_FLOAT_TO_UBYTE(cf[0], params[0]); + CLAMPED_FLOAT_TO_UBYTE(cf[1], params[1]); + CLAMPED_FLOAT_TO_UBYTE(cf[2], params[2]); + CLAMPED_FLOAT_TO_UBYTE(cf[3], params[3]); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); break; /* TODO: unsure about the rest.*/ default: @@ -585,11 +595,12 @@ static void nv10LineWidth(GLcontext *ctx, GLfloat width) static void nv10LogicOpcode(GLcontext *ctx, GLenum opcode) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + if (nmesa->screen->card->type < NV_11) { return; } - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); OUT_RING_CACHE(opcode); } -- cgit v1.2.3 From 3b582dff8c72870fb4d0b3641015365ea9026022 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Wed, 19 Sep 2007 23:20:13 +0200 Subject: nouveau : add OUT_RING_CACHE_FORCE* to add stuff in the cache even if the value didn't change --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 34 +++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 0805882025..3ca1560e3a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -145,6 +145,9 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); #define OUT_RING_CACHE(n) OUT_RING((n)) #define OUT_RING_CACHEf(n) OUT_RINGf((n)) #define OUT_RING_CACHEp(ptr, sz) OUT_RINGp((ptr), (sz)) +#define OUT_RING_CACHE_FORCE(n) OUT_RING((n)) +#define OUT_RING_CACHE_FORCEf(n) OUT_RINGf((n)) +#define OUT_RING_CACHE_FORCEp(ptr, sz) OUT_RINGp((ptr), (sz)) #else #define BEGIN_RING_CACHE(subchannel,tag,size) do { \ nmesa->state_cache.dirty=1; \ @@ -162,17 +165,40 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); }while(0) #define OUT_RING_CACHEf(n) do { \ - if ((*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \ + if ((*(GLfloat*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \ nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ - (*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\ + (*(GLfloat*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\ } \ nmesa->state_cache.current_pos++; \ }while(0) #define OUT_RING_CACHEp(ptr,sz) do { \ -uint32_t* p=(uint32_t*)(ptr); \ -int i; for(i=0;istate_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \ + nmesa->state_cache.current_pos++; \ +}while(0) + +#define OUT_RING_CACHE_FORCEf(n) do { \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ + (*(GLfloat*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\ + nmesa->state_cache.current_pos++; \ +}while(0) + +#define OUT_RING_CACHE_FORCEp(ptr,sz) do { \ + GLuint* p=(GLuint*)(ptr); \ + int i; \ + for(i=0;i Date: Wed, 19 Sep 2007 23:22:39 +0200 Subject: nouveau : nv1x use OUT_RING_CACHE_FORCE for NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX as strange results appear when the matrix is partialy updated. --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 99975c3d8b..8cbe72020f 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -801,8 +801,8 @@ static void nv10UpdateProjectionMatrix(GLcontext *ctx) projection[i+12] = ctx->_ModelProjectMatrix.m[i*4+3]; } - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); - OUT_RINGp(projection, 16); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX(0), 16); + OUT_RING_CACHE_FORCEp(projection, 16); } static void nv10UpdateModelviewMatrix(GLcontext *ctx) -- cgit v1.2.3 From 6f2ca13f903508e50946f525fc01d862cd8bd1f5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 20 Sep 2007 13:36:31 +1000 Subject: nouveau: add GeForce 7300 SE to card list --- src/mesa/drivers/dri/nouveau/nouveau_card_list.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h index c2600bc532..b1a0e7bfd1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h @@ -113,6 +113,7 @@ static nouveau_card nouveau_card_list[]={ {0x0193, "GeForce 8800 GTS", NV30_TCL_PRIMITIVE_3D|0x5000, NV_50, 0}, {0x01A0, "GeForce2 MX Integrated Graphics", NV11_TCL_PRIMITIVE_3D, NV_11, 0}, {0x01D1, "GeForce 7300 LE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x01D3, "GeForce 7300 SE", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x01D6, "GeForce Go 7200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x01D7, "Quadro NVS 110M / GeForce Go 7300", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x01D8, "GeForce Go 7400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, -- cgit v1.2.3 From 8fc1a6808d88bd1dd641751f2f50c867a05dcc07 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 20 Sep 2007 17:37:04 +0800 Subject: fix memory access error in vbo_bind_vertex_list --- src/mesa/vbo/vbo_save_draw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index da7bc765b7..ee6df22605 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -131,7 +131,7 @@ static void vbo_bind_vertex_list( GLcontext *ctx, break; } - for (attr = 0; attr < VBO_ATTRIB_MAX; attr++) { + for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { GLuint src = map[attr]; if (node->attrsz[src]) { -- cgit v1.2.3 From 2c88bfeaa47bf464b02275e10e6c348e5172a0a1 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 20 Sep 2007 17:42:13 +0800 Subject: i965: fix an error in brw_vs_tnl.c if the state of TEXMAT is changed, the VS isn't updated. --- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 2ed80dc36e..27210d1a37 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1628,7 +1628,8 @@ const struct brw_tracked_state brw_tnl_vertprog = { _NEW_FOG | _NEW_HINT | _NEW_POINT | - _NEW_TEXTURE), + _NEW_TEXTURE | + _NEW_TEXTURE_MATRIX), .brw = (BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_INPUT_VARYING), .cache = 0 -- cgit v1.2.3 From b7fd06a871893d8ed482d16207136e324bb7d85c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Sep 2007 09:20:48 -0700 Subject: Fix flipped sign to strerror. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index 8c36502b85..e264048b70 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -270,7 +270,7 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) /* XXX: add to fence list for sanity checking */ } else { fprintf(stderr, "failed to validate buffer (%s): %s\n", - ttm_buf->name, strerror(err)); + ttm_buf->name, strerror(-err)); } buf->offset = ttm_buf->drm_bo.offset; @@ -301,7 +301,7 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->fence.bufmgr = bufmgr; ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); if (ret) { - fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(ret)); + fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret)); free(fence_ttm); return NULL; } -- cgit v1.2.3 From 75912596741d1afe5827dab6913c3d810eda8788 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Sep 2007 11:38:32 -0700 Subject: Add disabled-by-default tracing of TTM bufmgr operations. --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index e264048b70..f864b1bc89 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -42,6 +42,8 @@ #include "string.h" #include "imports.h" +#define BUFMGR_DEBUG 0 + typedef struct _dri_bufmgr_ttm { dri_bufmgr bufmgr; @@ -128,6 +130,10 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, ttm_buf->name = name; ttm_buf->refcount = 1; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return &ttm_buf->bo; } @@ -174,6 +180,11 @@ dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, ttm_buf->name = name; ttm_buf->refcount = 1; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo, + ttm_buf->name); +#endif + return &ttm_buf->bo; } @@ -222,6 +233,10 @@ dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable) assert(buf->virtual == NULL); +#if BUFMGR_DEBUG + fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual); } @@ -240,6 +255,10 @@ dri_ttm_bo_unmap(dri_bo *buf) buf->virtual = NULL; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo); } @@ -275,6 +294,10 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) buf->offset = ttm_buf->drm_bo.offset; +#if BUFMGR_DEBUG + fprintf(stderr, "bo_validate: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); +#endif + return err; } @@ -305,6 +328,12 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, free(fence_ttm); return NULL; } + +#if BUFMGR_DEBUG + fprintf(stderr, "fence_validated: %p (%s)\n", &fence_ttm->fence, + fence_ttm->name); +#endif + return &fence_ttm->fence; } @@ -354,6 +383,11 @@ dri_ttm_fence_wait(dri_fence *fence) __FILE__, __LINE__, ret, fence_ttm->name); abort(); } + +#if BUFMGR_DEBUG + fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence, + fence_ttm->name); +#endif } static void -- cgit v1.2.3 From c1ecc383204914567c6de1587d7b9559ec72ce6e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 20 Sep 2007 11:41:25 -0700 Subject: Uniquely validate the batchbuffer-referenced buffers. Otherwise, for multiple references by the batchbuffer, the kernel would see the buffer already on the unfenced list and wait for it to leave the list before continuing, leading to hanging and eventual -EBUSY. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 47 +++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index 5515d6c235..8ee48b5a68 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -116,6 +116,14 @@ intel_batchbuffer_free(struct intel_batchbuffer *batch) free(batch); } +static int +relocation_sort(const void *a_in, const void *b_in) { + const struct buffer_reloc *a = a_in, *b = b_in; + + return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; +} + + /* TODO: Push this whole function into bufmgr. */ static void @@ -132,13 +140,49 @@ do_flush_locked(struct intel_batchbuffer *batch, assert(batch->buf->virtual != NULL); ptr = batch->buf->virtual; + /* Sort our relocation list in terms of referenced buffer pointer. + * This lets us uniquely validate the buffers with the sum of all the flags, + * while avoiding O(n^2) on number of relocations. + */ + qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), + relocation_sort); + + /* Perform the necessary validations of buffers, and enter the relocations + * in the batchbuffer. + */ for (i = 0; i < batch->nr_relocs; i++) { struct buffer_reloc *r = &batch->reloc[i]; if (r->validate_flags & DRM_BO_FLAG_WRITE) performed_rendering = GL_TRUE; - dri_bo_validate(r->buf, r->validate_flags); + /* If this is the first time we've seen this buffer in the relocation + * list, figure out our flags and validate it. + */ + if (i == 0 || batch->reloc[i - 1].buf != r->buf) { + uint32_t validate_flags; + int j, ret; + + /* Accumulate the flags we need for validating this buffer. */ + validate_flags = r->validate_flags; + for (j = i + 1; j < batch->nr_relocs; j++) { + if (batch->reloc[j].buf != r->buf) + break; + validate_flags |= batch->reloc[j].validate_flags; + } + + /* Validate. If we fail, fence to clear the unfenced list and bail + * out. + */ + ret = dri_bo_validate(r->buf, validate_flags); + if (ret != 0) { + dri_bo_unmap(batch->buf); + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "batchbuffer failure fence", GL_TRUE); + dri_fence_unreference(fo); + goto done; + } + } ptr[r->offset / 4] = r->buf->offset + r->delta; dri_bo_unreference(r->buf); } @@ -193,6 +237,7 @@ do_flush_locked(struct intel_batchbuffer *batch, intel->vtbl.lost_hardware(intel); } +done: if (INTEL_DEBUG & DEBUG_BATCH) { dri_bo_map(batch->buf, GL_FALSE); intel_decode(ptr, used / 4, batch->buf->offset); -- cgit v1.2.3 From a5467fbdd9ca599c9512433ece30f90fd67f15e3 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 20 Sep 2007 15:11:14 -0600 Subject: fixes for bluegene-xlc-osmesa config --- Makefile | 1 + src/mesa/main/glheader.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/Makefile b/Makefile index 59e6d82511..ef607f4944 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,7 @@ aix-64-static \ aix-gcc \ aix-static \ bluegene-osmesa \ +bluegene-xlc-osmesa \ beos \ darwin \ darwin-static \ diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h index fd4127558a..2d2da49fe5 100644 --- a/src/mesa/main/glheader.h +++ b/src/mesa/main/glheader.h @@ -237,7 +237,7 @@ #endif -#if !defined __GNUC__ || __GNUC__ < 3 +#if (!defined(__GNUC__) || __GNUC__ < 3) && !defined(__IBMC__) # define __builtin_expect(x, y) x #endif -- cgit v1.2.3 From d0350dadaa52064f67e4e9001145af14478b2849 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 21 Sep 2007 16:16:54 -0700 Subject: Fix buffer/fence reference counting due to Destroy vs Unreference difference. While here, remove the unnecessary fence type saving for the wait ioctl, as a 0 argument for type means "use your other saved copy". --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 46 +++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index f864b1bc89..bda8e34190 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -59,6 +59,11 @@ typedef struct _dri_bo_ttm { int refcount; /* Protected by bufmgr->mutex */ drmBO drm_bo; const char *name; + /** + * Note whether we are the owner of the buffer, to determine if we must + * drmBODestroy or drmBOUnreference to unreference the buffer. + */ + GLboolean owner; } dri_bo_ttm; typedef struct _dri_fence_ttm @@ -66,8 +71,6 @@ typedef struct _dri_fence_ttm dri_fence fence; int refcount; /* Protected by bufmgr->mutex */ - /** Fence type from when the fence was created, used for later waits */ - unsigned int type; const char *name; drmFence drm_fence; } dri_fence_ttm; @@ -129,6 +132,7 @@ dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.bufmgr = bufmgr; ttm_buf->name = name; ttm_buf->refcount = 1; + ttm_buf->owner = GL_TRUE; #if BUFMGR_DEBUG fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name); @@ -179,6 +183,7 @@ dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name, ttm_buf->bo.bufmgr = bufmgr; ttm_buf->name = name; ttm_buf->refcount = 1; + ttm_buf->owner = GL_FALSE; #if BUFMGR_DEBUG fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo, @@ -210,7 +215,24 @@ dri_ttm_bo_unreference(dri_bo *buf) _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); if (--ttm_buf->refcount == 0) { - drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo); + int ret; + + /* XXX Having to use drmBODestroy as the opposite of drmBOCreate instead + * of simply unreferencing is madness, and leads to behaviors we may not + * want (making the buffer unsharable). + */ + if (ttm_buf->owner) + ret = drmBODestroy(bufmgr_ttm->fd, &ttm_buf->drm_bo); + else + ret = drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo); + if (ret != 0) { + fprintf(stderr, "drmBOUnReference failed (%s): %s\n", ttm_buf->name, + strerror(-ret)); + } +#if BUFMGR_DEBUG + fprintf(stderr, "bo_unreference final: %p (%s)\n", + &ttm_buf->bo, ttm_buf->name); +#endif _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); free(buf); return; @@ -320,7 +342,6 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->refcount = 1; fence_ttm->name = name; - fence_ttm->type = type; fence_ttm->fence.bufmgr = bufmgr; ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); if (ret) { @@ -359,7 +380,19 @@ dri_ttm_fence_unreference(dri_fence *fence) _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); if (--fence_ttm->refcount == 0) { - drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence); + int ret; + + /* XXX Having to use drmFenceDestroy as the opposite of drmFenceBuffers + * instead of simply unreferencing is madness, and leads to behaviors we + * may not want (making the fence unsharable). This behavior by the DRM + * ioctls should be fixed, and drmFenceDestroy eliminated. + */ + ret = drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence); + if (ret != 0) { + fprintf(stderr, "drmFenceDestroy failed (%s): %s\n", + fence_ttm->name, strerror(-ret)); + } + _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); free(fence); return; @@ -375,8 +408,7 @@ dri_ttm_fence_wait(dri_fence *fence) int ret; _glthread_LOCK_MUTEX(bufmgr_ttm->mutex); - ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, - fence_ttm->type); + ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, 0); _glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex); if (ret != 0) { _mesa_printf("%s:%d: Error %d waiting for fence %s.\n", -- cgit v1.2.3 From ef5935bc94a1439eb8f1731732a3eabd0e360407 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 23 Sep 2007 13:56:46 -0600 Subject: fix DrawRangeElements error msg --- src/mesa/main/api_validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 3e4fe46b1d..e2eebccd47 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -214,7 +214,7 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /* make sure count doesn't go outside buffer bounds */ if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) { - _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); + _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); return GL_FALSE; } } -- cgit v1.2.3 From 439fa7957874d564b30a92345e74ee57b388ebec Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Mon, 24 Sep 2007 16:48:55 +0800 Subject: fix fd.o bug #12217, recalcuate urb when clip plane size change --- src/mesa/drivers/dri/i965/brw_curbe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 3f0aaa1f86..5bf0ed536b 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -90,7 +90,7 @@ static void calculate_curbe_offsets( struct brw_context *brw ) */ if (nr_fp_regs > brw->curbe.wm_size || nr_vp_regs > brw->curbe.vs_size || - nr_clip_regs > brw->curbe.clip_size || + nr_clip_regs != brw->curbe.clip_size || (total_regs < brw->curbe.total_size / 4 && brw->curbe.total_size > 16)) { -- cgit v1.2.3 From 8fba8d2018643444fc17c590f3e8732e1a76c6b8 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Sep 2007 09:55:16 -0700 Subject: Remove the old i915 driver now that i915tex works without TTM. --- configs/freebsd-dri | 2 +- configs/linux-dri | 2 +- src/mesa/drivers/dri/i915/Makefile | 50 - src/mesa/drivers/dri/i915/i830_context.c | 124 --- src/mesa/drivers/dri/i915/i830_context.h | 218 ---- src/mesa/drivers/dri/i915/i830_metaops.c | 922 ----------------- src/mesa/drivers/dri/i915/i830_reg.h | 641 ------------ src/mesa/drivers/dri/i915/i830_state.c | 1089 -------------------- src/mesa/drivers/dri/i915/i830_tex.c | 356 ------- src/mesa/drivers/dri/i915/i830_texblend.c | 465 --------- src/mesa/drivers/dri/i915/i830_texstate.c | 483 --------- src/mesa/drivers/dri/i915/i830_vtbl.c | 540 ---------- src/mesa/drivers/dri/i915/i915_context.c | 186 ---- src/mesa/drivers/dri/i915/i915_context.h | 358 ------- src/mesa/drivers/dri/i915/i915_debug.c | 299 ------ src/mesa/drivers/dri/i915/i915_fragprog.c | 1080 -------------------- src/mesa/drivers/dri/i915/i915_metaops.c | 711 ------------- src/mesa/drivers/dri/i915/i915_program.c | 499 --------- src/mesa/drivers/dri/i915/i915_program.h | 163 --- src/mesa/drivers/dri/i915/i915_reg.h | 835 --------------- src/mesa/drivers/dri/i915/i915_state.c | 970 ------------------ src/mesa/drivers/dri/i915/i915_tex.c | 187 ---- src/mesa/drivers/dri/i915/i915_texprog.c | 676 ------------- src/mesa/drivers/dri/i915/i915_texstate.c | 975 ------------------ src/mesa/drivers/dri/i915/i915_vtbl.c | 469 --------- src/mesa/drivers/dri/i915/intel_batchbuffer.c | 829 --------------- src/mesa/drivers/dri/i915/intel_batchbuffer.h | 126 --- src/mesa/drivers/dri/i915/intel_context.c | 776 -------------- src/mesa/drivers/dri/i915/intel_context.h | 564 ----------- src/mesa/drivers/dri/i915/intel_ioctl.c | 668 ------------ src/mesa/drivers/dri/i915/intel_ioctl.h | 72 -- src/mesa/drivers/dri/i915/intel_pixel.c | 524 ---------- src/mesa/drivers/dri/i915/intel_reg.h | 84 -- src/mesa/drivers/dri/i915/intel_render.c | 242 ----- src/mesa/drivers/dri/i915/intel_rotate.c | 221 ---- src/mesa/drivers/dri/i915/intel_rotate.h | 41 - src/mesa/drivers/dri/i915/intel_screen.c | 690 ------------- src/mesa/drivers/dri/i915/intel_screen.h | 112 --- src/mesa/drivers/dri/i915/intel_span.c | 258 ----- src/mesa/drivers/dri/i915/intel_span.h | 41 - src/mesa/drivers/dri/i915/intel_state.c | 281 ------ src/mesa/drivers/dri/i915/intel_tex.c | 879 ---------------- src/mesa/drivers/dri/i915/intel_tex.h | 45 - src/mesa/drivers/dri/i915/intel_texmem.c | 72 -- src/mesa/drivers/dri/i915/intel_tris.c | 945 ----------------- src/mesa/drivers/dri/i915/intel_tris.h | 46 - src/mesa/drivers/dri/i915/server/i830_common.h | 212 ---- src/mesa/drivers/dri/i915/server/i830_dri.h | 73 -- src/mesa/drivers/dri/i915/server/intel.h | 328 ------ src/mesa/drivers/dri/i915/server/intel_dri.c | 1283 ------------------------ 50 files changed, 2 insertions(+), 21710 deletions(-) delete mode 100644 src/mesa/drivers/dri/i915/Makefile delete mode 100644 src/mesa/drivers/dri/i915/i830_context.c delete mode 100644 src/mesa/drivers/dri/i915/i830_context.h delete mode 100644 src/mesa/drivers/dri/i915/i830_metaops.c delete mode 100644 src/mesa/drivers/dri/i915/i830_reg.h delete mode 100644 src/mesa/drivers/dri/i915/i830_state.c delete mode 100644 src/mesa/drivers/dri/i915/i830_tex.c delete mode 100644 src/mesa/drivers/dri/i915/i830_texblend.c delete mode 100644 src/mesa/drivers/dri/i915/i830_texstate.c delete mode 100644 src/mesa/drivers/dri/i915/i830_vtbl.c delete mode 100644 src/mesa/drivers/dri/i915/i915_context.c delete mode 100644 src/mesa/drivers/dri/i915/i915_context.h delete mode 100644 src/mesa/drivers/dri/i915/i915_debug.c delete mode 100644 src/mesa/drivers/dri/i915/i915_fragprog.c delete mode 100644 src/mesa/drivers/dri/i915/i915_metaops.c delete mode 100644 src/mesa/drivers/dri/i915/i915_program.c delete mode 100644 src/mesa/drivers/dri/i915/i915_program.h delete mode 100644 src/mesa/drivers/dri/i915/i915_reg.h delete mode 100644 src/mesa/drivers/dri/i915/i915_state.c delete mode 100644 src/mesa/drivers/dri/i915/i915_tex.c delete mode 100644 src/mesa/drivers/dri/i915/i915_texprog.c delete mode 100644 src/mesa/drivers/dri/i915/i915_texstate.c delete mode 100644 src/mesa/drivers/dri/i915/i915_vtbl.c delete mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.c delete mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.h delete mode 100644 src/mesa/drivers/dri/i915/intel_context.c delete mode 100644 src/mesa/drivers/dri/i915/intel_context.h delete mode 100644 src/mesa/drivers/dri/i915/intel_ioctl.c delete mode 100644 src/mesa/drivers/dri/i915/intel_ioctl.h delete mode 100644 src/mesa/drivers/dri/i915/intel_pixel.c delete mode 100644 src/mesa/drivers/dri/i915/intel_reg.h delete mode 100644 src/mesa/drivers/dri/i915/intel_render.c delete mode 100644 src/mesa/drivers/dri/i915/intel_rotate.c delete mode 100644 src/mesa/drivers/dri/i915/intel_rotate.h delete mode 100644 src/mesa/drivers/dri/i915/intel_screen.c delete mode 100644 src/mesa/drivers/dri/i915/intel_screen.h delete mode 100644 src/mesa/drivers/dri/i915/intel_span.c delete mode 100644 src/mesa/drivers/dri/i915/intel_span.h delete mode 100644 src/mesa/drivers/dri/i915/intel_state.c delete mode 100644 src/mesa/drivers/dri/i915/intel_tex.c delete mode 100644 src/mesa/drivers/dri/i915/intel_tex.h delete mode 100644 src/mesa/drivers/dri/i915/intel_texmem.c delete mode 100644 src/mesa/drivers/dri/i915/intel_tris.c delete mode 100644 src/mesa/drivers/dri/i915/intel_tris.h delete mode 100644 src/mesa/drivers/dri/i915/server/i830_common.h delete mode 100644 src/mesa/drivers/dri/i915/server/i830_dri.h delete mode 100644 src/mesa/drivers/dri/i915/server/intel.h delete mode 100644 src/mesa/drivers/dri/i915/server/intel_dri.c (limited to 'src') diff --git a/configs/freebsd-dri b/configs/freebsd-dri index 9750017c23..e4d6b02bc2 100644 --- a/configs/freebsd-dri +++ b/configs/freebsd-dri @@ -45,6 +45,6 @@ DRM_SOURCE_PATH=$(TOP)/../drm # ffb and gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon tdfx \ +DRI_DIRS = i810 i915tex i965 mach64 mga r128 r200 r300 radeon tdfx \ unichrome savage sis diff --git a/configs/linux-dri b/configs/linux-dri index 5f945a73f1..3cba192569 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -66,5 +66,5 @@ WINDOW_SYSTEM=dri # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \ +DRI_DIRS = i810 i915tex i965 mach64 mga r128 r200 r300 radeon s3v \ savage sis tdfx trident unichrome ffb diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile deleted file mode 100644 index 805abf75e0..0000000000 --- a/src/mesa/drivers/dri/i915/Makefile +++ /dev/null @@ -1,50 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = i915_dri.so - -MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = \ - i915_context.c \ - i915_debug.c \ - i915_fragprog.c \ - i915_metaops.c \ - i915_program.c \ - i915_state.c \ - i915_tex.c \ - i915_texprog.c \ - i915_texstate.c \ - i915_vtbl.c \ - i830_context.c \ - i830_metaops.c \ - i830_state.c \ - i830_texblend.c \ - i830_tex.c \ - i830_texstate.c \ - i830_vtbl.c \ - intel_batchbuffer.c \ - intel_context.c \ - intel_ioctl.c \ - intel_pixel.c \ - intel_render.c \ - intel_rotate.c \ - intel_screen.c \ - intel_span.c \ - intel_state.c \ - intel_tex.c \ - intel_texmem.c \ - intel_tris.c - -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - - - -include ../Makefile.template - -symlinks: diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c deleted file mode 100644 index 7ca601e1b5..0000000000 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ /dev/null @@ -1,124 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "i830_context.h" -#include "imports.h" -#include "texmem.h" -#include "intel_tex.h" -#include "tnl/tnl.h" -#include "tnl/t_vertex.h" -#include "tnl/t_context.h" -#include "utils.h" - -/*************************************** - * Mesa's Driver Functions - ***************************************/ - -static const struct dri_extension i830_extensions[] = -{ - { "GL_ARB_texture_env_crossbar", NULL }, - { NULL, NULL } -}; - - -static void i830InitDriverFunctions( struct dd_function_table *functions ) -{ - intelInitDriverFunctions( functions ); - i830InitStateFuncs( functions ); - i830InitTextureFuncs( functions ); -} - - -GLboolean i830CreateContext( const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate) -{ - struct dd_function_table functions; - i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context); - intelContextPtr intel = &i830->intel; - GLcontext *ctx = &intel->ctx; - GLuint i; - if (!i830) return GL_FALSE; - - i830InitVtbl( i830 ); - i830InitDriverFunctions( &functions ); - - if (!intelInitContext( intel, mesaVis, driContextPriv, - sharedContextPrivate, &functions )) { - FREE(i830); - return GL_FALSE; - } - - intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; - intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; - intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; - - intel->nr_heaps = 1; - intel->texture_heaps[0] = - driCreateTextureHeap( 0, intel, - intel->intelScreen->tex.size, - 12, - I830_NR_TEX_REGIONS, - intel->sarea->texList, - (unsigned *) & intel->sarea->texAge, - & intel->swapped, - sizeof( struct i830_texture_object ), - (destroy_texture_object_t *)intelDestroyTexObj ); - - /* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are tightly - * FIXME: packed, but they're not in Intel graphics hardware. - */ - intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; - i = driQueryOptioni( &intel->optionCache, "allow_large_textures"); - driCalculateMaxTextureLevels( intel->texture_heaps, - intel->nr_heaps, - &intel->ctx.Const, - 4, - 11, /* max 2D texture size is 2048x2048 */ - 8, /* max 3D texture size is 256^3 */ - 10, /* max CUBE texture size is 1024x1024 */ - 11, /* max RECT. supported */ - 12, - GL_FALSE, - i ); - - _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, - 18 * sizeof(GLfloat) ); - - intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; - - driInitExtensions( ctx, i830_extensions, GL_FALSE ); - - i830InitState( i830 ); - - - _tnl_allow_vertex_fog( ctx, 1 ); - _tnl_allow_pixel_fog( ctx, 0 ); - - return GL_TRUE; -} - diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h deleted file mode 100644 index bae777dd5a..0000000000 --- a/src/mesa/drivers/dri/i915/i830_context.h +++ /dev/null @@ -1,218 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef I830CONTEXT_INC -#define I830CONTEXT_INC - -#include "intel_context.h" - -#define I830_FALLBACK_TEXTURE 0x1000 -#define I830_FALLBACK_COLORMASK 0x2000 -#define I830_FALLBACK_STENCIL 0x4000 -#define I830_FALLBACK_STIPPLE 0x8000 -#define I830_FALLBACK_LOGICOP 0x10000 - -#define I830_UPLOAD_CTX 0x1 -#define I830_UPLOAD_BUFFERS 0x2 -#define I830_UPLOAD_STIPPLE 0x4 -#define I830_UPLOAD_INVARIENT 0x8 -#define I830_UPLOAD_TEX(i) (0x10<<(i)) -#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i)) -#define I830_UPLOAD_TEX_ALL (0x0f0) -#define I830_UPLOAD_TEXBLEND_ALL (0xf00) - -/* State structure offsets - these will probably disappear. - */ -#define I830_DESTREG_CBUFADDR0 0 -#define I830_DESTREG_CBUFADDR1 1 -#define I830_DESTREG_CBUFADDR2 2 -#define I830_DESTREG_DBUFADDR0 3 -#define I830_DESTREG_DBUFADDR1 4 -#define I830_DESTREG_DBUFADDR2 5 -#define I830_DESTREG_DV0 6 -#define I830_DESTREG_DV1 7 -#define I830_DESTREG_SENABLE 8 -#define I830_DESTREG_SR0 9 -#define I830_DESTREG_SR1 10 -#define I830_DESTREG_SR2 11 -#define I830_DEST_SETUP_SIZE 12 - -#define I830_CTXREG_STATE1 0 -#define I830_CTXREG_STATE2 1 -#define I830_CTXREG_STATE3 2 -#define I830_CTXREG_STATE4 3 -#define I830_CTXREG_STATE5 4 -#define I830_CTXREG_IALPHAB 5 -#define I830_CTXREG_STENCILTST 6 -#define I830_CTXREG_ENABLES_1 7 -#define I830_CTXREG_ENABLES_2 8 -#define I830_CTXREG_AA 9 -#define I830_CTXREG_FOGCOLOR 10 -#define I830_CTXREG_BLENDCOLOR0 11 -#define I830_CTXREG_BLENDCOLOR1 12 -#define I830_CTXREG_VF 13 -#define I830_CTXREG_VF2 14 -#define I830_CTXREG_MCSB0 15 -#define I830_CTXREG_MCSB1 16 -#define I830_CTX_SETUP_SIZE 17 - -#define I830_STPREG_ST0 0 -#define I830_STPREG_ST1 1 -#define I830_STP_SETUP_SIZE 2 - -#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ -#define I830_TEXREG_TM0S0 1 -#define I830_TEXREG_TM0S1 2 -#define I830_TEXREG_TM0S2 3 -#define I830_TEXREG_TM0S3 4 -#define I830_TEXREG_TM0S4 5 -#define I830_TEXREG_MCS 6 /* _3DSTATE_MAP_COORD_SETS */ -#define I830_TEXREG_CUBE 7 /* _3DSTATE_MAP_SUBE */ -#define I830_TEX_SETUP_SIZE 8 - -#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ - -struct i830_texture_object -{ - struct intel_texture_object intel; - GLuint Setup[I830_TEX_SETUP_SIZE]; -}; - -#define I830_TEX_UNITS 4 - -struct i830_hw_state { - GLuint Ctx[I830_CTX_SETUP_SIZE]; - GLuint Buffer[I830_DEST_SETUP_SIZE]; - GLuint Stipple[I830_STP_SETUP_SIZE]; - GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE]; - GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE]; - GLuint TexBlendWordsUsed[I830_TEX_UNITS]; - GLuint emitted; /* I810_UPLOAD_* */ - GLuint active; -}; - -struct i830_context -{ - struct intel_context intel; - - DECLARE_RENDERINPUTS(last_index_bitset); - - struct i830_hw_state meta, initial, state, *current; -}; - -typedef struct i830_context *i830ContextPtr; -typedef struct i830_texture_object *i830TextureObjectPtr; - -#define I830_CONTEXT(ctx) ((i830ContextPtr)(ctx)) - - - -#define I830_STATECHANGE(i830, flag) \ -do { \ - INTEL_FIREVERTICES( &i830->intel ); \ - i830->state.emitted &= ~flag; \ -} while (0) - -#define I830_ACTIVESTATE(i830, flag, mode) \ -do { \ - INTEL_FIREVERTICES( &i830->intel ); \ - if (mode) \ - i830->state.active |= flag; \ - else \ - i830->state.active &= ~flag; \ -} while (0) - -/* i830_vtbl.c - */ -extern void -i830InitVtbl( i830ContextPtr i830 ); - -/* i830_context.c - */ -extern GLboolean -i830CreateContext( const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate); - -/* i830_tex.c, i830_texstate.c - */ -extern void -i830UpdateTextureState( intelContextPtr intel ); - -extern void -i830InitTextureFuncs( struct dd_function_table *functions ); - -extern intelTextureObjectPtr -i830AllocTexObj( struct gl_texture_object *tObj ); - -/* i830_texblend.c - */ -extern GLuint i830SetTexEnvCombine(i830ContextPtr i830, - const struct gl_tex_env_combine_state * combine, GLint blendUnit, - GLuint texel_op, GLuint *state, const GLfloat *factor ); - -extern void -i830EmitTextureBlend( i830ContextPtr i830 ); - - -/* i830_state.c - */ -extern void -i830InitStateFuncs( struct dd_function_table *functions ); - -extern void -i830EmitState( i830ContextPtr i830 ); - -extern void -i830InitState( i830ContextPtr i830 ); - -/* i830_metaops.c - */ -extern GLboolean -i830TryTextureReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ); - -extern GLboolean -i830TryTextureDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ); - -extern void -i830ClearWithTris( intelContextPtr intel, GLbitfield mask, - GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch); - -extern void -i830RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv, - GLuint srcBuf); - -#endif - diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c deleted file mode 100644 index c1d7fe349c..0000000000 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ /dev/null @@ -1,922 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" - -#include "i830_context.h" -#include "i830_reg.h" - -/* A large amount of state doesn't need to be uploaded. - */ -#define ACTIVE (I830_UPLOAD_INVARIENT | \ - I830_UPLOAD_TEXBLEND(0) | \ - I830_UPLOAD_STIPPLE | \ - I830_UPLOAD_CTX | \ - I830_UPLOAD_BUFFERS | \ - I830_UPLOAD_TEX(0)) - - -#define SET_STATE( i830, STATE ) \ -do { \ - i830->current->emitted = 0; \ - i830->current = &i830->STATE; \ - i830->current->emitted = 0; \ -} while (0) - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void set_initial_state( i830ContextPtr i830 ) -{ - memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); - i830->meta.active = ACTIVE; - i830->meta.emitted = 0; -} - - -static void set_no_depth_stencil_write( i830ContextPtr i830 ) -{ - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; - - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Set stencil unit to replace always with the reference value. - */ -static void set_stencil_replace( i830ContextPtr i830, - GLuint s_mask, - GLuint s_clear) -{ - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; - - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK((s_mask&0xff))); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE((s_clear&0xff)) | - STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); - - - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void set_color_mask( i830ContextPtr i830, GLboolean state ) -{ - const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | - (1 << WRITEMASK_GREEN_SHIFT) | - (1 << WRITEMASK_BLUE_SHIFT) | - (1 << WRITEMASK_ALPHA_SHIFT)); - - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; - - if (state) { - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= - (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); - } - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Installs a one-stage passthrough texture blend pipeline. Is there - * more that can be done to turn off texturing? - */ -static void set_no_texture( i830ContextPtr i830 ) -{ - static const struct gl_tex_env_combine_state comb = { - GL_NONE, GL_NONE, - { GL_TEXTURE, 0, 0, }, { GL_TEXTURE, 0, 0, }, - { GL_SRC_COLOR, 0, 0 }, { GL_SRC_ALPHA, 0, 0 }, - 0, 0, 0, 0 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine( i830, & comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); -} - -/* Set up a single element blend stage for 'replace' texturing with no - * funny ops. - */ -static void enable_texture_blend_replace( i830ContextPtr i830 ) -{ - static const struct gl_tex_env_combine_state comb = { - GL_REPLACE, GL_REPLACE, - { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE }, { GL_TEXTURE, GL_TEXTURE, GL_TEXTURE, }, - { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR }, { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }, - 0, 0, 1, 1 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine( i830, & comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); - -/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ -/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ -} - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static void set_tex_rect_source( i830ContextPtr i830, - GLuint offset, - GLuint width, - GLuint height, - GLuint pitch, /* in bytes */ - GLuint textureFormat ) -{ - GLint numLevels = 1; - GLuint *setup = i830->meta.Tex[0]; - -/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */ -/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */ - - setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << 0) | 4); - setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | offset); - setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | - ((width - 1) << TM0S1_WIDTH_SHIFT) | - textureFormat); - setup[I830_TEXREG_TM0S2] = ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); - setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; - setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; - setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; - - setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_IN_TEXELUNITS | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - - i830->meta.emitted &= ~I830_UPLOAD_TEX(0); -} - - -/* Select between front and back draw buffers. - */ -static void set_draw_region( i830ContextPtr i830, - const intelRegion *region ) -{ - i830->meta.Buffer[I830_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE); - i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = region->offset; - i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; -} - -/* Setup an arbitary draw format, useful for targeting - * texture or agp memory. - */ -#if 0 -static void set_draw_format( i830ContextPtr i830, - GLuint format, - GLuint depth_format) -{ - i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - format | - DEPTH_IS_Z | - depth_format); -} -#endif - - -static void set_vertex_format( i830ContextPtr i830 ) -{ - i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | - VFT0_TEX_COUNT(1) | - VFT0_DIFFUSE | - VFT0_SPEC | - VFT0_XYZW); - i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | - VFT1_TEX0_FMT(TEXCOORDFMT_2D) | - VFT1_TEX1_FMT(TEXCOORDFMT_2D) | - VFT1_TEX2_FMT(TEXCOORDFMT_2D) | - VFT1_TEX3_FMT(TEXCOORDFMT_2D)); - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void draw_quad(i830ContextPtr i830, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLubyte red, GLubyte green, - GLubyte blue, GLubyte alpha, - GLfloat s0, GLfloat s1, - GLfloat t0, GLfloat t1 ) -{ - GLuint vertex_size = 8; - GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel, - PRIM3D_TRIFAN, - 4*vertex_size, - vertex_size ); - intelVertex tmp; - int i; - - -/* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", */ -/* __FUNCTION__, */ -/* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */ - - - /* initial vertex, left bottom */ - tmp.v.x = x0; - tmp.v.y = y0; - tmp.v.z = 1.0; - tmp.v.w = 1.0; - tmp.v.color.red = red; - tmp.v.color.green = green; - tmp.v.color.blue = blue; - tmp.v.color.alpha = alpha; - tmp.v.specular.red = 0; - tmp.v.specular.green = 0; - tmp.v.specular.blue = 0; - tmp.v.specular.alpha = 0; - tmp.v.u0 = s0; - tmp.v.v0 = t0; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - - /* right bottom */ - vb += 8; - tmp.v.x = x1; - tmp.v.u0 = s1; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - - /* right top */ - vb += 8; - tmp.v.y = y1; - tmp.v.v0 = t1; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - - /* left top */ - vb += 8; - tmp.v.x = x0; - tmp.v.u0 = s0; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - -/* fprintf(stderr, "%s: DV1: %x\n", */ -/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */ -} - -static void draw_poly(i830ContextPtr i830, - GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha, - GLuint numVerts, - GLfloat verts[][2], - GLfloat texcoords[][2]) -{ - GLuint vertex_size = 8; - GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel, - PRIM3D_TRIFAN, - numVerts * vertex_size, - vertex_size ); - intelVertex tmp; - int i, k; - - /* initial constant vertex fields */ - tmp.v.z = 1.0; - tmp.v.w = 1.0; - tmp.v.color.red = red; - tmp.v.color.green = green; - tmp.v.color.blue = blue; - tmp.v.color.alpha = alpha; - tmp.v.specular.red = 0; - tmp.v.specular.green = 0; - tmp.v.specular.blue = 0; - tmp.v.specular.alpha = 0; - - for (k = 0; k < numVerts; k++) { - tmp.v.x = verts[k][0]; - tmp.v.y = verts[k][1]; - tmp.v.u0 = texcoords[k][0]; - tmp.v.v0 = texcoords[k][1]; - - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - vb += vertex_size; - } -} - -void -i830ClearWithTris(intelContextPtr intel, GLbitfield mask, - GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) -{ - i830ContextPtr i830 = I830_CONTEXT( intel ); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - intelScreenPrivate *screen = intel->intelScreen; - int x0, y0, x1, y1; - GLint cx, cy, cw, ch; - GLboolean all; - - INTEL_FIREVERTICES(intel); - SET_STATE( i830, meta ); - set_initial_state( i830 ); -/* set_no_texture( i830 ); */ - set_vertex_format( i830 ); - - LOCK_HARDWARE(intel); - - /* get clear bounds after locking */ - cx = intel->ctx.DrawBuffer->_Xmin; - cy = intel->ctx.DrawBuffer->_Ymin; - cw = intel->ctx.DrawBuffer->_Xmax - cx; - ch = intel->ctx.DrawBuffer->_Ymax - cy; - all = (cw == intel->ctx.DrawBuffer->Width && - ch == intel->ctx.DrawBuffer->Height); - - if(!all) { - x0 = cx; - y0 = cy; - x1 = x0 + cw; - y1 = y0 + ch; - } else { - x0 = 0; - y0 = 0; - x1 = x0 + dPriv->w; - y1 = y0 + dPriv->h; - } - - /* Don't do any clipping to screen - these are window coordinates. - * The active cliprects will be applied as for any other geometry. - */ - - if(mask & BUFFER_BIT_FRONT_LEFT) { - set_no_depth_stencil_write( i830 ); - set_color_mask( i830, GL_TRUE ); - set_draw_region( i830, &screen->front ); - draw_quad(i830, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } - - if(mask & BUFFER_BIT_BACK_LEFT) { - set_no_depth_stencil_write( i830 ); - set_color_mask( i830, GL_TRUE ); - set_draw_region( i830, &screen->back ); - - draw_quad(i830, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } - - if(mask & BUFFER_BIT_STENCIL) { - set_stencil_replace( i830, - intel->ctx.Stencil.WriteMask[0], - intel->ctx.Stencil.Clear); - - set_color_mask( i830, GL_FALSE ); - set_draw_region( i830, &screen->front ); - draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 ); - } - - UNLOCK_HARDWARE(intel); - - INTEL_FIREVERTICES(intel); - SET_STATE( i830, state ); -} - - -#if 0 - -GLboolean -i830TryTextureReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - intelContextPtr intel = INTEL_CONTEXT(ctx); - intelScreenPrivate *screen = i830->intel.intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - __DRIdrawablePrivate *dPriv = i830->intel.driDrawable; - int textureFormat; - GLenum glTextureFormat; - int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2]; - int destOffset = intelAgpOffsetFromVirtual( &i830->intel, pixels); - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if ( ctx->_ImageTransferState || - pack->SwapBytes || - pack->LsbFirst || - !pack->Invert) { - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - switch (screen->fbFormat) { - case DV_PF_565: - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - glTextureFormat = GL_RGB; - break; - case DV_PF_555: - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - glTextureFormat = GL_RGBA; - break; - case DV_PF_8888: - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - glTextureFormat = GL_RGBA; - break; - default: - fprintf(stderr, "%s: textureFormat failed %x\n", __FUNCTION__, - screen->fbFormat); - return GL_FALSE; - } - - - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - if (format != GL_RGB) return GL_FALSE; - destFormat = COLR_BUF_RGB565; - depthFormat = DEPTH_FRMT_16_FIXED; - destPitch = pitch * 2; - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (format != GL_BGRA) return GL_FALSE; - destFormat = COLR_BUF_ARGB8888; - depthFormat = DEPTH_FRMT_24_FIXED_8_OTHER; - destPitch = pitch * 4; - break; - default: - fprintf(stderr, "%s: destFormat failed %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(type)); - return GL_FALSE; - } - - destFormat |= (0x02<<24); - -/* fprintf(stderr, "type: %s destFormat: %x\n", */ -/* _mesa_lookup_enum_by_nr(type), */ -/* destFormat); */ - - intelFlush( ctx ); - - SET_STATE( i830, meta ); - set_initial_state( i830 ); - set_no_depth_stencil_write( i830 ); - - LOCK_HARDWARE( intel ); - { - intelWaitForIdle( intel ); /* required by GL */ - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - SET_STATE(i830, state); - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - -#if 0 - /* FIXME -- Just emit the correct state - */ - if (i830SetParam(i830->driFd, I830_SETPARAM_CBUFFER_PITCH, - destPitch) != 0) { - UNLOCK_HARDWARE( intel ); - SET_STATE(i830, state); - fprintf(stderr, "%s: setparam failed\n", __FUNCTION__); - return GL_FALSE; - } -#endif - - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - set_tex_rect_source( i830, - src_offset, - screen->width, - screen->height, - screen->front.pitch, - textureFormat ); - - - enable_texture_blend_replace( i830 ); - - - /* Set the 3d engine to draw into the agp memory - */ - - set_draw_region( i830, destOffset ); - set_draw_format( i830, destFormat, depthFormat ); - - - /* Draw a single quad, no cliprects: - */ - i830->intel.numClipRects = 1; - i830->intel.pClipRects = &tmp; - i830->intel.pClipRects[0].x1 = 0; - i830->intel.pClipRects[0].y1 = 0; - i830->intel.pClipRects[0].x2 = width; - i830->intel.pClipRects[0].y2 = height; - - draw_quad( i830, - 0, width, 0, height, - 0, 255, 0, 0, - x, x+width, y, y+height ); - - intelWindowMoved( intel ); - } - UNLOCK_HARDWARE( intel ); - intelFinish( ctx ); /* required by GL */ - - SET_STATE( i830, state ); - return GL_TRUE; -} - - -GLboolean -i830TryTextureDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLint pitch = unpack->RowLength ? unpack->RowLength : width; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int textureFormat; - GLenum glTextureFormat; - int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2]; - int src_offset = intelAgpOffsetFromVirtual( intel, pixels ); - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Todo -- upload images that aren't in agp space, then texture - * from them. - */ - - if ( !intelIsAgpMemory( intel, pixels, pitch*height ) ) { - fprintf(stderr, "%s: intelIsAgpMemory failed\n", __FUNCTION__); - return GL_FALSE; - } - - /* Todo -- don't want to clobber all the drawing state like we do - * for readpixels -- most of this state can be handled just fine. - */ - if ( ctx->_ImageTransferState || - unpack->SwapBytes || - unpack->LsbFirst || - ctx->Color.AlphaEnabled || - ctx->Depth.Test || - ctx->Fog.Enabled || - ctx->Scissor.Enabled || - ctx->Stencil.Enabled || - !ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3] || - ctx->Color.ColorLogicOpEnabled || - ctx->Texture._EnabledUnits || - ctx->Depth.OcclusionTest) { - fprintf(stderr, "%s: other tests failed\n", __FUNCTION__); - return GL_FALSE; - } - - /* Todo -- remove these restrictions: - */ - if (ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != -1.0F) - return GL_FALSE; - - - - switch (type) { - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (format != GL_BGRA) return GL_FALSE; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - glTextureFormat = GL_RGBA; - break; - case GL_UNSIGNED_SHORT_5_6_5: - if (format != GL_RGB) return GL_FALSE; - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - glTextureFormat = GL_RGB; - break; - case GL_UNSIGNED_SHORT_8_8_MESA: - if (format != GL_YCBCR_MESA) return GL_FALSE; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY -/* | TM0S1_COLORSPACE_CONVERSION */ - ); - glTextureFormat = GL_YCBCR_MESA; - break; - case GL_UNSIGNED_SHORT_8_8_REV_MESA: - if (format != GL_YCBCR_MESA) return GL_FALSE; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL -/* | TM0S1_COLORSPACE_CONVERSION */ - ); - glTextureFormat = GL_YCBCR_MESA; - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (format != GL_BGRA) return GL_FALSE; - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - glTextureFormat = GL_RGBA; - break; - default: - fprintf(stderr, "%s: destFormat failed\n", __FUNCTION__); - return GL_FALSE; - } - - intelFlush( ctx ); - - SET_STATE( i830, meta ); - - LOCK_HARDWARE( intel ); - { - intelWaitForIdle( intel ); /* required by GL */ - - y -= height; /* cope with pixel zoom */ - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - SET_STATE(i830, state); - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - - - y = dPriv->h - y - height; - - set_initial_state( i830 ); - - /* Set the pixel image up as a rectangular texture. - */ - set_tex_rect_source( i830, - src_offset, - width, - height, - pitch, /* XXXX!!!! -- /2 sometimes */ - textureFormat ); - - - enable_texture_blend_replace( i830 ); - - - /* Draw to the current draw buffer: - */ - set_draw_offset( i830, dst_offset ); - - /* Draw a quad, use regular cliprects - */ -/* fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */ - - draw_quad( i830, - x, x+width, y, y+height, - 0, 255, 0, 0, - 0, width, 0, height ); - - intelWindowMoved( intel ); - } - UNLOCK_HARDWARE( intel ); - intelFinish( ctx ); /* required by GL */ - - SET_STATE(i830, state); - - return GL_TRUE; -} - -#endif - -/** - * Copy the window contents named by dPriv to the rotated (or reflected) - * color buffer. - * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source. - */ -void -i830RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv, - GLuint srcBuf) -{ - i830ContextPtr i830 = I830_CONTEXT( intel ); - intelScreenPrivate *screen = intel->intelScreen; - const GLuint cpp = screen->cpp; - drm_clip_rect_t fullRect; - GLuint textureFormat, srcOffset, srcPitch; - const drm_clip_rect_t *clipRects; - int numClipRects; - int i; - - int xOrig, yOrig; - int origNumClipRects; - drm_clip_rect_t *origRects; - - /* - * set up hardware state - */ - intelFlush( &intel->ctx ); - - SET_STATE( i830, meta ); - set_initial_state( i830 ); - set_no_texture( i830 ); - set_vertex_format( i830 ); - set_no_depth_stencil_write( i830 ); - set_color_mask( i830, GL_FALSE ); - - LOCK_HARDWARE(intel); - - /* save current drawing origin and cliprects (restored at end) */ - xOrig = intel->drawX; - yOrig = intel->drawY; - origNumClipRects = intel->numClipRects; - origRects = intel->pClipRects; - - if (!intel->numClipRects) - goto done; - - /* - * set drawing origin, cliprects for full-screen access to rotated screen - */ - fullRect.x1 = 0; - fullRect.y1 = 0; - fullRect.x2 = screen->rotatedWidth; - fullRect.y2 = screen->rotatedHeight; - intel->drawX = 0; - intel->drawY = 0; - intel->numClipRects = 1; - intel->pClipRects = &fullRect; - - set_draw_region( i830, &screen->rotated ); - - if (cpp == 4) - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - else - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - - if (srcBuf == BUFFER_BIT_FRONT_LEFT) { - srcPitch = screen->front.pitch; /* in bytes */ - srcOffset = screen->front.offset; /* bytes */ - clipRects = dPriv->pClipRects; - numClipRects = dPriv->numClipRects; - } - else { - srcPitch = screen->back.pitch; /* in bytes */ - srcOffset = screen->back.offset; /* bytes */ - clipRects = dPriv->pBackClipRects; - numClipRects = dPriv->numBackClipRects; - } - - /* set the whole screen up as a texture to avoid alignment issues */ - set_tex_rect_source(i830, - srcOffset, - screen->width, - screen->height, - srcPitch, - textureFormat); - - enable_texture_blend_replace(i830); - - /* - * loop over the source window's cliprects - */ - for (i = 0; i < numClipRects; i++) { - int srcX0 = clipRects[i].x1; - int srcY0 = clipRects[i].y1; - int srcX1 = clipRects[i].x2; - int srcY1 = clipRects[i].y2; - GLfloat verts[4][2], tex[4][2]; - int j; - - /* build vertices for four corners of clip rect */ - verts[0][0] = srcX0; verts[0][1] = srcY0; - verts[1][0] = srcX1; verts[1][1] = srcY0; - verts[2][0] = srcX1; verts[2][1] = srcY1; - verts[3][0] = srcX0; verts[3][1] = srcY1; - - /* .. and texcoords */ - tex[0][0] = srcX0; tex[0][1] = srcY0; - tex[1][0] = srcX1; tex[1][1] = srcY0; - tex[2][0] = srcX1; tex[2][1] = srcY1; - tex[3][0] = srcX0; tex[3][1] = srcY1; - - /* transform coords to rotated screen coords */ - - for (j = 0; j < 4; j++) { - matrix23TransformCoordf(&screen->rotMatrix, - &verts[j][0], &verts[j][1]); - } - - /* draw polygon to map source image to dest region */ - draw_poly(i830, 255, 255, 255, 255, 4, verts, tex); - - } /* cliprect loop */ - - intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE ); - - done: - /* restore original drawing origin and cliprects */ - intel->drawX = xOrig; - intel->drawY = yOrig; - intel->numClipRects = origNumClipRects; - intel->pClipRects = origRects; - - UNLOCK_HARDWARE(intel); - - SET_STATE( i830, state ); -} - diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h deleted file mode 100644 index 98cee2f214..0000000000 --- a/src/mesa/drivers/dri/i915/i830_reg.h +++ /dev/null @@ -1,641 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef _I830_REG_H_ -#define _I830_REG_H_ - - -#include "intel_reg.h" - -#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) - -#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) -#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) -#define AA_LINE_ECAAR_WIDTH_0_5 0 -#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) -#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) -#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) -#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) -#define AA_LINE_REGION_WIDTH_0_5 0 -#define AA_LINE_REGION_WIDTH_1_0 (1<<6) -#define AA_LINE_REGION_WIDTH_2_0 (2<<6) -#define AA_LINE_REGION_WIDTH_4_0 (3<<6) -#define AA_LINE_ENABLE ((1<<1) | 1) -#define AA_LINE_DISABLE (1<<1) - -#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) -/* Dword 1 */ -#define BUF_3D_ID_COLOR_BACK (0x3<<24) -#define BUF_3D_ID_DEPTH (0x7<<24) -#define BUF_3D_USE_FENCE (1<<23) -#define BUF_3D_TILED_SURFACE (1<<22) -#define BUF_3D_TILE_WALK_X 0 -#define BUF_3D_TILE_WALK_Y (1<<21) -#define BUF_3D_PITCH(x) (((x)/4)<<2) -/* Dword 2 */ -#define BUF_3D_ADDR(x) ((x) & ~0x3) - - -#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) - -#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ - ((0x90+(stage))<<16)) - -#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) - -#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) - -#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) - -#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) - - -#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) -/* Dword 1 */ -#define DSTORG_HORT_BIAS(x) ((x)<<20) -#define DSTORG_VERT_BIAS(x) ((x)<<16) -#define COLOR_4_2_2_CHNL_WRT_ALL 0 -#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) -#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) -#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) -#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) -#define COLR_BUF_8BIT 0 -#define COLR_BUF_RGB555 (1<<8) -#define COLR_BUF_RGB565 (2<<8) -#define COLR_BUF_ARGB8888 (3<<8) -#define DEPTH_IS_Z 0 -#define DEPTH_IS_W (1<<6) -#define DEPTH_FRMT_16_FIXED 0 -#define DEPTH_FRMT_16_FLOAT (1<<2) -#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) -#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) -#define VERT_LINE_STRIDE_1 (1<<1) -#define VERT_LINE_STRIDE_0 0 -#define VERT_LINE_STRIDE_OFS_1 1 -#define VERT_LINE_STRIDE_OFS_0 0 - - -#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) -/* Dword 1 */ -#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) -#define DRAW_DITHER_OFS_X(x) ((x)<<26) -#define DRAW_DITHER_OFS_Y(x) ((x)<<24) -/* Dword 2 */ -#define DRAW_YMIN(x) ((x)<<16) -#define DRAW_XMIN(x) (x) -/* Dword 3 */ -#define DRAW_YMAX(x) ((x)<<16) -#define DRAW_XMAX(x) (x) -/* Dword 4 */ -#define DRAW_YORG(x) ((x)<<16) -#define DRAW_XORG(x) (x) - - -#define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) -#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) -#define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) -#define DISABLE_LOGIC_OP (1<<23) -#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) -#define DISABLE_STENCIL_TEST (1<<21) -#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) -#define DISABLE_DEPTH_BIAS (1<<11) -#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) -#define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) -#define DISABLE_SPEC_ADD (1<<9) -#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) -#define ENABLE_FOG ((1<<7)|(1<<6)) -#define DISABLE_FOG (1<<7) -#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) -#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) -#define DISABLE_ALPHA_TEST (1<<5) -#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) -#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) -#define DISABLE_COLOR_BLEND (1<<3) -#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) -#define ENABLE_DEPTH_TEST ((1<<1)|1) -#define DISABLE_DEPTH_TEST (1<<1) - -/* _3DSTATE_ENABLES_2, p138 */ -#define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) -#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) -#define DISABLE_STENCIL_WRITE (1<<21) -#define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) -#define DISABLE_TEX_CACHE (1<<17) -#define ENABLE_DITHER ((1<<9)|(1<<8)) -#define DISABLE_DITHER (1<<9) -#define ENABLE_COLOR_MASK (1<<10) -#define WRITEMASK_ALPHA (1<<7) -#define WRITEMASK_ALPHA_SHIFT 7 -#define WRITEMASK_RED (1<<6) -#define WRITEMASK_RED_SHIFT 6 -#define WRITEMASK_GREEN (1<<5) -#define WRITEMASK_GREEN_SHIFT 5 -#define WRITEMASK_BLUE (1<<4) -#define WRITEMASK_BLUE_SHIFT 4 -#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) -#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) -#define DISABLE_COLOR_WRITE (1<<3) -#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 -#define ENABLE_DEPTH_WRITE ((1<<1)|1) -#define DISABLE_DEPTH_WRITE (1<<1) - -/* _3DSTATE_FOG_COLOR, p139 */ -#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) -#define FOG_COLOR_RED(x) ((x)<<16) -#define FOG_COLOR_GREEN(x) ((x)<<8) -#define FOG_COLOR_BLUE(x) (x) - -/* _3DSTATE_FOG_MODE, p140 */ -#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) -/* Dword 1 */ -#define FOGFUNC_ENABLE (1<<31) -#define FOGFUNC_VERTEX 0 -#define FOGFUNC_PIXEL_EXP (1<<28) -#define FOGFUNC_PIXEL_EXP2 (2<<28) -#define FOGFUNC_PIXEL_LINEAR (3<<28) -#define FOGSRC_INDEX_Z (1<<27) -#define FOGSRC_INDEX_W ((1<<27)|(1<<25)) -#define FOG_LINEAR_CONST (1<<24) -#define FOG_CONST_1(x) ((x)<<4) -#define ENABLE_FOG_DENSITY (1<<23) -/* Dword 2 */ -#define FOG_CONST_2(x) (x) -/* Dword 3 */ -#define FOG_DENSITY(x) (x) - -/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ -#define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) -#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) -#define DISABLE_INDPT_ALPHA_BLEND (1<<23) -#define ALPHA_BLENDFUNC_MASK 0x3f0000 -#define ENABLE_ALPHA_BLENDFUNC (1<<21) -#define ABLENDFUNC_ADD 0 -#define ABLENDFUNC_SUB (1<<16) -#define ABLENDFUNC_RVSE_SUB (2<<16) -#define ABLENDFUNC_MIN (3<<16) -#define ABLENDFUNC_MAX (4<<16) -#define SRC_DST_ABLEND_MASK 0xfff -#define ENABLE_SRC_ABLEND_FACTOR (1<<11) -#define SRC_ABLEND_FACT(x) ((x)<<6) -#define ENABLE_DST_ABLEND_FACTOR (1<<5) -#define DST_ABLEND_FACT(x) (x) - - -/* _3DSTATE_MAP_BLEND_ARG, p152 */ -#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) - -#define TEXPIPE_COLOR 0 -#define TEXPIPE_ALPHA (1<<18) -#define TEXPIPE_KILL (2<<18) -#define TEXBLEND_ARG0 0 -#define TEXBLEND_ARG1 (1<<15) -#define TEXBLEND_ARG2 (2<<15) -#define TEXBLEND_ARG3 (3<<15) -#define TEXBLENDARG_MODIFY_PARMS (1<<6) -#define TEXBLENDARG_REPLICATE_ALPHA (1<<5) -#define TEXBLENDARG_INV_ARG (1<<4) -#define TEXBLENDARG_ONE 0 -#define TEXBLENDARG_FACTOR 0x01 -#define TEXBLENDARG_ACCUM 0x02 -#define TEXBLENDARG_DIFFUSE 0x03 -#define TEXBLENDARG_SPEC 0x04 -#define TEXBLENDARG_CURRENT 0x05 -#define TEXBLENDARG_TEXEL0 0x06 -#define TEXBLENDARG_TEXEL1 0x07 -#define TEXBLENDARG_TEXEL2 0x08 -#define TEXBLENDARG_TEXEL3 0x09 -#define TEXBLENDARG_FACTOR_N 0x0e - -/* _3DSTATE_MAP_BLEND_OP, p155 */ -#define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) -#if 0 -# define TEXPIPE_COLOR 0 -# define TEXPIPE_ALPHA (1<<18) -# define TEXPIPE_KILL (2<<18) -#endif -#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) -#define TEXOP_OUTPUT_CURRENT 0 -#define TEXOP_OUTPUT_ACCUM (1<<15) -#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) -#define DISABLE_TEX_CNTRL_STAGE (1<<12) -#define TEXOP_SCALE_SHIFT 9 -#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) -#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) -#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) -#define TEXOP_MODIFY_PARMS (1<<8) -#define TEXOP_LAST_STAGE (1<<7) -#define TEXBLENDOP_KILLPIXEL 0x02 -#define TEXBLENDOP_ARG1 0x01 -#define TEXBLENDOP_ARG2 0x02 -#define TEXBLENDOP_MODULATE 0x03 -#define TEXBLENDOP_ADD 0x06 -#define TEXBLENDOP_ADDSIGNED 0x07 -#define TEXBLENDOP_BLEND 0x08 -#define TEXBLENDOP_BLEND_AND_ADD 0x09 -#define TEXBLENDOP_SUBTRACT 0x0a -#define TEXBLENDOP_DOT3 0x0b -#define TEXBLENDOP_DOT4 0x0c -#define TEXBLENDOP_MODULATE_AND_ADD 0x0d -#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e -#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f - -/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ -/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ - -#define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) -#define DISABLE_TEX_TRANSFORM (1<<28) -#define TEXTURE_SET(x) (x<<29) - -#define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) -#define DISABLE_VIEWPORT_TRANSFORM (1<<31) -#define DISABLE_PERSPECTIVE_DIVIDE (1<<29) - - -/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ -#define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) -#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) -#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) -#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) -#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) - -#define TEXBIND_SET3(x) ((x)<<12) -#define TEXBIND_SET2(x) ((x)<<8) -#define TEXBIND_SET1(x) ((x)<<4) -#define TEXBIND_SET0(x) (x) - -#define TEXCOORDSRC_KEEP 0 -#define TEXCOORDSRC_DEFAULT 0x01 -#define TEXCOORDSRC_VTXSET_0 0x08 -#define TEXCOORDSRC_VTXSET_1 0x09 -#define TEXCOORDSRC_VTXSET_2 0x0a -#define TEXCOORDSRC_VTXSET_3 0x0b -#define TEXCOORDSRC_VTXSET_4 0x0c -#define TEXCOORDSRC_VTXSET_5 0x0d -#define TEXCOORDSRC_VTXSET_6 0x0e -#define TEXCOORDSRC_VTXSET_7 0x0f - -#define MAP_UNIT(unit) ((unit)<<16) -#define MAP_UNIT_MASK (0x7<<16) - -/* _3DSTATE_MAP_COORD_SETS, p164 */ -#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) -#define ENABLE_TEXCOORD_PARAMS (1<<15) -#define TEXCOORDS_ARE_NORMAL (1<<14) -#define TEXCOORDS_ARE_IN_TEXELUNITS 0 -#define TEXCOORDTYPE_CARTESIAN 0 -#define TEXCOORDTYPE_HOMOGENEOUS (1<<11) -#define TEXCOORDTYPE_VECTOR (2<<11) -#define TEXCOORDTYPE_MASK (0x7<<11) -#define ENABLE_ADDR_V_CNTL (1<<7) -#define ENABLE_ADDR_U_CNTL (1<<3) -#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) -#define TEXCOORD_ADDR_U_MODE(x) (x) -#define TEXCOORDMODE_WRAP 0 -#define TEXCOORDMODE_MIRROR 1 -#define TEXCOORDMODE_CLAMP 2 -#define TEXCOORDMODE_WRAP_SHORTEST 3 -#define TEXCOORDMODE_CLAMP_BORDER 4 -#define TEXCOORD_ADDR_V_MASK 0x70 -#define TEXCOORD_ADDR_U_MASK 0x7 - -/* _3DSTATE_MAP_CUBE, p168 TODO */ -#define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) -#define CUBE_NEGX_ENABLE (1<<5) -#define CUBE_POSX_ENABLE (1<<4) -#define CUBE_NEGY_ENABLE (1<<3) -#define CUBE_POSY_ENABLE (1<<2) -#define CUBE_NEGZ_ENABLE (1<<1) -#define CUBE_POSZ_ENABLE (1<<0) - - -/* _3DSTATE_MODES_1, p190 */ -#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) -#define BLENDFUNC_MASK 0x3f0000 -#define ENABLE_COLR_BLND_FUNC (1<<21) -#define BLENDFUNC_ADD 0 -#define BLENDFUNC_SUB (1<<16) -#define BLENDFUNC_RVRSE_SUB (2<<16) -#define BLENDFUNC_MIN (3<<16) -#define BLENDFUNC_MAX (4<<16) -#define SRC_DST_BLND_MASK 0xfff -#define ENABLE_SRC_BLND_FACTOR (1<<11) -#define ENABLE_DST_BLND_FACTOR (1<<5) -#define SRC_BLND_FACT(x) ((x)<<6) -#define DST_BLND_FACT(x) (x) - - -/* _3DSTATE_MODES_2, p192 */ -#define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) -#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) -#define GLOBAL_DEPTH_BIAS(x) ((x)<<14) -#define ENABLE_ALPHA_TEST_FUNC (1<<13) -#define ENABLE_ALPHA_REF_VALUE (1<<8) -#define ALPHA_TEST_FUNC(x) ((x)<<9) -#define ALPHA_REF_VALUE(x) (x) - -#define ALPHA_TEST_REF_MASK 0x3fff - -/* _3DSTATE_MODES_3, p193 */ -#define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) -#define DEPTH_TEST_FUNC_MASK 0x1f0000 -#define ENABLE_DEPTH_TEST_FUNC (1<<20) -/* Uses COMPAREFUNC */ -#define DEPTH_TEST_FUNC(x) ((x)<<16) -#define ENABLE_ALPHA_SHADE_MODE (1<<11) -#define ENABLE_FOG_SHADE_MODE (1<<9) -#define ENABLE_SPEC_SHADE_MODE (1<<7) -#define ENABLE_COLOR_SHADE_MODE (1<<5) -#define ALPHA_SHADE_MODE(x) ((x)<<10) -#define FOG_SHADE_MODE(x) ((x)<<8) -#define SPEC_SHADE_MODE(x) ((x)<<6) -#define COLOR_SHADE_MODE(x) ((x)<<4) -#define CULLMODE_MASK 0xf -#define ENABLE_CULL_MODE (1<<3) -#define CULLMODE_BOTH 0 -#define CULLMODE_NONE 1 -#define CULLMODE_CW 2 -#define CULLMODE_CCW 3 - -#define SHADE_MODE_LINEAR 0 -#define SHADE_MODE_FLAT 0x1 - -/* _3DSTATE_MODES_4, p195 */ -#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) -#define ENABLE_LOGIC_OP_FUNC (1<<23) -#define LOGIC_OP_FUNC(x) ((x)<<18) -#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) -#define LOGICOP_CLEAR 0 -#define LOGICOP_NOR 0x1 -#define LOGICOP_AND_INV 0x2 -#define LOGICOP_COPY_INV 0x3 -#define LOGICOP_AND_RVRSE 0x4 -#define LOGICOP_INV 0x5 -#define LOGICOP_XOR 0x6 -#define LOGICOP_NAND 0x7 -#define LOGICOP_AND 0x8 -#define LOGICOP_EQUIV 0x9 -#define LOGICOP_NOOP 0xa -#define LOGICOP_OR_INV 0xb -#define LOGICOP_COPY 0xc -#define LOGICOP_OR_RVRSE 0xd -#define LOGICOP_OR 0xe -#define LOGICOP_SET 0xf -#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) -#define ENABLE_STENCIL_TEST_MASK (1<<17) -#define STENCIL_TEST_MASK(x) ((x)<<8) -#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) -#define ENABLE_STENCIL_WRITE_MASK (1<<16) -#define STENCIL_WRITE_MASK(x) ((x)&0xff) - -/* _3DSTATE_MODES_5, p196 */ -#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) -#define ENABLE_SPRITE_POINT_TEX (1<<23) -#define SPRITE_POINT_TEX_ON (1<<22) -#define SPRITE_POINT_TEX_OFF 0 -#define FLUSH_RENDER_CACHE (1<<18) -#define FLUSH_TEXTURE_CACHE (1<<16) -#define FIXED_LINE_WIDTH_MASK 0xfc00 -#define ENABLE_FIXED_LINE_WIDTH (1<<15) -#define FIXED_LINE_WIDTH(x) ((x)<<10) -#define FIXED_POINT_WIDTH_MASK 0x3ff -#define ENABLE_FIXED_POINT_WIDTH (1<<9) -#define FIXED_POINT_WIDTH(x) (x) - -/* _3DSTATE_RASTERIZATION_RULES, p198 */ -#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) -#define ENABLE_POINT_RASTER_RULE (1<<15) -#define OGL_POINT_RASTER_RULE (1<<13) -#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) -#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) -#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) -#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) -#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) -#define TRI_STRIP_PROVOKE_VRTX(x) (x) - -/* _3DSTATE_SCISSOR_ENABLE, p200 */ -#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) -#define ENABLE_SCISSOR_RECT ((1<<1) | 1) -#define DISABLE_SCISSOR_RECT (1<<1) - -/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ -#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) -/* Dword 1 */ -#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) -#define SCISSOR_RECT_0_XMIN(x) (x) -/* Dword 2 */ -#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) -#define SCISSOR_RECT_0_XMAX(x) (x) - -/* _3DSTATE_STENCIL_TEST, p202 */ -#define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) -#define ENABLE_STENCIL_PARMS (1<<23) -#define STENCIL_OPS_MASK (0xffc000) -#define STENCIL_FAIL_OP(x) ((x)<<20) -#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) -#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) - -#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) -#define ENABLE_STENCIL_TEST_FUNC (1<<13) -/* Uses COMPAREFUNC */ -#define STENCIL_TEST_FUNC(x) ((x)<<9) -#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) -#define ENABLE_STENCIL_REF_VALUE (1<<8) -#define STENCIL_REF_VALUE(x) (x) - -/* _3DSTATE_VERTEX_FORMAT, p204 */ -#define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) -#define VFT0_POINT_WIDTH (1<<12) -#define VFT0_TEX_COUNT_MASK (7<<8) -#define VFT0_TEX_COUNT_SHIFT 8 -#define VFT0_TEX_COUNT(x) ((x)<<8) -#define VFT0_SPEC (1<<7) -#define VFT0_DIFFUSE (1<<6) -#define VFT0_DEPTH_OFFSET (1<<5) -#define VFT0_XYZ (1<<1) -#define VFT0_XYZW (2<<1) -#define VFT0_XY (3<<1) -#define VFT0_XYW (4<<1) -#define VFT0_XYZW_MASK (7<<1) - -/* _3DSTATE_VERTEX_FORMAT_2, p206 */ -#define _3DSTATE_VFT1_CMD (CMD_3D|(0x0a<<24)) -#define VFT1_TEX7_FMT(x) ((x)<<14) -#define VFT1_TEX6_FMT(x) ((x)<<12) -#define VFT1_TEX5_FMT(x) ((x)<<10) -#define VFT1_TEX4_FMT(x) ((x)<<8) -#define VFT1_TEX3_FMT(x) ((x)<<6) -#define VFT1_TEX2_FMT(x) ((x)<<4) -#define VFT1_TEX1_FMT(x) ((x)<<2) -#define VFT1_TEX0_FMT(x) (x) -#define VFT1_TEX0_MASK 3 -#define VFT1_TEX1_SHIFT 2 -#define TEXCOORDFMT_2D 0 -#define TEXCOORDFMT_3D 1 -#define TEXCOORDFMT_4D 2 -#define TEXCOORDFMT_1D 3 - -/*New stuff picked up along the way */ - -#define MLC_LOD_BIAS_MASK ((1<<7)-1) - - -/* _3DSTATE_VERTEX_TRANSFORM, p207 */ -#define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) -#define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) -/* Dword 1 */ -#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) -#define DISABLE_VIEWPORT_TRANSFORM (1<<31) -#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) -#define DISABLE_PERSP_DIVIDE (1<<29) -#define VRTX_TRANS_LOAD_MATRICES 0x7421 -#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 -/* Dword 2 -> 7 are matrix elements */ - -/* _3DSTATE_W_STATE, p209 */ -#define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) -/* Dword 1 */ -#define MAGIC_W_STATE_DWORD1 0x00000008 -/* Dword 2 */ -#define WFAR_VALUE(x) (x) - - -/* Stipple command, carried over from the i810, apparently: - */ -#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define ST1_ENABLE (1<<16) -#define ST1_MASK (0xffff) - - - -#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) -#define LOAD_TEXTURE_MAP0 (1<<11) -#define LOAD_GLOBAL_COLOR_FACTOR (1<<6) - -#define TM0S0_ADDRESS_MASK 0xfffffffc -#define TM0S0_USE_FENCE (1<<1) - -#define TM0S1_HEIGHT_SHIFT 21 -#define TM0S1_WIDTH_SHIFT 10 -#define TM0S1_PALETTE_SELECT (1<<9) -#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) -#define TM0S1_MAPSURF_FORMAT_SHIFT 6 -#define MAPSURF_8BIT_INDEXED (0<<6) -#define MAPSURF_8BIT (1<<6) -#define MAPSURF_16BIT (2<<6) -#define MAPSURF_32BIT (3<<6) -#define MAPSURF_411 (4<<6) -#define MAPSURF_422 (5<<6) -#define MAPSURF_COMPRESSED (6<<6) -#define MAPSURF_4BIT_INDEXED (7<<6) -#define TM0S1_MT_FORMAT_MASK (0x7 << 3) -#define TM0S1_MT_FORMAT_SHIFT 3 -#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ -#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ -#define MT_8BIT_IDX_ARGB1555 (1<<3) -#define MT_8BIT_IDX_ARGB4444 (2<<3) -#define MT_8BIT_IDX_AY88 (3<<3) -#define MT_8BIT_IDX_ABGR8888 (4<<3) -#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) -#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) -#define MT_8BIT_IDX_ARGB8888 (7<<3) -#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ -#define MT_8BIT_L8 (1<<3) -#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ -#define MT_16BIT_ARGB1555 (1<<3) -#define MT_16BIT_ARGB4444 (2<<3) -#define MT_16BIT_AY88 (3<<3) -#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) -#define MT_16BIT_BUMP_88DVDU (5<<3) -#define MT_16BIT_BUMP_655LDVDU (6<<3) -#define MT_16BIT_DIB_RGB565_8888 (7<<3) -#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ -#define MT_32BIT_ABGR8888 (1<<3) -#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) -#define MT_32BIT_DIB_8888 (7<<3) -#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ -#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ -#define MT_422_YCRCB_NORMAL (1<<3) -#define MT_422_YCRCB_SWAPUV (2<<3) -#define MT_422_YCRCB_SWAPUVY (3<<3) -#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ -#define MT_COMPRESS_DXT2_3 (1<<3) -#define MT_COMPRESS_DXT4_5 (2<<3) -#define MT_COMPRESS_FXT1 (3<<3) -#define TM0S1_COLORSPACE_CONVERSION (1 << 2) -#define TM0S1_TILED_SURFACE (1 << 1) -#define TM0S1_TILE_WALK (1 << 0) - -#define TM0S2_PITCH_SHIFT 21 -#define TM0S2_CUBE_FACE_ENA_SHIFT 15 -#define TM0S2_CUBE_FACE_ENA_MASK (1<<15) -#define TM0S2_MAP_FORMAT (1<<14) -#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) -#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) -#define TM0S2_OUTPUT_CHAN_SHIFT 10 -#define TM0S2_OUTPUT_CHAN_MASK (3<<10) - -#define TM0S3_MIP_FILTER_MASK (0x3<<30) -#define TM0S3_MIP_FILTER_SHIFT 30 -#define MIPFILTER_NONE 0 -#define MIPFILTER_NEAREST 1 -#define MIPFILTER_LINEAR 3 -#define TM0S3_MAG_FILTER_MASK (0x3<<28) -#define TM0S3_MAG_FILTER_SHIFT 28 -#define TM0S3_MIN_FILTER_MASK (0x3<<26) -#define TM0S3_MIN_FILTER_SHIFT 26 -#define FILTER_NEAREST 0 -#define FILTER_LINEAR 1 -#define FILTER_ANISOTROPIC 2 - -#define TM0S3_LOD_BIAS_SHIFT 17 -#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) -#define TM0S3_MAX_MIP_SHIFT 9 -#define TM0S3_MAX_MIP_MASK (0xff<<9) -#define TM0S3_MIN_MIP_SHIFT 3 -#define TM0S3_MIN_MIP_MASK (0x3f<<3) -#define TM0S3_KILL_PIXEL (1<<2) -#define TM0S3_KEYED_FILTER (1<<1) -#define TM0S3_CHROMA_KEY (1<<0) - - -/* _3DSTATE_MAP_TEXEL_STREAM, p188 */ -#define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) -#define DISABLE_TEX_STREAM_BUMP (1<<12) -#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) -#define TEX_MODIFY_UNIT_0 0 -#define TEX_MODIFY_UNIT_1 (1<<8) -#define ENABLE_TEX_STREAM_COORD_SET (1<<7) -#define TEX_STREAM_COORD_SET(x) ((x)<<4) -#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) -#define TEX_STREAM_MAP_IDX(x) (x) - - -#define MI_FLUSH ((0<<29)|(4<<23)) -#define FLUSH_MAP_CACHE (1<<0) - -#endif diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c deleted file mode 100644 index f7980201f9..0000000000 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ /dev/null @@ -1,1089 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" - -#include "texmem.h" - -#include "drivers/common/driverfuncs.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" - -#include "i830_context.h" -#include "i830_reg.h" - -static void -i830StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, - GLuint mask) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - - mask = mask & 0xff; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(func), ref, mask); - - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(mask)); - i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); - i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE(ref) | - STENCIL_TEST_FUNC(test)); -} - -static void -i830StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); - - mask = mask & 0xff; - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(mask)); -} - -static void -i830StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, - GLenum zpass) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - int fop, dfop, dpop; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(fail), - _mesa_lookup_enum_by_nr(zfail), - _mesa_lookup_enum_by_nr(zpass)); - - fop = 0; dfop = 0; dpop = 0; - - switch(fail) { - case GL_KEEP: - fop = STENCILOP_KEEP; - break; - case GL_ZERO: - fop = STENCILOP_ZERO; - break; - case GL_REPLACE: - fop = STENCILOP_REPLACE; - break; - case GL_INCR: - fop = STENCILOP_INCRSAT; - break; - case GL_DECR: - fop = STENCILOP_DECRSAT; - break; - case GL_INCR_WRAP: - fop = STENCILOP_INCR; - break; - case GL_DECR_WRAP: - fop = STENCILOP_DECR; - break; - case GL_INVERT: - fop = STENCILOP_INVERT; - break; - default: - break; - } - switch(zfail) { - case GL_KEEP: - dfop = STENCILOP_KEEP; - break; - case GL_ZERO: - dfop = STENCILOP_ZERO; - break; - case GL_REPLACE: - dfop = STENCILOP_REPLACE; - break; - case GL_INCR: - dfop = STENCILOP_INCRSAT; - break; - case GL_DECR: - dfop = STENCILOP_DECRSAT; - break; - case GL_INCR_WRAP: - dfop = STENCILOP_INCR; - break; - case GL_DECR_WRAP: - dfop = STENCILOP_DECR; - break; - case GL_INVERT: - dfop = STENCILOP_INVERT; - break; - default: - break; - } - switch(zpass) { - case GL_KEEP: - dpop = STENCILOP_KEEP; - break; - case GL_ZERO: - dpop = STENCILOP_ZERO; - break; - case GL_REPLACE: - dpop = STENCILOP_REPLACE; - break; - case GL_INCR: - dpop = STENCILOP_INCRSAT; - break; - case GL_DECR: - dpop = STENCILOP_DECRSAT; - break; - case GL_INCR_WRAP: - dpop = STENCILOP_INCR; - break; - case GL_DECR_WRAP: - dpop = STENCILOP_DECR; - break; - case GL_INVERT: - dpop = STENCILOP_INVERT; - break; - default: - break; - } - - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); - i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(fop) | - STENCIL_PASS_DEPTH_FAIL_OP(dfop) | - STENCIL_PASS_DEPTH_PASS_OP(dpop)); -} - -static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - GLubyte refByte; - GLuint refInt; - - UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); - refInt = (GLuint)refByte; - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; - i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | - ENABLE_ALPHA_REF_VALUE | - ALPHA_TEST_FUNC(test) | - ALPHA_REF_VALUE(refInt)); -} - -/** - * Makes sure that the proper enables are set for LogicOp, Independant Alpha - * Blend, and Blending. It needs to be called from numerous places where we - * could change the LogicOp or Independant Alpha Blend without subsequent - * calls to glEnable. - * - * \todo - * This function is substantially different from the old i830-specific driver. - * I'm not sure which is correct. - */ -static void i830EvalLogicOpBlendState(GLcontext *ctx) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - if (RGBA_LOGICOP_ENABLED(ctx)) { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | - ENABLE_LOGIC_OP_MASK); - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | - ENABLE_LOGIC_OP); - } else if (ctx->Color.BlendEnabled) { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | - ENABLE_LOGIC_OP_MASK); - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND | - DISABLE_LOGIC_OP); - } else { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | - ENABLE_LOGIC_OP_MASK); - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | - DISABLE_LOGIC_OP); - } -} - -static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLubyte r, g, b, a; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b; -} - -/** - * Sets both the blend equation (called "function" in i830 docs) and the - * blend function (called "factor" in i830 docs). This is done in a single - * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) - * change the interpretation of the blend function. - */ -static void i830_set_blend_state( GLcontext * ctx ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - int funcA; - int funcRGB; - int eqnA; - int eqnRGB; - int iab; - int s1; - - - funcRGB = SRC_BLND_FACT( intel_translate_blend_factor( ctx->Color.BlendSrcRGB ) ) - | DST_BLND_FACT( intel_translate_blend_factor( ctx->Color.BlendDstRGB ) ); - - switch(ctx->Color.BlendEquationRGB) { - case GL_FUNC_ADD: - eqnRGB = BLENDFUNC_ADD; - break; - case GL_MIN: - eqnRGB = BLENDFUNC_MIN; - funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_MAX: - eqnRGB = BLENDFUNC_MAX; - funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_FUNC_SUBTRACT: - eqnRGB = BLENDFUNC_SUB; - break; - case GL_FUNC_REVERSE_SUBTRACT: - eqnRGB = BLENDFUNC_RVRSE_SUB; - break; - default: - fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB ); - return; - } - - - funcA = SRC_ABLEND_FACT( intel_translate_blend_factor( ctx->Color.BlendSrcA ) ) - | DST_ABLEND_FACT( intel_translate_blend_factor( ctx->Color.BlendDstA ) ); - - switch(ctx->Color.BlendEquationA) { - case GL_FUNC_ADD: - eqnA = BLENDFUNC_ADD; - break; - case GL_MIN: - eqnA = BLENDFUNC_MIN; - funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_MAX: - eqnA = BLENDFUNC_MAX; - funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_FUNC_SUBTRACT: - eqnA = BLENDFUNC_SUB; - break; - case GL_FUNC_REVERSE_SUBTRACT: - eqnA = BLENDFUNC_RVRSE_SUB; - break; - default: - fprintf( stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationA ); - return; - } - - iab = eqnA | funcA - | _3DSTATE_INDPT_ALPHA_BLEND_CMD - | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR - | ENABLE_ALPHA_BLENDFUNC; - s1 = eqnRGB | funcRGB - | _3DSTATE_MODES_1_CMD - | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR - | ENABLE_COLR_BLND_FUNC; - - if ( (eqnA | funcA) != (eqnRGB | funcRGB) ) - iab |= ENABLE_INDPT_ALPHA_BLEND; - else - iab |= DISABLE_INDPT_ALPHA_BLEND; - - if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] || - s1 != i830->state.Ctx[I830_CTXREG_STATE1]) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_IALPHAB] = iab; - i830->state.Ctx[I830_CTXREG_STATE1] = s1; - } - - /* This will catch a logicop blend equation. It will also ensure - * independant alpha blend is really in the correct state (either enabled - * or disabled) if blending is already enabled. - */ - - i830EvalLogicOpBlendState(ctx); - - if (0) { - fprintf(stderr, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n", - __FUNCTION__, __LINE__, - i830->state.Ctx[I830_CTXREG_STATE1], - i830->state.Ctx[I830_CTXREG_IALPHAB], - (ctx->Color.BlendEnabled) ? "en" : "dis"); - } -} - - -static void i830BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, - GLenum modeA) -{ - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s -> %s, %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(modeRGB), - _mesa_lookup_enum_by_nr(modeA)); - - (void) modeRGB; - (void) modeA; - i830_set_blend_state( ctx ); -} - - -static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, - GLenum dfactorRGB, GLenum sfactorA, - GLenum dfactorA ) -{ - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(sfactorRGB), - _mesa_lookup_enum_by_nr(dfactorRGB), - _mesa_lookup_enum_by_nr(sfactorA), - _mesa_lookup_enum_by_nr(dfactorA)); - - (void) sfactorRGB; - (void) dfactorRGB; - (void) sfactorA; - (void) dfactorA; - i830_set_blend_state( ctx ); -} - - - -static void i830DepthFunc(GLcontext *ctx, GLenum func) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; - i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC(test)); -} - -static void i830DepthMask(GLcontext *ctx, GLboolean flag) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - - if (flag && ctx->Depth.Test) - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; - else - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; -} - -/* ============================================================= - * Polygon stipple - * - * The i830 supports a 4x4 stipple natively, GL wants 32x32. - * Fortunately stipple is usually a repeating pattern. - */ -static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - const GLubyte *m = mask; - GLubyte p[4]; - int i,j,k; - int active = (ctx->Polygon.StippleFlag && - i830->intel.reduced_primitive == GL_TRIANGLES); - GLuint newMask; - - if (active) { - I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); - i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - } - - p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; - p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; - p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; - p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; - - for (k = 0 ; k < 8 ; k++) - for (j = 3 ; j >= 0; j--) - for (i = 0 ; i < 4 ; i++, m++) - if (*m != p[j]) { - i830->intel.hw_stipple = 0; - return; - } - - newMask = (((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | - ((p[3] & 0xf) << 12)); - - - if (newMask == 0xffff || newMask == 0x0) { - /* this is needed to make conform pass */ - i830->intel.hw_stipple = 0; - return; - } - - i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff; - i830->state.Stipple[I830_STPREG_ST1] |= newMask; - i830->intel.hw_stipple = 1; - - if (active) - i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; -} - - -/* ============================================================= - * Hardware clipping - */ -static void i830Scissor(GLcontext *ctx, GLint x, GLint y, - GLsizei w, GLsizei h) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - intelScreenPrivate *screen = i830->intel.intelScreen; - int x1, y1, x2, y2; - - if (!i830->intel.driDrawable) - return; - - x1 = x; - y1 = i830->intel.driDrawable->h - (y + h); - x2 = x + w - 1; - y2 = y1 + h - 1; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__, - x, y, w, h); - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 < 0) x2 = 0; - if (y2 < 0) y2 = 0; - - if (x2 >= screen->width) x2 = screen->width-1; - if (y2 >= screen->height) y2 = screen->height-1; - if (x1 >= screen->width) x1 = screen->width-1; - if (y1 >= screen->height) y1 = screen->height-1; - - - I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); - i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); - i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); -} - -static void i830LogicOp(GLcontext *ctx, GLenum opcode) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - int tmp = intel_translate_logic_op( opcode ); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; - i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); -} - - - -static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLuint mode; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (!ctx->Polygon.CullFlag) { - mode = CULLMODE_NONE; - } - else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { - mode = CULLMODE_CW; - - if (ctx->Polygon.CullFaceMode == GL_FRONT) - mode ^= (CULLMODE_CW ^ CULLMODE_CCW); - if (ctx->Polygon.FrontFace != GL_CCW) - mode ^= (CULLMODE_CW ^ CULLMODE_CCW); - } - else { - mode = CULLMODE_BOTH; - } - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; -} - -static void i830LineWidth( GLcontext *ctx, GLfloat widthf ) -{ - i830ContextPtr i830 = I830_CONTEXT( ctx ); - int width; - int state5; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - width = (int)(widthf * 2); - CLAMP_SELF(width, 1, 15); - - state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK; - state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width)); - - if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE5] = state5; - } -} - -static void i830PointSize(GLcontext *ctx, GLfloat size) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLint point_size = (int)size; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - CLAMP_SELF(point_size, 1, 256); - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; - i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | - FIXED_POINT_WIDTH(point_size)); -} - - -/* ============================================================= - * Color masks - */ - -static void i830ColorMask(GLcontext *ctx, - GLboolean r, GLboolean g, - GLboolean b, GLboolean a) -{ - i830ContextPtr i830 = I830_CONTEXT( ctx ); - GLuint tmp = 0; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); - - tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) | - ENABLE_COLOR_MASK | - ENABLE_COLOR_WRITE | - ((!r) << WRITEMASK_RED_SHIFT) | - ((!g) << WRITEMASK_GREEN_SHIFT) | - ((!b) << WRITEMASK_BLUE_SHIFT) | - ((!a) << WRITEMASK_ALPHA_SHIFT)); - - if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp; - } -} - -static void update_specular( GLcontext *ctx ) -{ - i830ContextPtr i830 = I830_CONTEXT( ctx ); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; - - if (NEED_SECONDARY_COLOR(ctx)) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; -} - -static void i830LightModelfv(GLcontext *ctx, GLenum pname, - const GLfloat *param) -{ - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - update_specular( ctx ); - } -} - -/* In Mesa 3.5 we can reliably do native flatshading. - */ -static void i830ShadeModel(GLcontext *ctx, GLenum mode) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - -#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) - - i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; - - if (mode == GL_FLAT) { - i830->state.Ctx[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | - FOG_SHADE_MODE(SHADE_MODE_FLAT) | - SPEC_SHADE_MODE(SHADE_MODE_FLAT) | - COLOR_SHADE_MODE(SHADE_MODE_FLAT)); - } else { - i830->state.Ctx[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | - FOG_SHADE_MODE(SHADE_MODE_LINEAR) | - SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | - COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); - } -} - -/* ============================================================= - * Fog - */ -static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (pname == GL_FOG_COLOR) { - GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | - ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | - ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | color); - } -} - -/* ============================================================= - */ - -static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - - switch(cap) { - case GL_LIGHTING: - case GL_COLOR_SUM: - update_specular( ctx ); - break; - - case GL_ALPHA_TEST: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; - - break; - - case GL_BLEND: - i830EvalLogicOpBlendState(ctx); - break; - - case GL_COLOR_LOGIC_OP: - i830EvalLogicOpBlendState(ctx); - - /* Logicop doesn't seem to work at 16bpp: - */ - if (i830->intel.intelScreen->cpp == 2) - FALLBACK( &i830->intel, I830_FALLBACK_LOGICOP, state ); - break; - - case GL_DITHER: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; - - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; - else - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; - break; - - case GL_DEPTH_TEST: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - - /* Also turn off depth writes when GL_DEPTH_TEST is disabled: - */ - i830DepthMask( ctx, ctx->Depth.Mask ); - break; - - case GL_SCISSOR_TEST: - I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); - - if (state) - i830->state.Buffer[I830_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | - ENABLE_SCISSOR_RECT); - else - i830->state.Buffer[I830_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - - break; - - case GL_LINE_SMOOTH: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; - if (state) - i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE; - else - i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE; - break; - - case GL_FOG: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG; - break; - - case GL_CULL_FACE: - i830CullFaceFrontFace(ctx, 0); - break; - - case GL_TEXTURE_2D: - break; - - case GL_STENCIL_TEST: - if (i830->intel.hw_stencil) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - if (state) { - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; - } else { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; - } - } else { - FALLBACK( &i830->intel, I830_FALLBACK_STENCIL, state ); - } - break; - - case GL_POLYGON_STIPPLE: - /* The stipple command worked on my 855GM box, but not my 845G. - * I'll do more testing later to find out exactly which hardware - * supports it. Disabled for now. - */ - if (i830->intel.hw_stipple && - i830->intel.reduced_primitive == GL_TRIANGLES) - { - I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); - i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - if (state) - i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; - } - break; - - default: - ; - } -} - - -static void i830_init_packets( i830ContextPtr i830 ) -{ - intelScreenPrivate *screen = i830->intel.intelScreen; - - /* Zero all state */ - memset(&i830->state, 0, sizeof(i830->state)); - - /* Set default blend state */ - i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXOP_LAST_STAGE | - TEXBLENDOP_ARG1); - i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_DIFFUSE); - i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_DIFFUSE); - - i830->state.TexBlendWordsUsed[0] = 4; - - - i830->state.Ctx[I830_CTXREG_VF] = 0; - i830->state.Ctx[I830_CTXREG_VF2] = 0; - - i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | - AA_LINE_REGION_WIDTH_1_0 | - AA_LINE_DISABLE); - - i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD | - DISABLE_LOGIC_OP | - DISABLE_STENCIL_TEST | - DISABLE_DEPTH_BIAS | - DISABLE_SPEC_ADD | - DISABLE_FOG | - DISABLE_ALPHA_TEST | - DISABLE_COLOR_BLEND | - DISABLE_DEPTH_TEST); - - if (i830->intel.hw_stencil) { - i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | - ENABLE_STENCIL_WRITE | - ENABLE_TEX_CACHE | - ENABLE_DITHER | - ENABLE_COLOR_MASK | - /* set no color comps disabled */ - ENABLE_COLOR_WRITE | - ENABLE_DEPTH_WRITE); - } else { - i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | - DISABLE_STENCIL_WRITE | - ENABLE_TEX_CACHE | - ENABLE_DITHER | - ENABLE_COLOR_MASK | - /* set no color comps disabled */ - ENABLE_COLOR_WRITE | - ENABLE_DEPTH_WRITE); - } - - i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD | - ENABLE_COLR_BLND_FUNC | - BLENDFUNC_ADD | - ENABLE_SRC_BLND_FACTOR | - SRC_BLND_FACT(BLENDFACT_ONE) | - ENABLE_DST_BLND_FACTOR | - DST_BLND_FACT(BLENDFACT_ZERO) ); - - i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD | - ENABLE_GLOBAL_DEPTH_BIAS | - GLOBAL_DEPTH_BIAS(0) | - ENABLE_ALPHA_TEST_FUNC | - ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) | - ALPHA_REF_VALUE(0) ); - - i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD | - ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | - ENABLE_ALPHA_SHADE_MODE | - ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_FOG_SHADE_MODE | - FOG_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_SPEC_SHADE_MODE | - SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_COLOR_SHADE_MODE | - COLOR_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_CULL_MODE | - CULLMODE_NONE); - - i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff) | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(0xff)); - - i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD | - ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(STENCILOP_KEEP) | - STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) | - STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) | - ENABLE_STENCIL_REF_VALUE | - STENCIL_REF_VALUE(0) ); - - i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD | - FLUSH_TEXTURE_CACHE | - ENABLE_SPRITE_POINT_TEX | - SPRITE_POINT_TEX_OFF | - ENABLE_FIXED_LINE_WIDTH | - FIXED_LINE_WIDTH(0x2) | /* 1.0 */ - ENABLE_FIXED_POINT_WIDTH | - FIXED_POINT_WIDTH(1) ); - - i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD | - DISABLE_INDPT_ALPHA_BLEND | - ENABLE_ALPHA_BLENDFUNC | - ABLENDFUNC_ADD); - - i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | - FOG_COLOR_RED(0) | - FOG_COLOR_GREEN(0) | - FOG_COLOR_BLUE(0)); - - i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0; - - i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD; - i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | - TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | - TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | - TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); - - - i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE; - - i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i830->state.Buffer[I830_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - - - i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i830->state.Buffer[I830_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset; - - - i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; - - switch (screen->fbFormat) { - case DV_PF_555: - case DV_PF_565: - i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - screen->fbFormat | - DEPTH_IS_Z | - DEPTH_FRMT_16_FIXED); - break; - case DV_PF_8888: - i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - screen->fbFormat | - DEPTH_IS_Z | - DEPTH_FRMT_24_FIXED_8_OTHER); - break; - } - - i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; - i830->state.Buffer[I830_DESTREG_SR1] = 0; - i830->state.Buffer[I830_DESTREG_SR2] = 0; -} - - -void i830InitStateFuncs( struct dd_function_table *functions ) -{ - functions->AlphaFunc = i830AlphaFunc; - functions->BlendColor = i830BlendColor; - functions->BlendEquationSeparate = i830BlendEquationSeparate; - functions->BlendFuncSeparate = i830BlendFuncSeparate; - functions->ColorMask = i830ColorMask; - functions->CullFace = i830CullFaceFrontFace; - functions->DepthFunc = i830DepthFunc; - functions->DepthMask = i830DepthMask; - functions->Enable = i830Enable; - functions->Fogfv = i830Fogfv; - functions->FrontFace = i830CullFaceFrontFace; - functions->LightModelfv = i830LightModelfv; - functions->LineWidth = i830LineWidth; - functions->LogicOpcode = i830LogicOp; - functions->PointSize = i830PointSize; - functions->PolygonStipple = i830PolygonStipple; - functions->Scissor = i830Scissor; - functions->ShadeModel = i830ShadeModel; - functions->StencilFuncSeparate = i830StencilFuncSeparate; - functions->StencilMaskSeparate = i830StencilMaskSeparate; - functions->StencilOpSeparate = i830StencilOpSeparate; -} - -void i830InitState( i830ContextPtr i830 ) -{ - GLcontext *ctx = &i830->intel.ctx; - - i830_init_packets( i830 ); - - _mesa_init_driver_state(ctx); - - memcpy( &i830->initial, &i830->state, sizeof(i830->state) ); - - i830->current = &i830->state; - i830->state.emitted = 0; - i830->state.active = (I830_UPLOAD_TEXBLEND(0) | - I830_UPLOAD_STIPPLE | - I830_UPLOAD_CTX | - I830_UPLOAD_BUFFERS); -} diff --git a/src/mesa/drivers/dri/i915/i830_tex.c b/src/mesa/drivers/dri/i915/i830_tex.c deleted file mode 100644 index 3c4aedb35c..0000000000 --- a/src/mesa/drivers/dri/i915/i830_tex.c +++ /dev/null @@ -1,356 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "simple_list.h" -#include "enums.h" -#include "image.h" -#include "texstore.h" -#include "texformat.h" -#include "texmem.h" -#include "swrast/swrast.h" - -#include "mm.h" - -#include "intel_ioctl.h" - -#include "i830_context.h" -#include "i830_reg.h" - - - - -/** - * Set the texture wrap modes. - * - * The i830M (and related graphics cores) do not support GL_CLAMP. The Intel - * drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - * - * \param t Texture object whose wrap modes are to be set - * \param swrap Wrap mode for the \a s texture coordinate - * \param twrap Wrap mode for the \a t texture coordinate - */ -static void i830SetTexWrapping(i830TextureObjectPtr tex, - GLenum swrap, - GLenum twrap) -{ - tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK); - - switch( swrap ) { - case GL_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP); - break; - case GL_CLAMP: - case GL_CLAMP_TO_EDGE: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP); - break; - case GL_CLAMP_TO_BORDER: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER); - break; - case GL_MIRRORED_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR); - break; - default: - break; - } - - switch( twrap ) { - case GL_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP); - break; - case GL_CLAMP: - case GL_CLAMP_TO_EDGE: - tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP); - break; - case GL_CLAMP_TO_BORDER: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER); - break; - case GL_MIRRORED_REPEAT: - tex->Setup[I830_TEXREG_MCS] |= - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR); - break; - default: - break; - } -} - - -/** - * Set the texture magnification and minification modes. - * - * \param t Texture whose filter modes are to be set - * \param minf Texture minification mode - * \param magf Texture magnification mode - * \param bias LOD bias for this texture unit. - */ - -static void i830SetTexFilter( i830TextureObjectPtr t, GLenum minf, GLenum magf, - GLfloat maxanisotropy ) -{ - int minFilt = 0, mipFilt = 0, magFilt = 0; - - if(INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - if ( maxanisotropy > 1.0 ) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - switch (minf) { - case GL_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NONE; - break; - case GL_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_LINEAR; - break; - default: - break; - } - - switch (magf) { - case GL_NEAREST: - magFilt = FILTER_NEAREST; - break; - case GL_LINEAR: - magFilt = FILTER_LINEAR; - break; - default: - break; - } - } - - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK; - t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | - (mipFilt << TM0S3_MIP_FILTER_SHIFT) | - (magFilt << TM0S3_MAG_FILTER_SHIFT)); -} - -static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) -{ - if(INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - t->Setup[I830_TEXREG_TM0S4] = - INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]); -} - - -/** - * Allocate space for and load the mesa images into the texture memory block. - * This will happen before drawing with a new texture, or drawing with a - * texture after it was swapped out or teximaged again. - */ - -intelTextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj ) -{ - i830TextureObjectPtr t = CALLOC_STRUCT( i830_texture_object ); - if ( !t ) - return NULL; - - texObj->DriverData = t; - t->intel.base.tObj = texObj; - t->intel.dirty = I830_UPLOAD_TEX_ALL; - make_empty_list( &t->intel.base ); - - t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */ - t->Setup[I830_TEXREG_TM0S0] = 0; - t->Setup[I830_TEXREG_TM0S1] = 0; - t->Setup[I830_TEXREG_TM0S2] = 0; - t->Setup[I830_TEXREG_TM0S3] = 0; - t->Setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_NORMAL | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - - - i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT ); - i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter, - texObj->MaxAnisotropy ); - i830SetTexBorderColor( t, texObj->_BorderChan ); - - return &t->intel; -} - - -static void i830TexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) -{ - i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; - if (!t) - return; - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter, - tObj->MaxAnisotropy); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); - break; - - case GL_TEXTURE_BORDER_COLOR: - i830SetTexBorderColor( t, tObj->_BorderChan ); - break; - - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - /* The i830 and its successors can do a lot of this without - * reloading the textures. A project for someone? - */ - intelFlush( ctx ); - driSwapOutTextureObject( (driTextureObject *) t ); - break; - - default: - return; - } - - t->intel.dirty = I830_UPLOAD_TEX_ALL; -} - - -static void i830TexEnv( GLcontext *ctx, GLenum target, - GLenum pname, const GLfloat *param ) -{ - i830ContextPtr i830 = I830_CONTEXT( ctx ); - GLuint unit = ctx->Texture.CurrentUnit; - - switch (pname) { - case GL_TEXTURE_ENV_COLOR: -#if 0 - { - GLubyte r, g, b, a; - GLuint col; - - UNCLAMPED_FLOAT_TO_UBYTE(r, param[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, param[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, param[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, param[ACOMP]); - - col = ((a << 24) | (r << 16) | (g << 8) | b); - - if (col != i830->state.TexEnv[unit][I830_TEXENVREG_COL1]) { - I830_STATECHANGE(i830, I830_UPLOAD_TEXENV); - i830->state.TexEnv[unit][I830_TEXENVREG_COL1] = col; - } - - break; - } -#endif - case GL_TEXTURE_ENV_MODE: - case GL_COMBINE_RGB: - case GL_COMBINE_ALPHA: - case GL_SOURCE0_RGB: - case GL_SOURCE1_RGB: - case GL_SOURCE2_RGB: - case GL_SOURCE0_ALPHA: - case GL_SOURCE1_ALPHA: - case GL_SOURCE2_ALPHA: - case GL_OPERAND0_RGB: - case GL_OPERAND1_RGB: - case GL_OPERAND2_RGB: - case GL_OPERAND0_ALPHA: - case GL_OPERAND1_ALPHA: - case GL_OPERAND2_ALPHA: - case GL_RGB_SCALE: - case GL_ALPHA_SCALE: - break; - - case GL_TEXTURE_LOD_BIAS: { - int b = (int) ((*param) * 16.0); - if (b > 63) b = 63; - if (b < -64) b = -64; - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK; - i830->state.Tex[unit][I830_TEXREG_TM0S3] |= - ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); - break; - } - - default: - break; - } -} - -static void i830BindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj ) -{ - i830TextureObjectPtr tex; - - if (!texObj->DriverData) - i830AllocTexObj( texObj ); - - tex = (i830TextureObjectPtr)texObj->DriverData; -} - - - -void i830InitTextureFuncs( struct dd_function_table *functions ) -{ - functions->BindTexture = i830BindTexture; - functions->TexEnv = i830TexEnv; - functions->TexParameter = i830TexParameter; -} diff --git a/src/mesa/drivers/dri/i915/i830_texblend.c b/src/mesa/drivers/dri/i915/i830_texblend.c deleted file mode 100644 index 49e0347643..0000000000 --- a/src/mesa/drivers/dri/i915/i830_texblend.c +++ /dev/null @@ -1,465 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "simple_list.h" -#include "enums.h" -#include "texformat.h" -#include "texstore.h" - -#include "mm.h" - -#include "intel_screen.h" -#include "intel_ioctl.h" -#include "intel_tex.h" - -#include "i830_context.h" -#include "i830_reg.h" - - -/* ================================================================ - * Texture combine functions - */ -static GLuint pass_through( GLuint *state, GLuint blendUnit ) -{ - state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - - return 4; -} - -static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count, - const GLfloat *factor ) -{ - GLubyte r, g, b, a; - GLuint col; - - if (0) - fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n", - blendUnit, factor[0], factor[1], factor[2], factor[3]); - - UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]); - - col = ((a << 24) | (r << 16) | (g << 8) | b); - - state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit); - state[count++] = col; - - return count; -} - - -static __inline__ GLuint GetTexelOp(GLint unit) -{ - switch(unit) { - case 0: return TEXBLENDARG_TEXEL0; - case 1: return TEXBLENDARG_TEXEL1; - case 2: return TEXBLENDARG_TEXEL2; - case 3: return TEXBLENDARG_TEXEL3; - default: return TEXBLENDARG_TEXEL0; - } -} - - -/** - * Calculate the hardware instuctions to setup the current texture enviromnemt - * settings. Since \c gl_texture_unit::_CurrentCombine is used, both - * "classic" texture enviroments and GL_ARB_texture_env_combine type texture - * environments are treated identically. - * - * \todo - * This function should return \c GLboolean. When \c GL_FALSE is returned, - * it means that an environment is selected that the hardware cannot do. This - * is the way the Radeon and R200 drivers work. - * - * \todo - * Looking at i830_3d_regs.h, it seems the i830 can do part of - * GL_ATI_texture_env_combine3. It can handle using \c GL_ONE and - * \c GL_ZERO as combine inputs (which the code already supports). It can - * also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating - * partial support for the extension? - */ -GLuint -i830SetTexEnvCombine(i830ContextPtr i830, - const struct gl_tex_env_combine_state * combine, - GLint blendUnit, - GLuint texel_op, - GLuint *state, - const GLfloat *factor ) -{ - const GLuint numColorArgs = combine->_NumArgsRGB; - const GLuint numAlphaArgs = combine->_NumArgsA; - - GLuint blendop; - GLuint ablendop; - GLuint args_RGB[3]; - GLuint args_A[3]; - GLuint rgb_shift; - GLuint alpha_shift; - GLboolean need_factor = 0; - int i; - unsigned used; - static const GLuint tex_blend_rgb[3] = { - TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, - }; - static const GLuint tex_blend_a[3] = { - TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, - }; - - if(INTEL_DEBUG&DEBUG_TEXTURE) - fprintf(stderr, "%s\n", __FUNCTION__); - - - /* The EXT version of the DOT3 extension does not support the - * scale factor, but the ARB version (and the version in OpenGL - * 1.3) does. - */ - switch (combine->ModeRGB) { - case GL_DOT3_RGB_EXT: - alpha_shift = combine->ScaleShiftA; - rgb_shift = 0; - break; - - case GL_DOT3_RGBA_EXT: - alpha_shift = 0; - rgb_shift = 0; - break; - - default: - rgb_shift = combine->ScaleShiftRGB; - alpha_shift = combine->ScaleShiftA; - break; - } - - - switch(combine->ModeRGB) { - case GL_REPLACE: - blendop = TEXBLENDOP_ARG1; - break; - case GL_MODULATE: - blendop = TEXBLENDOP_MODULATE; - break; - case GL_ADD: - blendop = TEXBLENDOP_ADD; - break; - case GL_ADD_SIGNED: - blendop = TEXBLENDOP_ADDSIGNED; - break; - case GL_INTERPOLATE: - blendop = TEXBLENDOP_BLEND; - break; - case GL_SUBTRACT: - blendop = TEXBLENDOP_SUBTRACT; - break; - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGB: - blendop = TEXBLENDOP_DOT3; - break; - case GL_DOT3_RGBA_EXT: - case GL_DOT3_RGBA: - blendop = TEXBLENDOP_DOT3; - break; - default: - return pass_through( state, blendUnit ); - } - - blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); - - - /* Handle RGB args */ - for(i = 0; i < 3; i++) { - switch(combine->SourceRGB[i]) { - case GL_TEXTURE: - args_RGB[i] = texel_op; - break; - case GL_TEXTURE0: - case GL_TEXTURE1: - case GL_TEXTURE2: - case GL_TEXTURE3: - args_RGB[i] = GetTexelOp( combine->SourceRGB[i] - GL_TEXTURE0 ); - break; - case GL_CONSTANT: - args_RGB[i] = TEXBLENDARG_FACTOR_N; - need_factor = 1; - break; - case GL_PRIMARY_COLOR: - args_RGB[i] = TEXBLENDARG_DIFFUSE; - break; - case GL_PREVIOUS: - args_RGB[i] = TEXBLENDARG_CURRENT; - break; - default: - return pass_through( state, blendUnit ); - } - - switch(combine->OperandRGB[i]) { - case GL_SRC_COLOR: - args_RGB[i] |= 0; - break; - case GL_ONE_MINUS_SRC_COLOR: - args_RGB[i] |= TEXBLENDARG_INV_ARG; - break; - case GL_SRC_ALPHA: - args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; - break; - case GL_ONE_MINUS_SRC_ALPHA: - args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | - TEXBLENDARG_INV_ARG); - break; - default: - return pass_through( state, blendUnit ); - } - } - - - /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to - * match the spec. Can't use DOT3 as it won't propogate values - * into alpha as required: - * - * Note - the global factor is set up with alpha == .5, so - * the alpha part of the DOT4 calculation should be zero. - */ - if ( combine->ModeRGB == GL_DOT3_RGBA_EXT || - combine->ModeRGB == GL_DOT3_RGBA ) { - ablendop = TEXBLENDOP_DOT4; - args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */ - args_A[1] = TEXBLENDARG_FACTOR; - args_A[2] = TEXBLENDARG_FACTOR; - } - else { - switch(combine->ModeA) { - case GL_REPLACE: - ablendop = TEXBLENDOP_ARG1; - break; - case GL_MODULATE: - ablendop = TEXBLENDOP_MODULATE; - break; - case GL_ADD: - ablendop = TEXBLENDOP_ADD; - break; - case GL_ADD_SIGNED: - ablendop = TEXBLENDOP_ADDSIGNED; - break; - case GL_INTERPOLATE: - ablendop = TEXBLENDOP_BLEND; - break; - case GL_SUBTRACT: - ablendop = TEXBLENDOP_SUBTRACT; - break; - default: - return pass_through( state, blendUnit ); - } - - - ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); - - /* Handle A args */ - for(i = 0; i < 3; i++) { - switch(combine->SourceA[i]) { - case GL_TEXTURE: - args_A[i] = texel_op; - break; - case GL_TEXTURE0: - case GL_TEXTURE1: - case GL_TEXTURE2: - case GL_TEXTURE3: - args_A[i] = GetTexelOp( combine->SourceA[i] - GL_TEXTURE0 ); - break; - case GL_CONSTANT: - args_A[i] = TEXBLENDARG_FACTOR_N; - need_factor = 1; - break; - case GL_PRIMARY_COLOR: - args_A[i] = TEXBLENDARG_DIFFUSE; - break; - case GL_PREVIOUS: - args_A[i] = TEXBLENDARG_CURRENT; - break; - default: - return pass_through( state, blendUnit ); - } - - switch(combine->OperandA[i]) { - case GL_SRC_ALPHA: - args_A[i] |= 0; - break; - case GL_ONE_MINUS_SRC_ALPHA: - args_A[i] |= TEXBLENDARG_INV_ARG; - break; - default: - return pass_through( state, blendUnit ); - } - } - } - - - - /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ - /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ - /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ - - /* When we render we need to figure out which is the last really enabled - * tex unit, and put last stage on it - */ - - - /* Build color & alpha pipelines */ - - used = 0; - state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_MODIFY_PARMS | - blendop); - state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_MODIFY_PARMS | - ablendop); - - for ( i = 0 ; i < numColorArgs ; i++ ) { - state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - tex_blend_rgb[i] | args_RGB[i]); - } - - for ( i = 0 ; i < numAlphaArgs ; i++ ) { - state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - tex_blend_a[i] | args_A[i]); - } - - - if (need_factor) - return emit_factor( blendUnit, state, used, factor ); - else - return used; -} - - -static void emit_texblend( i830ContextPtr i830, GLuint unit, GLuint blendUnit, - GLboolean last_stage ) -{ - struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; - GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; - - - if (0) fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); - - /* Update i830->state.TexBlend - */ - tmp_sz = i830SetTexEnvCombine(i830, texUnit->_CurrentCombine, blendUnit, - GetTexelOp(unit), tmp, - texUnit->EnvColor ); - - if (last_stage) - tmp[0] |= TEXOP_LAST_STAGE; - - if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] || - memcmp( tmp, i830->state.TexBlend[blendUnit], tmp_sz * sizeof(GLuint))) { - - I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(blendUnit) ); - memcpy( i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint)); - i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz; - } - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); -} - -static void emit_passthrough( i830ContextPtr i830 ) -{ - GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; - GLuint unit = 0; - - tmp_sz = pass_through( tmp, unit ); - tmp[0] |= TEXOP_LAST_STAGE; - - if (tmp_sz != i830->state.TexBlendWordsUsed[unit] || - memcmp( tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) { - - I830_STATECHANGE( i830, I830_UPLOAD_TEXBLEND(unit) ); - memcpy( i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint)); - i830->state.TexBlendWordsUsed[unit] = tmp_sz; - } - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); -} - -void i830EmitTextureBlend( i830ContextPtr i830 ) -{ - GLcontext *ctx = &i830->intel.ctx; - GLuint unit, last_stage = 0, blendunit = 0; - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE); - - if (ctx->Texture._EnabledUnits) { - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) - if (ctx->Texture.Unit[unit]._ReallyEnabled) - last_stage = unit; - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) - if (ctx->Texture.Unit[unit]._ReallyEnabled) - emit_texblend( i830, unit, blendunit++, last_stage == unit ); - } - else { - emit_passthrough( i830 ); - } -} - diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c deleted file mode 100644 index ba972dac8f..0000000000 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ /dev/null @@ -1,483 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "simple_list.h" -#include "enums.h" -#include "texformat.h" -#include "texstore.h" - -#include "mm.h" - -#include "intel_screen.h" -#include "intel_ioctl.h" -#include "intel_tex.h" - -#include "i830_context.h" -#include "i830_reg.h" - -static const GLint initial_offsets[6][2] = { {0,0}, - {0,2}, - {1,0}, - {1,2}, - {1,1}, - {1,3} }; - -static const GLint step_offsets[6][2] = { {0,2}, - {0,2}, - {-1,2}, - {-1,2}, - {-1,1}, - {-1,1} }; - -#define I830_TEX_UNIT_ENABLED(unit) (1<DriverData; - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - GLint firstLevel, lastLevel, numLevels; - - switch( baseImage->TexFormat->MesaFormat ) { - case MESA_FORMAT_L8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_L8; - break; - - case MESA_FORMAT_I8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_I8; - break; - - case MESA_FORMAT_A8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_I8; /* Kludge -- check with conform, glean */ - break; - - case MESA_FORMAT_AL88: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; - break; - - case MESA_FORMAT_RGB565: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - break; - - case MESA_FORMAT_ARGB1555: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - break; - - case MESA_FORMAT_ARGB4444: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; - break; - - case MESA_FORMAT_ARGB8888: - t->intel.texelBytes = 4; - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - break; - - case MESA_FORMAT_YCBCR_REV: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL | - TM0S1_COLORSPACE_CONVERSION); - break; - - case MESA_FORMAT_YCBCR: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY | /* ??? */ - TM0S1_COLORSPACE_CONVERSION); - break; - - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_COMPRESSED | MT_COMPRESS_FXT1; - break; - - case MESA_FORMAT_RGBA_DXT1: - case MESA_FORMAT_RGB_DXT1: - /* - * DXTn pitches are Width/4 * blocksize in bytes - * for DXT1: blocksize=8 so Width/4*8 = Width * 2 - * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 - */ - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - break; - case MESA_FORMAT_RGBA_DXT3: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - break; - case MESA_FORMAT_RGBA_DXT5: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); - break; - - default: - fprintf(stderr, "%s: bad image format\n", __FUNCTION__); - abort(); - } - - /* Compute which mipmap levels we really want to send to the hardware. - * This depends on the base image size, GL_TEXTURE_MIN_LOD, - * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. - * Yes, this looks overly complicated, but it's all needed. - */ - driCalculateTextureFirstLastLevel( (driTextureObject *) t ); - - - /* Figure out the amount of memory required to hold all the mipmap - * levels. Choose the smallest pitch to accomodate the largest - * mipmap: - */ - firstLevel = t->intel.base.firstLevel; - lastLevel = t->intel.base.lastLevel; - numLevels = lastLevel - firstLevel + 1; - - - /* All images must be loaded at this pitch. Count the number of - * lines required: - */ - switch (tObj->Target) { - case GL_TEXTURE_CUBE_MAP: { - const GLuint dim = tObj->Image[0][firstLevel]->Width; - GLuint face; - - pitch = dim * t->intel.texelBytes; - pitch *= 2; /* double pitch for cube layouts */ - pitch = (pitch + 3) & ~3; - - total_height = dim * 4; - - for ( face = 0 ; face < 6 ; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - t->intel.base.dirty_images[face] = ~0; - - assert(tObj->Image[face][firstLevel]->Width == dim); - assert(tObj->Image[face][firstLevel]->Height == dim); - - for (i = 0; i < numLevels; i++) { - t->intel.image[face][i].image = tObj->Image[face][firstLevel + i]; - if (!t->intel.image[face][i].image) { - fprintf(stderr, "no image %d %d\n", face, i); - break; /* can't happen */ - } - - t->intel.image[face][i].offset = - y * pitch + x * t->intel.texelBytes; - t->intel.image[face][i].internalFormat = baseImage->_BaseFormat; - - d >>= 1; - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - } - } - break; - } - default: - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - t->intel.base.dirty_images[0] = ~0; - - for ( total_height = i = 0 ; i < numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - if (t->intel.image[0][i].image->IsCompressed) - { - if (t->intel.image[0][i].image->Height > 4) - total_height += t->intel.image[0][i].image->Height/4; - else - total_height += 1; - } - else - total_height += MAX2(2, t->intel.image[0][i].image->Height); - } - break; - } - - t->intel.Pitch = pitch; - t->intel.base.totalSize = total_height*pitch; - t->intel.max_level = i-1; - t->Setup[I830_TEXREG_TM0S1] = - (((tObj->Image[0][firstLevel]->Height - 1) << TM0S1_HEIGHT_SHIFT) | - ((tObj->Image[0][firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) | - textureFormat); - t->Setup[I830_TEXREG_TM0S2] = - (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | - TM0S2_CUBE_FACE_ENA_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; - t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; - t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; - t->intel.dirty = I830_UPLOAD_TEX_ALL; - - return intelUploadTexImages( &i830->intel, &t->intel, 0 ); -} - - -static void i830_import_tex_unit( i830ContextPtr i830, - i830TextureObjectPtr t, - GLuint unit ) -{ - if(INTEL_DEBUG&DEBUG_TEXTURE) - fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); - - if (i830->intel.CurrentTexObj[unit]) - i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit); - - i830->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t; - t->intel.base.bound |= (1 << unit); - - I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) ); - - i830->state.Tex[unit][I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << unit) | 4); - i830->state.Tex[unit][I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | - t->intel.TextureOffset); - - i830->state.Tex[unit][I830_TEXREG_TM0S1] = t->Setup[I830_TEXREG_TM0S1]; - i830->state.Tex[unit][I830_TEXREG_TM0S2] = t->Setup[I830_TEXREG_TM0S2]; - - i830->state.Tex[unit][I830_TEXREG_TM0S3] &= TM0S3_LOD_BIAS_MASK; - i830->state.Tex[unit][I830_TEXREG_TM0S3] |= (t->Setup[I830_TEXREG_TM0S3] & - ~TM0S3_LOD_BIAS_MASK); - - i830->state.Tex[unit][I830_TEXREG_TM0S4] = t->Setup[I830_TEXREG_TM0S4]; - i830->state.Tex[unit][I830_TEXREG_MCS] = (t->Setup[I830_TEXREG_MCS] & - ~MAP_UNIT_MASK); - i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE]; - i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit); - - t->intel.dirty &= ~I830_UPLOAD_TEX(unit); -} - - - -static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; - - if (0) fprintf(stderr, "%s\n", __FUNCTION__); - - /* Fallback if there's a texture border */ - if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) { - fprintf(stderr, "Texture border\n"); - return GL_FALSE; - } - - /* Upload teximages (not pipelined) - */ - if (t->intel.base.dirty_images[0]) { - if (!i830SetTexImages( i830, tObj )) { - return GL_FALSE; - } - } - - /* Update state if this is a different texture object to last - * time. - */ - if (i830->intel.CurrentTexObj[unit] != &t->intel || - (t->intel.dirty & I830_UPLOAD_TEX(unit))) { - i830_import_tex_unit( i830, t, unit); - } - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); - - return GL_TRUE; -} - -static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; - - mcs &= ~TEXCOORDS_ARE_NORMAL; - mcs |= TEXCOORDS_ARE_IN_TEXELUNITS; - - if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) - || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; - i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; - } - - return GL_TRUE; -} - - -static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; - - mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; - mcs |= TEXCOORDS_ARE_NORMAL; - - if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) - || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; - i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; - } - - return GL_TRUE; -} - - -static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; - GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; - const GLuint cube = CUBE_NEGX_ENABLE | CUBE_POSX_ENABLE - | CUBE_NEGY_ENABLE | CUBE_POSY_ENABLE - | CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE; - GLuint face; - - mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; - mcs |= TEXCOORDS_ARE_NORMAL; - - if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) - || (cube != i830->state.Tex[unit][I830_TEXREG_CUBE])) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; - i830->state.Tex[unit][I830_TEXREG_CUBE] = cube; - } - - /* Upload teximages (not pipelined) - */ - if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] || - t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] || - t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) { - i830SetTexImages( i830, tObj ); - } - - /* upload (per face) */ - for (face = 0; face < 6; face++) { - if (t->intel.base.dirty_images[face]) { - if (!intelUploadTexImages( &i830->intel, &t->intel, face )) { - return GL_FALSE; - } - } - } - - - return GL_TRUE; -} - - -static GLboolean disable_tex( GLcontext *ctx, GLuint unit ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - - /* This is happening too often. I need to conditionally send diffuse - * state to the card. Perhaps a diffuse dirty flag of some kind. - * Will need to change this logic if more than 2 texture units are - * used. We need to only do this up to the last unit enabled, or unit - * one if nothing is enabled. - */ - - if ( i830->intel.CurrentTexObj[unit] != NULL ) { - /* The old texture is no longer bound to this texture unit. - * Mark it as such. - */ - - i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0); - i830->intel.CurrentTexObj[unit] = NULL; - } - - return GL_TRUE; -} - -static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) -{ - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - - if (texUnit->_ReallyEnabled && - INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024) - return GL_FALSE; - - switch(texUnit->_ReallyEnabled) { - case TEXTURE_1D_BIT: - case TEXTURE_2D_BIT: - return (enable_tex_common( ctx, unit ) && - enable_tex_2d( ctx, unit )); - case TEXTURE_RECT_BIT: - return (enable_tex_common( ctx, unit ) && - enable_tex_rect( ctx, unit )); - case TEXTURE_CUBE_BIT: - return (enable_tex_common( ctx, unit ) && - enable_tex_cube( ctx, unit )); - case 0: - return disable_tex( ctx, unit ); - default: - return GL_FALSE; - } -} - - -void i830UpdateTextureState( intelContextPtr intel ) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - GLcontext *ctx = &intel->ctx; - GLboolean ok; - - if (0) fprintf(stderr, "%s\n", __FUNCTION__); - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEX_ALL, GL_FALSE); - - ok = (i830UpdateTexUnit( ctx, 0 ) && - i830UpdateTexUnit( ctx, 1 ) && - i830UpdateTexUnit( ctx, 2 ) && - i830UpdateTexUnit( ctx, 3 )); - - FALLBACK( intel, I830_FALLBACK_TEXTURE, !ok ); - - if (ok) - i830EmitTextureBlend( i830 ); -} - - - diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c deleted file mode 100644 index cf1d0b0c1e..0000000000 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ /dev/null @@ -1,540 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "i830_context.h" -#include "i830_reg.h" - -#include "intel_batchbuffer.h" - -#include "tnl/t_context.h" -#include "tnl/t_vertex.h" - -static GLboolean i830_check_vertex_size( intelContextPtr intel, - GLuint expected ); - -#define SZ_TO_HW(sz) ((sz-2)&0x3) -#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) -#define EMIT_ATTR( ATTR, STYLE, V0 ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ - intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ - intel->vertex_attr_count++; \ - v0 |= V0; \ -} while (0) - -#define EMIT_PAD( N ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ - intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ - intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ - intel->vertex_attr_count++; \ -} while (0) - - -#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) -#define TEXBIND_SET(n, x) ((x)<<((n)*4)) - - static void -i830_render_prevalidate(struct intel_context *intel) -{ -} - -static void i830_render_start( intelContextPtr intel ) -{ - GLcontext *ctx = &intel->ctx; - i830ContextPtr i830 = I830_CONTEXT(intel); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - DECLARE_RENDERINPUTS(index_bitset); - GLuint v0 = _3DSTATE_VFT0_CMD; - GLuint v2 = _3DSTATE_VFT1_CMD; - GLuint mcsb1 = 0; - - RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); - - /* Important: - */ - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - intel->vertex_attr_count = 0; - - /* EMIT_ATTR's must be in order as they tell t_vertex.c how to - * build up a hardware vertex. - */ - if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW ); - intel->coloroffset = 4; - } - else { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ ); - intel->coloroffset = 3; - } - - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) { - EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH ); - } - - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE ); - - intel->specoffset = 0; - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) || - RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { - intel->specoffset = intel->coloroffset + 1; - EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC ); - } - else - EMIT_PAD( 3 ); - - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) - EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC ); - else - EMIT_PAD( 1 ); - } - - if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { - int i, count = 0; - - for (i = 0; i < I830_TEX_UNITS; i++) { - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { - GLuint sz = VB->TexCoordPtr[i]->size; - GLuint emit; - GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] & - ~TEXCOORDTYPE_MASK); - - switch (sz) { - case 1: - case 2: - emit = EMIT_2F; - sz = 2; - mcs |= TEXCOORDTYPE_CARTESIAN; - break; - case 3: - emit = EMIT_3F; - sz = 3; - mcs |= TEXCOORDTYPE_VECTOR; - break; - case 4: - emit = EMIT_3F_XYW; - sz = 3; - mcs |= TEXCOORDTYPE_HOMOGENEOUS; - break; - default: - continue; - }; - - - EMIT_ATTR( _TNL_ATTRIB_TEX0+i, emit, 0 ); - v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz)); - mcsb1 |= (count+8)<<(i*4); - - if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(i)); - i830->state.Tex[i][I830_TEXREG_MCS] = mcs; - } - - count++; - } - } - - v0 |= VFT0_TEX_COUNT(count); - } - - /* Only need to change the vertex emit code if there has been a - * statechange to a new hardware vertex format: - */ - if (v0 != i830->state.Ctx[I830_CTXREG_VF] || - v2 != i830->state.Ctx[I830_CTXREG_VF2] || - mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] || - !RENDERINPUTS_EQUAL( index_bitset, i830->last_index_bitset )) { - - I830_STATECHANGE( i830, I830_UPLOAD_CTX ); - - /* Must do this *after* statechange, so as not to affect - * buffered vertices reliant on the old state: - */ - intel->vertex_size = - _tnl_install_attrs( ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0 ); - - intel->vertex_size >>= 2; - - i830->state.Ctx[I830_CTXREG_VF] = v0; - i830->state.Ctx[I830_CTXREG_VF2] = v2; - i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1; - RENDERINPUTS_COPY( i830->last_index_bitset, index_bitset ); - - assert(i830_check_vertex_size( intel, intel->vertex_size )); - } -} - -static void i830_reduced_primitive_state( intelContextPtr intel, - GLenum rprim ) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - GLuint st1 = i830->state.Stipple[I830_STPREG_ST1]; - - st1 &= ~ST1_ENABLE; - - switch (rprim) { - case GL_TRIANGLES: - if (intel->ctx.Polygon.StippleFlag && - intel->hw_stipple) - st1 |= ST1_ENABLE; - break; - case GL_LINES: - case GL_POINTS: - default: - break; - } - - i830->intel.reduced_primitive = rprim; - - if (st1 != i830->state.Stipple[I830_STPREG_ST1]) { - I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); - i830->state.Stipple[I830_STPREG_ST1] = st1; - } -} - -/* Pull apart the vertex format registers and figure out how large a - * vertex is supposed to be. - */ -static GLboolean i830_check_vertex_size( intelContextPtr intel, - GLuint expected ) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - int vft0 = i830->current->Ctx[I830_CTXREG_VF]; - int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; - int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; - int i, sz = 0; - - switch (vft0 & VFT0_XYZW_MASK) { - case VFT0_XY: sz = 2; break; - case VFT0_XYZ: sz = 3; break; - case VFT0_XYW: sz = 3; break; - case VFT0_XYZW: sz = 4; break; - default: - fprintf(stderr, "no xyzw specified\n"); - return 0; - } - - if (vft0 & VFT0_SPEC) sz++; - if (vft0 & VFT0_DIFFUSE) sz++; - if (vft0 & VFT0_DEPTH_OFFSET) sz++; - if (vft0 & VFT0_POINT_WIDTH) sz++; - - for (i = 0 ; i < nrtex ; i++) { - switch (vft1 & VFT1_TEX0_MASK) { - case TEXCOORDFMT_2D: sz += 2; break; - case TEXCOORDFMT_3D: sz += 3; break; - case TEXCOORDFMT_4D: sz += 4; break; - case TEXCOORDFMT_1D: sz += 1; break; - } - vft1 >>= VFT1_TEX1_SHIFT; - } - - if (sz != expected) - fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); - - return sz == expected; -} - -static void i830_emit_invarient_state( intelContextPtr intel ) -{ - BATCH_LOCALS; - - BEGIN_BATCH( 40 ); - - OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0)); - OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1)); - OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(2)); - OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(3)); - - OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_Z_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_FOG_MODE_CMD); - OUT_BATCH(FOGFUNC_ENABLE | - FOG_LINEAR_CONST | - FOGSRC_INDEX_Z | - ENABLE_FOG_DENSITY); - OUT_BATCH(0); - OUT_BATCH(0); - - - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(0) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(0) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0)); - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(1) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(1) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1)); - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(2) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(2) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2)); - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(3) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(3) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); - - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1)); - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2)); - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3)); - - OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - ENABLE_TRI_STRIP_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | - TRI_STRIP_PROVOKE_VRTX(2)); - - OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - - OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM); - OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); - - OUT_BATCH(_3DSTATE_W_STATE_CMD); - OUT_BATCH(MAGIC_W_STATE_DWORD1); - OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ ); - - - OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD); - OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */ - - ADVANCE_BATCH(); -} - - -#define emit( intel, state, size ) \ -do { \ - int k; \ - BEGIN_BATCH( size / sizeof(GLuint)); \ - for (k = 0 ; k < size / sizeof(GLuint) ; k++) \ - OUT_BATCH(state[k]); \ - ADVANCE_BATCH(); \ -} while (0); - -static GLuint get_state_size( struct i830_hw_state *state ) -{ - GLuint dirty = state->active & ~state->emitted; - GLuint sz = 0; - GLuint i; - - if (dirty & I830_UPLOAD_INVARIENT) - sz += 40 * sizeof(int); - - if (dirty & I830_UPLOAD_CTX) - sz += sizeof(state->Ctx); - - if (dirty & I830_UPLOAD_BUFFERS) - sz += sizeof(state->Buffer); - - if (dirty & I830_UPLOAD_STIPPLE) - sz += sizeof(state->Stipple); - - for (i = 0; i < I830_TEX_UNITS; i++) { - if ((dirty & I830_UPLOAD_TEX(i))) - sz += sizeof(state->Tex[i]); - - if (dirty & I830_UPLOAD_TEXBLEND(i)) - sz += state->TexBlendWordsUsed[i] * 4; - } - - return sz; -} - - -/* Push the state into the sarea and/or texture memory. - */ -static void i830_emit_state( intelContextPtr intel ) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - struct i830_hw_state *state = i830->current; - int i; - GLuint dirty = state->active & ~state->emitted; - GLuint counter = intel->batch.counter; - BATCH_LOCALS; - - if (intel->batch.space < get_state_size(state)) { - intelFlushBatch(intel, GL_TRUE); - dirty = state->active & ~state->emitted; - counter = intel->batch.counter; - } - - if (dirty & I830_UPLOAD_INVARIENT) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_INVARIENT:\n"); - i830_emit_invarient_state( intel ); - } - - if (dirty & I830_UPLOAD_CTX) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_CTX:\n"); - emit( i830, state->Ctx, sizeof(state->Ctx) ); - } - - if (dirty & I830_UPLOAD_BUFFERS) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_BUFFERS:\n"); - emit( i830, state->Buffer, sizeof(state->Buffer) ); - } - - if (dirty & I830_UPLOAD_STIPPLE) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_STIPPLE:\n"); - emit( i830, state->Stipple, sizeof(state->Stipple) ); - } - - for (i = 0; i < I830_TEX_UNITS; i++) { - if ((dirty & I830_UPLOAD_TEX(i))) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEX(%d):\n", i); - emit( i830, state->Tex[i], sizeof(state->Tex[i])); - } - - if (dirty & I830_UPLOAD_TEXBLEND(i)) { - if (VERBOSE) fprintf(stderr, "I830_UPLOAD_TEXBLEND(%d):\n", i); - emit( i830, state->TexBlend[i], - state->TexBlendWordsUsed[i] * 4 ); - } - } - - state->emitted |= dirty; - intel->batch.last_emit_state = counter; - assert(counter == intel->batch.counter); -} - -static void i830_destroy_context( intelContextPtr intel ) -{ - _tnl_free_vertices(&intel->ctx); -} - -static void -i830_set_color_region(intelContextPtr intel, const intelRegion *region) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS ); - i830->state.Buffer[I830_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_CBUFADDR2] = region->offset; -} - - -static void -i830_set_z_region(intelContextPtr intel, const intelRegion *region) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS ); - i830->state.Buffer[I830_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_DBUFADDR2] = region->offset; -} - - -static void -i830_update_color_z_regions(intelContextPtr intel, - const intelRegion *colorRegion, - const intelRegion *depthRegion) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - - i830->state.Buffer[I830_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset; - - i830->state.Buffer[I830_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset; -} - - -/* This isn't really handled at the moment. - */ -static void i830_lost_hardware( intelContextPtr intel ) -{ - I830_CONTEXT(intel)->state.emitted = 0; -} - - - -static void i830_emit_flush( intelContextPtr intel ) -{ - BATCH_LOCALS; - - BEGIN_BATCH(2); - OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE ); - OUT_BATCH( 0 ); - ADVANCE_BATCH(); -} - - - - -void i830InitVtbl( i830ContextPtr i830 ) -{ - i830->intel.vtbl.alloc_tex_obj = i830AllocTexObj; - i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; - i830->intel.vtbl.clear_with_tris = i830ClearWithTris; - i830->intel.vtbl.rotate_window = i830RotateWindow; - i830->intel.vtbl.destroy = i830_destroy_context; - i830->intel.vtbl.emit_state = i830_emit_state; - i830->intel.vtbl.lost_hardware = i830_lost_hardware; - i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state; - i830->intel.vtbl.set_color_region = i830_set_color_region; - i830->intel.vtbl.set_z_region = i830_set_z_region; - i830->intel.vtbl.update_color_z_regions = i830_update_color_z_regions; - i830->intel.vtbl.update_texture_state = i830UpdateTextureState; - i830->intel.vtbl.emit_flush = i830_emit_flush; - i830->intel.vtbl.render_start = i830_render_start; - i830->intel.vtbl.render_prevalidate = i830_render_prevalidate; -} diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c deleted file mode 100644 index 2bc1cae9c3..0000000000 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ /dev/null @@ -1,186 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "i915_context.h" -#include "imports.h" -#include "intel_tex.h" -#include "intel_tris.h" -#include "tnl/t_context.h" -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" -#include "vbo/vbo.h" - - -#include "utils.h" -#include "i915_reg.h" - -/*************************************** - * Mesa's Driver Functions - ***************************************/ - -static const struct dri_extension i915_extensions[] = -{ - { "GL_ARB_depth_texture", NULL }, - { "GL_ARB_fragment_program", NULL }, - { "GL_ARB_shadow", NULL }, - { "GL_ARB_texture_env_crossbar", NULL }, - { "GL_EXT_shadow_funcs", NULL }, - /* ARB extn won't work if not enabled */ - { "GL_SGIX_depth_texture", NULL }, - { NULL, NULL } -}; - -/* Override intel default. - */ -static void i915InvalidateState( GLcontext *ctx, GLuint new_state ) -{ - _swrast_InvalidateState( ctx, new_state ); - _swsetup_InvalidateState( ctx, new_state ); - _vbo_InvalidateState( ctx, new_state ); - _tnl_InvalidateState( ctx, new_state ); - _tnl_invalidate_vertex_state( ctx, new_state ); - INTEL_CONTEXT(ctx)->NewGLState |= new_state; - - /* Todo: gather state values under which tracked parameters become - * invalidated, add callbacks for things like - * ProgramLocalParameters, etc. - */ - { - struct i915_fragment_program *p = - (struct i915_fragment_program *)ctx->FragmentProgram._Current; - if (p && p->nr_params) - p->params_uptodate = 0; - } - - if (new_state & (_NEW_FOG|_NEW_HINT|_NEW_PROGRAM)) - i915_update_fog(ctx); -} - - -static void i915InitDriverFunctions( struct dd_function_table *functions ) -{ - intelInitDriverFunctions( functions ); - i915InitStateFunctions( functions ); - i915InitTextureFuncs( functions ); - i915InitFragProgFuncs( functions ); - functions->UpdateState = i915InvalidateState; -} - - - -GLboolean i915CreateContext( const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate) -{ - struct dd_function_table functions; - i915ContextPtr i915 = (i915ContextPtr) CALLOC_STRUCT(i915_context); - intelContextPtr intel = &i915->intel; - GLcontext *ctx = &intel->ctx; - GLuint i; - - if (!i915) return GL_FALSE; - - i915InitVtbl( i915 ); - - i915InitDriverFunctions( &functions ); - - if (!intelInitContext( intel, mesaVis, driContextPriv, - sharedContextPrivate, &functions )) { - FREE(i915); - return GL_FALSE; - } - - ctx->Const.MaxTextureUnits = I915_TEX_UNITS; - ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS; - ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS; - - intel->nr_heaps = 1; - intel->texture_heaps[0] = - driCreateTextureHeap( 0, intel, - intel->intelScreen->tex.size, - 12, - I830_NR_TEX_REGIONS, - intel->sarea->texList, - (unsigned *) & intel->sarea->texAge, - & intel->swapped, - sizeof( struct i915_texture_object ), - (destroy_texture_object_t *)intelDestroyTexObj ); - - /* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are - * tightly packed, but they're not in Intel graphics - * hardware. - */ - ctx->Const.MaxTextureUnits = I915_TEX_UNITS; - i = driQueryOptioni( &intel->optionCache, "allow_large_textures"); - driCalculateMaxTextureLevels( intel->texture_heaps, - intel->nr_heaps, - &intel->ctx.Const, - 4, - 11, /* max 2D texture size is 2048x2048 */ - 8, /* 3D texture */ - 11, /* cube texture. */ - 11, /* rect texture */ - 12, - GL_FALSE, - i ); - - /* GL_ARB_fragment_program limits - don't think Mesa actually - * validates programs against these, and in any case one ARB - * instruction can translate to more than one HW instruction, so - * we'll still have to check and fallback each time. - */ - - ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY; - ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */ - ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT; - ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN; - ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN; - ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN + - I915_MAX_TEX_INSN); - ctx->Const.FragmentProgram.MaxNativeTexIndirections = I915_MAX_TEX_INDIRECT; - ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; - - - driInitExtensions( ctx, i915_extensions, GL_FALSE ); - - - _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, - 36 * sizeof(GLfloat) ); - - intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; - - i915InitState( i915 ); - - return GL_TRUE; -} - diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h deleted file mode 100644 index ec1550126a..0000000000 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ /dev/null @@ -1,358 +0,0 @@ - /************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef I915CONTEXT_INC -#define I915CONTEXT_INC - -#include "intel_context.h" - -#define I915_FALLBACK_TEXTURE 0x1000 -#define I915_FALLBACK_COLORMASK 0x2000 -#define I915_FALLBACK_STENCIL 0x4000 -#define I915_FALLBACK_STIPPLE 0x8000 -#define I915_FALLBACK_PROGRAM 0x10000 -#define I915_FALLBACK_LOGICOP 0x20000 -#define I915_FALLBACK_POLYGON_SMOOTH 0x40000 -#define I915_FALLBACK_POINT_SMOOTH 0x80000 - -#define I915_UPLOAD_CTX 0x1 -#define I915_UPLOAD_BUFFERS 0x2 -#define I915_UPLOAD_STIPPLE 0x4 -#define I915_UPLOAD_PROGRAM 0x8 -#define I915_UPLOAD_CONSTANTS 0x10 -#define I915_UPLOAD_FOG 0x20 -#define I915_UPLOAD_INVARIENT 0x40 -#define I915_UPLOAD_TEX(i) (0x00010000<<(i)) -#define I915_UPLOAD_TEX_ALL (0x00ff0000) -#define I915_UPLOAD_TEX_0_SHIFT 16 - - -/* State structure offsets - these will probably disappear. - */ -#define I915_DESTREG_CBUFADDR0 0 -#define I915_DESTREG_CBUFADDR1 1 -#define I915_DESTREG_CBUFADDR2 2 -#define I915_DESTREG_DBUFADDR0 3 -#define I915_DESTREG_DBUFADDR1 4 -#define I915_DESTREG_DBUFADDR2 5 -#define I915_DESTREG_DV0 6 -#define I915_DESTREG_DV1 7 -#define I915_DESTREG_SENABLE 8 -#define I915_DESTREG_SR0 9 -#define I915_DESTREG_SR1 10 -#define I915_DESTREG_SR2 11 -#define I915_DEST_SETUP_SIZE 12 - -#define I915_CTXREG_STATE4 0 -#define I915_CTXREG_LI 1 -#define I915_CTXREG_LIS2 2 -#define I915_CTXREG_LIS4 3 -#define I915_CTXREG_LIS5 4 -#define I915_CTXREG_LIS6 5 -#define I915_CTXREG_IAB 6 -#define I915_CTXREG_BLENDCOLOR0 7 -#define I915_CTXREG_BLENDCOLOR1 8 -#define I915_CTX_SETUP_SIZE 9 - -#define I915_FOGREG_COLOR 0 -#define I915_FOGREG_MODE0 1 -#define I915_FOGREG_MODE1 2 -#define I915_FOGREG_MODE2 3 -#define I915_FOGREG_MODE3 4 -#define I915_FOG_SETUP_SIZE 5 - -#define I915_STPREG_ST0 0 -#define I915_STPREG_ST1 1 -#define I915_STP_SETUP_SIZE 2 - -#define I915_TEXREG_MS2 0 -#define I915_TEXREG_MS3 1 -#define I915_TEXREG_MS4 2 -#define I915_TEXREG_SS2 3 -#define I915_TEXREG_SS3 4 -#define I915_TEXREG_SS4 5 -#define I915_TEX_SETUP_SIZE 6 - -#define I915_MAX_CONSTANT 32 -#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) - - -#define I915_PROGRAM_SIZE 192 - - -/* Hardware version of a parsed fragment program. "Derived" from the - * mesa fragment_program struct. - */ -struct i915_fragment_program { - struct gl_fragment_program FragProg; - - GLboolean translated; - GLboolean params_uptodate; - GLboolean on_hardware; - GLboolean error; /* If program is malformed for any reason. */ - - GLuint nr_tex_indirect; - GLuint nr_tex_insn; - GLuint nr_alu_insn; - GLuint nr_decl_insn; - - - - - /* TODO: split between the stored representation of a program and - * the state used to build that representation. - */ - GLcontext *ctx; - - GLuint declarations[I915_PROGRAM_SIZE]; - GLuint program[I915_PROGRAM_SIZE]; - - GLfloat constant[I915_MAX_CONSTANT][4]; - GLuint constant_flags[I915_MAX_CONSTANT]; - GLuint nr_constants; - - GLuint *csr; /* Cursor, points into program. - */ - - GLuint *decl; /* Cursor, points into declarations. - */ - - GLuint decl_s; /* flags for which s regs need to be decl'd */ - GLuint decl_t; /* flags for which t regs need to be decl'd */ - - GLuint temp_flag; /* Tracks temporary regs which are in - * use. - */ - - GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in - * use. - */ - - - - /* Helpers for i915_fragprog.c: - */ - GLuint wpos_tex; - GLboolean depth_written; - - struct { - GLuint reg; /* Hardware constant idx */ - const GLfloat *values; /* Pointer to tracked values */ - } param[I915_MAX_CONSTANT]; - GLuint nr_params; - - - - - /* Helpers for i915_texprog.c: - */ - GLuint src_texture; /* Reg containing sampled texture color, - * else UREG_BAD. - */ - - GLuint src_previous; /* Reg containing color from previous - * stage. May need to be decl'd. - */ - - GLuint last_tex_stage; /* Number of last enabled texture unit */ - - struct vertex_buffer *VB; -}; - - - - - - -struct i915_texture_object -{ - struct intel_texture_object intel; - GLenum lastTarget; - GLboolean refs_border_color; - GLuint Setup[I915_TEX_SETUP_SIZE]; -}; - -#define I915_TEX_UNITS 8 - - -struct i915_hw_state { - GLuint Ctx[I915_CTX_SETUP_SIZE]; - GLuint Buffer[I915_DEST_SETUP_SIZE]; - GLuint Stipple[I915_STP_SETUP_SIZE]; - GLuint Fog[I915_FOG_SETUP_SIZE]; - GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; - GLuint Constant[I915_CONSTANT_SIZE]; - GLuint ConstantSize; - GLuint Program[I915_PROGRAM_SIZE]; - GLuint ProgramSize; - GLuint active; /* I915_UPLOAD_* */ - GLuint emitted; /* I915_UPLOAD_* */ -}; - -#define I915_FOG_PIXEL 2 -#define I915_FOG_VERTEX 1 -#define I915_FOG_NONE 0 - -struct i915_context -{ - struct intel_context intel; - - GLuint last_ReallyEnabled; - GLuint vertex_fog; - - struct i915_fragment_program tex_program; - struct i915_fragment_program *current_program; - - struct i915_hw_state meta, initial, state, *current; -}; - - -typedef struct i915_context *i915ContextPtr; -typedef struct i915_texture_object *i915TextureObjectPtr; - -#define I915_CONTEXT(ctx) ((i915ContextPtr)(ctx)) - - - -#define I915_STATECHANGE(i915, flag) \ -do { \ - if (0) fprintf(stderr, "I915_STATECHANGE %x in %s\n", flag, __FUNCTION__); \ - INTEL_FIREVERTICES( &(i915)->intel ); \ - (i915)->state.emitted &= ~(flag); \ -} while (0) - -#define I915_ACTIVESTATE(i915, flag, mode) \ -do { \ - if (0) fprintf(stderr, "I915_ACTIVESTATE %x %d in %s\n", \ - flag, mode, __FUNCTION__); \ - INTEL_FIREVERTICES( &(i915)->intel ); \ - if (mode) \ - (i915)->state.active |= (flag); \ - else \ - (i915)->state.active &= ~(flag); \ -} while (0) - - -/*====================================================================== - * i915_vtbl.c - */ -extern void i915InitVtbl( i915ContextPtr i915 ); - - - -#define SZ_TO_HW(sz) ((sz-2)&0x3) -#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) -#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ - intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ - s4 |= S4; \ - intel->vertex_attr_count++; \ - offset += (SZ); \ -} while (0) - -#define EMIT_PAD( N ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ - intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ - intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ - intel->vertex_attr_count++; \ - offset += (N); \ -} while (0) - - - -/*====================================================================== - * i915_context.c - */ -extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate); - - -/*====================================================================== - * i915_texprog.c - */ -extern void i915ValidateTextureProgram( i915ContextPtr i915 ); - - -/*====================================================================== - * i915_debug.c - */ -extern void i915_disassemble_program( const GLuint *program, GLuint sz ); -extern void i915_print_ureg( const char *msg, GLuint ureg ); - - -/*====================================================================== - * i915_state.c - */ -extern void i915InitStateFunctions( struct dd_function_table *functions ); -extern void i915InitState( i915ContextPtr i915 ); -extern void i915_update_fog(GLcontext *ctxx); - - -/*====================================================================== - * i915_tex.c - */ -extern void i915UpdateTextureState( intelContextPtr intel ); -extern void i915InitTextureFuncs( struct dd_function_table *functions ); -extern intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj ); - -/*====================================================================== - * i915_metaops.c - */ -extern GLboolean -i915TryTextureReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ); - -extern GLboolean -i915TryTextureDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ); - -extern void -i915ClearWithTris( intelContextPtr intel, GLbitfield mask, - GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch); - - -extern void -i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv, - GLuint srcBuf); - -/*====================================================================== - * i915_fragprog.c - */ -extern void i915ValidateFragmentProgram( i915ContextPtr i915 ); -extern void i915InitFragProgFuncs( struct dd_function_table *functions ); - -#endif - diff --git a/src/mesa/drivers/dri/i915/i915_debug.c b/src/mesa/drivers/dri/i915/i915_debug.c deleted file mode 100644 index 054b561605..0000000000 --- a/src/mesa/drivers/dri/i915/i915_debug.c +++ /dev/null @@ -1,299 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "i915_reg.h" -#include "i915_context.h" -#include - - -static const char *opcodes[0x20] = { - "NOP", - "ADD", - "MOV", - "MUL", - "MAD", - "DP2ADD", - "DP3", - "DP4", - "FRC", - "RCP", - "RSQ", - "EXP", - "LOG", - "CMP", - "MIN", - "MAX", - "FLR", - "MOD", - "TRC", - "SGE", - "SLT", - "TEXLD", - "TEXLDP", - "TEXLDB", - "TEXKILL", - "DCL", - "0x1a", - "0x1b", - "0x1c", - "0x1d", - "0x1e", - "0x1f", -}; - - -static const int args[0x20] = { - 0, /* 0 nop */ - 2, /* 1 add */ - 1, /* 2 mov */ - 2, /* 3 m ul */ - 3, /* 4 mad */ - 3, /* 5 dp2add */ - 2, /* 6 dp3 */ - 2, /* 7 dp4 */ - 1, /* 8 frc */ - 1, /* 9 rcp */ - 1, /* a rsq */ - 1, /* b exp */ - 1, /* c log */ - 3, /* d cmp */ - 2, /* e min */ - 2, /* f max */ - 1, /* 10 flr */ - 1, /* 11 mod */ - 1, /* 12 trc */ - 2, /* 13 sge */ - 2, /* 14 slt */ - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - - -static const char *regname[0x8] = { - "R", - "T", - "CONST", - "S", - "OC", - "OD", - "U", - "UNKNOWN", -}; - -static void print_reg_type_nr( GLuint type, GLuint nr ) -{ - switch (type) { - case REG_TYPE_T: - switch (nr) { - case T_DIFFUSE: fprintf(stderr, "T_DIFFUSE"); return; - case T_SPECULAR: fprintf(stderr, "T_SPECULAR"); return; - case T_FOG_W: fprintf(stderr, "T_FOG_W"); return; - default: fprintf(stderr, "T_TEX%d", nr); return; - } - case REG_TYPE_OC: - if (nr == 0) { - fprintf(stderr, "oC"); - return; - } - break; - case REG_TYPE_OD: - if (nr == 0) { - fprintf(stderr, "oD"); - return; - } - break; - default: - break; - } - - fprintf(stderr, "%s[%d]", regname[type], nr); -} - -#define REG_SWIZZLE_MASK 0x7777 -#define REG_NEGATE_MASK 0x8888 - -#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ - (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) - - -static void print_reg_neg_swizzle( GLuint reg ) -{ - int i; - - if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && - (reg & REG_NEGATE_MASK) == 0) - return; - - fprintf(stderr, "."); - - for (i = 3 ; i >= 0; i--) { - if (reg & (1<<((i*4)+3))) - fprintf(stderr, "-"); - - switch ((reg>>(i*4)) & 0x7) { - case 0: fprintf(stderr, "x"); break; - case 1: fprintf(stderr, "y"); break; - case 2: fprintf(stderr, "z"); break; - case 3: fprintf(stderr, "w"); break; - case 4: fprintf(stderr, "0"); break; - case 5: fprintf(stderr, "1"); break; - default: fprintf(stderr, "?"); break; - } - } -} - - -static void print_src_reg( GLuint dword ) -{ - GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; - GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; - print_reg_type_nr( type, nr ); - print_reg_neg_swizzle( dword ); -} - -void i915_print_ureg( const char *msg, GLuint ureg ) -{ - fprintf(stderr, "%s: ", msg); - print_src_reg( ureg >> 8 ); - fprintf(stderr, "\n"); -} - -static void print_dest_reg( GLuint dword ) -{ - GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; - GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; - print_reg_type_nr( type, nr ); - if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) - return; - fprintf(stderr, "."); - if (dword & A0_DEST_CHANNEL_X) fprintf(stderr, "x"); - if (dword & A0_DEST_CHANNEL_Y) fprintf(stderr, "y"); - if (dword & A0_DEST_CHANNEL_Z) fprintf(stderr, "z"); - if (dword & A0_DEST_CHANNEL_W) fprintf(stderr, "w"); -} - - -#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) -#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) -#define GET_SRC2_REG(r) (r) - - -static void print_arith_op( GLuint opcode, const GLuint *program ) -{ - if (opcode != A0_NOP) { - print_dest_reg(program[0]); - if (program[0] & A0_DEST_SATURATE) - fprintf(stderr, " = SATURATE "); - else - fprintf(stderr, " = "); - } - - fprintf(stderr, "%s ", opcodes[opcode]); - - print_src_reg(GET_SRC0_REG(program[0], program[1])); - if (args[opcode] == 1) { - fprintf(stderr, "\n"); - return; - } - - fprintf(stderr, ", "); - print_src_reg(GET_SRC1_REG(program[1], program[2])); - if (args[opcode] == 2) { - fprintf(stderr, "\n"); - return; - } - - fprintf(stderr, ", "); - print_src_reg(GET_SRC2_REG(program[2])); - fprintf(stderr, "\n"); - return; -} - - -static void print_tex_op( GLuint opcode, const GLuint *program ) -{ - print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - fprintf(stderr, " = "); - - fprintf(stderr, "%s ", opcodes[opcode]); - - fprintf(stderr, "S[%d],", - program[0] & T0_SAMPLER_NR_MASK); - - print_reg_type_nr( (program[1]>>T1_ADDRESS_REG_TYPE_SHIFT) & REG_TYPE_MASK, - (program[1]>>T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK ); - fprintf(stderr, "\n"); -} - -static void print_dcl_op( GLuint opcode, const GLuint *program ) -{ - fprintf(stderr, "%s ", opcodes[opcode]); - print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - fprintf(stderr, "\n"); -} - - -void i915_disassemble_program( const GLuint *program, GLuint sz ) -{ - GLuint size = program[0] & 0x1ff; - GLint i; - - fprintf(stderr, "BEGIN\n"); - - if (size+2 != sz) { - fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__, - size+2, sz); - exit(1); - } - - program ++; - for (i = 1 ; i < sz ; i+=3, program+=3) { - GLuint opcode = program[0] & (0x1f<<24); - - if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) - print_arith_op(opcode >> 24, program); - else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) - print_tex_op(opcode >> 24, program); - else if (opcode == D0_DCL) - print_dcl_op(opcode >> 24, program); - else - fprintf(stderr, "Unknown opcode 0x%x\n", opcode); - } - - fprintf(stderr, "END\n\n"); -} diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c deleted file mode 100644 index c839bbdea5..0000000000 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ /dev/null @@ -1,1080 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/program.h" -#include "shader/programopt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" - -#include "intel_batchbuffer.h" - -#include "i915_reg.h" -#include "i915_context.h" -#include "i915_program.h" - - - -/* 1, -1/3!, 1/5!, -1/7! */ -static const GLfloat sin_constants[4] = { 1.0, - -1.0/(3*2*1), - 1.0/(5*4*3*2*1), - -1.0/(7*6*5*4*3*2*1) }; - -/* 1, -1/2!, 1/4!, -1/6! */ -static const GLfloat cos_constants[4] = { 1.0, - -1.0/(2*1), - 1.0/(4*3*2*1), - -1.0/(6*5*4*3*2*1) }; - -/** - * Retrieve a ureg for the given source register. Will emit - * constants, apply swizzling and negation as needed. - */ -static GLuint src_vector( struct i915_fragment_program *p, - const struct prog_src_register *source, - const struct gl_fragment_program *program ) -{ - GLuint src; - - switch (source->File) { - - /* Registers: - */ - case PROGRAM_TEMPORARY: - if (source->Index >= I915_MAX_TEMPORARY) { - i915_program_error( p, "Exceeded max temporary reg" ); - return 0; - } - src = UREG( REG_TYPE_R, source->Index ); - break; - case PROGRAM_INPUT: - switch (source->Index) { - case FRAG_ATTRIB_WPOS: - src = i915_emit_decl( p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL ); - break; - case FRAG_ATTRIB_COL0: - src = i915_emit_decl( p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL ); - break; - case FRAG_ATTRIB_COL1: - src = i915_emit_decl( p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ ); - src = swizzle( src, X, Y, Z, ONE ); - break; - case FRAG_ATTRIB_FOGC: - src = i915_emit_decl( p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W ); - src = swizzle( src, W, W, W, W ); - break; - case FRAG_ATTRIB_TEX0: - case FRAG_ATTRIB_TEX1: - case FRAG_ATTRIB_TEX2: - case FRAG_ATTRIB_TEX3: - case FRAG_ATTRIB_TEX4: - case FRAG_ATTRIB_TEX5: - case FRAG_ATTRIB_TEX6: - case FRAG_ATTRIB_TEX7: - src = i915_emit_decl( p, REG_TYPE_T, - T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0), - D0_CHANNEL_ALL ); - break; - - default: - i915_program_error( p, "Bad source->Index" ); - return 0; - } - break; - - /* Various paramters and env values. All emitted to - * hardware as program constants. - */ - case PROGRAM_LOCAL_PARAM: - src = i915_emit_param4fv( - p, program->Base.LocalParams[source->Index]); - break; - - case PROGRAM_ENV_PARAM: - src = i915_emit_param4fv( - p, p->ctx->FragmentProgram.Parameters[source->Index]); - break; - - case PROGRAM_CONSTANT: - case PROGRAM_STATE_VAR: - case PROGRAM_NAMED_PARAM: - src = i915_emit_param4fv( - p, program->Base.Parameters->ParameterValues[source->Index] ); - break; - - default: - i915_program_error( p, "Bad source->File" ); - return 0; - } - - src = swizzle(src, - GET_SWZ(source->Swizzle, 0), - GET_SWZ(source->Swizzle, 1), - GET_SWZ(source->Swizzle, 2), - GET_SWZ(source->Swizzle, 3)); - - if (source->NegateBase) - src = negate( src, - GET_BIT(source->NegateBase, 0), - GET_BIT(source->NegateBase, 1), - GET_BIT(source->NegateBase, 2), - GET_BIT(source->NegateBase, 3)); - - return src; -} - - -static GLuint get_result_vector( struct i915_fragment_program *p, - const struct prog_instruction *inst ) -{ - switch (inst->DstReg.File) { - case PROGRAM_OUTPUT: - switch (inst->DstReg.Index) { - case FRAG_RESULT_COLR: - return UREG(REG_TYPE_OC, 0); - case FRAG_RESULT_DEPR: - p->depth_written = 1; - return UREG(REG_TYPE_OD, 0); - default: - i915_program_error( p, "Bad inst->DstReg.Index" ); - return 0; - } - case PROGRAM_TEMPORARY: - return UREG(REG_TYPE_R, inst->DstReg.Index); - default: - i915_program_error( p, "Bad inst->DstReg.File" ); - return 0; - } -} - -static GLuint get_result_flags( const struct prog_instruction *inst ) -{ - GLuint flags = 0; - - if (inst->SaturateMode == SATURATE_ZERO_ONE) flags |= A0_DEST_SATURATE; - if (inst->DstReg.WriteMask & WRITEMASK_X) flags |= A0_DEST_CHANNEL_X; - if (inst->DstReg.WriteMask & WRITEMASK_Y) flags |= A0_DEST_CHANNEL_Y; - if (inst->DstReg.WriteMask & WRITEMASK_Z) flags |= A0_DEST_CHANNEL_Z; - if (inst->DstReg.WriteMask & WRITEMASK_W) flags |= A0_DEST_CHANNEL_W; - - return flags; -} - -static GLuint translate_tex_src_target( struct i915_fragment_program *p, - GLubyte bit ) -{ - switch (bit) { - case TEXTURE_1D_INDEX: return D0_SAMPLE_TYPE_2D; - case TEXTURE_2D_INDEX: return D0_SAMPLE_TYPE_2D; - case TEXTURE_RECT_INDEX: return D0_SAMPLE_TYPE_2D; - case TEXTURE_3D_INDEX: return D0_SAMPLE_TYPE_VOLUME; - case TEXTURE_CUBE_INDEX: return D0_SAMPLE_TYPE_CUBE; - default: i915_program_error(p, "TexSrcBit"); return 0; - } -} - -#define EMIT_TEX( OP ) \ -do { \ - GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget ); \ - GLuint sampler = i915_emit_decl(p, REG_TYPE_S, \ - inst->TexSrcUnit, dim); \ - GLuint coord = src_vector( p, &inst->SrcReg[0], program); \ - /* Texel lookup */ \ - \ - i915_emit_texld( p, \ - get_result_vector( p, inst ), \ - get_result_flags( inst ), \ - sampler, \ - coord, \ - OP); \ -} while (0) - -#define EMIT_ARITH( OP, N ) \ -do { \ - i915_emit_arith( p, \ - OP, \ - get_result_vector( p, inst ), \ - get_result_flags( inst ), 0, \ - (N<1)?0:src_vector( p, &inst->SrcReg[0], program), \ - (N<2)?0:src_vector( p, &inst->SrcReg[1], program), \ - (N<3)?0:src_vector( p, &inst->SrcReg[2], program)); \ -} while (0) - -#define EMIT_1ARG_ARITH( OP ) EMIT_ARITH( OP, 1 ) -#define EMIT_2ARG_ARITH( OP ) EMIT_ARITH( OP, 2 ) -#define EMIT_3ARG_ARITH( OP ) EMIT_ARITH( OP, 3 ) - - -/* Possible concerns: - * - * SIN, COS -- could use another taylor step? - * LIT -- results seem a little different to sw mesa - * LOG -- different to mesa on negative numbers, but this is conformant. - * - * Parse failures -- Mesa doesn't currently give a good indication - * internally whether a particular program string parsed or not. This - * can lead to confusion -- hopefully we cope with it ok now. - * - */ -static void upload_program( struct i915_fragment_program *p ) -{ - const struct gl_fragment_program *program = p->ctx->FragmentProgram._Current; - const struct prog_instruction *inst = program->Base.Instructions; - -/* _mesa_debug_fp_inst(program->Base.NumInstructions, inst); */ - - /* Is this a parse-failed program? Ensure a valid program is - * loaded, as the flagging of an error isn't sufficient to stop - * this being uploaded to hardware. - */ - if (inst[0].Opcode == OPCODE_END) { - GLuint tmp = i915_get_utemp( p ); - i915_emit_arith( p, - A0_MOV, - UREG(REG_TYPE_OC, 0), - A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp,ONE,ZERO,ONE,ONE), 0, 0); - return; - } - - while (1) { - GLuint src0, src1, src2, flags; - GLuint tmp = 0; - - switch (inst->Opcode) { - case OPCODE_ABS: - src0 = src_vector( p, &inst->SrcReg[0], program); - i915_emit_arith( p, - A0_MAX, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - src0, negate(src0, 1,1,1,1), 0); - break; - - case OPCODE_ADD: - EMIT_2ARG_ARITH( A0_ADD ); - break; - - case OPCODE_CMP: - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - src2 = src_vector( p, &inst->SrcReg[2], program); - i915_emit_arith( p, - A0_CMP, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - src0, src2, src1); /* NOTE: order of src2, src1 */ - break; - - case OPCODE_COS: - src0 = src_vector( p, &inst->SrcReg[0], program); - tmp = i915_get_utemp( p ); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - src0, - i915_emit_const1f(p, 1.0/(M_PI)), - 0); - - i915_emit_arith( p, - A0_MOD, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, - 0, 0 ); - - /* By choosing different taylor constants, could get rid of this mul: - */ - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, - i915_emit_const1f(p, (M_PI)), - 0); - - /* - * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 - * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 - * t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 - * result = DP4 t0, cos_constants - */ - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XY, 0, - swizzle(tmp, X,X,ONE,ONE), - swizzle(tmp, X,ONE,ONE,ONE), 0); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XYZ, 0, - swizzle(tmp, X,Y,X,ONE), - swizzle(tmp, X,X,ONE,ONE), 0); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XYZ, 0, - swizzle(tmp, X,X,Z,ONE), - swizzle(tmp, Z,ONE,ONE,ONE), 0); - - i915_emit_arith( p, - A0_DP4, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(tmp, ONE,Z,Y,X), - i915_emit_const4fv( p, cos_constants ), 0); - - break; - - case OPCODE_DP3: - EMIT_2ARG_ARITH( A0_DP3 ); - break; - - case OPCODE_DP4: - EMIT_2ARG_ARITH( A0_DP4 ); - break; - - case OPCODE_DPH: - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - - i915_emit_arith( p, - A0_DP4, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(src0, X,Y,Z,ONE), src1, 0); - break; - - case OPCODE_DST: - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - - /* result[0] = 1 * 1; - * result[1] = a[1] * b[1]; - * result[2] = a[2] * 1; - * result[3] = 1 * b[3]; - */ - i915_emit_arith( p, - A0_MUL, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(src0, ONE, Y, Z, ONE), - swizzle(src1, ONE, Y, ONE, W ), - 0); - break; - - case OPCODE_EX2: - src0 = src_vector( p, &inst->SrcReg[0], program); - - i915_emit_arith( p, - A0_EXP, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(src0,X,X,X,X), 0, 0); - break; - - case OPCODE_FLR: - EMIT_1ARG_ARITH( A0_FLR ); - break; - - case OPCODE_FRC: - EMIT_1ARG_ARITH( A0_FRC ); - break; - - case OPCODE_KIL: - src0 = src_vector( p, &inst->SrcReg[0], program); - tmp = i915_get_utemp( p ); - - i915_emit_texld( p, - tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ - 0, - src0, - T0_TEXKILL ); - break; - - case OPCODE_LG2: - src0 = src_vector( p, &inst->SrcReg[0], program); - - i915_emit_arith( p, - A0_LOG, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(src0,X,X,X,X), 0, 0); - break; - - case OPCODE_LIT: - src0 = src_vector( p, &inst->SrcReg[0], program); - tmp = i915_get_utemp( p ); - - /* tmp = max( a.xyzw, a.00zw ) - * XXX: Clamp tmp.w to -128..128 - * tmp.y = log(tmp.y) - * tmp.y = tmp.w * tmp.y - * tmp.y = exp(tmp.y) - * result = cmp (a.11-x1, a.1x01, a.1xy1 ) - */ - i915_emit_arith( p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0, - src0, swizzle(src0, ZERO, ZERO, Z, W), 0 ); - - i915_emit_arith( p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0, - swizzle(tmp, Y, Y, Y, Y), 0, 0 ); - - i915_emit_arith( p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0, - swizzle(tmp, ZERO, Y, ZERO, ZERO), - swizzle(tmp, ZERO, W, ZERO, ZERO), 0 ); - - i915_emit_arith( p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0, - swizzle(tmp, Y, Y, Y, Y), 0, 0 ); - - i915_emit_arith( p, A0_CMP, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - negate(swizzle(tmp, ONE, ONE, X, ONE),0,0,1,0), - swizzle(tmp, ONE, X, ZERO, ONE), - swizzle(tmp, ONE, X, Y, ONE)); - - break; - - case OPCODE_LRP: - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - src2 = src_vector( p, &inst->SrcReg[2], program); - flags = get_result_flags( inst ); - tmp = i915_get_utemp( p ); - - /* b*a + c*(1-a) - * - * b*a + c - ca - * - * tmp = b*a + c, - * result = (-c)*a + tmp - */ - i915_emit_arith( p, A0_MAD, tmp, - flags & A0_DEST_CHANNEL_ALL, 0, - src1, src0, src2 ); - - i915_emit_arith( p, A0_MAD, - get_result_vector( p, inst ), - flags, 0, - negate(src2, 1,1,1,1), src0, tmp ); - break; - - case OPCODE_MAD: - EMIT_3ARG_ARITH( A0_MAD ); - break; - - case OPCODE_MAX: - EMIT_2ARG_ARITH( A0_MAX ); - break; - - case OPCODE_MIN: - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - tmp = i915_get_utemp( p ); - flags = get_result_flags( inst ); - - i915_emit_arith( p, - A0_MAX, - tmp, flags & A0_DEST_CHANNEL_ALL, 0, - negate(src0,1,1,1,1), - negate(src1,1,1,1,1), 0); - - i915_emit_arith( p, - A0_MOV, - get_result_vector( p, inst ), - flags, 0, - negate(tmp, 1,1,1,1), 0, 0); - break; - - case OPCODE_MOV: - EMIT_1ARG_ARITH( A0_MOV ); - break; - - case OPCODE_MUL: - EMIT_2ARG_ARITH( A0_MUL ); - break; - - case OPCODE_POW: - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - tmp = i915_get_utemp( p ); - flags = get_result_flags( inst ); - - /* XXX: masking on intermediate values, here and elsewhere. - */ - i915_emit_arith( p, - A0_LOG, - tmp, A0_DEST_CHANNEL_X, 0, - swizzle(src0,X,X,X,X), 0, 0); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, src1, 0); - - - i915_emit_arith( p, - A0_EXP, - get_result_vector( p, inst ), - flags, 0, - swizzle(tmp,X,X,X,X), 0, 0); - - break; - - case OPCODE_RCP: - src0 = src_vector( p, &inst->SrcReg[0], program); - - i915_emit_arith( p, - A0_RCP, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(src0,X,X,X,X), 0, 0); - break; - - case OPCODE_RSQ: - - src0 = src_vector( p, &inst->SrcReg[0], program); - - i915_emit_arith( p, - A0_RSQ, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(src0,X,X,X,X), 0, 0); - break; - - case OPCODE_SCS: - src0 = src_vector( p, &inst->SrcReg[0], program); - tmp = i915_get_utemp( p ); - - /* - * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 - * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x - * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x - * scs.x = DP4 t1, sin_constants - * t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 - * scs.y = DP4 t1, cos_constants - */ - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XY, 0, - swizzle(src0, X,X,ONE,ONE), - swizzle(src0, X,ONE,ONE,ONE), 0); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X,Y,X,Y), - swizzle(tmp, X,X,ONE,ONE), 0); - - if (inst->DstReg.WriteMask & WRITEMASK_Y) { - GLuint tmp1; - - if (inst->DstReg.WriteMask & WRITEMASK_X) - tmp1 = i915_get_utemp( p ); - else - tmp1 = tmp; - - i915_emit_arith( p, - A0_MUL, - tmp1, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X,Y,Y,W), - swizzle(tmp, X,Z,ONE,ONE), 0); - - i915_emit_arith( p, - A0_DP4, - get_result_vector( p, inst ), - A0_DEST_CHANNEL_Y, 0, - swizzle(tmp1, W,Z,Y,X), - i915_emit_const4fv( p, sin_constants ), 0); - } - - if (inst->DstReg.WriteMask & WRITEMASK_X) { - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XYZ, 0, - swizzle(tmp, X,X,Z,ONE), - swizzle(tmp, Z,ONE,ONE,ONE), 0); - - i915_emit_arith( p, - A0_DP4, - get_result_vector( p, inst ), - A0_DEST_CHANNEL_X, 0, - swizzle(tmp, ONE,Z,Y,X), - i915_emit_const4fv( p, cos_constants ), 0); - } - break; - - case OPCODE_SGE: - EMIT_2ARG_ARITH( A0_SGE ); - break; - - case OPCODE_SIN: - src0 = src_vector( p, &inst->SrcReg[0], program); - tmp = i915_get_utemp( p ); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - src0, - i915_emit_const1f(p, 1.0/(M_PI)), - 0); - - i915_emit_arith( p, - A0_MOD, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, - 0, 0 ); - - /* By choosing different taylor constants, could get rid of this mul: - */ - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, - i915_emit_const1f(p, (M_PI)), - 0); - - /* - * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 - * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x - * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x - * result = DP4 t1.wzyx, sin_constants - */ - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XY, 0, - swizzle(tmp, X,X,ONE,ONE), - swizzle(tmp, X,ONE,ONE,ONE), 0); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X,Y,X,Y), - swizzle(tmp, X,X,ONE,ONE), 0); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X,Y,Y,W), - swizzle(tmp, X,Z,ONE,ONE), 0); - - i915_emit_arith( p, - A0_DP4, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(tmp, W, Z, Y, X ), - i915_emit_const4fv( p, sin_constants ), 0); - break; - - case OPCODE_SLT: - EMIT_2ARG_ARITH( A0_SLT ); - break; - - case OPCODE_SUB: - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - - i915_emit_arith( p, - A0_ADD, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - src0, negate(src1, 1,1,1,1), 0); - break; - - case OPCODE_SWZ: - EMIT_1ARG_ARITH( A0_MOV ); /* extended swizzle handled natively */ - break; - - case OPCODE_TEX: - EMIT_TEX( T0_TEXLD ); - break; - - case OPCODE_TXB: - EMIT_TEX( T0_TEXLDB ); - break; - - case OPCODE_TXP: - EMIT_TEX( T0_TEXLDP ); - break; - - case OPCODE_XPD: - /* Cross product: - * result.x = src0.y * src1.z - src0.z * src1.y; - * result.y = src0.z * src1.x - src0.x * src1.z; - * result.z = src0.x * src1.y - src0.y * src1.x; - * result.w = undef; - */ - src0 = src_vector( p, &inst->SrcReg[0], program); - src1 = src_vector( p, &inst->SrcReg[1], program); - tmp = i915_get_utemp( p ); - - i915_emit_arith( p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(src0,Z,X,Y,ONE), - swizzle(src1,Y,Z,X,ONE), 0); - - i915_emit_arith( p, - A0_MAD, - get_result_vector( p, inst ), - get_result_flags( inst ), 0, - swizzle(src0,Y,Z,X,ONE), - swizzle(src1,Z,X,Y,ONE), - negate(tmp,1,1,1,0)); - break; - - case OPCODE_END: - return; - - default: - i915_program_error( p, "bad opcode" ); - return; - } - - inst++; - i915_release_utemps( p ); - } -} - -/* Rather than trying to intercept and jiggle depth writes during - * emit, just move the value into its correct position at the end of - * the program: - */ -static void fixup_depth_write( struct i915_fragment_program *p ) -{ - if (p->depth_written) { - GLuint depth = UREG(REG_TYPE_OD, 0); - - i915_emit_arith( p, - A0_MOV, - depth, A0_DEST_CHANNEL_W, 0, - swizzle(depth,X,Y,Z,Z), - 0, 0); - } -} - - -static void check_wpos( struct i915_fragment_program *p ) -{ - GLuint inputs = p->FragProg.Base.InputsRead; - GLint i; - - p->wpos_tex = -1; - - for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { - if (inputs & FRAG_BIT_TEX(i)) - continue; - else if (inputs & FRAG_BIT_WPOS) { - p->wpos_tex = i; - inputs &= ~FRAG_BIT_WPOS; - } - } - - if (inputs & FRAG_BIT_WPOS) { - i915_program_error(p, "No free texcoord for wpos value"); - } -} - - -static void translate_program( struct i915_fragment_program *p ) -{ - i915ContextPtr i915 = I915_CONTEXT(p->ctx); - - i915_init_program( i915, p ); - check_wpos( p ); - upload_program( p ); - fixup_depth_write( p ); - i915_fini_program( p ); - - p->translated = 1; -} - - -static void track_params( struct i915_fragment_program *p ) -{ - GLint i; - - if (p->nr_params) - _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters); - - for (i = 0; i < p->nr_params; i++) { - GLint reg = p->param[i].reg; - COPY_4V( p->constant[reg], p->param[i].values ); - } - - p->params_uptodate = 1; - p->on_hardware = 0; /* overkill */ -} - - -static void i915BindProgram( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct i915_fragment_program *p = (struct i915_fragment_program *)prog; - - if (i915->current_program == p) - return; - - if (i915->current_program) { - i915->current_program->on_hardware = 0; - i915->current_program->params_uptodate = 0; - } - - i915->current_program = p; - - assert(p->on_hardware == 0); - assert(p->params_uptodate == 0); - - } -} - -static struct gl_program *i915NewProgram( GLcontext *ctx, - GLenum target, - GLuint id ) -{ - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - return _mesa_init_vertex_program( ctx, CALLOC_STRUCT(gl_vertex_program), - target, id ); - - case GL_FRAGMENT_PROGRAM_ARB: { - struct i915_fragment_program *prog = CALLOC_STRUCT(i915_fragment_program); - if (prog) { - i915_init_program( I915_CONTEXT(ctx), prog ); - - return _mesa_init_fragment_program( ctx, &prog->FragProg, - target, id ); - } - else - return NULL; - } - - default: - /* Just fallback: - */ - return _mesa_new_program( ctx, target, id ); - } -} - -static void i915DeleteProgram( GLcontext *ctx, - struct gl_program *prog ) -{ - if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct i915_fragment_program *p = (struct i915_fragment_program *)prog; - - if (i915->current_program == p) - i915->current_program = 0; - } - - _mesa_delete_program( ctx, prog ); -} - - -static GLboolean i915IsProgramNative( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_fragment_program *p = (struct i915_fragment_program *)prog; - - if (!p->translated) - translate_program( p ); - - return !p->error; - } - else - return GL_TRUE; -} - -static void i915ProgramStringNotify( GLcontext *ctx, - GLenum target, - struct gl_program *prog ) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_fragment_program *p = (struct i915_fragment_program *)prog; - p->translated = 0; - - /* Hack: make sure fog is correctly enabled according to this - * fragment program's fog options. - */ - if (p->FragProg.FogOption) { - /* add extra instructions to do fog, then turn off FogOption field */ - _mesa_append_fog_code(ctx, &p->FragProg); - p->FragProg.FogOption = GL_NONE; - } - } - - _tnl_program_string(ctx, target, prog); -} - - -void i915ValidateFragmentProgram( i915ContextPtr i915 ) -{ - GLcontext *ctx = &i915->intel.ctx; - intelContextPtr intel = INTEL_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - - struct i915_fragment_program *p = - (struct i915_fragment_program *)ctx->FragmentProgram._Current; - - const GLuint inputsRead = p->FragProg.Base.InputsRead; - GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; - GLuint s2 = S2_TEXCOORD_NONE; - int i, offset = 0; - - if (i915->current_program != p) - { - if (i915->current_program) { - i915->current_program->on_hardware = 0; - i915->current_program->params_uptodate = 0; - } - - i915->current_program = p; - } - - - /* Important: - */ - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - - if (!p->translated) - translate_program( p ); - - intel->vertex_attr_count = 0; - intel->wpos_offset = 0; - intel->wpos_size = 0; - intel->coloroffset = 0; - intel->specoffset = 0; - - if (inputsRead & FRAG_BITS_TEX_ANY) { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 ); - } - else { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12 ); - } - - if (inputsRead & FRAG_BIT_COL0) { - intel->coloroffset = offset / 4; - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4 ); - } - - if ((inputsRead & (FRAG_BIT_COL1|FRAG_BIT_FOGC)) || - i915->vertex_fog != I915_FOG_NONE) { - - if (inputsRead & FRAG_BIT_COL1) { - intel->specoffset = offset / 4; - EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3 ); - } - else - EMIT_PAD(3); - - if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) - EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1 ); - else - EMIT_PAD( 1 ); - } - - /* XXX this was disabled, but enabling this code helped fix the Glean - * tfragprog1 fog tests. - */ -#if 1 - if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { - EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4 ); - } -#endif - - for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { - if (inputsRead & FRAG_BIT_TEX(i)) { - int sz = VB->TexCoordPtr[i]->size; - - s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); - s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); - - EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0, sz * 4 ); - } - else if (i == p->wpos_tex) { - - /* If WPOS is required, duplicate the XYZ position data in an - * unused texture coordinate: - */ - s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); - s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); - - intel->wpos_offset = offset; - intel->wpos_size = 3 * sizeof(GLuint); - - EMIT_PAD( intel->wpos_size ); - } - } - - if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || - s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - - I915_STATECHANGE( i915, I915_UPLOAD_CTX ); - - /* Must do this *after* statechange, so as not to affect - * buffered vertices reliant on the old state: - */ - intel->vertex_size = _tnl_install_attrs( &intel->ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0 ); - - intel->vertex_size >>= 2; - - i915->state.Ctx[I915_CTXREG_LIS2] = s2; - i915->state.Ctx[I915_CTXREG_LIS4] = s4; - - assert(intel->vtbl.check_vertex_size( intel, intel->vertex_size )); - } - - if (!p->params_uptodate) - track_params( p ); - - if (!p->on_hardware) - i915_upload_program( i915, p ); -} - -void i915InitFragProgFuncs( struct dd_function_table *functions ) -{ - functions->BindProgram = i915BindProgram; - functions->NewProgram = i915NewProgram; - functions->DeleteProgram = i915DeleteProgram; - functions->IsProgramNative = i915IsProgramNative; - functions->ProgramStringNotify = i915ProgramStringNotify; -} diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c deleted file mode 100644 index 1be7ac4c48..0000000000 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ /dev/null @@ -1,711 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_rotate.h" - -#include "i915_context.h" -#include "i915_reg.h" - -/* A large amount of state doesn't need to be uploaded. - */ -#define ACTIVE (I915_UPLOAD_INVARIENT | \ - I915_UPLOAD_PROGRAM | \ - I915_UPLOAD_STIPPLE | \ - I915_UPLOAD_CTX | \ - I915_UPLOAD_BUFFERS | \ - I915_UPLOAD_TEX(0)) - -#define SET_STATE( i915, STATE ) \ -do { \ - i915->current->emitted &= ~ACTIVE; \ - i915->current = &i915->STATE; \ - i915->current->emitted &= ~ACTIVE; \ -} while (0) - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void set_initial_state( i915ContextPtr i915 ) -{ - memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) ); - i915->meta.active = ACTIVE; - i915->meta.emitted = 0; -} - - -static void set_no_depth_stencil_write( i915ContextPtr i915 ) -{ - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -/* Set stencil unit to replace always with the reference value. - */ -static void set_stencil_replace( i915ContextPtr i915, - GLuint s_mask, - GLuint s_clear) -{ - GLuint op = STENCILOP_REPLACE; - GLuint func = COMPAREFUNC_ALWAYS; - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(s_mask)); - - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); - - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | - (func << S5_STENCIL_TEST_FUNC_SHIFT)); - - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -static void set_color_mask( i915ContextPtr i915, GLboolean state ) -{ - const GLuint mask = (S5_WRITEDISABLE_RED | - S5_WRITEDISABLE_GREEN | - S5_WRITEDISABLE_BLUE | - S5_WRITEDISABLE_ALPHA); - - /* Copy colormask state from "regular" hw context. - */ - if (state) { - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; - i915->meta.Ctx[I915_CTXREG_LIS5] |= - (i915->state.Ctx[I915_CTXREG_LIS5] & mask); - } - else - i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - - -#define REG( type, nr ) (((type)<<5)|(nr)) - -#define REG_R(x) REG(REG_TYPE_R, x) -#define REG_T(x) REG(REG_TYPE_T, x) -#define REG_CONST(x) REG(REG_TYPE_CONST, x) -#define REG_S(x) REG(REG_TYPE_S, x) -#define REG_OC REG(REG_TYPE_OC, 0) -#define REG_OD REG(REG_TYPE_OD, 0) -#define REG_U(x) REG(REG_TYPE_U, x) - -#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) -#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) -#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) -#define REG_T_TEX(x) REG(REG_TYPE_T, x) - - -#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) -#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) -#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) -#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) -#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) -#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) -#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) - -#define T0_SAMPLER( unit ) ((unit)<meta.Program, prog, sizeof(prog) ); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - - -static void enable_texture_blend_replace( i915ContextPtr i915 ) -{ - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare the sampler: - */ - (D0_DCL | - D0_DECL_REG( REG_S(0) ) | - D0_SAMPLE_TYPE_2D | - D0_CHANNEL_NONE), - D1_MBZ, - D2_MBZ, - - /* Declare the interpolated texture coordinate: - */ - (D0_DCL | - D0_DECL_REG( REG_T_TEX(0) ) | - D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = texld(sample0, texcoord0) - */ - (T0_TEXLD | - T0_DEST_REG( REG_OC ) | - T0_SAMPLER( 0 )), - T1_ADDRESS_REG(REG_TYPE_T, 0), - T2_MBZ - }; - - memcpy( i915->meta.Program, prog, sizeof(prog) ); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - - - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static void set_tex_rect_source( i915ContextPtr i915, - GLuint offset, - GLuint width, - GLuint height, - GLuint pitch, /* in bytes! */ - GLuint textureFormat ) -{ - GLuint unit = 0; - GLint numLevels = 1; - GLuint *state = i915->meta.Tex[0]; - -#if 0 - printf("TexRect source offset 0x%x pitch %d\n", offset, pitch); -#endif - -/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */ -/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */ - - state[I915_TEXREG_MS2] = offset; - state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | - ((width - 1) << MS3_WIDTH_SHIFT) | - textureFormat | - MS3_USE_FENCE_REGS); - - state[I915_TEXREG_MS4] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | - ((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT)); - - state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | - (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); - state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | - (unit<meta.emitted &= ~I915_UPLOAD_TEX(0); -} - - -/* Select between front and back draw buffers. - */ -static void set_draw_region( i915ContextPtr i915, const intelRegion *region ) -{ -#if 0 - printf("Rotate into region: offset 0x%x pitch %d\n", - region->offset, region->pitch); -#endif - i915->meta.Buffer[I915_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE); - i915->meta.Buffer[I915_DESTREG_CBUFADDR2] = region->offset; - i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; -} - - -#if 0 -/* Setup an arbitary draw format, useful for targeting texture or agp - * memory. - */ -static void set_draw_format( i915ContextPtr i915, - GLuint format, - GLuint depth_format) -{ - i915->meta.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - format | - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - depth_format); - - i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; -/* fprintf(stderr, "%s: DV1: %x\n", */ -/* __FUNCTION__, i915->meta.Buffer[I915_DESTREG_DV1]); */ -} -#endif - -static void set_vertex_format( i915ContextPtr i915 ) -{ - i915->meta.Ctx[I915_CTXREG_LIS2] = - (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | - S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); - - i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; - - i915->meta.Ctx[I915_CTXREG_LIS4] |= - (S4_VFMT_COLOR | - S4_VFMT_SPEC_FOG | - S4_VFMT_XYZW); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; - -} - - -static void draw_quad(i915ContextPtr i915, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLubyte red, GLubyte green, - GLubyte blue, GLubyte alpha, - GLfloat s0, GLfloat s1, - GLfloat t0, GLfloat t1 ) -{ - GLuint vertex_size = 8; - GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel, - PRIM3D_TRIFAN, - 4 * vertex_size, - vertex_size ); - intelVertex tmp; - int i; - - if (0) - fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", - __FUNCTION__, - x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); - - - /* initial vertex, left bottom */ - tmp.v.x = x0; - tmp.v.y = y0; - tmp.v.z = 1.0; - tmp.v.w = 1.0; - tmp.v.color.red = red; - tmp.v.color.green = green; - tmp.v.color.blue = blue; - tmp.v.color.alpha = alpha; - tmp.v.specular.red = 0; - tmp.v.specular.green = 0; - tmp.v.specular.blue = 0; - tmp.v.specular.alpha = 0; - tmp.v.u0 = s0; - tmp.v.v0 = t0; - - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - /* right bottom */ - vb += vertex_size; - tmp.v.x = x1; - tmp.v.u0 = s1; - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - /* right top */ - vb += vertex_size; - tmp.v.y = y1; - tmp.v.v0 = t1; - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - /* left top */ - vb += vertex_size; - tmp.v.x = x0; - tmp.v.u0 = s0; - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; -} - - -static void draw_poly(i915ContextPtr i915, - GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha, - GLuint numVerts, - /*const*/ GLfloat verts[][2], - /*const*/ GLfloat texcoords[][2]) -{ - GLuint vertex_size = 8; - GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel, - PRIM3D_TRIFAN, - numVerts * vertex_size, - vertex_size ); - intelVertex tmp; - int i, k; - - /* initial constant vertex fields */ - tmp.v.z = 1.0; - tmp.v.w = 1.0; - tmp.v.color.red = red; - tmp.v.color.green = green; - tmp.v.color.blue = blue; - tmp.v.color.alpha = alpha; - tmp.v.specular.red = 0; - tmp.v.specular.green = 0; - tmp.v.specular.blue = 0; - tmp.v.specular.alpha = 0; - - for (k = 0; k < numVerts; k++) { - tmp.v.x = verts[k][0]; - tmp.v.y = verts[k][1]; - tmp.v.u0 = texcoords[k][0]; - tmp.v.v0 = texcoords[k][1]; - - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - vb += vertex_size; - } -} - - -void -i915ClearWithTris(intelContextPtr intel, GLbitfield buffers, - GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) -{ - i915ContextPtr i915 = I915_CONTEXT( intel ); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - intelScreenPrivate *screen = intel->intelScreen; - int x0, y0, x1, y1; - GLint cx, cy, cw, ch; - GLboolean all; - - SET_STATE( i915, meta ); - set_initial_state( i915 ); - set_no_texture( i915 ); - set_vertex_format( i915 ); - - LOCK_HARDWARE(intel); - - /* get clear bounds after locking */ - cx = intel->ctx.DrawBuffer->_Xmin; - cy = intel->ctx.DrawBuffer->_Ymin; - cw = intel->ctx.DrawBuffer->_Xmax - cx; - ch = intel->ctx.DrawBuffer->_Ymax - cy; - all = (cw == intel->ctx.DrawBuffer->Width && - ch == intel->ctx.DrawBuffer->Height); - - if (!all) { - x0 = cx; - y0 = cy; - x1 = x0 + cw; - y1 = y0 + ch; - } else { - x0 = 0; - y0 = 0; - x1 = x0 + dPriv->w; - y1 = y0 + dPriv->h; - } - - /* Don't do any clipping to screen - these are window coordinates. - * The active cliprects will be applied as for any other geometry. - */ - - if (buffers & BUFFER_BIT_FRONT_LEFT) { - set_no_depth_stencil_write( i915 ); - set_color_mask( i915, GL_TRUE ); - set_draw_region( i915, &screen->front ); - - draw_quad(i915, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } - - if (buffers & BUFFER_BIT_BACK_LEFT) { - set_no_depth_stencil_write( i915 ); - set_color_mask( i915, GL_TRUE ); - set_draw_region( i915, &screen->back ); - - draw_quad(i915, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } - - if (buffers & BUFFER_BIT_STENCIL) { - set_stencil_replace( i915, - intel->ctx.Stencil.WriteMask[0], - intel->ctx.Stencil.Clear); - - set_color_mask( i915, GL_FALSE ); - set_draw_region( i915, &screen->front ); /* could be either? */ - - draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 ); - } - - UNLOCK_HARDWARE(intel); - - SET_STATE( i915, state ); -} - - -/** - * Copy the window contents named by dPriv to the rotated (or reflected) - * color buffer. - * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source. - */ -void -i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv, - GLuint srcBuf) -{ - i915ContextPtr i915 = I915_CONTEXT( intel ); - intelScreenPrivate *screen = intel->intelScreen; - const GLuint cpp = screen->cpp; - drm_clip_rect_t fullRect; - GLuint textureFormat, srcOffset, srcPitch; - const drm_clip_rect_t *clipRects; - int numClipRects; - int i; - - int xOrig, yOrig; - int origNumClipRects; - drm_clip_rect_t *origRects; - - /* - * set up hardware state - */ - intelFlush( &intel->ctx ); - - SET_STATE( i915, meta ); - set_initial_state( i915 ); - set_no_texture( i915 ); - set_vertex_format( i915 ); - set_no_depth_stencil_write( i915 ); - set_color_mask( i915, GL_TRUE ); - - LOCK_HARDWARE(intel); - - /* save current drawing origin and cliprects (restored at end) */ - xOrig = intel->drawX; - yOrig = intel->drawY; - origNumClipRects = intel->numClipRects; - origRects = intel->pClipRects; - - if (!intel->numClipRects) - goto done; - - /* - * set drawing origin, cliprects for full-screen access to rotated screen - */ - fullRect.x1 = 0; - fullRect.y1 = 0; - fullRect.x2 = screen->rotatedWidth; - fullRect.y2 = screen->rotatedHeight; - intel->drawX = 0; - intel->drawY = 0; - intel->numClipRects = 1; - intel->pClipRects = &fullRect; - - set_draw_region( i915, &screen->rotated ); - - if (cpp == 4) - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - else - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - - if (srcBuf == BUFFER_BIT_FRONT_LEFT) { - srcPitch = screen->front.pitch; /* in bytes */ - srcOffset = screen->front.offset; /* bytes */ - clipRects = dPriv->pClipRects; - numClipRects = dPriv->numClipRects; - } - else { - srcPitch = screen->back.pitch; /* in bytes */ - srcOffset = screen->back.offset; /* bytes */ - clipRects = dPriv->pBackClipRects; - numClipRects = dPriv->numBackClipRects; - } - - /* set the whole screen up as a texture to avoid alignment issues */ - set_tex_rect_source(i915, - srcOffset, - screen->width, - screen->height, - srcPitch, - textureFormat); - - enable_texture_blend_replace(i915); - - /* - * loop over the source window's cliprects - */ - for (i = 0; i < numClipRects; i++) { - int srcX0 = clipRects[i].x1; - int srcY0 = clipRects[i].y1; - int srcX1 = clipRects[i].x2; - int srcY1 = clipRects[i].y2; - GLfloat verts[4][2], tex[4][2]; - int j; - - /* build vertices for four corners of clip rect */ - verts[0][0] = srcX0; verts[0][1] = srcY0; - verts[1][0] = srcX1; verts[1][1] = srcY0; - verts[2][0] = srcX1; verts[2][1] = srcY1; - verts[3][0] = srcX0; verts[3][1] = srcY1; - - /* .. and texcoords */ - tex[0][0] = srcX0; tex[0][1] = srcY0; - tex[1][0] = srcX1; tex[1][1] = srcY0; - tex[2][0] = srcX1; tex[2][1] = srcY1; - tex[3][0] = srcX0; tex[3][1] = srcY1; - - /* transform coords to rotated screen coords */ - for (j = 0; j < 4; j++) { - matrix23TransformCoordf(&screen->rotMatrix, - &verts[j][0], &verts[j][1]); - } - - /* draw polygon to map source image to dest region */ - draw_poly(i915, 255, 255, 255, 255, 4, verts, tex); - - } /* cliprect loop */ - - intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE ); - - done: - /* restore original drawing origin and cliprects */ - intel->drawX = xOrig; - intel->drawY = yOrig; - intel->numClipRects = origNumClipRects; - intel->pClipRects = origRects; - - UNLOCK_HARDWARE(intel); - - SET_STATE( i915, state ); -} - diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c deleted file mode 100644 index 6849112444..0000000000 --- a/src/mesa/drivers/dri/i915/i915_program.c +++ /dev/null @@ -1,499 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include - -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "tnl/t_context.h" -#include "intel_batchbuffer.h" - -#include "i915_reg.h" -#include "i915_context.h" -#include "i915_program.h" - - -#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) -#define A1_SRC0( reg ) (((reg)&UREG_MASK)<>UREG_A1_SRC1_SHIFT_LEFT) -#define A2_SRC1( reg ) (((reg)&UREG_MASK)<>UREG_A2_SRC2_SHIFT_LEFT) - -/* These are special, and don't have swizzle/negate bits. - */ -#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<temp_flag ); - if (!bit) { - fprintf(stderr, "%s: out of temporaries\n", __FILE__); - exit(1); - } - - p->temp_flag |= 1<<(bit-1); - return UREG(REG_TYPE_R, (bit-1)); -} - - -GLuint i915_get_utemp( struct i915_fragment_program *p ) -{ - int bit = ffs( ~p->utemp_flag ); - if (!bit) { - fprintf(stderr, "%s: out of temporaries\n", __FILE__); - exit(1); - } - - p->utemp_flag |= 1<<(bit-1); - return UREG(REG_TYPE_U, (bit-1)); -} - -void i915_release_utemps( struct i915_fragment_program *p ) -{ - p->utemp_flag = ~0x7; -} - - -GLuint i915_emit_decl( struct i915_fragment_program *p, - GLuint type, GLuint nr, GLuint d0_flags ) -{ - GLuint reg = UREG(type, nr); - - if (type == REG_TYPE_T) { - if (p->decl_t & (1<decl_t |= (1<decl_s & (1<decl_s |= (1<decl++) = (D0_DCL | D0_DEST( reg ) | d0_flags); - *(p->decl++) = D1_MBZ; - *(p->decl++) = D2_MBZ; - - p->nr_decl_insn++; - return reg; -} - -GLuint i915_emit_arith( struct i915_fragment_program *p, - GLuint op, - GLuint dest, - GLuint mask, - GLuint saturate, - GLuint src0, - GLuint src1, - GLuint src2 ) -{ - GLuint c[3]; - GLuint nr_const = 0; - - assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); - assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); - - if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) c[nr_const++] = 0; - if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) c[nr_const++] = 1; - if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) c[nr_const++] = 2; - - /* Recursively call this function to MOV additional const values - * into temporary registers. Use utemp registers for this - - * currently shouldn't be possible to run out, but keep an eye on - * this. - */ - if (nr_const > 1) { - GLuint s[3], first, i, old_utemp_flag; - - s[0] = src0; - s[1] = src1; - s[2] = src2; - old_utemp_flag = p->utemp_flag; - - first = GET_UREG_NR(s[c[0]]); - for (i = 1 ; i < nr_const ; i++) { - if (GET_UREG_NR(s[c[i]]) != first) { - GLuint tmp = i915_get_utemp(p); - - i915_emit_arith( p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, - s[c[i]], 0, 0 ); - s[c[i]] = tmp; - } - } - - src0 = s[0]; - src1 = s[1]; - src2 = s[2]; - p->utemp_flag = old_utemp_flag; /* restore */ - } - - *(p->csr++) = (op | - A0_DEST( dest ) | - mask | - saturate | - A0_SRC0( src0 )); - *(p->csr++) = (A1_SRC0( src0 ) | - A1_SRC1( src1 )); - *(p->csr++) = (A2_SRC1( src1 ) | - A2_SRC2( src2 )); - - p->nr_alu_insn++; - return dest; -} - -GLuint i915_emit_texld( struct i915_fragment_program *p, - GLuint dest, - GLuint destmask, - GLuint sampler, - GLuint coord, - GLuint op ) -{ - if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { - /* No real way to work around this in the general case - need to - * allocate and declare a new temporary register (a utemp won't - * do). Will fallback for now. - */ - i915_program_error(p, "Can't (yet) swizzle TEX arguments"); - return 0; - } - - /* Don't worry about saturate as we only support - */ - if (destmask != A0_DEST_CHANNEL_ALL) { - GLuint tmp = i915_get_utemp(p); - i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); - i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); - return dest; - } - else { - assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); - assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); - - if (GET_UREG_TYPE(coord) != REG_TYPE_T) { - p->nr_tex_indirect++; - } - - *(p->csr++) = (op | - T0_DEST( dest ) | - T0_SAMPLER( sampler )); - - *(p->csr++) = T1_ADDRESS_REG( coord ); - *(p->csr++) = T2_MBZ; - - p->nr_tex_insn++; - return dest; - } -} - - -GLuint i915_emit_const1f( struct i915_fragment_program *p, GLfloat c0 ) -{ - GLint reg, idx; - - if (c0 == 0.0) return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); - if (c0 == 1.0) return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE ); - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) - continue; - for (idx = 0; idx < 4; idx++) { - if (!(p->constant_flags[reg] & (1<constant[reg][idx] == c0) { - p->constant[reg][idx] = c0; - p->constant_flags[reg] |= 1< p->nr_constants) p->nr_constants = reg+1; - return swizzle(UREG(REG_TYPE_CONST, reg),idx,ZERO,ZERO,ONE); - } - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - -GLuint i915_emit_const2f( struct i915_fragment_program *p, - GLfloat c0, GLfloat c1 ) -{ - GLint reg, idx; - - if (c0 == 0.0) return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); - if (c0 == 1.0) return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); - - if (c1 == 0.0) return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); - if (c1 == 1.0) return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf || - p->constant_flags[reg] == I915_CONSTFLAG_PARAM) - continue; - for (idx = 0; idx < 3; idx++) { - if (!(p->constant_flags[reg] & (3<constant[reg][idx] = c0; - p->constant[reg][idx+1] = c1; - p->constant_flags[reg] |= 3< p->nr_constants) p->nr_constants = reg+1; - return swizzle(UREG(REG_TYPE_CONST, reg),idx,idx+1,ZERO,ONE); - } - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - - -GLuint i915_emit_const4f( struct i915_fragment_program *p, - GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3 ) -{ - GLint reg; - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf && - p->constant[reg][0] == c0 && - p->constant[reg][1] == c1 && - p->constant[reg][2] == c2 && - p->constant[reg][3] == c3) { - return UREG(REG_TYPE_CONST, reg); - } - else if (p->constant_flags[reg] == 0) { - p->constant[reg][0] = c0; - p->constant[reg][1] = c1; - p->constant[reg][2] = c2; - p->constant[reg][3] = c3; - p->constant_flags[reg] = 0xf; - if (reg+1 > p->nr_constants) p->nr_constants = reg+1; - return UREG(REG_TYPE_CONST, reg); - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - -GLuint i915_emit_const4fv( struct i915_fragment_program *p, const GLfloat *c ) -{ - return i915_emit_const4f( p, c[0], c[1], c[2], c[3] ); -} - - -GLuint i915_emit_param4fv( struct i915_fragment_program *p, - const GLfloat *values ) -{ - GLint reg, i; - - for (i = 0; i < p->nr_params; i++) { - if (p->param[i].values == values) - return UREG(REG_TYPE_CONST, p->param[i].reg); - } - - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0) { - p->constant_flags[reg] = I915_CONSTFLAG_PARAM; - i = p->nr_params++; - - p->param[i].values = values; - p->param[i].reg = reg; - p->params_uptodate = 0; - - if (reg+1 > p->nr_constants) p->nr_constants = reg+1; - return UREG(REG_TYPE_CONST, reg); - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - - - -void i915_program_error( struct i915_fragment_program *p, const char *msg ) -{ - _mesa_problem(NULL, "i915_program_error: %s", msg); - p->error = 1; -} - -void i915_init_program( i915ContextPtr i915, struct i915_fragment_program *p ) -{ - GLcontext *ctx = &i915->intel.ctx; - TNLcontext *tnl = TNL_CONTEXT( ctx ); - - p->translated = 0; - p->params_uptodate = 0; - p->on_hardware = 0; - p->error = 0; - - p->nr_tex_indirect = 1; /* correct? */ - p->nr_tex_insn = 0; - p->nr_alu_insn = 0; - p->nr_decl_insn = 0; - - p->ctx = ctx; - memset( p->constant_flags, 0, sizeof(p->constant_flags) ); - - p->nr_constants = 0; - p->csr = p->program; - p->decl = p->declarations; - p->decl_s = 0; - p->decl_t = 0; - p->temp_flag = 0xffff000; - p->utemp_flag = ~0x7; - p->wpos_tex = -1; - p->depth_written = 0; - p->nr_params = 0; - - p->src_texture = UREG_BAD; - p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE); - p->last_tex_stage = 0; - p->VB = &tnl->vb; - - *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; -} - - -void i915_fini_program( struct i915_fragment_program *p ) -{ - GLuint program_size = p->csr - p->program; - GLuint decl_size = p->decl - p->declarations; - - if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) - i915_program_error(p, "Exceeded max nr indirect texture lookups"); - - if (p->nr_tex_insn > I915_MAX_TEX_INSN) - i915_program_error(p, "Exceeded max TEX instructions"); - - if (p->nr_alu_insn > I915_MAX_ALU_INSN) - i915_program_error(p, "Exceeded max ALU instructions"); - - if (p->nr_decl_insn > I915_MAX_DECL_INSN) - i915_program_error(p, "Exceeded max DECL instructions"); - - if (p->error) { - p->FragProg.Base.NumNativeInstructions = 0; - p->FragProg.Base.NumNativeAluInstructions = 0; - p->FragProg.Base.NumNativeTexInstructions = 0; - p->FragProg.Base.NumNativeTexIndirections = 0; - } - else { - p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + - p->nr_tex_insn + - p->nr_decl_insn); - p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn; - p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn; - p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect; - } - - p->declarations[0] |= program_size + decl_size - 2; -} - -void i915_upload_program( i915ContextPtr i915, struct i915_fragment_program *p ) -{ - GLuint program_size = p->csr - p->program; - GLuint decl_size = p->decl - p->declarations; - - FALLBACK( &i915->intel, I915_FALLBACK_PROGRAM, p->error ); - - /* Could just go straight to the batchbuffer from here: - */ - if (i915->state.ProgramSize != (program_size + decl_size) || - memcmp(i915->state.Program + decl_size, p->program, - program_size*sizeof(int)) != 0) { - I915_STATECHANGE( i915, I915_UPLOAD_PROGRAM ); - memcpy(i915->state.Program, p->declarations, decl_size*sizeof(int)); - memcpy(i915->state.Program + decl_size, p->program, - program_size*sizeof(int)); - i915->state.ProgramSize = decl_size + program_size; - } - - /* Always seemed to get a failure if I used memcmp() to - * shortcircuit this state upload. Needs further investigation? - */ - if (p->nr_constants) { - GLuint nr = p->nr_constants; - - I915_ACTIVESTATE( i915, I915_UPLOAD_CONSTANTS, 1 ); - I915_STATECHANGE( i915, I915_UPLOAD_CONSTANTS ); - - i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); - i915->state.Constant[1] = (1<<(nr-1)) | ((1<<(nr-1))-1); - - memcpy(&i915->state.Constant[2], p->constant, 4*sizeof(int)*(nr)); - i915->state.ConstantSize = 2 + (nr) * 4; - - if (0) { - GLuint i; - for (i = 0; i < nr; i++) { - fprintf(stderr, "const[%d]: %f %f %f %f\n", i, - p->constant[i][0], - p->constant[i][1], - p->constant[i][2], - p->constant[i][3]); - } - } - } - else { - I915_ACTIVESTATE( i915, I915_UPLOAD_CONSTANTS, 0 ); - } - - p->on_hardware = 1; -} diff --git a/src/mesa/drivers/dri/i915/i915_program.h b/src/mesa/drivers/dri/i915/i915_program.h deleted file mode 100644 index 8891a17785..0000000000 --- a/src/mesa/drivers/dri/i915/i915_program.h +++ /dev/null @@ -1,163 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef I915_PROGRAM_H -#define I915_PROGRAM_H - -#include "i915_context.h" -#include "i915_reg.h" - - - -/* Having zero and one in here makes the definition of swizzle a lot - * easier. - */ -#define UREG_TYPE_SHIFT 29 -#define UREG_NR_SHIFT 24 -#define UREG_CHANNEL_X_NEGATE_SHIFT 23 -#define UREG_CHANNEL_X_SHIFT 20 -#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 -#define UREG_CHANNEL_Y_SHIFT 16 -#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 -#define UREG_CHANNEL_Z_SHIFT 12 -#define UREG_CHANNEL_W_NEGATE_SHIFT 11 -#define UREG_CHANNEL_W_SHIFT 8 -#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 -#define UREG_CHANNEL_ZERO_SHIFT 4 -#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 -#define UREG_CHANNEL_ONE_SHIFT 0 - -#define UREG_BAD 0xffffffff /* not a valid ureg */ - -#define X SRC_X -#define Y SRC_Y -#define Z SRC_Z -#define W SRC_W -#define ZERO SRC_ZERO -#define ONE SRC_ONE - -/* Construct a ureg: - */ -#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ - ((nr) << UREG_NR_SHIFT) | \ - (X << UREG_CHANNEL_X_SHIFT) | \ - (Y << UREG_CHANNEL_Y_SHIFT) | \ - (Z << UREG_CHANNEL_Z_SHIFT) | \ - (W << UREG_CHANNEL_W_SHIFT) | \ - (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ - (ONE << UREG_CHANNEL_ONE_SHIFT)) - -#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) -#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) - -#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) -#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) - - - -#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 - -/* One neat thing about the UREG representation: - */ -static __inline int swizzle( int reg, int x, int y, int z, int w ) -{ - return ((reg & ~UREG_XYZW_CHANNEL_MASK) | - CHANNEL_SRC( GET_CHANNEL_SRC( reg, x ), 0 ) | - CHANNEL_SRC( GET_CHANNEL_SRC( reg, y ), 1 ) | - CHANNEL_SRC( GET_CHANNEL_SRC( reg, z ), 2 ) | - CHANNEL_SRC( GET_CHANNEL_SRC( reg, w ), 3 )); -} - -/* Another neat thing about the UREG representation: - */ -static __inline int negate( int reg, int x, int y, int z, int w ) -{ - return reg ^ (((x&1)<= 0.0) ? src1 : src2 */ -#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ -#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ -#define A0_FLR (0x10<<24) /* dst = floor(src0) */ -#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ -#define A0_TRC (0x12<<24) /* dst = int(src0) */ -#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ -#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ -#define A0_DEST_SATURATE (1<<22) -#define A0_DEST_TYPE_SHIFT 19 -/* Allow: R, OC, OD, U */ -#define A0_DEST_NR_SHIFT 14 -/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ -#define A0_DEST_CHANNEL_X (1<<10) -#define A0_DEST_CHANNEL_Y (2<<10) -#define A0_DEST_CHANNEL_Z (4<<10) -#define A0_DEST_CHANNEL_W (8<<10) -#define A0_DEST_CHANNEL_ALL (0xf<<10) -#define A0_DEST_CHANNEL_SHIFT 10 -#define A0_SRC0_TYPE_SHIFT 7 -#define A0_SRC0_NR_SHIFT 2 - -#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) -#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) - - -#define SRC_X 0 -#define SRC_Y 1 -#define SRC_Z 2 -#define SRC_W 3 -#define SRC_ZERO 4 -#define SRC_ONE 5 - -#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) -#define A1_SRC0_CHANNEL_X_SHIFT 28 -#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) -#define A1_SRC0_CHANNEL_Y_SHIFT 24 -#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) -#define A1_SRC0_CHANNEL_Z_SHIFT 20 -#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) -#define A1_SRC0_CHANNEL_W_SHIFT 16 -#define A1_SRC1_TYPE_SHIFT 13 -#define A1_SRC1_NR_SHIFT 8 -#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) -#define A1_SRC1_CHANNEL_X_SHIFT 4 -#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) -#define A1_SRC1_CHANNEL_Y_SHIFT 0 - -#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) -#define A2_SRC1_CHANNEL_Z_SHIFT 28 -#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) -#define A2_SRC1_CHANNEL_W_SHIFT 24 -#define A2_SRC2_TYPE_SHIFT 21 -#define A2_SRC2_NR_SHIFT 16 -#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) -#define A2_SRC2_CHANNEL_X_SHIFT 12 -#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) -#define A2_SRC2_CHANNEL_Y_SHIFT 8 -#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) -#define A2_SRC2_CHANNEL_Z_SHIFT 4 -#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) -#define A2_SRC2_CHANNEL_W_SHIFT 0 - - - -/* Texture instructions */ -#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared - * sampler and address, and output - * filtered texel data to destination - * register */ -#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a - * perspective divide of the texture - * coordinate .xyz values by .w before - * sampling. */ -#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the - * computed LOD by w. Only S4.6 two's - * comp is used. This implies that a - * float to fixed conversion is - * done. */ -#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling - * operation. Simply kills the pixel - * if any channel of the address - * register is < 0.0. */ -#define T0_DEST_TYPE_SHIFT 19 -/* Allow: R, OC, OD, U */ -/* Note: U (unpreserved) regs do not retain their values between - * phases (cannot be used for feedback) - * - * Note: oC and OD registers can only be used as the destination of a - * texture instruction once per phase (this is an implementation - * restriction). - */ -#define T0_DEST_NR_SHIFT 14 -/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ -#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ -#define T0_SAMPLER_NR_MASK (0xf<<0) - -#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ -/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ -#define T1_ADDRESS_REG_NR_SHIFT 17 -#define T2_MBZ 0 - -/* Declaration instructions */ -#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) - * register or an s (sampler) - * register. */ -#define D0_SAMPLE_TYPE_SHIFT 22 -#define D0_SAMPLE_TYPE_2D (0x0<<22) -#define D0_SAMPLE_TYPE_CUBE (0x1<<22) -#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) -#define D0_SAMPLE_TYPE_MASK (0x3<<22) - -#define D0_TYPE_SHIFT 19 -/* Allow: T, S */ -#define D0_NR_SHIFT 14 -/* Allow T: 0..10, S: 0..15 */ -#define D0_CHANNEL_X (1<<10) -#define D0_CHANNEL_Y (2<<10) -#define D0_CHANNEL_Z (4<<10) -#define D0_CHANNEL_W (8<<10) -#define D0_CHANNEL_ALL (0xf<<10) -#define D0_CHANNEL_NONE (0<<10) - -#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) -#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) - -/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse - * or specular declarations. - * - * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) - * - * Must be zero for S (sampler) dcls - */ -#define D1_MBZ 0 -#define D2_MBZ 0 - - - -/* p207 */ -#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) - -#define MS1_MAPMASK_SHIFT 0 -#define MS1_MAPMASK_MASK (0x8fff<<0) - -#define MS2_UNTRUSTED_SURFACE (1<<31) -#define MS2_ADDRESS_MASK 0xfffffffc -#define MS2_VERTICAL_LINE_STRIDE (1<<1) -#define MS2_VERTICAL_OFFSET (1<<1) - -#define MS3_HEIGHT_SHIFT 21 -#define MS3_WIDTH_SHIFT 10 -#define MS3_PALETTE_SELECT (1<<9) -#define MS3_MAPSURF_FORMAT_SHIFT 7 -#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) -#define MAPSURF_8BIT (1<<7) -#define MAPSURF_16BIT (2<<7) -#define MAPSURF_32BIT (3<<7) -#define MAPSURF_422 (5<<7) -#define MAPSURF_COMPRESSED (6<<7) -#define MAPSURF_4BIT_INDEXED (7<<7) -#define MS3_MT_FORMAT_MASK (0x7 << 3) -#define MS3_MT_FORMAT_SHIFT 3 -#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ -#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ -#define MT_8BIT_L8 (1<<3) -#define MT_8BIT_A8 (4<<3) -#define MT_8BIT_MONO8 (5<<3) -#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ -#define MT_16BIT_ARGB1555 (1<<3) -#define MT_16BIT_ARGB4444 (2<<3) -#define MT_16BIT_AY88 (3<<3) -#define MT_16BIT_88DVDU (5<<3) -#define MT_16BIT_BUMP_655LDVDU (6<<3) -#define MT_16BIT_I16 (7<<3) -#define MT_16BIT_L16 (8<<3) -#define MT_16BIT_A16 (9<<3) -#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ -#define MT_32BIT_ABGR8888 (1<<3) -#define MT_32BIT_XRGB8888 (2<<3) -#define MT_32BIT_XBGR8888 (3<<3) -#define MT_32BIT_QWVU8888 (4<<3) -#define MT_32BIT_AXVU8888 (5<<3) -#define MT_32BIT_LXVU8888 (6<<3) -#define MT_32BIT_XLVU8888 (7<<3) -#define MT_32BIT_ARGB2101010 (8<<3) -#define MT_32BIT_ABGR2101010 (9<<3) -#define MT_32BIT_AWVU2101010 (0xA<<3) -#define MT_32BIT_GR1616 (0xB<<3) -#define MT_32BIT_VU1616 (0xC<<3) -#define MT_32BIT_xI824 (0xD<<3) -#define MT_32BIT_xA824 (0xE<<3) -#define MT_32BIT_xL824 (0xF<<3) -#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ -#define MT_422_YCRCB_NORMAL (1<<3) -#define MT_422_YCRCB_SWAPUV (2<<3) -#define MT_422_YCRCB_SWAPUVY (3<<3) -#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ -#define MT_COMPRESS_DXT2_3 (1<<3) -#define MT_COMPRESS_DXT4_5 (2<<3) -#define MT_COMPRESS_FXT1 (3<<3) -#define MT_COMPRESS_DXT1_RGB (4<<3) -#define MS3_USE_FENCE_REGS (1<<2) -#define MS3_TILED_SURFACE (1<<1) -#define MS3_TILE_WALK (1<<0) - -#define MS4_PITCH_SHIFT 21 -#define MS4_CUBE_FACE_ENA_NEGX (1<<20) -#define MS4_CUBE_FACE_ENA_POSX (1<<19) -#define MS4_CUBE_FACE_ENA_NEGY (1<<18) -#define MS4_CUBE_FACE_ENA_POSY (1<<17) -#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) -#define MS4_CUBE_FACE_ENA_POSZ (1<<15) -#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) -#define MS4_MAX_LOD_SHIFT 9 -#define MS4_MAX_LOD_MASK (0x3f<<9) -#define MS4_MIP_LAYOUT_LEGACY (0<<8) -#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) -#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) -#define MS4_VOLUME_DEPTH_SHIFT 0 -#define MS4_VOLUME_DEPTH_MASK (0xff<<0) - -/* p244 */ -#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) - -#define SS1_MAPMASK_SHIFT 0 -#define SS1_MAPMASK_MASK (0x8fff<<0) - -#define SS2_REVERSE_GAMMA_ENABLE (1<<31) -#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) -#define SS2_COLORSPACE_CONVERSION (1<<29) -#define SS2_CHROMAKEY_SHIFT 27 -#define SS2_BASE_MIP_LEVEL_SHIFT 22 -#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) -#define SS2_MIP_FILTER_SHIFT 20 -#define SS2_MIP_FILTER_MASK (0x3<<20) -#define MIPFILTER_NONE 0 -#define MIPFILTER_NEAREST 1 -#define MIPFILTER_LINEAR 3 -#define SS2_MAG_FILTER_SHIFT 17 -#define SS2_MAG_FILTER_MASK (0x7<<17) -#define FILTER_NEAREST 0 -#define FILTER_LINEAR 1 -#define FILTER_ANISOTROPIC 2 -#define FILTER_4X4_1 3 -#define FILTER_4X4_2 4 -#define FILTER_4X4_FLAT 5 -#define FILTER_6X5_MONO 6 /* XXX - check */ -#define SS2_MIN_FILTER_SHIFT 14 -#define SS2_MIN_FILTER_MASK (0x7<<14) -#define SS2_LOD_BIAS_SHIFT 5 -#define SS2_LOD_BIAS_ONE (0x10<<5) -#define SS2_LOD_BIAS_MASK (0x1ff<<5) -/* Shadow requires: - * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format - * FILTER_4X4_x MIN and MAG filters - */ -#define SS2_SHADOW_ENABLE (1<<4) -#define SS2_MAX_ANISO_MASK (1<<3) -#define SS2_MAX_ANISO_2 (0<<3) -#define SS2_MAX_ANISO_4 (1<<3) -#define SS2_SHADOW_FUNC_SHIFT 0 -#define SS2_SHADOW_FUNC_MASK (0x7<<0) -/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ - -#define SS3_MIN_LOD_SHIFT 24 -#define SS3_MIN_LOD_ONE (0x10<<24) -#define SS3_MIN_LOD_MASK (0xff<<24) -#define SS3_KILL_PIXEL_ENABLE (1<<17) -#define SS3_TCX_ADDR_MODE_SHIFT 12 -#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) -#define TEXCOORDMODE_WRAP 0 -#define TEXCOORDMODE_MIRROR 1 -#define TEXCOORDMODE_CLAMP_EDGE 2 -#define TEXCOORDMODE_CUBE 3 -#define TEXCOORDMODE_CLAMP_BORDER 4 -#define TEXCOORDMODE_MIRROR_ONCE 5 -#define SS3_TCY_ADDR_MODE_SHIFT 9 -#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) -#define SS3_TCZ_ADDR_MODE_SHIFT 6 -#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) -#define SS3_NORMALIZED_COORDS (1<<5) -#define SS3_TEXTUREMAP_INDEX_SHIFT 1 -#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) -#define SS3_DEINTERLACER_ENABLE (1<<0) - -#define SS4_BORDER_COLOR_MASK (~0) - -/* 3DSTATE_SPAN_STIPPLE, p258 - */ -#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define ST1_ENABLE (1<<16) -#define ST1_MASK (0xffff) - - -#define MI_FLUSH ((0<<29)|(4<<23)) -#define FLUSH_MAP_CACHE (1<<0) -#define FLUSH_RENDER_CACHE (1<<1) - - -#endif diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c deleted file mode 100644 index 1c4ec74755..0000000000 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ /dev/null @@ -1,970 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" -#include "tnl/tnl.h" -#include "tnl/t_context.h" - -#include "texmem.h" - -#include "drivers/common/driverfuncs.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" - -#include "i915_context.h" -#include "i915_reg.h" - - - -static void -i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, - GLuint mask) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func( func ); - - mask = mask & 0xff; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(func), ref, mask); - - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(mask)); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | - (test << S5_STENCIL_TEST_FUNC_SHIFT)); -} - -static void -i915StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); - - mask = mask & 0xff; - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(mask)); -} - - -static void -i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, - GLenum zpass) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - int fop = intel_translate_stencil_op(fail); - int dfop = intel_translate_stencil_op(zfail); - int dpop = intel_translate_stencil_op(zpass); - - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(fail), - _mesa_lookup_enum_by_nr(zfail), - _mesa_lookup_enum_by_nr(zpass)); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | - (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT)); -} - -static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func( func ); - GLubyte refByte; - - UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | - S6_ALPHA_REF_MASK); - i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | - (((GLuint)refByte) << S6_ALPHA_REF_SHIFT)); -} - -/* This function makes sure that the proper enables are - * set for LogicOp, Independant Alpha Blend, and Blending. - * It needs to be called from numerous places where we - * could change the LogicOp or Independant Alpha Blend without subsequent - * calls to glEnable. - */ -static void i915EvalLogicOpBlendState(GLcontext *ctx) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (RGBA_LOGICOP_ENABLED(ctx)) { - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; - } else { - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; - - if (ctx->Color.BlendEnabled) { - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; - } else { - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; - } - } -} - -static void i915BlendColor(GLcontext *ctx, const GLfloat color[4]) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - GLubyte r, g, b, a; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b; -} - - -#define DST_BLND_FACT(f) ((f)<state.Ctx[I915_CTXREG_IAB] & - ~(IAB_SRC_FACTOR_MASK | - IAB_DST_FACTOR_MASK | - (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | - IAB_ENABLE)); - - GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & - ~(S6_CBUF_SRC_BLEND_FACT_MASK | - S6_CBUF_DST_BLEND_FACT_MASK | - S6_CBUF_BLEND_FUNC_MASK)); - - GLuint eqRGB = ctx->Color.BlendEquationRGB; - GLuint eqA = ctx->Color.BlendEquationA; - GLuint srcRGB = ctx->Color.BlendSrcRGB; - GLuint dstRGB = ctx->Color.BlendDstRGB; - GLuint srcA = ctx->Color.BlendSrcA; - GLuint dstA = ctx->Color.BlendDstA; - - if (eqRGB == GL_MIN || eqRGB == GL_MAX) { - srcRGB = dstRGB = GL_ONE; - } - - if (eqA == GL_MIN || eqA == GL_MAX) { - srcA = dstA = GL_ONE; - } - - lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); - lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); - lis6 |= translate_blend_equation( eqRGB ) << S6_CBUF_BLEND_FUNC_SHIFT; - - iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); - iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); - iab |= translate_blend_equation( eqA ) << IAB_FUNC_SHIFT; - - if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) - iab |= IAB_ENABLE; - - if (iab != i915->state.Ctx[I915_CTXREG_IAB] || - lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_IAB] = iab; - i915->state.Ctx[I915_CTXREG_LIS6] = lis6; - } - - /* This will catch a logicop blend equation */ - i915EvalLogicOpBlendState(ctx); -} - - -static void i915BlendFuncSeparate(GLcontext *ctx, GLenum srcRGB, - GLenum dstRGB, GLenum srcA, - GLenum dstA ) -{ - i915UpdateBlendState( ctx ); -} - - -static void i915BlendEquationSeparate(GLcontext *ctx, GLenum eqRGB, - GLenum eqA) -{ - i915UpdateBlendState( ctx ); -} - - -static void i915DepthFunc(GLcontext *ctx, GLenum func) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func( func ); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; -} - -static void i915DepthMask(GLcontext *ctx, GLboolean flag) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (flag && ctx->Depth.Test) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; -} - -/* ============================================================= - * Polygon stipple - * - * The i915 supports a 4x4 stipple natively, GL wants 32x32. - * Fortunately stipple is usually a repeating pattern. - */ -static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - const GLubyte *m = mask; - GLubyte p[4]; - int i,j,k; - int active = (ctx->Polygon.StippleFlag && - i915->intel.reduced_primitive == GL_TRIANGLES); - GLuint newMask; - - if (active) { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; - } - - p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; - p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; - p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; - p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; - - for (k = 0 ; k < 8 ; k++) - for (j = 3 ; j >= 0; j--) - for (i = 0 ; i < 4 ; i++, m++) - if (*m != p[j]) { - i915->intel.hw_stipple = 0; - return; - } - - newMask = (((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | - ((p[3] & 0xf) << 12)); - - - if (newMask == 0xffff || newMask == 0x0) { - /* this is needed to make conform pass */ - i915->intel.hw_stipple = 0; - return; - } - - i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; - i915->state.Stipple[I915_STPREG_ST1] |= newMask; - i915->intel.hw_stipple = 1; - - if (active) - i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; -} - - -/* ============================================================= - * Hardware clipping - */ -static void i915Scissor(GLcontext *ctx, GLint x, GLint y, - GLsizei w, GLsizei h) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - intelScreenPrivate *screen = i915->intel.intelScreen; - int x1, y1, x2, y2; - - if (!i915->intel.driDrawable) - return; - - x1 = x; - y1 = i915->intel.driDrawable->h - (y + h); - x2 = x + w - 1; - y2 = y1 + h - 1; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__, - x, y, w, h); - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 < 0) x2 = 0; - if (y2 < 0) y2 = 0; - - if (x2 >= screen->width) x2 = screen->width-1; - if (y2 >= screen->height) y2 = screen->height-1; - if (x1 >= screen->width) x1 = screen->width-1; - if (y1 >= screen->height) y1 = screen->height-1; - - - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); - i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); -} - -static void i915LogicOp(GLcontext *ctx, GLenum opcode) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - int tmp = intel_translate_logic_op(opcode); - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); -} - - - -static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - GLuint mode; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (!ctx->Polygon.CullFlag) { - mode = S4_CULLMODE_NONE; - } - else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { - mode = S4_CULLMODE_CW; - - if (ctx->Polygon.CullFaceMode == GL_FRONT) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - if (ctx->Polygon.FrontFace != GL_CCW) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - } - else { - mode = S4_CULLMODE_BOTH; - } - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; - i915->state.Ctx[I915_CTXREG_LIS4] |= mode; -} - -static void i915LineWidth( GLcontext *ctx, GLfloat widthf ) -{ - i915ContextPtr i915 = I915_CONTEXT( ctx ); - int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; - int width; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - width = (int)(widthf * 2); - CLAMP_SELF(width, 1, 0xf); - lis4 |= width << S4_LINE_WIDTH_SHIFT; - - if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] = lis4; - } -} - -static void i915PointSize(GLcontext *ctx, GLfloat size) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; - GLint point_size = (int)size; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - CLAMP_SELF(point_size, 1, 255); - lis4 |= point_size << S4_POINT_WIDTH_SHIFT; - - if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] = lis4; - } -} - - -/* ============================================================= - * Color masks - */ - -static void i915ColorMask(GLcontext *ctx, - GLboolean r, GLboolean g, - GLboolean b, GLboolean a) -{ - i915ContextPtr i915 = I915_CONTEXT( ctx ); - GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; - - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); - - if (!r) tmp |= S5_WRITEDISABLE_RED; - if (!g) tmp |= S5_WRITEDISABLE_GREEN; - if (!b) tmp |= S5_WRITEDISABLE_BLUE; - if (!a) tmp |= S5_WRITEDISABLE_ALPHA; - - if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS5] = tmp; - } -} - -static void update_specular( GLcontext *ctx ) -{ - /* A hack to trigger the rebuild of the fragment program. - */ - INTEL_CONTEXT(ctx)->NewGLState |= _NEW_TEXTURE; - I915_CONTEXT(ctx)->tex_program.translated = 0; -} - -static void i915LightModelfv(GLcontext *ctx, GLenum pname, - const GLfloat *param) -{ - if (INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - update_specular( ctx ); - } -} - -static void i915ShadeModel(GLcontext *ctx, GLenum mode) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (mode == GL_SMOOTH) { - i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); - } else { - i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); - } -} - -/* ============================================================= - * Fog - */ -void i915_update_fog( GLcontext *ctx ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - GLenum mode; - GLboolean enabled; - GLboolean try_pixel_fog; - - if (ctx->FragmentProgram._Active) { - /* Pull in static fog state from program */ - - mode = ctx->FragmentProgram._Current->FogOption; - enabled = (mode != GL_NONE); - try_pixel_fog = 0; - } - else { - enabled = ctx->Fog.Enabled; - mode = ctx->Fog.Mode; -#if 0 - /* XXX - DISABLED -- Need ortho fallback */ - try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT - &&ctx->Hint.Fog == GL_NICEST); -#else - try_pixel_fog = 0; -#endif - } - - if (!enabled) { - i915->vertex_fog = I915_FOG_NONE; - } - else if (try_pixel_fog) { - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; - i915->vertex_fog = I915_FOG_PIXEL; - - switch (mode) { - case GL_LINEAR: - if (ctx->Fog.End <= ctx->Fog.Start) { - /* XXX - this won't work with fragment programs. Need to - * either fallback or append fog instructions to end of - * program in the case of linear fog. - */ - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; - i915->vertex_fog = I915_FOG_VERTEX; - } - else { - GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); - GLfloat c1 = ctx->Fog.End * c2; - - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; - i915->state.Fog[I915_FOGREG_MODE1] |= - ((GLuint)(c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; - - if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE2] - = (GLuint)(c2 * FMC2_C2_ONE); - } - else { - fi_type fi; - fi.f = c2; - i915->state.Fog[I915_FOGREG_MODE2] = fi.i; - } - } - break; - case GL_EXP: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; - break; - case GL_EXP2: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; - break; - default: - break; - } - } - else /* if (i915->vertex_fog != I915_FOG_VERTEX) */ { - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; - i915->vertex_fog = I915_FOG_VERTEX; - } - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); - if (enabled) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; - - /* Always enable pixel fog. Vertex fog using fog coord will conflict - * with fog code appended onto fragment program. - */ - _tnl_allow_vertex_fog( ctx, 0 ); - _tnl_allow_pixel_fog( ctx, 1 ); -} - -static void -i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - - switch (pname) { - case GL_FOG_COORDINATE_SOURCE_EXT: - case GL_FOG_MODE: - case GL_FOG_START: - case GL_FOG_END: - break; - - case GL_FOG_DENSITY: - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - - if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE3] - = (GLuint)(ctx->Fog.Density * FMC3_D_ONE); - } - else { - union { float f; int i; } fi; - fi.f = ctx->Fog.Density; - i915->state.Fog[I915_FOGREG_MODE3] = fi.i; - } - break; - - case GL_FOG_COLOR: - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_COLOR] = - (_3DSTATE_FOG_COLOR_CMD | - ((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | - ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | - ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); - break; - - default: - break; - } -} - -static void i915Hint(GLcontext *ctx, GLenum target, GLenum state) -{ - switch (target) { - case GL_FOG_HINT: - break; - default: - break; - } -} - -/* ============================================================= - */ - -static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - - switch(cap) { - case GL_TEXTURE_2D: - break; - - case GL_LIGHTING: - case GL_COLOR_SUM: - update_specular( ctx ); - break; - - case GL_ALPHA_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; - break; - - case GL_BLEND: - i915EvalLogicOpBlendState(ctx); - break; - - case GL_COLOR_LOGIC_OP: - i915EvalLogicOpBlendState(ctx); - - /* Logicop doesn't seem to work at 16bpp: - */ - if (i915->intel.intelScreen->cpp == 2) - FALLBACK( &i915->intel, I915_FALLBACK_LOGICOP, state ); - break; - - case GL_FRAGMENT_PROGRAM_ARB: - break; - - case GL_DITHER: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; - break; - - case GL_DEPTH_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; - - i915DepthMask( ctx, ctx->Depth.Mask ); - break; - - case GL_SCISSOR_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - if (state) - i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - ENABLE_SCISSOR_RECT); - else - i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - break; - - case GL_LINE_SMOOTH: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; - break; - - case GL_FOG: - break; - - case GL_CULL_FACE: - i915CullFaceFrontFace(ctx, 0); - break; - - case GL_STENCIL_TEST: - if (i915->intel.hw_stencil) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - } else { - FALLBACK( &i915->intel, I915_FALLBACK_STENCIL, state ); - } - break; - - case GL_POLYGON_STIPPLE: - /* The stipple command worked on my 855GM box, but not my 845G. - * I'll do more testing later to find out exactly which hardware - * supports it. Disabled for now. - */ - if (i915->intel.hw_stipple && - i915->intel.reduced_primitive == GL_TRIANGLES) - { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - if (state) - i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; - else - i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; - } - break; - - case GL_POLYGON_SMOOTH: - FALLBACK( &i915->intel, I915_FALLBACK_POLYGON_SMOOTH, state ); - break; - - case GL_POINT_SMOOTH: - FALLBACK( &i915->intel, I915_FALLBACK_POINT_SMOOTH, state ); - break; - - default: - ; - } -} - - -static void i915_init_packets( i915ContextPtr i915 ) -{ - intelScreenPrivate *screen = i915->intel.intelScreen; - - /* Zero all state */ - memset(&i915->state, 0, sizeof(i915->state)); - - - { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - /* Probably don't want to upload all this stuff every time one - * piece changes. - */ - i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(2) | - I1_LOAD_S(4) | - I1_LOAD_S(5) | - I1_LOAD_S(6) | - (3)); - i915->state.Ctx[I915_CTXREG_LIS2] = 0; - i915->state.Ctx[I915_CTXREG_LIS4] = 0; - i915->state.Ctx[I915_CTXREG_LIS5] = 0; - - if (screen->cpp == 2) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; - - - i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | - (2 << S6_TRISTRIP_PV_SHIFT)); - - i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff) | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(0xff)); - - - i915->state.Ctx[I915_CTXREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | - IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | - IAB_MODIFY_SRC_FACTOR | - IAB_MODIFY_DST_FACTOR); - - i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; - - } - - { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; - } - - - { - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; - i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | - FMC1_FOGFUNC_VERTEX | - FMC1_FOGINDEX_MODIFY_ENABLE | - FMC1_FOGINDEX_W | - FMC1_C1_C2_MODIFY_ENABLE | - FMC1_DENSITY_MODIFY_ENABLE); - i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; - } - - - { - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - /* color buffer offset/stride */ - i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i915->state.Buffer[I915_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - /*i915->state.Buffer[I915_DESTREG_CBUFADDR2] is the offset */ - - - /* depth/Z buffer offset/stride */ - i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i915->state.Buffer[I915_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_DBUFADDR2] = screen->depth.offset; - - - i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; - - /* color/depth pixel format */ - switch (screen->fbFormat) { - case DV_PF_555: - case DV_PF_565: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - DITHER_FULL_ALWAYS | - screen->fbFormat | - DEPTH_FRMT_16_FIXED); - break; - case DV_PF_8888: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - screen->fbFormat | - DEPTH_FRMT_24_FIXED_8_OTHER); - break; - } - - /* scissor */ - i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; - i915->state.Buffer[I915_DESTREG_SR1] = 0; - i915->state.Buffer[I915_DESTREG_SR2] = 0; - } - - - /* These will be emitted every at the head of every buffer, unless - * we get hardware contexts working. - */ - i915->state.active = (I915_UPLOAD_PROGRAM | - I915_UPLOAD_STIPPLE | - I915_UPLOAD_CTX | - I915_UPLOAD_BUFFERS | - I915_UPLOAD_INVARIENT); -} - -void i915InitStateFunctions( struct dd_function_table *functions ) -{ - functions->AlphaFunc = i915AlphaFunc; - functions->BlendColor = i915BlendColor; - functions->BlendEquationSeparate = i915BlendEquationSeparate; - functions->BlendFuncSeparate = i915BlendFuncSeparate; - functions->ColorMask = i915ColorMask; - functions->CullFace = i915CullFaceFrontFace; - functions->DepthFunc = i915DepthFunc; - functions->DepthMask = i915DepthMask; - functions->Enable = i915Enable; - functions->Fogfv = i915Fogfv; - functions->FrontFace = i915CullFaceFrontFace; - functions->Hint = i915Hint; - functions->LightModelfv = i915LightModelfv; - functions->LineWidth = i915LineWidth; - functions->LogicOpcode = i915LogicOp; - functions->PointSize = i915PointSize; - functions->PolygonStipple = i915PolygonStipple; - functions->Scissor = i915Scissor; - functions->ShadeModel = i915ShadeModel; - functions->StencilFuncSeparate = i915StencilFuncSeparate; - functions->StencilMaskSeparate = i915StencilMaskSeparate; - functions->StencilOpSeparate = i915StencilOpSeparate; -} - - -void i915InitState( i915ContextPtr i915 ) -{ - GLcontext *ctx = &i915->intel.ctx; - - i915_init_packets( i915 ); - - _mesa_init_driver_state(ctx); - - memcpy( &i915->initial, &i915->state, sizeof(i915->state) ); - i915->current = &i915->state; -} diff --git a/src/mesa/drivers/dri/i915/i915_tex.c b/src/mesa/drivers/dri/i915/i915_tex.c deleted file mode 100644 index d9609d3193..0000000000 --- a/src/mesa/drivers/dri/i915/i915_tex.c +++ /dev/null @@ -1,187 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "simple_list.h" -#include "enums.h" -#include "image.h" -#include "texstore.h" -#include "texformat.h" -#include "texmem.h" -#include "swrast/swrast.h" - -#include "mm.h" - -#include "intel_ioctl.h" - -#include "i915_context.h" -#include "i915_reg.h" - - - - - - -/** - * Allocate space for and load the mesa images into the texture memory block. - * This will happen before drawing with a new texture, or drawing with a - * texture after it was swapped out or teximaged again. - */ - -intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj ) -{ - i915TextureObjectPtr t = CALLOC_STRUCT( i915_texture_object ); - if ( !t ) - return NULL; - - texObj->DriverData = t; - t->intel.base.tObj = texObj; - t->intel.dirty = I915_UPLOAD_TEX_ALL; - make_empty_list( &t->intel.base ); - return &t->intel; -} - - -static void i915TexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, - GLenum pname, const GLfloat *params ) -{ - i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - case GL_TEXTURE_WRAP_R: - case GL_TEXTURE_BORDER_COLOR: - t->intel.dirty = I915_UPLOAD_TEX_ALL; - break; - - case GL_TEXTURE_COMPARE_MODE: - t->intel.dirty = I915_UPLOAD_TEX_ALL; - break; - case GL_TEXTURE_COMPARE_FUNC: - t->intel.dirty = I915_UPLOAD_TEX_ALL; - break; - - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - /* The i915 and its successors can do a lot of this without - * reloading the textures. A project for someone? - */ - intelFlush( ctx ); - driSwapOutTextureObject( (driTextureObject *) t ); - t->intel.dirty = I915_UPLOAD_TEX_ALL; - break; - - default: - return; - } -} - - -static void i915TexEnv( GLcontext *ctx, GLenum target, - GLenum pname, const GLfloat *param ) -{ - i915ContextPtr i915 = I915_CONTEXT( ctx ); - GLuint unit = ctx->Texture.CurrentUnit; - - switch (pname) { - case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ - case GL_TEXTURE_ENV_MODE: - case GL_COMBINE_RGB: - case GL_COMBINE_ALPHA: - case GL_SOURCE0_RGB: - case GL_SOURCE1_RGB: - case GL_SOURCE2_RGB: - case GL_SOURCE0_ALPHA: - case GL_SOURCE1_ALPHA: - case GL_SOURCE2_ALPHA: - case GL_OPERAND0_RGB: - case GL_OPERAND1_RGB: - case GL_OPERAND2_RGB: - case GL_OPERAND0_ALPHA: - case GL_OPERAND1_ALPHA: - case GL_OPERAND2_ALPHA: - case GL_RGB_SCALE: - case GL_ALPHA_SCALE: - i915->tex_program.translated = 0; - break; - - case GL_TEXTURE_LOD_BIAS: { - int b = (int) ((*param) * 16.0); - if (b > 255) b = 255; - if (b < -256) b = -256; - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->state.Tex[unit][I915_TEXREG_SS2] &= ~SS2_LOD_BIAS_MASK; - i915->state.Tex[unit][I915_TEXREG_SS2] |= - ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); - break; - } - - default: - break; - } -} - - -static void i915BindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj ) -{ - i915TextureObjectPtr tex; - - if (!texObj->DriverData) - i915AllocTexObj( texObj ); - - tex = (i915TextureObjectPtr)texObj->DriverData; - - if (tex->lastTarget != texObj->Target) { - tex->intel.dirty = I915_UPLOAD_TEX_ALL; - tex->lastTarget = texObj->Target; - } - - /* Need this if image format changes between bound textures. - * Could try and shortcircuit by checking for differences in - * state between incoming and outgoing textures: - */ - I915_CONTEXT(ctx)->tex_program.translated = 0; -} - - - -void i915InitTextureFuncs( struct dd_function_table *functions ) -{ - functions->BindTexture = i915BindTexture; - functions->TexEnv = i915TexEnv; - functions->TexParameter = i915TexParameter; -} diff --git a/src/mesa/drivers/dri/i915/i915_texprog.c b/src/mesa/drivers/dri/i915/i915_texprog.c deleted file mode 100644 index f6a8b0205a..0000000000 --- a/src/mesa/drivers/dri/i915/i915_texprog.c +++ /dev/null @@ -1,676 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include - -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "tnl/t_context.h" -#include "intel_batchbuffer.h" - -#include "i915_reg.h" -#include "i915_context.h" -#include "i915_program.h" - -static GLuint translate_tex_src_bit( struct i915_fragment_program *p, - GLubyte bit ) -{ - switch (bit) { - case TEXTURE_1D_BIT: return D0_SAMPLE_TYPE_2D; - case TEXTURE_2D_BIT: return D0_SAMPLE_TYPE_2D; - case TEXTURE_RECT_BIT: return D0_SAMPLE_TYPE_2D; - case TEXTURE_3D_BIT: return D0_SAMPLE_TYPE_VOLUME; - case TEXTURE_CUBE_BIT: return D0_SAMPLE_TYPE_CUBE; - default: i915_program_error(p, "TexSrcBit"); return 0; - } -} - -static GLuint get_source( struct i915_fragment_program *p, - GLenum src, GLuint unit ) -{ - switch (src) { - case GL_TEXTURE: - if (p->src_texture == UREG_BAD) { - - /* TODO: Use D0_CHANNEL_XY where possible. - */ - GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled); - GLuint sampler = i915_emit_decl(p, REG_TYPE_S, unit, dim); - GLuint texcoord = i915_emit_decl(p, REG_TYPE_T, unit, D0_CHANNEL_ALL); - GLuint tmp = i915_get_temp( p ); - GLuint op = T0_TEXLD; - - if (p->VB->TexCoordPtr[unit]->size == 4) - op = T0_TEXLDP; - - p->src_texture = i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, - sampler, texcoord, op ); - } - - return p->src_texture; - - /* Crossbar: */ - case GL_TEXTURE0: - case GL_TEXTURE1: - case GL_TEXTURE2: - case GL_TEXTURE3: - case GL_TEXTURE4: - case GL_TEXTURE5: - case GL_TEXTURE6: - case GL_TEXTURE7: { - return UREG_BAD; - } - - case GL_CONSTANT: - return i915_emit_const4fv( p, p->ctx->Texture.Unit[unit].EnvColor ); - case GL_PRIMARY_COLOR: - return i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); - case GL_PREVIOUS: - default: - i915_emit_decl(p, - GET_UREG_TYPE(p->src_previous), - GET_UREG_NR(p->src_previous), D0_CHANNEL_ALL); - return p->src_previous; - } -} - - -static GLuint emit_combine_source( struct i915_fragment_program *p, - GLuint mask, - GLuint unit, - GLenum source, - GLenum operand ) -{ - GLuint arg, src; - - src = get_source(p, source, unit); - - switch (operand) { - case GL_ONE_MINUS_SRC_COLOR: - /* Get unused tmp, - * Emit tmp = 1.0 + arg.-x-y-z-w - */ - arg = i915_get_temp( p ); - return i915_emit_arith( p, A0_ADD, arg, mask, 0, - swizzle(src, ONE, ONE, ONE, ONE ), - negate(src, 1,1,1,1), 0); - - case GL_SRC_ALPHA: - if (mask == A0_DEST_CHANNEL_W) - return src; - else - return swizzle( src, W, W, W, W ); - case GL_ONE_MINUS_SRC_ALPHA: - /* Get unused tmp, - * Emit tmp = 1.0 + arg.-w-w-w-w - */ - arg = i915_get_temp( p ); - return i915_emit_arith( p, A0_ADD, arg, mask, 0, - swizzle(src, ONE, ONE, ONE, ONE ), - negate( swizzle(src,W,W,W,W), 1,1,1,1), 0); - case GL_SRC_COLOR: - default: - return src; - } -} - - - -static int nr_args( GLenum mode ) -{ - switch (mode) { - case GL_REPLACE: return 1; - case GL_MODULATE: return 2; - case GL_ADD: return 2; - case GL_ADD_SIGNED: return 2; - case GL_INTERPOLATE: return 3; - case GL_SUBTRACT: return 2; - case GL_DOT3_RGB_EXT: return 2; - case GL_DOT3_RGBA_EXT: return 2; - case GL_DOT3_RGB: return 2; - case GL_DOT3_RGBA: return 2; - default: return 0; - } -} - - -static GLboolean args_match( struct gl_texture_unit *texUnit ) -{ - int i, nr = nr_args(texUnit->Combine.ModeRGB); - - for (i = 0 ; i < nr ; i++) { - if (texUnit->Combine.SourceA[i] != texUnit->Combine.SourceRGB[i]) - return GL_FALSE; - - switch(texUnit->Combine.OperandA[i]) { - case GL_SRC_ALPHA: - switch(texUnit->Combine.OperandRGB[i]) { - case GL_SRC_COLOR: - case GL_SRC_ALPHA: - break; - default: - return GL_FALSE; - } - break; - case GL_ONE_MINUS_SRC_ALPHA: - switch(texUnit->Combine.OperandRGB[i]) { - case GL_ONE_MINUS_SRC_COLOR: - case GL_ONE_MINUS_SRC_ALPHA: - break; - default: - return GL_FALSE; - } - break; - default: - return GL_FALSE; /* impossible */ - } - } - - return GL_TRUE; -} - - -static GLuint emit_combine( struct i915_fragment_program *p, - GLuint dest, - GLuint mask, - GLuint saturate, - GLuint unit, - GLenum mode, - const GLenum *source, - const GLenum *operand) -{ - int tmp, src[3], nr = nr_args(mode); - int i; - - for (i = 0; i < nr; i++) - src[i] = emit_combine_source( p, mask, unit, source[i], operand[i] ); - - switch (mode) { - case GL_REPLACE: - if (mask == A0_DEST_CHANNEL_ALL && !saturate) - return src[0]; - else - return i915_emit_arith( p, A0_MOV, dest, mask, saturate, src[0], 0, 0 ); - case GL_MODULATE: - return i915_emit_arith( p, A0_MUL, dest, mask, saturate, - src[0], src[1], 0 ); - case GL_ADD: - return i915_emit_arith( p, A0_ADD, dest, mask, saturate, - src[0], src[1], 0 ); - case GL_ADD_SIGNED: - /* tmp = arg0 + arg1 - * result = tmp + -.5 - */ - tmp = i915_emit_const1f(p, .5); - tmp = negate(swizzle(tmp,X,X,X,X),1,1,1,1); - i915_emit_arith( p, A0_ADD, dest, mask, 0, src[0], src[1], 0 ); - i915_emit_arith( p, A0_ADD, dest, mask, saturate, dest, tmp, 0 ); - return dest; - case GL_INTERPOLATE: /* TWO INSTRUCTIONS */ - /* Arg0 * (Arg2) + Arg1 * (1-Arg2) - * - * Arg0*Arg2 + Arg1 - Arg1Arg2 - * - * tmp = Arg0*Arg2 + Arg1, - * result = (-Arg1)Arg2 + tmp - */ - tmp = i915_get_temp( p ); - i915_emit_arith( p, A0_MAD, tmp, mask, 0, src[0], src[2], src[1] ); - i915_emit_arith( p, A0_MAD, dest, mask, saturate, - negate(src[1], 1,1,1,1), src[2], tmp ); - return dest; - case GL_SUBTRACT: - /* negate src[1] */ - return i915_emit_arith( p, A0_ADD, dest, mask, saturate, src[0], - negate(src[1],1,1,1,1), 0 ); - - case GL_DOT3_RGBA: - case GL_DOT3_RGBA_EXT: - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGB: { - GLuint tmp0 = i915_get_temp( p ); - GLuint tmp1 = i915_get_temp( p ); - GLuint neg1 = negate(swizzle(i915_emit_const1f(p, 1),X,X,X,X), 1,1,1,1); - GLuint two = swizzle(i915_emit_const1f(p, 2),X,X,X,X); - i915_emit_arith( p, A0_MAD, tmp0, A0_DEST_CHANNEL_ALL, 0, - two, src[0], neg1); - if (src[0] == src[1]) - tmp1 = tmp0; - else - i915_emit_arith( p, A0_MAD, tmp1, A0_DEST_CHANNEL_ALL, 0, - two, src[1], neg1); - i915_emit_arith( p, A0_DP3, dest, mask, saturate, tmp0, tmp1, 0); - return dest; - } - - default: - return src[0]; - } -} - -static GLuint get_dest( struct i915_fragment_program *p, int unit ) -{ - if (p->ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) - return i915_get_temp( p ); - else if (unit != p->last_tex_stage) - return i915_get_temp( p ); - else - return UREG(REG_TYPE_OC, 0); -} - - - -static GLuint emit_texenv( struct i915_fragment_program *p, int unit ) -{ - struct gl_texture_unit *texUnit = &p->ctx->Texture.Unit[unit]; - GLenum envMode = texUnit->EnvMode; - struct gl_texture_object *tObj = texUnit->_Current; - GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; - GLuint saturate = unit < p->last_tex_stage ? A0_DEST_SATURATE : 0; - - switch(envMode) { - case GL_BLEND: { - const int cf = get_source(p, GL_PREVIOUS, unit); - const int cc = get_source(p, GL_CONSTANT, unit); - const int cs = get_source(p, GL_TEXTURE, unit); - const int out = get_dest(p, unit); - - if (format == GL_INTENSITY) { - /* cv = cf(1 - cs) + cc.cs - * cv = cf - cf.cs + cc.cs - */ - /* u[2] = MAD( -cf * cs + cf ) - * cv = MAD( cc * cs + u[2] ) - */ - - i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0, - negate(cf,1,1,1,1), cs, cf ); - - i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, - cc, cs, out ); - - return out; - } else { - /* cv = cf(1 - cs) + cc.cs - * cv = cf - cf.cs + cc.cs - * av = af.as - */ - /* u[2] = MAD( cf.-x-y-zw * cs.xyzw + cf.xyz0 ) - * oC = MAD( cc.xyz0 * cs.xyz0 + u[2].xyzw ) - */ - i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0, - negate(cf,1,1,1,0), - cs, - swizzle(cf,X,Y,Z,ZERO) ); - - - i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, - swizzle(cc,X,Y,Z,ZERO), - swizzle(cs,X,Y,Z,ZERO), - out ); - - return out; - } - } - - case GL_DECAL: { - if (format == GL_RGB || - format == GL_RGBA) { - int cf = get_source( p, GL_PREVIOUS, unit ); - int cs = get_source( p, GL_TEXTURE, unit ); - int out = get_dest(p, unit); - - /* cv = cf(1-as) + cs.as - * cv = cf.(-as) + cf + cs.as - * av = af - */ - - /* u[2] = mad( cf.xyzw * cs.-w-w-w1 + cf.xyz0 ) - * oc = mad( cs.xyz0 * cs.www0 + u[2].xyzw ) - */ - i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, 0, - cf, - negate(swizzle(cs,W,W,W,ONE),1,1,1,0), - swizzle(cf,X,Y,Z,ZERO) ); - - i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, - swizzle(cs,X,Y,Z,ZERO), - swizzle(cs,W,W,W,ZERO), - out ); - return out; - } - else { - return get_source( p, GL_PREVIOUS, unit ); - } - } - - case GL_REPLACE: { - const int cs = get_source( p, GL_TEXTURE, unit ); /* saturated */ - switch (format) { - case GL_ALPHA: { - const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */ - i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_XYZ, 0, cf, 0, 0 ); - return cs; - } - case GL_RGB: - case GL_LUMINANCE: { - const int cf = get_source( p, GL_PREVIOUS, unit ); /* saturated */ - i915_emit_arith( p, A0_MOV, cs, A0_DEST_CHANNEL_W, 0, cf, 0, 0 ); - return cs; - } - default: - return cs; - } - } - - case GL_MODULATE: { - const int cf = get_source( p, GL_PREVIOUS, unit ); - const int cs = get_source( p, GL_TEXTURE, unit ); - const int out = get_dest(p, unit); - switch (format) { - case GL_ALPHA: - i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate, - swizzle(cs, ONE, ONE, ONE, W), cf, 0 ); - break; - default: - i915_emit_arith( p, A0_MUL, out, A0_DEST_CHANNEL_ALL, saturate, - cs, cf, 0 ); - break; - } - return out; - } - case GL_ADD: { - int cf = get_source( p, GL_PREVIOUS, unit ); - int cs = get_source( p, GL_TEXTURE, unit ); - const int out = get_dest( p, unit ); - - if (format == GL_INTENSITY) { - /* output-color.rgba = add( incoming, u[1] ) - */ - i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, saturate, - cs, cf, 0 ); - return out; - } - else { - /* cv.xyz = cf.xyz + cs.xyz - * cv.w = cf.w * cs.w - * - * cv.xyzw = MAD( cf.111w * cs.xyzw + cf.xyz0 ) - */ - i915_emit_arith( p, A0_MAD, out, A0_DEST_CHANNEL_ALL, saturate, - swizzle(cf,ONE,ONE,ONE,W), - cs, - swizzle(cf,X,Y,Z,ZERO) ); - return out; - } - break; - } - case GL_COMBINE: { - GLuint rgb_shift, alpha_shift, out, shift; - GLuint dest = get_dest(p, unit); - - /* The EXT version of the DOT3 extension does not support the - * scale factor, but the ARB version (and the version in OpenGL - * 1.3) does. - */ - switch (texUnit->Combine.ModeRGB) { - case GL_DOT3_RGB_EXT: - alpha_shift = texUnit->Combine.ScaleShiftA; - rgb_shift = 0; - break; - - case GL_DOT3_RGBA_EXT: - alpha_shift = 0; - rgb_shift = 0; - break; - - default: - rgb_shift = texUnit->Combine.ScaleShiftRGB; - alpha_shift = texUnit->Combine.ScaleShiftA; - break; - } - - - /* Emit the RGB and A combine ops - */ - if (texUnit->Combine.ModeRGB == texUnit->Combine.ModeA && - args_match( texUnit )) { - out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate, - unit, - texUnit->Combine.ModeRGB, - texUnit->Combine.SourceRGB, - texUnit->Combine.OperandRGB ); - } - else if (texUnit->Combine.ModeRGB == GL_DOT3_RGBA_EXT || - texUnit->Combine.ModeRGB == GL_DOT3_RGBA) { - - out = emit_combine( p, dest, A0_DEST_CHANNEL_ALL, saturate, - unit, - texUnit->Combine.ModeRGB, - texUnit->Combine.SourceRGB, - texUnit->Combine.OperandRGB ); - } - else { - /* Need to do something to stop from re-emitting identical - * argument calculations here: - */ - out = emit_combine( p, dest, A0_DEST_CHANNEL_XYZ, saturate, - unit, - texUnit->Combine.ModeRGB, - texUnit->Combine.SourceRGB, - texUnit->Combine.OperandRGB ); - out = emit_combine( p, dest, A0_DEST_CHANNEL_W, saturate, - unit, - texUnit->Combine.ModeA, - texUnit->Combine.SourceA, - texUnit->Combine.OperandA ); - } - - /* Deal with the final shift: - */ - if (alpha_shift || rgb_shift) { - if (rgb_shift == alpha_shift) { - shift = i915_emit_const1f(p, 1<ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - /* Emit specular add. - */ - GLuint s = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_ALL); - i915_emit_arith( p, A0_ADD, out, A0_DEST_CHANNEL_ALL, 0, cf, - swizzle(s, X,Y,Z,ZERO), 0 ); - } - else if (cf != out) { - /* Will wind up in here if no texture enabled or a couple of - * other scenarios (GL_REPLACE for instance). - */ - i915_emit_arith( p, A0_MOV, out, A0_DEST_CHANNEL_ALL, 0, cf, 0, 0 ); - } -} - - -static void i915EmitTextureProgram( i915ContextPtr i915 ) -{ - GLcontext *ctx = &i915->intel.ctx; - struct i915_fragment_program *p = &i915->tex_program; - GLuint unit; - - if (0) fprintf(stderr, "%s\n", __FUNCTION__); - - i915_init_program( i915, p ); - - if (ctx->Texture._EnabledUnits) { - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - p->last_tex_stage = unit; - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - p->src_previous = emit_texenv( p, unit ); - p->src_texture = UREG_BAD; - p->temp_flag = 0xffff000; - p->temp_flag |= 1 << GET_UREG_NR(p->src_previous); - } - } - - emit_program_fini( p ); - - i915_fini_program( p ); - i915_upload_program( i915, p ); - - p->translated = 1; -} - - -void i915ValidateTextureProgram( i915ContextPtr i915 ) -{ - intelContextPtr intel = &i915->intel; - GLcontext *ctx = &intel->ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - DECLARE_RENDERINPUTS(index_bitset); - int i, offset; - GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; - GLuint s2 = S2_TEXCOORD_NONE; - - RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); - - /* Important: - */ - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - intel->vertex_attr_count = 0; - intel->coloroffset = 0; - intel->specoffset = 0; - offset = 0; - - if (i915->current_program) { - i915->current_program->on_hardware = 0; - i915->current_program->params_uptodate = 0; - } - - if (i915->vertex_fog == I915_FOG_PIXEL) { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 ); - RENDERINPUTS_CLEAR( index_bitset, _TNL_ATTRIB_FOG ); - } - else if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16 ); - } - else { - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12 ); - } - - /* How undefined is undefined? */ - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) { - EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, S4_VFMT_POINT_WIDTH, 4 ); - } - - intel->coloroffset = offset / 4; - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4 ); - - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) || - RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { - intel->specoffset = offset / 4; - EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3 ); - } else - EMIT_PAD( 3 ); - - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) - EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1 ); - else - EMIT_PAD( 1 ); - } - - if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { - for (i = 0; i < 8; i++) { - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { - int sz = VB->TexCoordPtr[i]->size; - - s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); - s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); - - EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0, sz * 4 ); - } - } - } - - /* Only need to change the vertex emit code if there has been a - * statechange to a new hardware vertex format: - */ - if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || - s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - - I915_STATECHANGE( i915, I915_UPLOAD_CTX ); - - i915->tex_program.translated = 0; - - /* Must do this *after* statechange, so as not to affect - * buffered vertices reliant on the old state: - */ - intel->vertex_size = _tnl_install_attrs( ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0 ); - - intel->vertex_size >>= 2; - - i915->state.Ctx[I915_CTXREG_LIS2] = s2; - i915->state.Ctx[I915_CTXREG_LIS4] = s4; - - assert(intel->vtbl.check_vertex_size( intel, intel->vertex_size )); - } - - if (!i915->tex_program.translated || - i915->last_ReallyEnabled != ctx->Texture._EnabledUnits) { - i915EmitTextureProgram( i915 ); - i915->last_ReallyEnabled = ctx->Texture._EnabledUnits; - } -} diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c deleted file mode 100644 index 2b806cc36e..0000000000 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ /dev/null @@ -1,975 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "simple_list.h" -#include "enums.h" -#include "texformat.h" -#include "texstore.h" - -#include "mm.h" - -#include "intel_screen.h" -#include "intel_ioctl.h" -#include "intel_tex.h" - -#include "i915_context.h" -#include "i915_reg.h" - -static GLint initial_offsets[6][2] = { {0,0}, - {0,2}, - {1,0}, - {1,2}, - {1,1}, - {1,3} }; - - -static GLint step_offsets[6][2] = { {0,2}, - {0,2}, - {-1,2}, - {-1,2}, - {-1,1}, - {-1,1} }; - - -#define I915_TEX_UNIT_ENABLED(unit) (1<> 1); -} - -static void i915LayoutTextureImages( i915ContextPtr i915, - struct gl_texture_object *tObj ) -{ - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; - GLint firstLevel, lastLevel, numLevels; - GLint i, total_height, pitch; - - /* Compute which mipmap levels we really want to send to the hardware. - */ - driCalculateTextureFirstLastLevel( (driTextureObject *) t ); - - /* Figure out the amount of memory required to hold all the mipmap - * levels. Choose the smallest pitch to accomodate the largest - * mipmap: - */ - firstLevel = t->intel.base.firstLevel; - lastLevel = t->intel.base.lastLevel; - numLevels = lastLevel - firstLevel + 1; - - - - /* All images must be loaded at this pitch. Count the number of - * lines required: - */ - switch (tObj->Target) { - case GL_TEXTURE_CUBE_MAP: { - const GLuint dim = tObj->Image[0][firstLevel]->Width; - GLuint face; - - pitch = dim * t->intel.texelBytes; - pitch *= 2; /* double pitch for cube layouts */ - pitch = (pitch + 3) & ~3; - - total_height = dim * 4; - - for ( face = 0 ; face < 6 ; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - t->intel.base.dirty_images[face] = ~0; - - assert(tObj->Image[face][firstLevel]->Width == dim); - assert(tObj->Image[face][firstLevel]->Height == dim); - - for (i = 0; i < numLevels; i++) { - t->intel.image[face][i].image = tObj->Image[face][firstLevel + i]; - if (!t->intel.image[face][i].image) { - fprintf(stderr, "no image %d %d\n", face, i); - break; /* can't happen */ - } - - t->intel.image[face][i].offset = - y * pitch + x * t->intel.texelBytes; - t->intel.image[face][i].internalFormat = baseImage->_BaseFormat; - - d >>= 1; - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - } - } - break; - } - case GL_TEXTURE_3D: { - GLuint virtual_height; - GLuint tmp_numLevels = numLevels; - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - t->intel.base.dirty_images[0] = ~0; - - /* Calculate the size of a single slice. Hardware demands a - * minimum of 8 mipmaps, some of which might ultimately not be - * used: - */ - if (tmp_numLevels < 9) - tmp_numLevels = 9; - - virtual_height = tObj->Image[0][firstLevel]->Height; - - for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (t->intel.image[0][i].image) { - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - } - - total_height += MAX2(2, virtual_height); - virtual_height >>= 1; - } - - t->intel.depth_pitch = total_height * pitch; - - /* Multiply slice size by texture depth for total size. It's - * remarkable how wasteful of memory all the i8x0 texture - * layouts are. - */ - total_height *= t->intel.image[0][0].image->Depth; - break; - } - default: - if (baseImage->IsCompressed) { - GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat); - - pitch = align(tObj->Image[0][firstLevel]->Width, alignment) * t->intel.texelBytes; - } else { - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - } - - t->intel.base.dirty_images[0] = ~0; - - for ( total_height = i = 0 ; i < numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - if (t->intel.image[0][i].image->IsCompressed) { - total_height += (t->intel.image[0][i].image->Height + 3) / 4; - } - else - total_height += MAX2(2, t->intel.image[0][i].image->Height); - } - break; - } - - t->intel.Pitch = pitch; - t->intel.base.totalSize = total_height*pitch; - t->intel.max_level = numLevels-1; -} - - -static void i945LayoutTextureImages( i915ContextPtr i915, - struct gl_texture_object *tObj ) -{ - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; - GLint firstLevel, lastLevel, numLevels; - GLint i, total_height, pitch, sz, max_offset = 0, offset; - - - /* Compute which mipmap levels we really want to send to the hardware. - */ - driCalculateTextureFirstLastLevel( (driTextureObject *) t ); - - /* Figure out the amount of memory required to hold all the mipmap - * levels. Choose the smallest pitch to accomodate the largest - * mipmap: - */ - firstLevel = t->intel.base.firstLevel; - lastLevel = t->intel.base.lastLevel; - numLevels = lastLevel - firstLevel + 1; - - - - /* All images must be loaded at this pitch. Count the number of - * lines required: - */ - switch (tObj->Target) { - case GL_TEXTURE_CUBE_MAP: { - const GLuint dim = tObj->Image[0][firstLevel]->Width; - GLuint face; - - /* Depending on the size of the largest images, pitch can be - * determined either by the old-style packing of cubemap faces, - * or the final row of 4x4, 2x2 and 1x1 faces below this. - */ - if (dim > 32) { - pitch = dim * t->intel.texelBytes; - pitch *= 2; /* double pitch for cube layouts */ - pitch = (pitch + 3) & ~3; - } - else { - pitch = 14 * 8 * t->intel.texelBytes; /* determined by row of - * little maps at - * bottom */ - } - - total_height = dim * 4 + 4; - - for ( face = 0 ; face < 6 ; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - if (dim == 4 && face >= 4) { - y = total_height - 4; - x = (face - 4) * 8; - } - else if (dim < 4) { - y = total_height - 4; - x = face * 8; - } - - t->intel.base.dirty_images[face] = ~0; - - assert(tObj->Image[face][firstLevel]->Width == dim); - assert(tObj->Image[face][firstLevel]->Height == dim); - - for (i = 0; i < numLevels; i++) { - - - t->intel.image[face][i].image = tObj->Image[face][firstLevel + i]; - assert(t->intel.image[face][i].image); - - t->intel.image[face][i].offset = - y * pitch + x * t->intel.texelBytes; - t->intel.image[face][i].internalFormat = baseImage->_BaseFormat; - - d >>= 1; - - switch (d) { - case 4: - switch (face) { - case FACE_POS_X: - case FACE_NEG_X: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - case FACE_POS_Y: - case FACE_NEG_Y: - y += 12; - x -= 8; - break; - case FACE_POS_Z: - case FACE_NEG_Z: - y = total_height - 4; - x = (face - 4) * 8; - break; - } - - case 2: - y = total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - max_offset = total_height * pitch; - break; - } - case GL_TEXTURE_3D: { - GLuint depth_packing = 0, depth_pack_pitch; - GLuint tmp_numLevels = numLevels; - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - depth_pack_pitch = pitch; - - t->intel.base.dirty_images[0] = ~0; - - - for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - - - - total_height += MAX2(2, t->intel.image[0][i].image->Height) * - MAX2((t->intel.image[0][i].image->Depth >> depth_packing), 1); - - /* When alignment dominates, can't increase depth packing? - * Or does pitch grow??? What are the alignment constraints, - * anyway? - */ - if (depth_pack_pitch > 4) { - depth_packing++; - depth_pack_pitch <<= 2; - } - } - - max_offset = total_height * pitch; - break; - } - default: - if (baseImage->IsCompressed) { - GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat); - - pitch = align(tObj->Image[0][firstLevel]->Width, alignment); - if (numLevels > 2) { - GLint width0 = align(minify(tObj->Image[0][firstLevel]->Width), alignment) + - + align(minify(minify(tObj->Image[0][firstLevel]->Width)), alignment); - - if (width0 > pitch) - pitch = width0; - } - pitch = pitch * t->intel.texelBytes; - } else { - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - } - - t->intel.base.dirty_images[0] = ~0; - max_offset = 0; - - for ( offset = i = 0 ; i < numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - t->intel.image[0][i].offset = offset; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - - if (t->intel.image[0][i].image->IsCompressed) - sz = MAX2(1, t->intel.image[0][i].image->Height/4) * pitch; - else - sz = MAX2(2, t->intel.image[0][i].image->Height) * pitch; - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - max_offset = MAX2(max_offset, offset + sz); - - /* LPT change: step right after second mipmap. - */ - if (i == 1) - offset += pitch / 2; - else - offset += sz; - - } - break; - } - - t->intel.Pitch = pitch; - t->intel.base.totalSize = max_offset; - t->intel.max_level = numLevels-1; -} - - - - -static void i915SetTexImages( i915ContextPtr i915, - struct gl_texture_object *tObj ) -{ - GLuint textureFormat; - i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - GLint ss2 = 0; - - switch( baseImage->TexFormat->MesaFormat ) { - case MESA_FORMAT_L8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_L8; - break; - - case MESA_FORMAT_I8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_I8; - break; - - case MESA_FORMAT_A8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_A8; - break; - - case MESA_FORMAT_AL88: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; - break; - - case MESA_FORMAT_RGB565: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - break; - - case MESA_FORMAT_ARGB1555: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - break; - - case MESA_FORMAT_ARGB4444: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; - break; - - case MESA_FORMAT_ARGB8888: - t->intel.texelBytes = 4; - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - break; - - case MESA_FORMAT_YCBCR_REV: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL); - ss2 |= SS2_COLORSPACE_CONVERSION; - break; - - case MESA_FORMAT_YCBCR: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY); - ss2 |= SS2_COLORSPACE_CONVERSION; - break; - - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); - break; - - case MESA_FORMAT_Z16: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_16BIT | MT_16BIT_L16); - break; - - case MESA_FORMAT_RGBA_DXT1: - case MESA_FORMAT_RGB_DXT1: - /* - * DXTn pitches are Width/4 * blocksize in bytes - * for DXT1: blocksize=8 so Width/4*8 = Width * 2 - * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 - */ - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - break; - - case MESA_FORMAT_RGBA_DXT3: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - break; - - case MESA_FORMAT_RGBA_DXT5: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); - break; - -#if 0 - case MESA_FORMAT_Z24_S8: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_32BIT | MT_32BIT_xL824); - break; -#endif - - default: - fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, - baseImage->TexFormat->MesaFormat); - abort(); - } - - switch (i915->intel.intelScreen->deviceID) { - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - i945LayoutTextureImages( i915, tObj ); - break; - default: - i915LayoutTextureImages( i915, tObj ); - break; - } - - t->Setup[I915_TEXREG_MS3] = - (((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) | - ((tObj->Image[0][t->intel.base.firstLevel]->Width - 1) << MS3_WIDTH_SHIFT) | - textureFormat | - MS3_USE_FENCE_REGS); - - t->Setup[I915_TEXREG_MS4] = - ((((t->intel.Pitch / 4) - 1) << MS4_PITCH_SHIFT) | - MS4_CUBE_FACE_ENA_MASK | - (((t->intel.max_level * 4)) << MS4_MAX_LOD_SHIFT) | - ((tObj->Image[0][t->intel.base.firstLevel]->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); - - t->Setup[I915_TEXREG_SS2] &= ~(SS2_COLORSPACE_CONVERSION); - t->Setup[I915_TEXREG_SS2] |= ss2; - - t->intel.dirty = I915_UPLOAD_TEX_ALL; - -} - - -/* The i915 (and related graphics cores) do not support GL_CLAMP. The - * Intel drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - */ -static GLuint translate_wrap_mode( GLenum wrap ) -{ - switch( wrap ) { - case GL_REPEAT: return TEXCOORDMODE_WRAP; - case GL_CLAMP: return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ - case GL_CLAMP_TO_EDGE: return TEXCOORDMODE_CLAMP_EDGE; - case GL_CLAMP_TO_BORDER: return TEXCOORDMODE_CLAMP_BORDER; - case GL_MIRRORED_REPEAT: return TEXCOORDMODE_MIRROR; - default: return TEXCOORDMODE_WRAP; - } -} - - -/** - */ -static void i915ImportTexObjState( struct gl_texture_object *texObj ) -{ - i915TextureObjectPtr t = (i915TextureObjectPtr)texObj->DriverData; - int minFilt = 0, mipFilt = 0, magFilt = 0, shadow = 0; - - if(INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - switch (texObj->MinFilter) { - case GL_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NONE; - break; - case GL_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_LINEAR; - break; - default: - break; - } - - if ( texObj->MaxAnisotropy > 1.0 ) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - switch (texObj->MagFilter) { - case GL_NEAREST: - magFilt = FILTER_NEAREST; - break; - case GL_LINEAR: - magFilt = FILTER_LINEAR; - break; - default: - break; - } - } - - if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && - texObj->Target != GL_TEXTURE_3D) { - - shadow = SS2_SHADOW_ENABLE; - shadow |= intel_translate_compare_func( texObj->CompareFunc ); - - minFilt = FILTER_4X4_FLAT; - magFilt = FILTER_4X4_FLAT; - } - - - t->Setup[I915_TEXREG_SS2] &= ~(SS2_MIN_FILTER_MASK | - SS2_MIP_FILTER_MASK | - SS2_MAG_FILTER_MASK | - SS2_SHADOW_ENABLE | - SS2_SHADOW_FUNC_MASK); - t->Setup[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | - (mipFilt << SS2_MIP_FILTER_SHIFT) | - (magFilt << SS2_MAG_FILTER_SHIFT) | - shadow); - - { - GLuint ss3 = t->Setup[I915_TEXREG_SS3] & ~(SS3_TCX_ADDR_MODE_MASK | - SS3_TCY_ADDR_MODE_MASK | - SS3_TCZ_ADDR_MODE_MASK); - GLenum ws = texObj->WrapS; - GLenum wt = texObj->WrapT; - GLenum wr = texObj->WrapR; - - t->refs_border_color = 0; - - if (texObj->Target == GL_TEXTURE_3D && - (texObj->MinFilter != GL_NEAREST || - texObj->MagFilter != GL_NEAREST)) { - - /* Try to mimic GL_CLAMP functionality a little better - - * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is - * in use. Only do this for 3D textures at the moment -- - * doing it universally would fix the conform texbc.c - * failure, though. - */ - if (ws == GL_CLAMP) ws = GL_CLAMP_TO_BORDER; - if (wt == GL_CLAMP) wt = GL_CLAMP_TO_BORDER; - if (wr == GL_CLAMP) wr = GL_CLAMP_TO_BORDER; - - /* 3D textures don't seem to respect the border color. - * Fallback if there's ever a danger that they might refer to - * it. - */ - if (ws == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; - if (wt == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; - if (wr == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; - } - - ss3 |= translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT; - ss3 |= translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT; - ss3 |= translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT; - - if (ss3 != t->Setup[I915_TEXREG_SS3]) { - t->intel.dirty = I915_UPLOAD_TEX_ALL; - t->Setup[I915_TEXREG_SS3] = ss3; - } - } - - { - const GLubyte *color = texObj->_BorderChan; - - t->Setup[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(color[0],color[1], - color[2],color[3]); - } -} - - - -static void i915_import_tex_unit( i915ContextPtr i915, - i915TextureObjectPtr t, - GLuint unit ) -{ - GLuint state[I915_TEX_SETUP_SIZE]; - - if(INTEL_DEBUG&DEBUG_TEXTURE) - fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); - - if (i915->intel.CurrentTexObj[unit]) - i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit); - - i915->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t; - t->intel.base.bound |= (1 << unit); - - if (t->intel.dirty & I915_UPLOAD_TEX(unit)) { - i915ImportTexObjState( t->intel.base.tObj ); - t->intel.dirty &= ~I915_UPLOAD_TEX(unit); - } - - state[I915_TEXREG_MS2] = t->intel.TextureOffset; - state[I915_TEXREG_MS3] = t->Setup[I915_TEXREG_MS3]; - state[I915_TEXREG_MS4] = t->Setup[I915_TEXREG_MS4]; - - state[I915_TEXREG_SS2] = (i915->state.Tex[unit][I915_TEXREG_SS2] & - SS2_LOD_BIAS_MASK); - state[I915_TEXREG_SS2] |= (t->Setup[I915_TEXREG_SS2] & ~SS2_LOD_BIAS_MASK); - - state[I915_TEXREG_SS3] = (i915->state.Tex[unit][I915_TEXREG_SS3] & - SS3_NORMALIZED_COORDS); - state[I915_TEXREG_SS3] |= (t->Setup[I915_TEXREG_SS3] & - ~(SS3_NORMALIZED_COORDS| - SS3_TEXTUREMAP_INDEX_MASK)); - - state[I915_TEXREG_SS3] |= (unit<Setup[I915_TEXREG_SS4]; - - - if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) { - I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) ); - memcpy(i915->state.Tex[unit], state, sizeof(state)); - } -} - - - -static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - - if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, unit); - - if (!(i915->state.active & I915_UPLOAD_TEX(unit))) { - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); - } - - /* Fallback if there's a texture border */ - if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) { - return GL_FALSE; - } - - - /* Update state if this is a different texture object to last - * time. - */ - if (i915->intel.CurrentTexObj[unit] != &t->intel || - (t->intel.dirty & I915_UPLOAD_TEX(unit))) { - i915_import_tex_unit( i915, t, unit); - i915->tex_program.translated = 0; - } - - return GL_TRUE; -} - -static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3]; - - ss3 &= ~SS3_NORMALIZED_COORDS; - - if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) { - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->state.Tex[unit][I915_TEXREG_SS3] = ss3; - } - - /* Upload teximages (not pipelined) - */ - if (t->intel.base.dirty_images[0]) { - i915SetTexImages( i915, tObj ); - if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) { - return GL_FALSE; - } - } - - return GL_TRUE; -} - - -static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3]; - - ss3 |= SS3_NORMALIZED_COORDS; - - if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) { - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->state.Tex[unit][I915_TEXREG_SS3] = ss3; - } - - /* Upload teximages (not pipelined) - */ - if (t->intel.base.dirty_images[0]) { - i915SetTexImages( i915, tObj ); - if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) { - return GL_FALSE; - } - } - - return GL_TRUE; -} - -static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3]; - GLuint face; - - ss3 |= SS3_NORMALIZED_COORDS; - - if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) { - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->state.Tex[unit][I915_TEXREG_SS3] = ss3; - } - - /* Upload teximages (not pipelined) - */ - if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] || - t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] || - t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) { - i915SetTexImages( i915, tObj ); - } - - /* upload (per face) */ - for (face = 0; face < 6; face++) { - if (t->intel.base.dirty_images[face]) { - if (!intelUploadTexImages( &i915->intel, &t->intel, face )) { - return GL_FALSE; - } - } - } - - - return GL_TRUE; -} - -static GLboolean enable_tex_3d( GLcontext *ctx, GLuint unit ) -{ - struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - - /* 3D textures on I915 seem to get bogus border colors, hence this - * fallback: - */ - if (t->refs_border_color) - return GL_FALSE; - - return GL_TRUE; -} - - - - -static GLboolean disable_tex( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - - if (i915->state.active & I915_UPLOAD_TEX(unit)) { - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_FALSE); - } - - /* The old texture is no longer bound to this texture unit. - * Mark it as such. - */ - if ( i915->intel.CurrentTexObj[unit] != NULL ) { - i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0); - i915->intel.CurrentTexObj[unit] = NULL; - } - - return GL_TRUE; -} - -static GLboolean i915UpdateTexUnit( GLcontext *ctx, GLuint unit ) -{ - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - - if (texUnit->_ReallyEnabled && - INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024) - return GL_FALSE; - - switch (texUnit->_ReallyEnabled) { - case TEXTURE_1D_BIT: - case TEXTURE_2D_BIT: - return (enable_tex_2d( ctx, unit ) && - enable_tex_common( ctx, unit )); - case TEXTURE_RECT_BIT: - return (enable_tex_rect( ctx, unit ) && - enable_tex_common( ctx, unit )); - case TEXTURE_CUBE_BIT: - return (enable_tex_cube( ctx, unit ) && - enable_tex_common( ctx, unit )); - case TEXTURE_3D_BIT: - return (enable_tex_2d( ctx, unit ) && - enable_tex_common( ctx, unit ) && - enable_tex_3d( ctx, unit)); - case 0: - return disable_tex( ctx, unit ); - default: - return GL_FALSE; - } -} - - -void i915UpdateTextureState( intelContextPtr intel ) -{ - GLcontext *ctx = &intel->ctx; - GLboolean ok = GL_TRUE; - GLuint i; - - for (i = 0 ; i < I915_TEX_UNITS && ok ; i++) { - ok = i915UpdateTexUnit( ctx, i ); - } - - FALLBACK( intel, I915_FALLBACK_TEXTURE, !ok ); -} - - - diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c deleted file mode 100644 index 4ad95cf4e3..0000000000 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ /dev/null @@ -1,469 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - - -#include "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "macros.h" -#include "colormac.h" - -#include "tnl/t_context.h" -#include "tnl/t_vertex.h" - -#include "intel_batchbuffer.h" - -#include "i915_reg.h" -#include "i915_context.h" - -static void -i915_render_prevalidate(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - i915ContextPtr i915 = I915_CONTEXT(intel); - - if (ctx->FragmentProgram._Active) - i915ValidateFragmentProgram( i915 ); - else { - assert(!ctx->FragmentProgram._MaintainTexEnvProgram); - i915ValidateTextureProgram( i915 ); - } -} - -static void i915_render_start( intelContextPtr intel ) -{ -} - - -static void i915_reduced_primitive_state( intelContextPtr intel, - GLenum rprim ) -{ - i915ContextPtr i915 = I915_CONTEXT(intel); - GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; - - st1 &= ~ST1_ENABLE; - - switch (rprim) { - case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */ - case GL_TRIANGLES: - if (intel->ctx.Polygon.StippleFlag && - intel->hw_stipple) - st1 |= ST1_ENABLE; - break; - case GL_LINES: - case GL_POINTS: - default: - break; - } - - i915->intel.reduced_primitive = rprim; - - if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST1] = st1; - } -} - - -/* Pull apart the vertex format registers and figure out how large a - * vertex is supposed to be. - */ -static GLboolean i915_check_vertex_size( intelContextPtr intel, - GLuint expected ) -{ - i915ContextPtr i915 = I915_CONTEXT(intel); - int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; - int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; - int i, sz = 0; - - switch (lis4 & S4_VFMT_XYZW_MASK) { - case S4_VFMT_XY: sz = 2; break; - case S4_VFMT_XYZ: sz = 3; break; - case S4_VFMT_XYW: sz = 3; break; - case S4_VFMT_XYZW: sz = 4; break; - default: - fprintf(stderr, "no xyzw specified\n"); - return 0; - } - - if (lis4 & S4_VFMT_SPEC_FOG) sz++; - if (lis4 & S4_VFMT_COLOR) sz++; - if (lis4 & S4_VFMT_DEPTH_OFFSET) sz++; - if (lis4 & S4_VFMT_POINT_WIDTH) sz++; - if (lis4 & S4_VFMT_FOG_PARAM) sz++; - - for (i = 0 ; i < 8 ; i++) { - switch (lis2 & S2_TEXCOORD_FMT0_MASK) { - case TEXCOORDFMT_2D: sz += 2; break; - case TEXCOORDFMT_3D: sz += 3; break; - case TEXCOORDFMT_4D: sz += 4; break; - case TEXCOORDFMT_1D: sz += 1; break; - case TEXCOORDFMT_2D_16: sz += 1; break; - case TEXCOORDFMT_4D_16: sz += 2; break; - case TEXCOORDFMT_NOT_PRESENT: break; - default: - fprintf(stderr, "bad texcoord fmt %d\n", i); - return GL_FALSE; - } - lis2 >>= S2_TEXCOORD_FMT1_SHIFT; - } - - if (sz != expected) - fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); - - return sz == expected; -} - - -static void i915_emit_invarient_state( intelContextPtr intel ) -{ - BATCH_LOCALS; - - BEGIN_BATCH( 20 ); - - OUT_BATCH(_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | - AA_LINE_REGION_WIDTH_1_0); - - OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_Z_CMD); - OUT_BATCH(0); - - /* Don't support texture crossbar yet */ - OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | - CSB_TCB(5, 5) | - CSB_TCB(6, 6) | - CSB_TCB(7, 7)); - - OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | - ENABLE_TEXKILL_3D_4D | - TEXKILL_4D); - - /* Need to initialize this to zero. - */ - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(3) | - (0)); - OUT_BATCH(0); - - /* XXX: Use this */ - OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - - OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); - - OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ - OUT_BATCH(0); - - - /* Don't support twosided stencil yet */ - OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | - BFO_ENABLE_STENCIL_TWO_SIDE | - 0 ); - - ADVANCE_BATCH(); -} - - -#define emit( intel, state, size ) \ -do { \ - int k; \ - BEGIN_BATCH( (size) / sizeof(GLuint)); \ - for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \ - OUT_BATCH((state)[k]); \ - ADVANCE_BATCH(); \ -} while (0); - -static GLuint get_dirty( struct i915_hw_state *state ) -{ - GLuint dirty; - - /* Workaround the multitex hang - if one texture unit state is - * modified, emit all texture units. - */ - dirty = state->active & ~state->emitted; - if (dirty & I915_UPLOAD_TEX_ALL) - state->emitted &= ~I915_UPLOAD_TEX_ALL; - dirty = state->active & ~state->emitted; - - return dirty; -} - - -static GLuint get_state_size( struct i915_hw_state *state ) -{ - GLuint dirty = get_dirty(state); - GLuint i; - GLuint sz = 0; - - if (dirty & I915_UPLOAD_INVARIENT) - sz += 20 * sizeof(int); - - if (dirty & I915_UPLOAD_CTX) - sz += sizeof(state->Ctx); - - if (dirty & I915_UPLOAD_BUFFERS) - sz += sizeof(state->Buffer); - - if (dirty & I915_UPLOAD_STIPPLE) - sz += sizeof(state->Stipple); - - if (dirty & I915_UPLOAD_FOG) - sz += sizeof(state->Fog); - - if (dirty & I915_UPLOAD_TEX_ALL) { - int nr = 0; - for (i = 0; i < I915_TEX_UNITS; i++) - if (dirty & I915_UPLOAD_TEX(i)) - nr++; - - sz += (2+nr*3) * sizeof(GLuint) * 2; - } - - if (dirty & I915_UPLOAD_CONSTANTS) - sz += state->ConstantSize * sizeof(GLuint); - - if (dirty & I915_UPLOAD_PROGRAM) - sz += state->ProgramSize * sizeof(GLuint); - - return sz; -} - - -/* Push the state into the sarea and/or texture memory. - */ -static void i915_emit_state( intelContextPtr intel ) -{ - i915ContextPtr i915 = I915_CONTEXT(intel); - struct i915_hw_state *state = i915->current; - int i; - GLuint dirty = get_dirty(state); - GLuint counter = intel->batch.counter; - BATCH_LOCALS; - - if (intel->batch.space < get_state_size(state)) { - intelFlushBatch(intel, GL_TRUE); - dirty = get_dirty(state); - counter = intel->batch.counter; - } - - if (VERBOSE) - fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); - - if (dirty & I915_UPLOAD_INVARIENT) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); - i915_emit_invarient_state( intel ); - } - - if (dirty & I915_UPLOAD_CTX) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CTX:\n"); - emit( i915, state->Ctx, sizeof(state->Ctx) ); - } - - if (dirty & I915_UPLOAD_BUFFERS) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); - emit( i915, state->Buffer, sizeof(state->Buffer) ); - } - - if (dirty & I915_UPLOAD_STIPPLE) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); - emit( i915, state->Stipple, sizeof(state->Stipple) ); - } - - if (dirty & I915_UPLOAD_FOG) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_FOG:\n"); - emit( i915, state->Fog, sizeof(state->Fog) ); - } - - /* Combine all the dirty texture state into a single command to - * avoid lockups on I915 hardware. - */ - if (dirty & I915_UPLOAD_TEX_ALL) { - int nr = 0; - - for (i = 0; i < I915_TEX_UNITS; i++) - if (dirty & I915_UPLOAD_TEX(i)) - nr++; - - BEGIN_BATCH(2+nr*3); - OUT_BATCH(_3DSTATE_MAP_STATE | (3*nr)); - OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); - for (i = 0 ; i < I915_TEX_UNITS ; i++) - if (dirty & I915_UPLOAD_TEX(i)) { - OUT_BATCH(state->Tex[i][I915_TEXREG_MS2]); - OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); - OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); - } - ADVANCE_BATCH(); - - BEGIN_BATCH(2+nr*3); - OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3*nr)); - OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); - for (i = 0 ; i < I915_TEX_UNITS ; i++) - if (dirty & I915_UPLOAD_TEX(i)) { - OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); - OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); - OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); - } - ADVANCE_BATCH(); - } - - if (dirty & I915_UPLOAD_CONSTANTS) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); - emit( i915, state->Constant, state->ConstantSize * sizeof(GLuint) ); - } - - if (dirty & I915_UPLOAD_PROGRAM) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); - - assert((state->Program[0] & 0x1ff)+2 == state->ProgramSize); - - emit( i915, state->Program, state->ProgramSize * sizeof(GLuint) ); - if (VERBOSE) - i915_disassemble_program( state->Program, state->ProgramSize ); - } - - state->emitted |= dirty; - intel->batch.last_emit_state = counter; - assert(counter == intel->batch.counter); -} - -static void i915_destroy_context( intelContextPtr intel ) -{ - _tnl_free_vertices(&intel->ctx); -} - - -/** - * Set the color buffer drawing region. - */ -static void -i915_set_color_region( intelContextPtr intel, const intelRegion *region) -{ - i915ContextPtr i915 = I915_CONTEXT(intel); - I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS ); - i915->state.Buffer[I915_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_CBUFADDR2] = region->offset; -} - - -/** - * specify the z-buffer/stencil region - */ -static void -i915_set_z_region( intelContextPtr intel, const intelRegion *region) -{ - i915ContextPtr i915 = I915_CONTEXT(intel); - I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS ); - i915->state.Buffer[I915_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | BUF_3D_PITCH(region->pitch) | BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_DBUFADDR2] = region->offset; -} - - -/** - * Set both the color and Z/stencil drawing regions. - * Similar to two previous functions, but don't use I915_STATECHANGE() - */ -static void -i915_update_color_z_regions(intelContextPtr intel, - const intelRegion *colorRegion, - const intelRegion *depthRegion) -{ - i915ContextPtr i915 = I915_CONTEXT(intel); - - i915->state.Buffer[I915_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_CBUFADDR2] = colorRegion->offset; - - i915->state.Buffer[I915_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(depthRegion->pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_DBUFADDR2] = depthRegion->offset; -} - - -static void i915_lost_hardware( intelContextPtr intel ) -{ - I915_CONTEXT(intel)->state.emitted = 0; -} - -static void i915_emit_flush( intelContextPtr intel ) -{ - BATCH_LOCALS; - - BEGIN_BATCH(2); - OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE ); - OUT_BATCH( 0 ); - ADVANCE_BATCH(); -} - - -void i915InitVtbl( i915ContextPtr i915 ) -{ - i915->intel.vtbl.alloc_tex_obj = i915AllocTexObj; - i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; - i915->intel.vtbl.clear_with_tris = i915ClearWithTris; - i915->intel.vtbl.rotate_window = i915RotateWindow; - i915->intel.vtbl.destroy = i915_destroy_context; - i915->intel.vtbl.emit_state = i915_emit_state; - i915->intel.vtbl.lost_hardware = i915_lost_hardware; - i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; - i915->intel.vtbl.render_start = i915_render_start; - i915->intel.vtbl.render_prevalidate = i915_render_prevalidate; - i915->intel.vtbl.set_color_region = i915_set_color_region; - i915->intel.vtbl.set_z_region = i915_set_z_region; - i915->intel.vtbl.update_color_z_regions = i915_update_color_z_regions; - i915->intel.vtbl.update_texture_state = i915UpdateTextureState; - i915->intel.vtbl.emit_flush = i915_emit_flush; -} - diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c deleted file mode 100644 index 803b41b256..0000000000 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ /dev/null @@ -1,829 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include -#include - -#include "mtypes.h" -#include "context.h" -#include "enums.h" -#include "vblank.h" - -#include "intel_reg.h" -#include "intel_batchbuffer.h" -#include "intel_context.h" - - - - -/* ================================================================ - * Performance monitoring functions - */ - -static void intel_fill_box( intelContextPtr intel, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLubyte r, GLubyte g, GLubyte b ) -{ - x += intel->drawX; - y += intel->drawY; - - if (x >= 0 && y >= 0 && - x+w < intel->intelScreen->width && - y+h < intel->intelScreen->height) - intelEmitFillBlitLocked( intel, - intel->intelScreen->cpp, - intel->intelScreen->back.pitch, - intel->intelScreen->back.offset, - x, y, w, h, - INTEL_PACKCOLOR(intel->intelScreen->fbFormat, - r,g,b,0xff)); -} - -static void intel_draw_performance_boxes( intelContextPtr intel ) -{ - /* Purple box for page flipping - */ - if ( intel->perf_boxes & I830_BOX_FLIP ) - intel_fill_box( intel, 4, 4, 8, 8, 255, 0, 255 ); - - /* Red box if we have to wait for idle at any point - */ - if ( intel->perf_boxes & I830_BOX_WAIT ) - intel_fill_box( intel, 16, 4, 8, 8, 255, 0, 0 ); - - /* Blue box: lost context? - */ - if ( intel->perf_boxes & I830_BOX_LOST_CONTEXT ) - intel_fill_box( intel, 28, 4, 8, 8, 0, 0, 255 ); - - /* Yellow box for texture swaps - */ - if ( intel->perf_boxes & I830_BOX_TEXTURE_LOAD ) - intel_fill_box( intel, 40, 4, 8, 8, 255, 255, 0 ); - - /* Green box if hardware never idles (as far as we can tell) - */ - if ( !(intel->perf_boxes & I830_BOX_RING_EMPTY) ) - intel_fill_box( intel, 64, 4, 8, 8, 0, 255, 0 ); - - - /* Draw bars indicating number of buffers allocated - * (not a great measure, easily confused) - */ -#if 0 - if (intel->dma_used) { - int bar = intel->dma_used / 10240; - if (bar > 100) bar = 100; - if (bar < 1) bar = 1; - intel_fill_box( intel, 4, 16, bar, 4, 196, 128, 128 ); - intel->dma_used = 0; - } -#endif - - intel->perf_boxes = 0; -} - - - - - - -static int bad_prim_vertex_nr( int primitive, int nr ) -{ - switch (primitive & PRIM3D_MASK) { - case PRIM3D_POINTLIST: - return nr < 1; - case PRIM3D_LINELIST: - return (nr & 1) || nr == 0; - case PRIM3D_LINESTRIP: - return nr < 2; - case PRIM3D_TRILIST: - case PRIM3D_RECTLIST: - return nr % 3 || nr == 0; - case PRIM3D_POLY: - case PRIM3D_TRIFAN: - case PRIM3D_TRISTRIP: - case PRIM3D_TRISTRIP_RVRSE: - return nr < 3; - default: - return 1; - } -} - -static void intel_flush_inline_primitive( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - GLuint used = intel->batch.ptr - intel->prim.start_ptr; - GLuint vertcount; - - assert(intel->prim.primitive != ~0); - - if (1) { - /* Check vertex size against the vertex we're specifying to - * hardware. If it's wrong, ditch the primitive. - */ - if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size )) - goto do_discard; - - vertcount = (used - 4)/ (intel->vertex_size * 4); - - if (!vertcount) - goto do_discard; - - if (vertcount * intel->vertex_size * 4 != used - 4) { - fprintf(stderr, "vertex size confusion %d %d\n", used, - intel->vertex_size * vertcount * 4); - goto do_discard; - } - - if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) { - fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive, - vertcount); - goto do_discard; - } - } - - if (used < 8) - goto do_discard; - - *(int *)intel->prim.start_ptr = (_3DPRIMITIVE | - intel->prim.primitive | - (used/4-2)); - - goto finished; - - do_discard: - intel->batch.ptr -= used; - intel->batch.space += used; - assert(intel->batch.space >= 0); - - finished: - intel->prim.primitive = ~0; - intel->prim.start_ptr = 0; - intel->prim.flush = 0; -} - - -/* Emit a primitive referencing vertices in a vertex buffer. - */ -void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ) -{ - BATCH_LOCALS; - - if (0) - fprintf(stderr, "%s %x\n", __FUNCTION__, prim); - - - /* Finish any in-progress primitive: - */ - INTEL_FIREVERTICES( intel ); - - /* Emit outstanding state: - */ - intel->vtbl.emit_state( intel ); - - /* Make sure there is some space in this buffer: - */ - if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space) { - intelFlushBatch(intel, GL_TRUE); - intel->vtbl.emit_state( intel ); - } - -#if 1 - if (((unsigned long)intel->batch.ptr) & 0x4) { - BEGIN_BATCH(1); - OUT_BATCH(0); - ADVANCE_BATCH(); - } -#endif - - /* Emit a slot which will be filled with the inline primitive - * command later. - */ - BEGIN_BATCH(2); - OUT_BATCH( 0 ); - - intel->prim.start_ptr = batch_ptr; - intel->prim.primitive = prim; - intel->prim.flush = intel_flush_inline_primitive; - intel->batch.contains_geometry = 1; - - OUT_BATCH( 0 ); - ADVANCE_BATCH(); -} - - -void intelRestartInlinePrimitive( intelContextPtr intel ) -{ - GLuint prim = intel->prim.primitive; - - intel_flush_inline_primitive( &intel->ctx ); - if (1) intelFlushBatch(intel, GL_TRUE); /* GL_TRUE - is critical */ - intelStartInlinePrimitive( intel, prim ); -} - - - -void intelWrapInlinePrimitive( intelContextPtr intel ) -{ - GLuint prim = intel->prim.primitive; - - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - intel_flush_inline_primitive( &intel->ctx ); - intelFlushBatch(intel, GL_TRUE); - intelStartInlinePrimitive( intel, prim ); -} - - -/* Emit a primitive with space for inline vertices. - */ -GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel, - int primitive, - int dwords, - int vertex_size ) -{ - GLuint *tmp = 0; - BATCH_LOCALS; - - if (0) - fprintf(stderr, "%s 0x%x %d\n", __FUNCTION__, primitive, dwords); - - /* Emit outstanding state: - */ - intel->vtbl.emit_state( intel ); - - if ((1+dwords)*4 >= intel->batch.space) { - intelFlushBatch(intel, GL_TRUE); - intel->vtbl.emit_state( intel ); - } - - - if (1) { - int used = dwords * 4; - int vertcount; - - /* Check vertex size against the vertex we're specifying to - * hardware. If it's wrong, ditch the primitive. - */ - if (!intel->vtbl.check_vertex_size( intel, vertex_size )) - goto do_discard; - - vertcount = dwords / vertex_size; - - if (dwords % vertex_size) { - fprintf(stderr, "did not request a whole number of vertices\n"); - goto do_discard; - } - - if (bad_prim_vertex_nr( primitive, vertcount )) { - fprintf(stderr, "bad_prim_vertex_nr %x %d\n", primitive, vertcount); - goto do_discard; - } - - if (used < 8) - goto do_discard; - } - - /* Emit 3D_PRIMITIVE commands: - */ - BEGIN_BATCH(1 + dwords); - OUT_BATCH( _3DPRIMITIVE | - primitive | - (dwords-1) ); - - tmp = (GLuint *)batch_ptr; - batch_ptr += dwords * 4; - - ADVANCE_BATCH(); - - intel->batch.contains_geometry = 1; - - do_discard: - return tmp; -} - - -static void intelWaitForFrameCompletion( intelContextPtr intel ) -{ - drm_i915_sarea_t *sarea = (drm_i915_sarea_t *)intel->sarea; - - if (intel->do_irqs) { - if (intelGetLastFrame(intel) < sarea->last_dispatch) { - if (!intel->irqsEmitted) { - while (intelGetLastFrame (intel) < sarea->last_dispatch) - ; - } - else { - intelWaitIrq( intel, intel->alloc.irq_emitted ); - } - intel->irqsEmitted = 10; - } - - if (intel->irqsEmitted) { - LOCK_HARDWARE( intel ); - intelEmitIrqLocked( intel ); - intel->irqsEmitted--; - UNLOCK_HARDWARE( intel ); - } - } - else { - while (intelGetLastFrame (intel) < sarea->last_dispatch) { - if (intel->do_usleeps) - DO_USLEEP( 1 ); - } - } -} - -/* - * Copy the back buffer to the front buffer. - */ -void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, - const drm_clip_rect_t *rect) -{ - intelContextPtr intel; - const intelScreenPrivate *intelScreen; - GLboolean missed_target; - int64_t ust; - - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate; - - intelFlush( &intel->ctx ); - - intelScreen = intel->intelScreen; - - if (!rect && !intel->swap_scheduled && intelScreen->drmMinor >= 6 && - !(intel->vblank_flags & VBLANK_FLAG_NO_IRQ) && - intelScreen->current_rotation == 0) { - unsigned int interval = driGetVBlankInterval(dPriv, intel->vblank_flags); - unsigned int target; - drm_i915_vblank_swap_t swap; - - swap.drawable = dPriv->hHWDrawable; - swap.seqtype = DRM_VBLANK_ABSOLUTE; - target = swap.sequence = intel->vbl_seq + interval; - - if (intel->vblank_flags & VBLANK_FLAG_SYNC) { - swap.seqtype |= DRM_VBLANK_NEXTONMISS; - } else if (interval == 0) { - goto noschedule; - } - - if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) { - swap.seqtype |= DRM_VBLANK_SECONDARY; - } - - if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, - sizeof(swap))) { - intel->swap_scheduled = 1; - intel->vbl_seq = swap.sequence; - swap.sequence -= target; - missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); - } - } else { - intel->swap_scheduled = 0; - } -noschedule: - - if (!intel->swap_scheduled) { - intelWaitForFrameCompletion( intel ); - LOCK_HARDWARE( intel ); - - if (!rect) - { - UNLOCK_HARDWARE( intel ); - driWaitForVBlank( dPriv, &intel->vbl_seq, intel->vblank_flags, & missed_target ); - LOCK_HARDWARE( intel ); - } - { - const intelScreenPrivate *intelScreen = intel->intelScreen; - const __DRIdrawablePrivate *dPriv = intel->driDrawable; - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - drm_clip_rect_t box; - const int cpp = intelScreen->cpp; - const int pitch = intelScreen->front.pitch; /* in bytes */ - int i; - GLuint CMD, BR13; - BATCH_LOCALS; - - switch(cpp) { - case 2: - BR13 = (pitch) | (0xCC << 16) | (1<<24); - CMD = XY_SRC_COPY_BLT_CMD; - break; - case 4: - BR13 = (pitch) | (0xCC << 16) | (1<<24) | (1<<25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - break; - default: - BR13 = (pitch) | (0xCC << 16) | (1<<24); - CMD = XY_SRC_COPY_BLT_CMD; - break; - } - - if (0) - intel_draw_performance_boxes( intel ); - - for (i = 0 ; i < nbox; i++, pbox++) - { - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->width || - pbox->y2 > intelScreen->height) { - _mesa_warning(&intel->ctx, "Bad cliprect in intelCopyBuffer()"); - continue; - } - - box = *pbox; - - if (rect) - { - if (rect->x1 > box.x1) - box.x1 = rect->x1; - if (rect->y1 > box.y1) - box.y1 = rect->y1; - if (rect->x2 < box.x2) - box.x2 = rect->x2; - if (rect->y2 < box.y2) - box.y2 = rect->y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - BEGIN_BATCH( 8); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (box.y1 << 16) | box.x1 ); - OUT_BATCH( (box.y2 << 16) | box.x2 ); - - if (intel->sarea->pf_current_page == 0) - OUT_BATCH( intelScreen->front.offset ); - else - OUT_BATCH( intelScreen->back.offset ); - - OUT_BATCH( (box.y1 << 16) | box.x1 ); - OUT_BATCH( BR13 & 0xffff ); - - if (intel->sarea->pf_current_page == 0) - OUT_BATCH( intelScreen->back.offset ); - else - OUT_BATCH( intelScreen->front.offset ); - - ADVANCE_BATCH(); - } - } - intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE ); - UNLOCK_HARDWARE( intel ); - } - - if (!rect) - { - intel->swap_count++; - (*dri_interface->getUST)(&ust); - if (missed_target) { - intel->swap_missed_count++; - intel->swap_missed_ust = ust - intel->swap_ust; - } - - intel->swap_ust = ust; - } -} - - - - -void intelEmitFillBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort dst_pitch, /* in bytes */ - GLuint dst_offset, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLuint color ) -{ - GLuint BR13, CMD; - BATCH_LOCALS; - - switch(cpp) { - case 1: - case 2: - case 3: - BR13 = dst_pitch | (0xF0 << 16) | (1<<24); - CMD = XY_COLOR_BLT_CMD; - break; - case 4: - BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25); - CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB); - break; - default: - return; - } - - BEGIN_BATCH( 6); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (y << 16) | x ); - OUT_BATCH( ((y+h) << 16) | (x+w) ); - OUT_BATCH( dst_offset ); - OUT_BATCH( color ); - ADVANCE_BATCH(); -} - - -/* Copy BitBlt - */ -void intelEmitCopyBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort src_pitch, - GLuint src_offset, - GLshort dst_pitch, - GLuint dst_offset, - GLshort src_x, GLshort src_y, - GLshort dst_x, GLshort dst_y, - GLshort w, GLshort h ) -{ - GLuint CMD, BR13; - int dst_y2 = dst_y + h; - int dst_x2 = dst_x + w; - BATCH_LOCALS; - - src_pitch *= cpp; - dst_pitch *= cpp; - - switch(cpp) { - case 1: - case 2: - case 3: - BR13 = dst_pitch | (0xCC << 16) | (1<<24); - CMD = XY_SRC_COPY_BLT_CMD; - break; - case 4: - BR13 = dst_pitch | (0xCC << 16) | (1<<24) | (1<<25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - break; - default: - return; - } - - if (dst_y2 < dst_y || - dst_x2 < dst_x) { - return; - } - - BEGIN_BATCH( 12); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (dst_y << 16) | dst_x ); - OUT_BATCH( (dst_y2 << 16) | dst_x2 ); - OUT_BATCH( dst_offset ); - OUT_BATCH( (src_y << 16) | src_x ); - OUT_BATCH( src_pitch ); - OUT_BATCH( src_offset ); - ADVANCE_BATCH(); -} - - - -void intelClearWithBlit(GLcontext *ctx, GLbitfield buffers, GLboolean allFoo, - GLint cx1Foo, GLint cy1Foo, GLint cwFoo, GLint chFoo) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - intelScreenPrivate *intelScreen = intel->intelScreen; - GLuint clear_depth, clear_color; - GLint cx, cy, cw, ch; - GLboolean all; - GLint pitch; - GLint cpp = intelScreen->cpp; - GLint i; - GLuint BR13, CMD, D_CMD; - BATCH_LOCALS; - - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - - /* get clear bounds after locking */ - cx = intel->ctx.DrawBuffer->_Xmin; - cy = intel->ctx.DrawBuffer->_Ymin; - cw = intel->ctx.DrawBuffer->_Xmax - cx; - ch = intel->ctx.DrawBuffer->_Ymax - cy; - all = (cw == intel->ctx.DrawBuffer->Width && - ch == intel->ctx.DrawBuffer->Height); - - pitch = intelScreen->front.pitch; - - clear_color = intel->ClearColor; - clear_depth = 0; - - if (buffers & BUFFER_BIT_DEPTH) { - clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth); - } - - if (buffers & BUFFER_BIT_STENCIL) { - clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; - } - - switch(cpp) { - case 2: - BR13 = (0xF0 << 16) | (pitch) | (1<<24); - D_CMD = CMD = XY_COLOR_BLT_CMD; - break; - case 4: - BR13 = (0xF0 << 16) | (pitch) | (1<<24) | (1<<25); - CMD = (XY_COLOR_BLT_CMD | - XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB); - D_CMD = XY_COLOR_BLT_CMD; - if (buffers & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB; - if (buffers & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; - break; - default: - BR13 = (0xF0 << 16) | (pitch) | (1<<24); - D_CMD = CMD = XY_COLOR_BLT_CMD; - break; - } - - { - /* flip top to bottom */ - cy = intel->driDrawable->h - cy - ch; - cx = cx + intel->drawX; - cy += intel->drawY; - - /* adjust for page flipping */ - if ( intel->sarea->pf_current_page == 1 ) { - GLuint tmp = buffers; - - buffers &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); - if ( tmp & BUFFER_BIT_FRONT_LEFT ) buffers |= BUFFER_BIT_BACK_LEFT; - if ( tmp & BUFFER_BIT_BACK_LEFT ) buffers |= BUFFER_BIT_FRONT_LEFT; - } - - for (i = 0 ; i < intel->numClipRects ; i++) - { - drm_clip_rect_t *box = &intel->pClipRects[i]; - drm_clip_rect_t b; - - if (!all) { - GLint x = box->x1; - GLint y = box->y1; - GLint w = box->x2 - x; - GLint h = box->y2 - y; - - if (x < cx) w -= cx - x, x = cx; - if (y < cy) h -= cy - y, y = cy; - if (x + w > cx + cw) w = cx + cw - x; - if (y + h > cy + ch) h = cy + ch - y; - if (w <= 0) continue; - if (h <= 0) continue; - - b.x1 = x; - b.y1 = y; - b.x2 = x + w; - b.y2 = y + h; - } else { - b = *box; - } - - - if (b.x1 > b.x2 || - b.y1 > b.y2 || - b.x2 > intelScreen->width || - b.y2 > intelScreen->height) - continue; - - if ( buffers & BUFFER_BIT_FRONT_LEFT ) { - BEGIN_BATCH( 6); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (b.y1 << 16) | b.x1 ); - OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_BATCH( intelScreen->front.offset ); - OUT_BATCH( clear_color ); - ADVANCE_BATCH(); - } - - if ( buffers & BUFFER_BIT_BACK_LEFT ) { - BEGIN_BATCH( 6); - OUT_BATCH( CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (b.y1 << 16) | b.x1 ); - OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_BATCH( intelScreen->back.offset ); - OUT_BATCH( clear_color ); - ADVANCE_BATCH(); - } - - if ( buffers & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) { - BEGIN_BATCH( 6); - OUT_BATCH( D_CMD ); - OUT_BATCH( BR13 ); - OUT_BATCH( (b.y1 << 16) | b.x1 ); - OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_BATCH( intelScreen->depth.offset ); - OUT_BATCH( clear_depth ); - ADVANCE_BATCH(); - } - } - } - intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE ); - UNLOCK_HARDWARE( intel ); -} - - - - -void intelDestroyBatchBuffer( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - - if (intel->alloc.offset) { - intelFreeAGP( intel, intel->alloc.ptr ); - intel->alloc.ptr = NULL; - intel->alloc.offset = 0; - } - else if (intel->alloc.ptr) { - free(intel->alloc.ptr); - intel->alloc.ptr = NULL; - } - - memset(&intel->batch, 0, sizeof(intel->batch)); -} - - -void intelInitBatchBuffer( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - - /* This path isn't really safe with rotate: - */ - if (getenv("INTEL_BATCH") && intel->intelScreen->allow_batchbuffer) { - switch (intel->intelScreen->deviceID) { - case PCI_CHIP_I865_G: - /* HW bug? Seems to crash if batchbuffer crosses 4k boundary. - */ - intel->alloc.size = 8 * 1024; - break; - default: - /* This is the smallest amount of memory the kernel deals with. - * We'd ideally like to make this smaller. - */ - intel->alloc.size = 1 << intel->intelScreen->logTextureGranularity; - break; - } - - intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size ); - if (intel->alloc.ptr) - intel->alloc.offset = - intelAgpOffsetFromVirtual( intel, intel->alloc.ptr ); - else - intel->alloc.offset = 0; /* OK? */ - } - - /* The default is now to use a local buffer and pass that to the - * kernel. This is also a fallback if allocation fails on the - * above path: - */ - if (!intel->alloc.ptr) { - intel->alloc.size = 8 * 1024; - intel->alloc.ptr = malloc( intel->alloc.size ); - intel->alloc.offset = 0; - } - - assert(intel->alloc.ptr); -} diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h deleted file mode 100644 index 577d07137f..0000000000 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h +++ /dev/null @@ -1,126 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "intel_context.h" -#include "intel_ioctl.h" - - -#define BATCH_LOCALS GLubyte *batch_ptr; - -/* #define VERBOSE 0 */ -#ifndef VERBOSE -extern int VERBOSE; -#endif - - -#define BEGIN_BATCH(n) \ -do { \ - if (VERBOSE) fprintf(stderr, \ - "BEGIN_BATCH(%ld) in %s, %d dwords free\n", \ - ((unsigned long)n), __FUNCTION__, \ - intel->batch.space/4); \ - if (intel->batch.space < (n)*4) \ - intelFlushBatch(intel, GL_TRUE); \ - if (intel->batch.space == intel->batch.size) intel->batch.func = __FUNCTION__; \ - batch_ptr = intel->batch.ptr; \ -} while (0) - -#define OUT_BATCH(n) \ -do { \ - *(GLuint *)batch_ptr = (n); \ - if (VERBOSE) fprintf(stderr, " -- %08x at %s/%d\n", (n), __FILE__, __LINE__); \ - batch_ptr += 4; \ -} while (0) - -#define ADVANCE_BATCH() \ -do { \ - if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n"); \ - intel->batch.space -= (batch_ptr - intel->batch.ptr); \ - intel->batch.ptr = batch_ptr; \ - assert(intel->batch.space >= 0); \ -} while(0) - -extern void intelInitBatchBuffer( GLcontext *ctx ); -extern void intelDestroyBatchBuffer( GLcontext *ctx ); - -extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ); -extern void intelWrapInlinePrimitive( intelContextPtr intel ); -extern void intelRestartInlinePrimitive( intelContextPtr intel ); -extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel, - int primitive, int dwords, - int vertex_size); -extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, - const drm_clip_rect_t *rect); -extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch); - -extern void intelEmitCopyBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort src_pitch, - GLuint src_offset, - GLshort dst_pitch, - GLuint dst_offset, - GLshort srcx, GLshort srcy, - GLshort dstx, GLshort dsty, - GLshort w, GLshort h ); - -extern void intelEmitFillBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort dst_pitch, - GLuint dst_offset, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLuint color ); - - - - -static __inline GLuint *intelExtendInlinePrimitive( intelContextPtr intel, - GLuint dwords ) -{ - GLuint sz = dwords * sizeof(GLuint); - GLuint *ptr; - - if (intel->batch.space < sz) { - intelWrapInlinePrimitive( intel ); -/* assert(intel->batch.space >= sz); */ - } - -/* assert(intel->prim.primitive != ~0); */ - ptr = (GLuint *)intel->batch.ptr; - intel->batch.ptr += sz; - intel->batch.space -= sz; - - return ptr; -} - - - -#endif diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c deleted file mode 100644 index 07bee4ef9f..0000000000 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ /dev/null @@ -1,776 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "matrix.h" -#include "simple_list.h" -#include "extensions.h" -#include "framebuffer.h" -#include "imports.h" -#include "points.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" -#include "vbo/vbo.h" - -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" - -#include "drivers/common/driverfuncs.h" - -#include "intel_screen.h" - -#include "i830_dri.h" -#include "i830_common.h" - -#include "intel_tex.h" -#include "intel_span.h" -#include "intel_tris.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" - -#include "vblank.h" -#include "utils.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ -#ifndef INTEL_DEBUG -int INTEL_DEBUG = (0); -#endif - -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_NV_vertex_program -#include "extension_helper.h" - -#ifndef VERBOSE -int VERBOSE = 0; -#endif - -#if DEBUG_LOCKING -char *prevLockFile; -int prevLockLine; -#endif - -/*************************************** - * Mesa's Driver Functions - ***************************************/ - -#define DRIVER_DATE "20061017" - -const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) -{ - const char * chipset; - static char buffer[128]; - - switch (name) { - case GL_VENDOR: - return (GLubyte *)"Tungsten Graphics, Inc"; - break; - - case GL_RENDERER: - switch (INTEL_CONTEXT(ctx)->intelScreen->deviceID) { - case PCI_CHIP_845_G: - chipset = "Intel(R) 845G"; break; - case PCI_CHIP_I830_M: - chipset = "Intel(R) 830M"; break; - case PCI_CHIP_I855_GM: - chipset = "Intel(R) 852GM/855GM"; break; - case PCI_CHIP_I865_G: - chipset = "Intel(R) 865G"; break; - case PCI_CHIP_I915_G: - chipset = "Intel(R) 915G"; break; - case PCI_CHIP_I915_GM: - chipset = "Intel(R) 915GM"; break; - case PCI_CHIP_I945_G: - chipset = "Intel(R) 945G"; break; - case PCI_CHIP_I945_GM: - chipset = "Intel(R) 945GM"; break; - case PCI_CHIP_I945_GME: - chipset = "Intel(R) 945GME"; break; - case PCI_CHIP_G33_G: - chipset = "Intel(R) G33"; break; - case PCI_CHIP_Q35_G: - chipset = "Intel(R) Q35"; break; - case PCI_CHIP_Q33_G: - chipset = "Intel(R) Q33"; break; - default: - chipset = "Unknown Intel Chipset"; break; - } - - (void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 ); - return (GLubyte *) buffer; - - default: - return NULL; - } -} - - -/** - * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. - */ -const struct dri_extension card_extensions[] = -{ - { "GL_ARB_multisample", GL_ARB_multisample_functions }, - { "GL_ARB_multitexture", NULL }, - { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, - { "GL_ARB_texture_border_clamp", NULL }, - { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, - { "GL_ARB_texture_cube_map", NULL }, - { "GL_ARB_texture_env_add", NULL }, - { "GL_ARB_texture_env_combine", NULL }, - { "GL_ARB_texture_env_dot3", NULL }, - { "GL_ARB_texture_mirrored_repeat", NULL }, - { "GL_ARB_texture_rectangle", NULL }, - { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, - { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, - { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, - { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, - { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, - { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, - { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, - { "GL_EXT_blend_subtract", NULL }, - { "GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions }, - { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, - { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions }, - { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, - { "GL_EXT_stencil_wrap", NULL }, - { "GL_EXT_texture_edge_clamp", NULL }, - { "GL_EXT_texture_env_combine", NULL }, - { "GL_EXT_texture_env_dot3", NULL }, - { "GL_EXT_texture_filter_anisotropic", NULL }, - { "GL_EXT_texture_lod_bias", NULL }, - { "GL_3DFX_texture_compression_FXT1", NULL }, - { "GL_APPLE_client_storage", NULL }, - { "GL_MESA_pack_invert", NULL }, - { "GL_MESA_ycbcr_texture", NULL }, - { "GL_NV_blend_square", NULL }, - { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, - { "GL_NV_vertex_program1_1", NULL }, - { "GL_SGIS_generate_mipmap", NULL }, - { NULL, NULL } -}; - -extern const struct tnl_pipeline_stage _intel_render_stage; - -static const struct tnl_pipeline_stage *intel_pipeline[] = { - &_tnl_vertex_transform_stage, - &_tnl_vertex_cull_stage, - &_tnl_normal_transform_stage, - &_tnl_lighting_stage, - &_tnl_fog_coordinate_stage, - &_tnl_texgen_stage, - &_tnl_texture_transform_stage, - &_tnl_point_attenuation_stage, - &_tnl_vertex_program_stage, -#if 1 - &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */ -#endif - &_tnl_render_stage, - 0, -}; - - -static const struct dri_debug_control debug_control[] = -{ - { "fall", DEBUG_FALLBACKS }, - { "tex", DEBUG_TEXTURE }, - { "ioctl", DEBUG_IOCTL }, - { "prim", DEBUG_PRIMS }, - { "vert", DEBUG_VERTS }, - { "state", DEBUG_STATE }, - { "verb", DEBUG_VERBOSE }, - { "dri", DEBUG_DRI }, - { "dma", DEBUG_DMA }, - { "san", DEBUG_SANITY }, - { "sync", DEBUG_SYNC }, - { "sleep", DEBUG_SLEEP }, - { "pix", DEBUG_PIXEL }, - { NULL, 0 } -}; - - -static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) -{ - _swrast_InvalidateState( ctx, new_state ); - _swsetup_InvalidateState( ctx, new_state ); - _vbo_InvalidateState( ctx, new_state ); - _tnl_InvalidateState( ctx, new_state ); - _tnl_invalidate_vertex_state( ctx, new_state ); - INTEL_CONTEXT(ctx)->NewGLState |= new_state; -} - - -void intelInitDriverFunctions( struct dd_function_table *functions ) -{ - _mesa_init_driver_functions( functions ); - - functions->Clear = intelClear; - functions->Flush = intelglFlush; - functions->Finish = intelFinish; - functions->GetString = intelGetString; - functions->UpdateState = intelInvalidateState; - - intelInitTextureFuncs( functions ); - intelInitPixelFuncs( functions ); - intelInitStateFuncs( functions ); -} - -static void intel_emit_invarient_state( GLcontext *ctx ) -{ -} - - - -GLboolean intelInitContext( intelContextPtr intel, - const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate, - struct dd_function_table *functions ) -{ - GLcontext *ctx = &intel->ctx; - GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - drmI830Sarea *saPriv = (drmI830Sarea *) - (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); - int fthrottle_mode; - - if (!_mesa_initialize_context(&intel->ctx, - mesaVis, shareCtx, - functions, - (void*) intel)) - return GL_FALSE; - - driContextPriv->driverPrivate = intel; - intel->intelScreen = intelScreen; - intel->driScreen = sPriv; - intel->sarea = saPriv; - - - (void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) ); - make_empty_list( & intel->swapped ); - - driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache, - intel->driScreen->myNum, "i915"); - - ctx->Const.MaxTextureMaxAnisotropy = 2.0; - - ctx->Const.MinLineWidth = 1.0; - ctx->Const.MinLineWidthAA = 1.0; - ctx->Const.MaxLineWidth = 3.0; - ctx->Const.MaxLineWidthAA = 3.0; - ctx->Const.LineWidthGranularity = 1.0; - - ctx->Const.MinPointSize = 1.0; - ctx->Const.MinPointSizeAA = 1.0; - ctx->Const.MaxPointSize = 255.0; - ctx->Const.MaxPointSizeAA = 3.0; - ctx->Const.PointSizeGranularity = 1.0; - - /* reinitialize the context point state. - * It depend on constants in __GLcontextRec::Const - */ - _mesa_init_point(ctx); - - /* Initialize the software rasterizer and helper modules. */ - _swrast_CreateContext( ctx ); - _vbo_CreateContext( ctx ); - _tnl_CreateContext( ctx ); - _swsetup_CreateContext( ctx ); - - /* Install the customized pipeline: */ - _tnl_destroy_pipeline( ctx ); - _tnl_install_pipeline( ctx, intel_pipeline ); - - /* Configure swrast to match hardware characteristics: */ - _swrast_allow_pixel_fog( ctx, GL_FALSE ); - _swrast_allow_vertex_fog( ctx, GL_TRUE ); - - /* Dri stuff */ - intel->hHWContext = driContextPriv->hHWContext; - intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) &sPriv->pSAREA->lock; - - intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; - intel->hw_stipple = 1; - - switch(mesaVis->depthBits) { - case 0: /* what to do in this case? */ - case 16: - intel->depth_scale = 1.0/0xffff; - intel->polygon_offset_scale = 1.0/0xffff; - intel->depth_clear_mask = ~0; - intel->ClearDepth = 0xffff; - break; - case 24: - intel->depth_scale = 1.0/0xffffff; - intel->polygon_offset_scale = 2.0/0xffffff; /* req'd to pass glean */ - intel->depth_clear_mask = 0x00ffffff; - intel->stencil_clear_mask = 0xff000000; - intel->ClearDepth = 0x00ffffff; - break; - default: - assert(0); - break; - } - - /* Initialize swrast, tnl driver tables: */ - intelInitSpanFuncs( ctx ); - intelInitTriFuncs( ctx ); - - - intel->RenderIndex = ~0; - - fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->iw.irq_seq = -1; - intel->irqsEmitted = 0; - - intel->do_irqs = (intel->intelScreen->irq_active && - fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); - - intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); - - intel->vblank_flags = (intel->intelScreen->irq_active != 0) - ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; - - (*dri_interface->getUST)(&intel->swap_ust); - _math_matrix_ctr (&intel->ViewportMatrix); - - driInitExtensions( ctx, card_extensions, GL_TRUE ); - - if (intel->ctx.Mesa_DXTn) { - _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); - _mesa_enable_extension( ctx, "GL_S3_s3tc" ); - } - else if (driQueryOptionb (&intel->optionCache, "force_s3tc_enable")) { - _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); - } - -/* driInitTextureObjects( ctx, & intel->swapped, */ -/* DRI_TEXMGR_DO_TEXTURE_1D | */ -/* DRI_TEXMGR_DO_TEXTURE_2D | */ -/* DRI_TEXMGR_DO_TEXTURE_RECT ); */ - - - intelInitBatchBuffer(&intel->ctx); - intel->prim.flush = intel_emit_invarient_state; - intel->prim.primitive = ~0; - - -#if DO_DEBUG - INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ), - debug_control ); - INTEL_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ), - debug_control ); -#endif - -#ifndef VERBOSE - if (getenv("INTEL_VERBOSE")) - VERBOSE=1; -#endif - - if (getenv("INTEL_NO_RAST") || - getenv("INTEL_NO_RAST")) { - fprintf(stderr, "disabling 3D rasterization\n"); - FALLBACK(intel, INTEL_FALLBACK_USER, 1); - } - - return GL_TRUE; -} - -void intelDestroyContext(__DRIcontextPrivate *driContextPriv) -{ - intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate; - - assert(intel); /* should never be null */ - if (intel) { - GLboolean release_texture_heaps; - - INTEL_FIREVERTICES( intel ); - - intel->vtbl.destroy( intel ); - - release_texture_heaps = (intel->ctx.Shared->RefCount == 1); - _swsetup_DestroyContext (&intel->ctx); - _tnl_DestroyContext (&intel->ctx); - _vbo_DestroyContext (&intel->ctx); - - _swrast_DestroyContext (&intel->ctx); - intel->Fallback = 0; /* don't call _swrast_Flush later */ - - intelDestroyBatchBuffer(&intel->ctx); - - - if ( release_texture_heaps ) { - /* This share group is about to go away, free our private - * texture object data. - */ - int i; - - for ( i = 0 ; i < intel->nr_heaps ; i++ ) { - driDestroyTextureHeap( intel->texture_heaps[ i ] ); - intel->texture_heaps[ i ] = NULL; - } - - assert( is_empty_list( & intel->swapped ) ); - } - - /* free the Mesa context */ - _mesa_destroy_context(&intel->ctx); - } -} - -void intelSetFrontClipRects( intelContextPtr intel ) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - if (!dPriv) return; - - intel->numClipRects = dPriv->numClipRects; - intel->pClipRects = dPriv->pClipRects; - intel->drawX = dPriv->x; - intel->drawY = dPriv->y; -} - - -void intelSetBackClipRects( intelContextPtr intel ) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - if (!dPriv) return; - - if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { - intel->numClipRects = dPriv->numClipRects; - intel->pClipRects = dPriv->pClipRects; - intel->drawX = dPriv->x; - intel->drawY = dPriv->y; - } else { - intel->numClipRects = dPriv->numBackClipRects; - intel->pClipRects = dPriv->pBackClipRects; - intel->drawX = dPriv->backX; - intel->drawY = dPriv->backY; - - if (dPriv->numBackClipRects == 1 && - dPriv->x == dPriv->backX && - dPriv->y == dPriv->backY) { - - /* Repeat the calculation of the back cliprect dimensions here - * as early versions of dri.a in the Xserver are incorrect. Try - * very hard not to restrict future versions of dri.a which - * might eg. allocate truly private back buffers. - */ - int x1, y1; - int x2, y2; - - x1 = dPriv->x; - y1 = dPriv->y; - x2 = dPriv->x + dPriv->w; - y2 = dPriv->y + dPriv->h; - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width; - if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height; - - if (x1 == dPriv->pBackClipRects[0].x1 && - y1 == dPriv->pBackClipRects[0].y1) { - - dPriv->pBackClipRects[0].x2 = x2; - dPriv->pBackClipRects[0].y2 = y2; - } - } - } -} - - -void intelWindowMoved( intelContextPtr intel ) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - GLframebuffer *drawFb = (GLframebuffer *) dPriv->driverPrivate; - - if (!intel->ctx.DrawBuffer) { - intelSetFrontClipRects( intel ); - } - else { - driUpdateFramebufferSize(&intel->ctx, dPriv); - switch (drawFb->_ColorDrawBufferMask[0]) { - case BUFFER_BIT_FRONT_LEFT: - intelSetFrontClipRects( intel ); - break; - case BUFFER_BIT_BACK_LEFT: - intelSetBackClipRects( intel ); - break; - default: - /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ - intelSetFrontClipRects( intel ); - } - } - - if (drawFb->Width != dPriv->w || drawFb->Height != dPriv->h) { - /* update Mesa's notion of framebuffer/window size */ - _mesa_resize_framebuffer(&intel->ctx, drawFb, dPriv->w, dPriv->h); - drawFb->Initialized = GL_TRUE; /* XXX remove someday */ - } - - /* Set state we know depends on drawable parameters: - */ - { - GLcontext *ctx = &intel->ctx; - - if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) { - drmI830Sarea *sarea = intel->sarea; - drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, - .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; - drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, - .x2 = sarea->planeA_x + sarea->planeA_w, - .y1 = sarea->planeA_y, - .y2 = sarea->planeA_y + sarea->planeA_h }; - drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, - .x2 = sarea->planeB_x + sarea->planeB_w, - .y1 = sarea->planeB_y, - .y2 = sarea->planeB_y + sarea->planeB_h }; - GLint areaA = driIntersectArea( drw_rect, planeA_rect ); - GLint areaB = driIntersectArea( drw_rect, planeB_rect ); - GLuint flags = intel->vblank_flags; - - if (areaB > areaA || (areaA == areaB && areaB > 0)) { - flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY; - } else { - flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY; - } - - if (flags != intel->vblank_flags) { - intel->vblank_flags = flags; - driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq); - } - } else { - intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY; - } - - ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height ); - - ctx->Driver.DepthRange( ctx, - ctx->Viewport.Near, - ctx->Viewport.Far ); - } -} - -GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv) -{ - return GL_TRUE; -} - -GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) -{ - - if (driContextPriv) { - intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate; - - if ( intel->driDrawable != driDrawPriv ) { - /* Shouldn't the readbuffer be stored also? */ - driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, - &intel->vbl_seq ); - - intel->driDrawable = driDrawPriv; - intelWindowMoved( intel ); - } - - _mesa_make_current(&intel->ctx, - (GLframebuffer *) driDrawPriv->driverPrivate, - (GLframebuffer *) driReadPriv->driverPrivate); - - intel->ctx.Driver.DrawBuffer( &intel->ctx, intel->ctx.Color.DrawBuffer[0] ); - } else { - _mesa_make_current(NULL, NULL, NULL); - } - - return GL_TRUE; -} - -/** - * Use the information in the sarea to update the screen parameters - * related to screen rotation. - */ -static void -intelUpdateScreenRotation(intelContextPtr intel, - __DRIscreenPrivate *sPriv, - drmI830Sarea *sarea) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - intelRegion *colorBuf; - - intelUnmapScreenRegions(intelScreen); - - intelUpdateScreenFromSAREA(intelScreen, sarea); - - /* update the current hw offsets for the color and depth buffers */ - if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) - colorBuf = &intelScreen->back; - else - colorBuf = &intelScreen->front; - intel->vtbl.update_color_z_regions(intel, colorBuf, &intelScreen->depth); - - if (!intelMapScreenRegions(sPriv)) { - fprintf(stderr, "ERROR Remapping screen regions!!!\n"); - } -} - -void intelGetLock( intelContextPtr intel, GLuint flags ) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - __DRIscreenPrivate *sPriv = intel->driScreen; - intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - drmI830Sarea * sarea = intel->sarea; - unsigned i; - - drmGetLock(intel->driFd, intel->hHWContext, flags); - - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - if (dPriv) - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - - if (dPriv && intel->lastStamp != dPriv->lastStamp) { - intelWindowMoved( intel ); - intel->lastStamp = dPriv->lastStamp; - } - - /* If we lost context, need to dump all registers to hardware. - * Note that we don't care about 2d contexts, even if they perform - * accelerated commands, so the DRI locking in the X server is even - * more broken than usual. - */ - - if (sarea->width != intelScreen->width || - sarea->height != intelScreen->height || - sarea->rotation != intelScreen->current_rotation) { - intelUpdateScreenRotation(intel, sPriv, sarea); - - /* This will drop the outstanding batchbuffer on the floor */ - intel->batch.ptr -= (intel->batch.size - intel->batch.space); - intel->batch.space = intel->batch.size; - /* lose all primitives */ - intel->prim.primitive = ~0; - intel->prim.start_ptr = 0; - intel->prim.flush = 0; - intel->vtbl.lost_hardware( intel ); - - intel->lastStamp = 0; /* force window update */ - - /* Release batch buffer - */ - intelDestroyBatchBuffer(&intel->ctx); - intelInitBatchBuffer(&intel->ctx); - intel->prim.flush = intel_emit_invarient_state; - - /* Still need to reset the global LRU? - */ - intel_driReinitTextureHeap( intel->texture_heaps[0], intel->intelScreen->tex.size ); - } - - /* Shared texture managment - if another client has played with - * texture space, figure out which if any of our textures have been - * ejected, and update our global LRU. - */ - for ( i = 0 ; i < intel->nr_heaps ; i++ ) { - DRI_AGE_TEXTURES( intel->texture_heaps[ i ] ); - } -} - - -void intelSwapBuffers( __DRIdrawablePrivate *dPriv ) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - intelContextPtr intel; - GLcontext *ctx; - intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate; - ctx = &intel->ctx; - if (ctx->Visual.doubleBufferMode) { - intelScreenPrivate *screen = intel->intelScreen; - _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ - if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */ - intelPageFlip( dPriv ); - } else { - intelCopyBuffer( dPriv, NULL ); - } - if (screen->current_rotation != 0) { - intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); - } - } - } else { - /* XXX this shouldn't be an error but we can't handle it for now */ - fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); - } -} - -void intelCopySubBuffer( __DRIdrawablePrivate *dPriv, - int x, int y, int w, int h ) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - intelContextPtr intel; - GLcontext *ctx; - intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate; - ctx = &intel->ctx; - if (ctx->Visual.doubleBufferMode) { - drm_clip_rect_t rect; - rect.x1 = x + dPriv->x; - rect.y1 = (dPriv->h - y - h) + dPriv->y; - rect.x2 = rect.x1 + w; - rect.y2 = rect.y1 + h; - _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ - intelCopyBuffer( dPriv, &rect ); - } - } else { - /* XXX this shouldn't be an error but we can't handle it for now */ - fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); - } -} diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h deleted file mode 100644 index 914533d11b..0000000000 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ /dev/null @@ -1,564 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTELCONTEXT_INC -#define INTELCONTEXT_INC - - - -#include "mtypes.h" -#include "drm.h" -#include "mm.h" -#include "texmem.h" -#include "vblank.h" - -#include "intel_screen.h" -#include "i915_drm.h" -#include "i830_common.h" -#include "tnl/t_vertex.h" - -#define TAG(x) intel##x -#include "tnl_dd/t_dd_vertex.h" -#undef TAG - -#define DV_PF_555 (1<<8) -#define DV_PF_565 (2<<8) -#define DV_PF_8888 (3<<8) - -#define INTEL_CONTEXT(ctx) ((intelContextPtr)(ctx)) - -typedef struct intel_context intelContext; -typedef struct intel_context *intelContextPtr; -typedef struct intel_texture_object *intelTextureObjectPtr; - -typedef void (*intel_tri_func)(intelContextPtr, intelVertex *, intelVertex *, - intelVertex *); -typedef void (*intel_line_func)(intelContextPtr, intelVertex *, intelVertex *); -typedef void (*intel_point_func)(intelContextPtr, intelVertex *); - -#define INTEL_FALLBACK_DRAW_BUFFER 0x1 -#define INTEL_FALLBACK_READ_BUFFER 0x2 -#define INTEL_FALLBACK_USER 0x4 -#define INTEL_FALLBACK_NO_BATCHBUFFER 0x8 -#define INTEL_FALLBACK_NO_TEXMEM 0x10 -#define INTEL_FALLBACK_RENDERMODE 0x20 - -extern void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode ); -#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode ) - - -#define INTEL_TEX_MAXLEVELS 10 - - -struct intel_texture_object -{ - driTextureObject base; /* the parent class */ - - GLuint texelBytes; - GLuint age; - GLuint Pitch; - GLuint Height; - GLuint TextureOffset; - GLubyte *BufAddr; - - GLuint min_level; - GLuint max_level; - GLuint depth_pitch; - - struct { - const struct gl_texture_image *image; - GLuint offset; /* into BufAddr */ - GLuint height; - GLuint internalFormat; - } image[6][INTEL_TEX_MAXLEVELS]; - - GLuint dirty; - GLuint firstLevel,lastLevel; -}; - - -struct intel_context -{ - GLcontext ctx; /* the parent class */ - - struct { - void (*destroy)( intelContextPtr intel ); - void (*emit_state)( intelContextPtr intel ); - void (*lost_hardware)( intelContextPtr intel ); - void (*update_texture_state)( intelContextPtr intel ); - - void (*render_start)( intelContextPtr intel ); - void (*render_prevalidate) (struct intel_context * intel); - void (*set_color_region)( intelContextPtr intel, const intelRegion *reg ); - void (*set_z_region)( intelContextPtr intel, const intelRegion *reg ); - void (*update_color_z_regions)(intelContextPtr intel, - const intelRegion *colorRegion, - const intelRegion *depthRegion); - void (*emit_flush)( intelContextPtr intel ); - void (*reduced_primitive_state)( intelContextPtr intel, GLenum rprim ); - - GLboolean (*check_vertex_size)( intelContextPtr intel, GLuint expected ); - - void (*clear_with_tris)( intelContextPtr intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch); - - void (*rotate_window)( intelContextPtr intel, - __DRIdrawablePrivate *dPriv, GLuint srcBuf); - - intelTextureObjectPtr (*alloc_tex_obj)( struct gl_texture_object *tObj ); - - } vtbl; - - GLint refcount; - GLuint Fallback; - GLuint NewGLState; - - struct { - GLuint start_offset; - GLint size; - GLint space; - GLubyte *ptr; - GLuint counter; - GLuint last_emit_state; - GLboolean contains_geometry; - const char *func; - GLuint last_swap; - } batch; - - struct { - void *ptr; - GLint size; - GLuint offset; - GLuint active_buf; - GLuint irq_emitted; - } alloc; - - struct { - GLuint primitive; - GLubyte *start_ptr; - void (*flush)( GLcontext * ); - } prim; - - GLboolean locked; - - GLubyte clear_red; - GLubyte clear_green; - GLubyte clear_blue; - GLubyte clear_alpha; - GLuint ClearColor; - GLuint ClearDepth; - - GLuint coloroffset; - GLuint specoffset; - - /* Support for duplicating XYZW as WPOS parameter (crutch for I915). - */ - GLuint wpos_offset; - GLuint wpos_size; - - struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; - GLuint vertex_attr_count; - - GLfloat depth_scale; - GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */ - GLuint depth_clear_mask; - GLuint stencil_clear_mask; - - GLboolean hw_stencil; - GLboolean hw_stipple; - - /* Texture object bookkeeping - */ - GLuint nr_heaps; - driTexHeap * texture_heaps[1]; - driTextureObject swapped; - GLuint lastStamp; - - struct intel_texture_object *CurrentTexObj[MAX_TEXTURE_UNITS]; - - /* State for intelvb.c and inteltris.c. - */ - GLuint RenderIndex; - GLmatrix ViewportMatrix; - GLenum render_primitive; - GLenum reduced_primitive; - GLuint vertex_size; - unsigned char *verts; /* points to tnl->clipspace.vertex_buf */ - - - /* Fallback rasterization functions - */ - intel_point_func draw_point; - intel_line_func draw_line; - intel_tri_func draw_tri; - - /* Drawing buffer state - */ - intelRegion *drawRegion; /* current drawing buffer */ - intelRegion *readRegion; /* current reading buffer */ - - int drawX; /* origin of drawable in draw buffer */ - int drawY; - GLuint numClipRects; /* cliprects for that buffer */ - drm_clip_rect_t *pClipRects; - - int dirtyAge; - int perf_boxes; - - GLuint do_usleeps; - int do_irqs; - GLuint irqsEmitted; - drm_i915_irq_wait_t iw; - - GLboolean scissor; - drm_clip_rect_t draw_rect; - drm_clip_rect_t scissor_rect; - - drm_context_t hHWContext; - drmLock *driHwLock; - int driFd; - - __DRIdrawablePrivate *driDrawable; - __DRIscreenPrivate *driScreen; - intelScreenPrivate *intelScreen; - drmI830Sarea *sarea; - - /** - * Configuration cache - */ - driOptionCache optionCache; - - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - - int64_t swap_ust; - int64_t swap_missed_ust; - - GLuint swap_count; - GLuint swap_missed_count; - - GLuint swap_scheduled; -}; - - -#define DEBUG_LOCKING 1 - -#if DEBUG_LOCKING -extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -/* Slightly less broken way of detecting recursive locking in a - * threaded environment. The right way to do this would be to make - * prevLockFile, prevLockLine thread-local. - * - * This technique instead checks to see if the same context is - * requesting the lock twice -- this will not catch application - * breakages where the same context is active in two different threads - * at once, but it will catch driver breakages (recursive locking) in - * threaded apps. - */ -#define DEBUG_CHECK_LOCK() \ - do { \ - if ( *((volatile int *)intel->driHwLock) == \ - (DRM_LOCK_HELD | intel->hHWContext) ) { \ - fprintf( stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ - abort(); \ - } \ - } while (0) - -#else - -#define DEBUG_LOCK() -#define DEBUG_RESET() -#define DEBUG_CHECK_LOCK() - -#endif - - - - -/* Lock the hardware and validate our state. - */ -#define LOCK_HARDWARE( intel ) \ -do { \ - char __ret=0; \ - DEBUG_CHECK_LOCK(); \ - assert(!(intel)->locked); \ - if ((intel)->swap_scheduled) { \ - drmVBlank vbl; \ - vbl.request.type = DRM_VBLANK_ABSOLUTE; \ - if ((intel)->vblank_flags & \ - VBLANK_FLAG_SECONDARY) { \ - vbl.request.type |= DRM_VBLANK_SECONDARY; \ - } \ - vbl.request.sequence = (intel)->vbl_seq; \ - drmWaitVBlank((intel)->driFd, &vbl); \ - (intel)->swap_scheduled = 0; \ - } \ - DRM_CAS((intel)->driHwLock, (intel)->hHWContext, \ - (DRM_LOCK_HELD|(intel)->hHWContext), __ret); \ - if (__ret) \ - intelGetLock( (intel), 0 ); \ - DEBUG_LOCK(); \ - (intel)->locked = 1; \ -}while (0) - - - /* Unlock the hardware using the global current context - */ -#define UNLOCK_HARDWARE(intel) \ -do { \ - intel->locked = 0; \ - if (0) { \ - intel->perf_boxes |= intel->sarea->perf_boxes; \ - intel->sarea->perf_boxes = 0; \ - } \ - DRM_UNLOCK((intel)->driFd, (intel)->driHwLock, (intel)->hHWContext); \ - DEBUG_RESET(); \ -} while (0) - - -#define SUBPIXEL_X 0.125 -#define SUBPIXEL_Y 0.125 - -#define INTEL_FIREVERTICES(intel) \ -do { \ - if ((intel)->prim.flush) \ - (intel)->prim.flush(&(intel)->ctx); \ -} while (0) - -/* ================================================================ - * Color packing: - */ - -#define INTEL_PACKCOLOR4444(r,g,b,a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) - -#define INTEL_PACKCOLOR1555(r,g,b,a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) - -#define INTEL_PACKCOLOR565(r,g,b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) - -#define INTEL_PACKCOLOR8888(r,g,b,a) \ - ((a<<24) | (r<<16) | (g<<8) | b) - - -#define INTEL_PACKCOLOR(format, r, g, b, a) \ -(format == DV_PF_555 ? INTEL_PACKCOLOR1555(r,g,b,a) : \ - (format == DV_PF_565 ? INTEL_PACKCOLOR565(r,g,b) : \ - (format == DV_PF_8888 ? INTEL_PACKCOLOR8888(r,g,b,a) : \ - 0))) - - - -/* ================================================================ - * From linux kernel i386 header files, copes with odd sizes better - * than COPY_DWORDS would: - */ -#if defined(i386) || defined(__i386__) -static __inline__ void * __memcpy(void * to, const void * from, size_t n) -{ - int d0, d1, d2; - __asm__ __volatile__( - "rep ; movsl\n\t" - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) - : "memory"); - return (to); -} -#else -#define __memcpy(a,b,c) memcpy(a,b,c) -#endif - - - -/* ================================================================ - * Debugging: - */ -#define DO_DEBUG 1 -#if DO_DEBUG -extern int INTEL_DEBUG; -#else -#define INTEL_DEBUG 0 -#endif - -#define DEBUG_TEXTURE 0x1 -#define DEBUG_STATE 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_PRIMS 0x8 -#define DEBUG_VERTS 0x10 -#define DEBUG_FALLBACKS 0x20 -#define DEBUG_VERBOSE 0x40 -#define DEBUG_DRI 0x80 -#define DEBUG_DMA 0x100 -#define DEBUG_SANITY 0x200 -#define DEBUG_SYNC 0x400 -#define DEBUG_SLEEP 0x800 -#define DEBUG_PIXEL 0x1000 - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_Q33_G 0x29D2 - - -/* ================================================================ - * intel_context.c: - */ - -extern void intelInitDriverFunctions( struct dd_function_table *functions ); - -extern GLboolean intelInitContext( intelContextPtr intel, - const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate, - struct dd_function_table *functions ); - -extern void intelGetLock(intelContextPtr intel, GLuint flags); -extern void intelSetBackClipRects(intelContextPtr intel); -extern void intelSetFrontClipRects(intelContextPtr intel); -extern void intelWindowMoved( intelContextPtr intel ); - -extern const GLubyte *intelGetString( GLcontext *ctx, GLenum name ); - - -/* ================================================================ - * intel_state.c: - */ -extern void intelInitStateFuncs( struct dd_function_table *functions ); - -#define COMPAREFUNC_ALWAYS 0 -#define COMPAREFUNC_NEVER 0x1 -#define COMPAREFUNC_LESS 0x2 -#define COMPAREFUNC_EQUAL 0x3 -#define COMPAREFUNC_LEQUAL 0x4 -#define COMPAREFUNC_GREATER 0x5 -#define COMPAREFUNC_NOTEQUAL 0x6 -#define COMPAREFUNC_GEQUAL 0x7 - -#define STENCILOP_KEEP 0 -#define STENCILOP_ZERO 0x1 -#define STENCILOP_REPLACE 0x2 -#define STENCILOP_INCRSAT 0x3 -#define STENCILOP_DECRSAT 0x4 -#define STENCILOP_INCR 0x5 -#define STENCILOP_DECR 0x6 -#define STENCILOP_INVERT 0x7 - -#define LOGICOP_CLEAR 0 -#define LOGICOP_NOR 0x1 -#define LOGICOP_AND_INV 0x2 -#define LOGICOP_COPY_INV 0x3 -#define LOGICOP_AND_RVRSE 0x4 -#define LOGICOP_INV 0x5 -#define LOGICOP_XOR 0x6 -#define LOGICOP_NAND 0x7 -#define LOGICOP_AND 0x8 -#define LOGICOP_EQUIV 0x9 -#define LOGICOP_NOOP 0xa -#define LOGICOP_OR_INV 0xb -#define LOGICOP_COPY 0xc -#define LOGICOP_OR_RVRSE 0xd -#define LOGICOP_OR 0xe -#define LOGICOP_SET 0xf - -#define BLENDFACT_ZERO 0x01 -#define BLENDFACT_ONE 0x02 -#define BLENDFACT_SRC_COLR 0x03 -#define BLENDFACT_INV_SRC_COLR 0x04 -#define BLENDFACT_SRC_ALPHA 0x05 -#define BLENDFACT_INV_SRC_ALPHA 0x06 -#define BLENDFACT_DST_ALPHA 0x07 -#define BLENDFACT_INV_DST_ALPHA 0x08 -#define BLENDFACT_DST_COLR 0x09 -#define BLENDFACT_INV_DST_COLR 0x0a -#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b -#define BLENDFACT_CONST_COLOR 0x0c -#define BLENDFACT_INV_CONST_COLOR 0x0d -#define BLENDFACT_CONST_ALPHA 0x0e -#define BLENDFACT_INV_CONST_ALPHA 0x0f -#define BLENDFACT_MASK 0x0f - - -extern int intel_translate_compare_func( GLenum func ); -extern int intel_translate_stencil_op( GLenum op ); -extern int intel_translate_blend_factor( GLenum factor ); -extern int intel_translate_logic_op( GLenum opcode ); - - -/* ================================================================ - * intel_ioctl.c: - */ -extern void intel_dump_batchbuffer( long offset, - int *ptr, - int count ); - - -/* ================================================================ - * intel_pixel.c: - */ -extern void intelInitPixelFuncs( struct dd_function_table *functions ); - - - -#endif - diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c deleted file mode 100644 index ddd92782db..0000000000 --- a/src/mesa/drivers/dri/i915/intel_ioctl.c +++ /dev/null @@ -1,668 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include -#include -#include -#include - -#include "mtypes.h" -#include "context.h" -#include "swrast/swrast.h" - -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "drm.h" - -u_int32_t intelGetLastFrame (intelContextPtr intel) -{ - int ret; - u_int32_t frame; - drm_i915_getparam_t gp; - - gp.param = I915_PARAM_LAST_DISPATCH; - gp.value = (int *)&frame; - ret = drmCommandWriteRead( intel->driFd, DRM_I915_GETPARAM, - &gp, sizeof(gp) ); - return frame; -} - -/** - * Emits a marker in the command stream, numbered from 0x00000001 to - * 0x7fffffff. - */ -int intelEmitIrqLocked( intelContextPtr intel ) -{ - drmI830IrqEmit ie; - int ret, seq; - - assert(((*(int *)intel->driHwLock) & ~DRM_LOCK_CONT) == - (DRM_LOCK_HELD|intel->hHWContext)); - - /* Valgrind can't tell that the kernel will have copyout()ed onto this - * value, so initialize it now to prevent false positives. - */ - seq = 0; - ie.irq_seq = &seq; - - ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT, - &ie, sizeof(ie) ); - if ( ret ) { - fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret ); - exit(1); - } - - if (0) - fprintf(stderr, "%s --> %d\n", __FUNCTION__, seq ); - - return seq; -} - -/** Blocks on a marker returned by intelEitIrqLocked(). */ -void intelWaitIrq( intelContextPtr intel, int seq ) -{ - int ret; - - if (0) - fprintf(stderr, "%s %d\n", __FUNCTION__, seq ); - - intel->iw.irq_seq = seq; - - do { - ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, sizeof(intel->iw) ); - } while (ret == -EAGAIN || ret == -EINTR); - - if ( ret ) { - fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret ); - if (0) - intel_dump_batchbuffer( intel->alloc.offset, - intel->alloc.ptr, - intel->alloc.size ); - exit(1); - } -} - - - -static void age_intel( intelContextPtr intel, int age ) -{ - GLuint i; - - for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) - if (intel->CurrentTexObj[i]) - intel->CurrentTexObj[i]->age = age; -} - -void intel_dump_batchbuffer( long offset, - int *ptr, - int count ) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count); - for (i = 0; i < count/4; i += 4) - fprintf(stderr, "\t0x%x: 0x%08x 0x%08x 0x%08x 0x%08x\n", - (unsigned int)offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]); - fprintf(stderr, "END BATCH\n\n\n"); -} - -void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock ) -{ - GLuint last_irq = intel->alloc.irq_emitted; - GLuint half = intel->alloc.size / 2; - GLuint buf = (intel->alloc.active_buf ^= 1); - - intel->alloc.irq_emitted = intelEmitIrqLocked( intel ); - - if (last_irq) { - if (allow_unlock) UNLOCK_HARDWARE( intel ); - intelWaitIrq( intel, last_irq ); - if (allow_unlock) LOCK_HARDWARE( intel ); - } - - if (0) - fprintf(stderr, "%s: now using half %d\n", __FUNCTION__, buf); - - intel->batch.start_offset = intel->alloc.offset + buf * half; - intel->batch.ptr = (unsigned char *)intel->alloc.ptr + buf * half; - intel->batch.size = half - 8; - intel->batch.space = half - 8; - assert(intel->batch.space >= 0); -} - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -void intelFlushBatchLocked( intelContextPtr intel, - GLboolean ignore_cliprects, - GLboolean refill, - GLboolean allow_unlock) -{ - drmI830BatchBuffer batch; - - assert(intel->locked); - - if (0) - fprintf(stderr, "%s used %d of %d offset %x..%x refill %d (started in %s)\n", - __FUNCTION__, - (intel->batch.size - intel->batch.space), - intel->batch.size, - intel->batch.start_offset, - intel->batch.start_offset + - (intel->batch.size - intel->batch.space), - refill, - intel->batch.func); - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - if (intel->numClipRects == 0 && !ignore_cliprects) { - - /* Without this yeild, an application with no cliprects can hog - * the hardware. Without unlocking, the effect is much worse - - * effectively a lock-out of other contexts. - */ - if (allow_unlock) { - UNLOCK_HARDWARE( intel ); - sched_yield(); - LOCK_HARDWARE( intel ); - } - - /* Note that any state thought to have been emitted actually - * hasn't: - */ - intel->batch.ptr -= (intel->batch.size - intel->batch.space); - intel->batch.space = intel->batch.size; - intel->vtbl.lost_hardware( intel ); - } - - if (intel->batch.space != intel->batch.size) { - - if (intel->sarea->ctxOwner != intel->hHWContext) { - intel->perf_boxes |= I830_BOX_LOST_CONTEXT; - intel->sarea->ctxOwner = intel->hHWContext; - } - - batch.start = intel->batch.start_offset; - batch.used = intel->batch.size - intel->batch.space; - batch.cliprects = intel->pClipRects; - batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - batch.DR1 = 0; - batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) | - (((GLuint)intel->drawY) << 16)); - - if (intel->alloc.offset) { - if ((batch.used & 0x4) == 0) { - ((int *)intel->batch.ptr)[0] = 0; - ((int *)intel->batch.ptr)[1] = MI_BATCH_BUFFER_END; - batch.used += 0x8; - intel->batch.ptr += 0x8; - } - else { - ((int *)intel->batch.ptr)[0] = MI_BATCH_BUFFER_END; - batch.used += 0x4; - intel->batch.ptr += 0x4; - } - } - - if (0) - intel_dump_batchbuffer( batch.start, - (int *)(intel->batch.ptr - batch.used), - batch.used ); - - intel->batch.start_offset += batch.used; - intel->batch.size -= batch.used; - - if (intel->batch.size < 8) { - refill = GL_TRUE; - intel->batch.space = intel->batch.size = 0; - } - else { - intel->batch.size -= 8; - intel->batch.space = intel->batch.size; - } - - - assert(intel->batch.space >= 0); - assert(batch.start >= intel->alloc.offset); - assert(batch.start < intel->alloc.offset + intel->alloc.size); - assert(batch.start + batch.used > intel->alloc.offset); - assert(batch.start + batch.used <= - intel->alloc.offset + intel->alloc.size); - - - if (intel->alloc.offset) { - if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch, - sizeof(batch))) { - fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } - } else { - drmI830CmdBuffer cmd; - cmd.buf = (char *)intel->alloc.ptr + batch.start; - cmd.sz = batch.used; - cmd.DR1 = batch.DR1; - cmd.DR4 = batch.DR4; - cmd.num_cliprects = batch.num_cliprects; - cmd.cliprects = batch.cliprects; - - if (drmCommandWrite (intel->driFd, DRM_I830_CMDBUFFER, &cmd, - sizeof(cmd))) { - fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } - } - - - age_intel(intel, intel->sarea->last_enqueue); - - /* FIXME: use hardware contexts to avoid 'losing' hardware after - * each buffer flush. - */ - if (intel->batch.contains_geometry) - assert(intel->batch.last_emit_state == intel->batch.counter); - - intel->batch.counter++; - intel->batch.contains_geometry = 0; - intel->batch.func = 0; - intel->vtbl.lost_hardware( intel ); - } - - if (refill) - intelRefillBatchLocked( intel, allow_unlock ); -} - -void intelFlushBatch( intelContextPtr intel, GLboolean refill ) -{ - if (intel->locked) { - intelFlushBatchLocked( intel, GL_FALSE, refill, GL_FALSE ); - } - else { - LOCK_HARDWARE(intel); - intelFlushBatchLocked( intel, GL_FALSE, refill, GL_TRUE ); - UNLOCK_HARDWARE(intel); - } -} - - -void intelWaitForIdle( intelContextPtr intel ) -{ - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - - intel->vtbl.emit_flush( intel ); - intelFlushBatch( intel, GL_TRUE ); - - /* Use an irq to wait for dma idle -- Need to track lost contexts - * to shortcircuit consecutive calls to this function: - */ - intelWaitIrq( intel, intel->alloc.irq_emitted ); - intel->alloc.irq_emitted = 0; -} - - -/** - * Check if we need to rotate/warp the front color buffer to the - * rotated screen. We generally need to do this when we get a glFlush - * or glFinish after drawing to the front color buffer. - */ -static void -intelCheckFrontRotate(GLcontext *ctx) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { - intelScreenPrivate *screen = intel->intelScreen; - if (screen->current_rotation != 0) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); - } - } -} - - -/** - * NOT directly called via glFlush. - */ -void intelFlush( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - - if (intel->Fallback) - _swrast_flush( ctx ); - - INTEL_FIREVERTICES( intel ); - - if (intel->batch.size != intel->batch.space) - intelFlushBatch( intel, GL_FALSE ); -} - - -/** - * Called via glFlush. - */ -void intelglFlush( GLcontext *ctx ) -{ - intelFlush(ctx); - intelCheckFrontRotate(ctx); -} - - -void intelFinish( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - intelFlush( ctx ); - intelWaitForIdle( intel ); - intelCheckFrontRotate(ctx); -} - - -void intelClear(GLcontext *ctx, GLbitfield mask) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - GLbitfield tri_mask = 0; - GLbitfield blit_mask = 0; - GLbitfield swrast_mask = 0; - - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Take care of cliprects, which are handled differently for - * clears, etc. - */ - intelFlush( &intel->ctx ); - - if (mask & BUFFER_BIT_FRONT_LEFT) { - if (colorMask == ~0) { - blit_mask |= BUFFER_BIT_FRONT_LEFT; - } - else { - tri_mask |= BUFFER_BIT_FRONT_LEFT; - } - } - - if (mask & BUFFER_BIT_BACK_LEFT) { - if (colorMask == ~0) { - blit_mask |= BUFFER_BIT_BACK_LEFT; - } - else { - tri_mask |= BUFFER_BIT_BACK_LEFT; - } - } - - if (mask & BUFFER_BIT_DEPTH) { - blit_mask |= BUFFER_BIT_DEPTH; - } - - if (mask & BUFFER_BIT_STENCIL) { - if (!intel->hw_stencil) { - swrast_mask |= BUFFER_BIT_STENCIL; - } - else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { - tri_mask |= BUFFER_BIT_STENCIL; - } - else { - blit_mask |= BUFFER_BIT_STENCIL; - } - } - - swrast_mask |= (mask & BUFFER_BIT_ACCUM); - - if (blit_mask) - intelClearWithBlit( ctx, blit_mask, 0, 0, 0, 0, 0); - - if (tri_mask) - intel->vtbl.clear_with_tris( intel, tri_mask, 0, 0, 0, 0, 0); - - if (swrast_mask) - _swrast_Clear( ctx, swrast_mask ); -} - - -void -intelRotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv, - GLuint srcBuffer) -{ - if (intel->vtbl.rotate_window) { - intel->vtbl.rotate_window(intel, dPriv, srcBuffer); - } -} - - -void *intelAllocateAGP( intelContextPtr intel, GLsizei size ) -{ - int region_offset; - drmI830MemAlloc alloc; - int ret; - - if (0) - fprintf(stderr, "%s: %d bytes\n", __FUNCTION__, size); - - alloc.region = I830_MEM_REGION_AGP; - alloc.alignment = 0; - alloc.size = size; - alloc.region_offset = ®ion_offset; - - LOCK_HARDWARE(intel); - - /* Make sure the global heap is initialized - */ - if (intel->texture_heaps[0]) - driAgeTextures( intel->texture_heaps[0] ); - - - ret = drmCommandWriteRead( intel->driFd, - DRM_I830_ALLOC, - &alloc, sizeof(alloc)); - - if (ret) { - fprintf(stderr, "%s: DRM_I830_ALLOC ret %d\n", __FUNCTION__, ret); - UNLOCK_HARDWARE(intel); - return NULL; - } - - if (0) - fprintf(stderr, "%s: allocated %d bytes\n", __FUNCTION__, size); - - /* Need to propogate this information (agp memory in use) to our - * local texture lru. The kernel has already updated the global - * lru. An alternative would have been to allocate memory the - * usual way and then notify the kernel to pin the allocation. - */ - if (intel->texture_heaps[0]) - driAgeTextures( intel->texture_heaps[0] ); - - UNLOCK_HARDWARE(intel); - - return (void *)((char *)intel->intelScreen->tex.map + region_offset); -} - -void intelFreeAGP( intelContextPtr intel, void *pointer ) -{ - int region_offset; - drmI830MemFree memfree; - int ret; - - region_offset = (char *)pointer - (char *)intel->intelScreen->tex.map; - - if (region_offset < 0 || - region_offset > intel->intelScreen->tex.size) { - fprintf(stderr, "offset %d outside range 0..%d\n", region_offset, - intel->intelScreen->tex.size); - return; - } - - memfree.region = I830_MEM_REGION_AGP; - memfree.region_offset = region_offset; - - ret = drmCommandWrite( intel->driFd, - DRM_I830_FREE, - &memfree, sizeof(memfree)); - - if (ret) - fprintf(stderr, "%s: DRM_I830_FREE ret %d\n", __FUNCTION__, ret); -} - -/* This version of AllocateMemoryMESA allocates only agp memory, and - * only does so after the point at which the driver has been - * initialized. - * - * Theoretically a valid context isn't required. However, in this - * implementation, it is, as I'm using the hardware lock to protect - * the kernel data structures, and the current context to get the - * device fd. - */ -void *intelAllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn, - GLsizei size, GLfloat readfreq, - GLfloat writefreq, GLfloat priority) -{ - GET_CURRENT_CONTEXT(ctx); - - if (INTEL_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq, - writefreq, priority); - - if (getenv("INTEL_NO_ALLOC")) - return NULL; - - if (!ctx || INTEL_CONTEXT(ctx) == 0) - return NULL; - - return intelAllocateAGP( INTEL_CONTEXT(ctx), size ); -} - - -/* Called via glXFreeMemoryMESA() */ -void intelFreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer) -{ - GET_CURRENT_CONTEXT(ctx); - if (INTEL_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s %p\n", __FUNCTION__, pointer); - - if (!ctx || INTEL_CONTEXT(ctx) == 0) { - fprintf(stderr, "%s: no context\n", __FUNCTION__); - return; - } - - intelFreeAGP( INTEL_CONTEXT(ctx), pointer ); -} - -/* Called via glXGetMemoryOffsetMESA() - * - * Returns offset of pointer from the start of agp aperture. - */ -GLuint intelGetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn, - const GLvoid *pointer) -{ - GET_CURRENT_CONTEXT(ctx); - intelContextPtr intel; - - if (!ctx || !(intel = INTEL_CONTEXT(ctx)) ) { - fprintf(stderr, "%s: no context\n", __FUNCTION__); - return ~0; - } - - if (!intelIsAgpMemory( intel, pointer, 0 )) - return ~0; - - return intelAgpOffsetFromVirtual( intel, pointer ); -} - - -GLboolean intelIsAgpMemory( intelContextPtr intel, const GLvoid *pointer, - GLint size ) -{ - int offset = (char *)pointer - (char *)intel->intelScreen->tex.map; - int valid = (size >= 0 && - offset >= 0 && - offset + size < intel->intelScreen->tex.size); - - if (INTEL_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "intelIsAgpMemory( %p ) : %d\n", pointer, valid ); - - return valid; -} - - -GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *pointer ) -{ - int offset = (char *)pointer - (char *)intel->intelScreen->tex.map; - - if (offset < 0 || offset > intel->intelScreen->tex.size) - return ~0; - else - return intel->intelScreen->tex.offset + offset; -} - - - - - -/* Flip the front & back buffes - */ -void intelPageFlip( const __DRIdrawablePrivate *dPriv ) -{ -#if 0 - intelContextPtr intel; - int tmp, ret; - - if (INTEL_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate; - - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - - if (dPriv->pClipRects) { - *(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0]; - intel->sarea->nbox = 1; - } - - ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); - if (ret) { - fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); - UNLOCK_HARDWARE( intel ); - exit(1); - } - - tmp = intel->sarea->last_enqueue; - intelRefillBatchLocked( intel ); - UNLOCK_HARDWARE( intel ); - - - intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer ); -#endif -} diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h deleted file mode 100644 index 6ea47e462e..0000000000 --- a/src/mesa/drivers/dri/i915/intel_ioctl.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_IOCTL_H -#define INTEL_IOCTL_H - -#include "intel_context.h" - -extern void intelWaitAgeLocked( intelContextPtr intel, int age, GLboolean unlock ); - -extern void intelClear(GLcontext *ctx, GLbitfield mask); - -extern void intelPageFlip( const __DRIdrawablePrivate *dpriv ); - -extern void intelRotateWindow(intelContextPtr intel, - __DRIdrawablePrivate *dPriv, GLuint srcBuffer); - -extern void intelWaitForIdle( intelContextPtr intel ); -extern void intelFlushBatch( intelContextPtr intel, GLboolean refill ); -extern void intelFlushBatchLocked( intelContextPtr intel, - GLboolean ignore_cliprects, - GLboolean refill, - GLboolean allow_unlock); -extern void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock ); -extern void intelFinish( GLcontext *ctx ); -extern void intelFlush( GLcontext *ctx ); -extern void intelglFlush( GLcontext *ctx ); - -extern void *intelAllocateAGP( intelContextPtr intel, GLsizei size ); -extern void intelFreeAGP( intelContextPtr intel, void *pointer ); - -extern void *intelAllocateMemoryMESA( __DRInativeDisplay *dpy, int scrn, - GLsizei size, GLfloat readfreq, - GLfloat writefreq, GLfloat priority ); - -extern void intelFreeMemoryMESA( __DRInativeDisplay *dpy, int scrn, - GLvoid *pointer ); - -extern GLuint intelGetMemoryOffsetMESA( __DRInativeDisplay *dpy, int scrn, const GLvoid *pointer ); -extern GLboolean intelIsAgpMemory( intelContextPtr intel, const GLvoid *pointer, - GLint size ); - -extern GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *p ); - -extern void intelWaitIrq( intelContextPtr intel, int seq ); -extern u_int32_t intelGetLastFrame (intelContextPtr intel); -extern int intelEmitIrqLocked( intelContextPtr intel ); -#endif diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c deleted file mode 100644 index c3030d42b0..0000000000 --- a/src/mesa/drivers/dri/i915/intel_pixel.c +++ /dev/null @@ -1,524 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" - - - -static GLboolean -check_color( const GLcontext *ctx, GLenum type, GLenum format, - const struct gl_pixelstore_attrib *packing, - const void *pixels, GLint sz, GLint pitch ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - GLuint cpp = intel->intelScreen->cpp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if ( (pitch & 63) || - ctx->_ImageTransferState || - packing->SwapBytes || - packing->LsbFirst) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: failed 1\n", __FUNCTION__); - return GL_FALSE; - } - - if ( type == GL_UNSIGNED_INT_8_8_8_8_REV && - cpp == 4 && - format == GL_BGRA ) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: passed 2\n", __FUNCTION__); - return GL_TRUE; - } - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: failed\n", __FUNCTION__); - - return GL_FALSE; -} - -static GLboolean -check_color_per_fragment_ops( const GLcontext *ctx ) -{ - int result; - result = (!( ctx->Color.AlphaEnabled || - ctx->Depth.Test || - ctx->Fog.Enabled || - ctx->Scissor.Enabled || - ctx->Stencil.Enabled || - !ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3] || - ctx->Color.ColorLogicOpEnabled || - ctx->Texture._EnabledUnits - ) && - ctx->Current.RasterPosValid); - - return result; -} - - -/** - * Clip the given rectangle against the buffer's bounds (including scissor). - * \param size returns the - * \return GL_TRUE if any pixels remain, GL_FALSE if totally clipped. - * - * XXX Replace this with _mesa_clip_drawpixels() and _mesa_clip_readpixels() - * from Mesa 6.4. We shouldn't apply scissor for ReadPixels. - */ -static GLboolean -clip_pixelrect( const GLcontext *ctx, - const GLframebuffer *buffer, - GLint *x, GLint *y, - GLsizei *width, GLsizei *height) -{ - /* left clipping */ - if (*x < buffer->_Xmin) { - *width -= (buffer->_Xmin - *x); - *x = buffer->_Xmin; - } - - /* right clipping */ - if (*x + *width > buffer->_Xmax) - *width -= (*x + *width - buffer->_Xmax - 1); - - if (*width <= 0) - return GL_FALSE; - - /* bottom clipping */ - if (*y < buffer->_Ymin) { - *height -= (buffer->_Ymin - *y); - *y = buffer->_Ymin; - } - - /* top clipping */ - if (*y + *height > buffer->_Ymax) - *height -= (*y + *height - buffer->_Ymax - 1); - - if (*height <= 0) - return GL_FALSE; - - return GL_TRUE; -} - - -/** - * Compute intersection of a clipping rectangle and pixel rectangle, - * returning results in x/y/w/hOut vars. - * \return GL_TRUE if there's intersection, GL_FALSE if disjoint. - */ -static INLINE GLboolean -intersect_region(const drm_clip_rect_t *box, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint *xOut, GLint *yOut, GLint *wOut, GLint *hOut) -{ - GLint bx = box->x1; - GLint by = box->y1; - GLint bw = box->x2 - bx; - GLint bh = box->y2 - by; - - if (bx < x) bw -= x - bx, bx = x; - if (by < y) bh -= y - by, by = y; - if (bx + bw > x + width) bw = x + width - bx; - if (by + bh > y + height) bh = y + height - by; - - *xOut = bx; - *yOut = by; - *wOut = bw; - *hOut = bh; - - if (bw <= 0) return GL_FALSE; - if (bh <= 0) return GL_FALSE; - - return GL_TRUE; -} - - - -static GLboolean -intelTryReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - GLint size = 0; /* not really used */ - GLint pitch = pack->RowLength ? pack->RowLength : width; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Only accelerate reading to agp buffers. - */ - if ( !intelIsAgpMemory(intel, pixels, - pitch * height * intel->intelScreen->cpp ) ) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: dest not agp\n", __FUNCTION__); - return GL_FALSE; - } - - /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from - * blitter: - */ - if (!pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); - return GL_FALSE; - } - - if (!check_color(ctx, type, format, pack, pixels, size, pitch)) - return GL_FALSE; - - switch ( intel->intelScreen->cpp ) { - case 4: - break; - default: - return GL_FALSE; - } - - - /* Although the blits go on the command buffer, need to do this and - * fire with lock held to guarentee cliprects and drawing offset are - * correct. - * - * This is an unusual situation however, as the code which flushes - * a full command buffer expects to be called unlocked. As a - * workaround, immediately flush the buffer on aquiring the lock. - */ - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int nbox = dPriv->numClipRects; - int src_offset = intel->readRegion->offset; - int src_pitch = intel->intelScreen->front.pitch; - int dst_offset = intelAgpOffsetFromVirtual( intel, pixels); - drm_clip_rect_t *box = dPriv->pClipRects; - int i; - - assert(dst_offset != ~0); /* should have been caught above */ - - if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s totally clipped -- nothing to do\n", - __FUNCTION__); - return GL_TRUE; - } - - /* convert to screen coords (y=0=top) */ - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", - src_pitch, pitch); - - /* We don't really have to do window clipping for readpixels. - * The OpenGL spec says that pixels read from outside the - * visible window region (pixel ownership) have undefined value. - */ - for (i = 0 ; i < nbox ; i++) - { - GLint bx, by, bw, bh; - if (intersect_region(box+i, x, y, width, height, - &bx, &by, &bw, &bh)) { - intelEmitCopyBlitLocked( intel, - intel->intelScreen->cpp, - src_pitch, src_offset, - pitch, dst_offset, - bx, by, - bx - x, by - y, - bw, bh ); - } - } - } - UNLOCK_HARDWARE( intel ); - intelFinish( &intel->ctx ); - - return GL_TRUE; -} - -static void -intelReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (!intelTryReadPixels( ctx, x, y, width, height, format, type, pack, - pixels)) - _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, - pixels); -} - - - - -static void do_draw_pix( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint pitch, - const void *pixels, - GLuint dest ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - drm_clip_rect_t *box = dPriv->pClipRects; - int nbox = dPriv->numClipRects; - int i; - int src_offset = intelAgpOffsetFromVirtual( intel, pixels); - int src_pitch = pitch; - - assert(src_offset != ~0); /* should be caught earlier */ - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - if (ctx->DrawBuffer) - { - y -= height; /* cope with pixel zoom */ - - if (!clip_pixelrect(ctx, ctx->DrawBuffer, - &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - return; - } - - y = dPriv->h - y - height; /* convert from gl to hardware coords */ - x += dPriv->x; - y += dPriv->y; - - for (i = 0 ; i < nbox ; i++ ) - { - GLint bx, by, bw, bh; - if (intersect_region(box + i, x, y, width, height, - &bx, &by, &bw, &bh)) { - intelEmitCopyBlitLocked( intel, - intel->intelScreen->cpp, - src_pitch, src_offset, - intel->intelScreen->front.pitch, - intel->drawRegion->offset, - bx - x, by - y, - bx, by, - bw, bh ); - } - } - } - UNLOCK_HARDWARE( intel ); - intelFinish( &intel->ctx ); -} - - - -static GLboolean -intelTryDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - GLint pitch = unpack->RowLength ? unpack->RowLength : width; - GLuint dest; - GLuint cpp = intel->intelScreen->cpp; - GLint size = width * pitch * cpp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - switch (format) { - case GL_RGB: - case GL_RGBA: - case GL_BGRA: - dest = intel->drawRegion->offset; - - /* Planemask doesn't have full support in blits. - */ - if (!ctx->Color.ColorMask[RCOMP] || - !ctx->Color.ColorMask[GCOMP] || - !ctx->Color.ColorMask[BCOMP] || - !ctx->Color.ColorMask[ACOMP]) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: planemask\n", __FUNCTION__); - return GL_FALSE; - } - - /* Can't do conversions on agp reads/draws. - */ - if ( !intelIsAgpMemory( intel, pixels, size ) ) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: not agp memory\n", __FUNCTION__); - return GL_FALSE; - } - - if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) { - return GL_FALSE; - } - if (!check_color_per_fragment_ops(ctx)) { - return GL_FALSE; - } - - if (ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != -1.0F) - return GL_FALSE; - break; - - default: - return GL_FALSE; - } - - if ( intelIsAgpMemory(intel, pixels, size) ) - { - do_draw_pix( ctx, x, y, width, height, pitch, pixels, dest ); - return GL_TRUE; - } - else if (0) - { - /* Pixels is in regular memory -- get dma buffers and perform - * upload through them. No point doing this for regular uploads - * but once we remove some of the restrictions above (colormask, - * pixelformat conversion, zoom?, etc), this could be a win. - */ - } - else - return GL_FALSE; - - return GL_FALSE; -} - -static void -intelDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (intelTryDrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels )) - return; - - if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) { - /* - * We don't want the i915 texenv program to be applied to DrawPixels. - * This is really just a performance optimization (mesa will other- - * wise happily run the fragment program on each pixel in the image). - */ - struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current; - /* can't just set current frag prog to 0 here as on buffer resize - we'll get new state checks which will segfault. Remains a hack. */ - ctx->FragmentProgram._Current = NULL; - ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE; - ctx->FragmentProgram._Active = GL_FALSE; - _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); - ctx->FragmentProgram._Current = fpSave; - ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; - ctx->FragmentProgram._Active = GL_TRUE; - } - else { - _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); - } -} - - - - -/** - * Implement glCopyPixels for the front color buffer (or back buffer Pixmap) - * for the color buffer. Don't support zooming, pixel transfer, etc. - * We do support copying from one window to another, ala glXMakeCurrentRead. - */ -static void -intelCopyPixels( GLcontext *ctx, - GLint srcx, GLint srcy, GLsizei width, GLsizei height, - GLint destx, GLint desty, GLenum type ) -{ -#if 0 - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - const SWcontext *swrast = SWRAST_CONTEXT( ctx ); - XMesaDisplay *dpy = xmesa->xm_visual->display; - const XMesaDrawable drawBuffer = xmesa->xm_draw_buffer->buffer; - const XMesaDrawable readBuffer = xmesa->xm_read_buffer->buffer; - const XMesaGC gc = xmesa->xm_draw_buffer->gc; - - ASSERT(dpy); - ASSERT(gc); - - if (drawBuffer && /* buffer != 0 means it's a Window or Pixmap */ - readBuffer && - type == GL_COLOR && - (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ - ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ - ctx->Pixel.ZoomX == 1.0 && /* no zooming */ - ctx->Pixel.ZoomY == 1.0) { - /* Note: we don't do any special clipping work here. We could, - * but X will do it for us. - */ - srcy = FLIP(xmesa->xm_read_buffer, srcy) - height + 1; - desty = FLIP(xmesa->xm_draw_buffer, desty) - height + 1; - XCopyArea(dpy, readBuffer, drawBuffer, gc, - srcx, srcy, width, height, destx, desty); - } -#else - _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type ); -#endif -} - - - - -void intelInitPixelFuncs( struct dd_function_table *functions ) -{ - functions->CopyPixels = intelCopyPixels; - if (!getenv("INTEL_NO_BLITS")) { - functions->ReadPixels = intelReadPixels; - functions->DrawPixels = intelDrawPixels; - } -} diff --git a/src/mesa/drivers/dri/i915/intel_reg.h b/src/mesa/drivers/dri/i915/intel_reg.h deleted file mode 100644 index 1ec153266c..0000000000 --- a/src/mesa/drivers/dri/i915/intel_reg.h +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef _INTEL_REG_H_ -#define _INTEL_REG_H_ - - - -#define CMD_3D (0x3<<29) - - -#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24)) -#define PRIM_INDIRECT (1<<23) -#define PRIM_INLINE (0<<23) -#define PRIM_INDIRECT_SEQUENTIAL (0<<17) -#define PRIM_INDIRECT_ELTS (1<<17) - -#define PRIM3D_TRILIST (0x0<<18) -#define PRIM3D_TRISTRIP (0x1<<18) -#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) -#define PRIM3D_TRIFAN (0x3<<18) -#define PRIM3D_POLY (0x4<<18) -#define PRIM3D_LINELIST (0x5<<18) -#define PRIM3D_LINESTRIP (0x6<<18) -#define PRIM3D_RECTLIST (0x7<<18) -#define PRIM3D_POINTLIST (0x8<<18) -#define PRIM3D_DIB (0x9<<18) -#define PRIM3D_MASK (0x1f<<18) - -#define I915PACKCOLOR4444(r,g,b,a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) - -#define I915PACKCOLOR1555(r,g,b,a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) - -#define I915PACKCOLOR565(r,g,b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) - -#define I915PACKCOLOR8888(r,g,b,a) \ - ((a<<24) | (r<<16) | (g<<8) | b) - - - - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#endif diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c deleted file mode 100644 index 7bc02ba807..0000000000 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ /dev/null @@ -1,242 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* - * Render unclipped vertex buffers by emitting vertices directly to - * dma buffers. Use strip/fan hardware acceleration where possible. - * - */ -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "imports.h" -#include "mtypes.h" -#include "enums.h" - -#include "tnl/t_context.h" -#include "tnl/t_vertex.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_tris.h" -#include "intel_batchbuffer.h" -#include "intel_reg.h" - -/* - * Render unclipped vertex buffers by emitting vertices directly to - * dma buffers. Use strip/fan hardware primitives where possible. - * Try to simulate missing primitives with indexed vertices. - */ -#define HAVE_POINTS 0 /* Has it, but can't use because subpixel has to - * be adjusted for points on the INTEL/I845G - */ -#define HAVE_LINES 1 -#define HAVE_LINE_STRIPS 1 -#define HAVE_TRIANGLES 1 -#define HAVE_TRI_STRIPS 1 -#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ -#define HAVE_TRI_FANS 1 -#define HAVE_POLYGONS 1 -#define HAVE_QUADS 0 -#define HAVE_QUAD_STRIPS 0 - -#define HAVE_ELTS 0 - -static GLuint hw_prim[GL_POLYGON+1] = { - 0, - PRIM3D_LINELIST, - PRIM3D_LINESTRIP, - PRIM3D_LINESTRIP, - PRIM3D_TRILIST, - PRIM3D_TRISTRIP, - PRIM3D_TRIFAN, - 0, - 0, - PRIM3D_POLY -}; - -static const GLenum reduced_prim[GL_POLYGON+1] = { - GL_POINTS, - GL_LINES, - GL_LINES, - GL_LINES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES -}; - -static const int scale_prim[GL_POLYGON+1] = { - 0, /* fallback case */ - 1, - 2, - 2, - 1, - 3, - 3, - 0, /* fallback case */ - 0, /* fallback case */ - 3 -}; - - -static void intelDmaPrimitive( intelContextPtr intel, GLenum prim ) -{ - if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); - INTEL_FIREVERTICES(intel); - intel->vtbl.reduced_primitive_state( intel, reduced_prim[prim] ); - intelStartInlinePrimitive( intel, hw_prim[prim] ); -} - - -#define LOCAL_VARS intelContextPtr intel = INTEL_CONTEXT(ctx) -#define INIT( prim ) \ -do { \ - intelDmaPrimitive( intel, prim ); \ -} while (0) -#define FLUSH() INTEL_FIREVERTICES( intel ) - -#define GET_SUBSEQUENT_VB_MAX_VERTS() \ - (((intel->alloc.size / 2) - 1500) / (intel->vertex_size*4)) -#define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS() - -#define ALLOC_VERTS( nr ) \ - intelExtendInlinePrimitive( intel, (nr) * intel->vertex_size ) - -#define EMIT_VERTS( ctx, j, nr, buf ) \ - _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf ) - -#define TAG(x) intel_##x -#include "tnl_dd/t_dd_dmatmp.h" - - -/**********************************************************************/ -/* Render pipeline stage */ -/**********************************************************************/ - -/* Heuristic to choose between the two render paths: - */ -static GLboolean choose_render( intelContextPtr intel, - struct vertex_buffer *VB ) -{ - int vertsz = intel->vertex_size; - int cost_render = 0; - int cost_fallback = 0; - int nr_prims = 0; - int nr_rprims = 0; - int nr_rverts = 0; - int rprim = intel->reduced_primitive; - int i = 0; - - for (i = 0 ; i < VB->PrimitiveCount ; i++) { - GLuint prim = VB->Primitive[i].mode; - GLuint length = VB->Primitive[i].count; - - if (!length) - continue; - - nr_prims++; - nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK]; - - if (reduced_prim[prim & PRIM_MODE_MASK] != rprim) { - nr_rprims++; - rprim = reduced_prim[prim & PRIM_MODE_MASK]; - } - } - - /* One point for each generated primitive: - */ - cost_render = nr_prims; - cost_fallback = nr_rprims; - - /* One point for every 1024 dwords (4k) of dma: - */ - cost_render += (vertsz * i) / 1024; - cost_fallback += (vertsz * nr_rverts) / 1024; - - if (0) - fprintf(stderr, "cost render: %d fallback: %d\n", - cost_render, cost_fallback); - - if (cost_render > cost_fallback) - return GL_FALSE; - - return GL_TRUE; -} - - -static GLboolean intel_run_render( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint i; - - intel->vtbl.render_prevalidate( intel ); - - /* Don't handle clipping or indexed vertices. - */ - if (intel->RenderIndex != 0 || - !intel_validate_render( ctx, VB ) || - !choose_render( intel, VB )) { - return GL_TRUE; - } - - tnl->clipspace.new_inputs |= VERT_BIT_POS; - - tnl->Driver.Render.Start( ctx ); - - for (i = 0 ; i < VB->PrimitiveCount ; i++) - { - GLuint prim = VB->Primitive[i].mode; - GLuint start = VB->Primitive[i].start; - GLuint length = VB->Primitive[i].count; - - if (!length) - continue; - - intel_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length, - prim ); - } - - tnl->Driver.Render.Finish( ctx ); - - return GL_FALSE; /* finished the pipe */ -} - -const struct tnl_pipeline_stage _intel_render_stage = -{ - "intel render", - NULL, - NULL, - NULL, - NULL, - intel_run_render /* run */ -}; diff --git a/src/mesa/drivers/dri/i915/intel_rotate.c b/src/mesa/drivers/dri/i915/intel_rotate.c deleted file mode 100644 index a77640ee54..0000000000 --- a/src/mesa/drivers/dri/i915/intel_rotate.c +++ /dev/null @@ -1,221 +0,0 @@ - -/** - * Routines for simple 2D->2D transformations for rotated, flipped screens. - * - * XXX This code is not intel-specific. Move it into a common/utility - * someday. - */ - -#include "intel_rotate.h" - -#define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) ) - -#define ABS(A) ( ((A) < 0) ? -(A) : (A) ) - - -void -matrix23Set(struct matrix23 *m, - int m00, int m01, int m02, - int m10, int m11, int m12) -{ - m->m00 = m00; m->m01 = m01; m->m02 = m02; - m->m10 = m10; m->m11 = m11; m->m12 = m12; -} - - -/* - * Transform (x,y) coordinate by the given matrix. - */ -void -matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y) -{ - const float x0 = *x; - const float y0 = *y; - - *x = m->m00 * x0 + m->m01 * y0 + m->m02; - *y = m->m10 * x0 + m->m11 * y0 + m->m12; -} - - -void -matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y) -{ - const int x0 = *x; - const int y0 = *y; - - *x = m->m00 * x0 + m->m01 * y0 + m->m02; - *y = m->m10 * x0 + m->m11 * y0 + m->m12; -} - - -/* - * Transform a width and height by the given matrix. - * XXX this could be optimized quite a bit. - */ -void -matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist) -{ - int x0 = 0, y0 = 0; - int x1 = *xDist, y1 = 0; - int x2 = 0, y2 = *yDist; - matrix23TransformCoordi(m, &x0, &y0); - matrix23TransformCoordi(m, &x1, &y1); - matrix23TransformCoordi(m, &x2, &y2); - - *xDist = (x1 - x0) + (x2 - x0); - *yDist = (y1 - y0) + (y2 - y0); - - if (*xDist < 0) - *xDist = -*xDist; - if (*yDist < 0) - *yDist = -*yDist; -} - - -/** - * Transform the rect defined by (x, y, w, h) by m. - */ -void -matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w, int *h) -{ - int x0 = *x, y0 = *y; - int x1 = *x + *w, y1 = *y; - int x2 = *x + *w, y2 = *y + *h; - int x3 = *x, y3 = *y + *h; - matrix23TransformCoordi(m, &x0, &y0); - matrix23TransformCoordi(m, &x1, &y1); - matrix23TransformCoordi(m, &x2, &y2); - matrix23TransformCoordi(m, &x3, &y3); - *w = ABS(x1 - x0) + ABS(x2 - x1); - /**w = ABS(*w);*/ - *h = ABS(y1 - y0) + ABS(y2 - y1); - /**h = ABS(*h);*/ - *x = MIN2(x0, x1); - *x = MIN2(*x, x2); - *y = MIN2(y0, y1); - *y = MIN2(*y, y2); -} - - -/* - * Make rotation matrix for width X height screen. - */ -void -matrix23Rotate(struct matrix23 *m, int width, int height, int angle) -{ - switch (angle) { - case 0: - matrix23Set(m, 1, 0, 0, 0, 1, 0); - break; - case 90: - matrix23Set(m, 0, 1, 0, -1, 0, width); - break; - case 180: - matrix23Set(m, -1, 0, width, 0, -1, height); - break; - case 270: - matrix23Set(m, 0, -1, height, 1, 0, 0); - break; - default: - /*abort()*/; - } -} - - -/* - * Make flip/reflection matrix for width X height screen. - */ -void -matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip) -{ - if (xflip) { - m->m00 = -1; m->m01 = 0; m->m02 = width - 1; - } - else { - m->m00 = 1; m->m01 = 0; m->m02 = 0; - } - if (yflip) { - m->m10 = 0; m->m11 = -1; m->m12 = height - 1; - } - else { - m->m10 = 0; m->m11 = 1; m->m12 = 0; - } -} - - -/* - * result = a * b - */ -void -matrix23Multiply(struct matrix23 *result, - const struct matrix23 *a, const struct matrix23 *b) -{ - result->m00 = a->m00 * b->m00 + a->m01 * b->m10; - result->m01 = a->m00 * b->m01 + a->m01 * b->m11; - result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02; - - result->m10 = a->m10 * b->m00 + a->m11 * b->m10; - result->m11 = a->m10 * b->m01 + a->m11 * b->m11; - result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12; -} - - -#if 000 - -#include - -int -main(int argc, char *argv[]) -{ - int width = 500, height = 400; - int rot; - int fx = 0, fy = 0; /* flip x and/or y ? */ - int coords[4][2]; - - /* four corner coords to test with */ - coords[0][0] = 0; coords[0][1] = 0; - coords[1][0] = width-1; coords[1][1] = 0; - coords[2][0] = width-1; coords[2][1] = height-1; - coords[3][0] = 0; coords[3][1] = height-1; - - - for (rot = 0; rot < 360; rot += 90) { - struct matrix23 rotate, flip, m; - int i; - - printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy); - - /* make transformation matrix 'm' */ - matrix23Rotate(&rotate, width, height, rot); - matrix23Flip(&flip, width, height, fx, fy); - matrix23Multiply(&m, &rotate, &flip); - - /* xform four coords */ - for (i = 0; i < 4; i++) { - int x = coords[i][0]; - int y = coords[i][1]; - matrix23TransformCoordi(&m, &x, &y); - printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y); - } - - /* xform width, height */ - { - int x = width; - int y = height; - matrix23TransformDistance(&m, &x, &y); - printf(" %d x %d -> %d x %d\n", width, height, x, y); - } - - /* xform rect */ - { - int x = 50, y = 10, w = 200, h = 100; - matrix23TransformRect(&m, &x, &y, &w, &h); - printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100, - x, y, w, h); - } - - } - - return 0; -} -#endif diff --git a/src/mesa/drivers/dri/i915/intel_rotate.h b/src/mesa/drivers/dri/i915/intel_rotate.h deleted file mode 100644 index 0da45d20ce..0000000000 --- a/src/mesa/drivers/dri/i915/intel_rotate.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef INTEL_ROTATE_H -#define INTEL_ROTATE_H 1 - -struct matrix23 -{ - int m00, m01, m02; - int m10, m11, m12; -}; - - - -extern void -matrix23Set(struct matrix23 *m, - int m00, int m01, int m02, - int m10, int m11, int m12); - -extern void -matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y); - -extern void -matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y); - -extern void -matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist); - -extern void -matrix23TransformRect(const struct matrix23 *m, - int *x, int *y, int *w, int *h); - -extern void -matrix23Rotate(struct matrix23 *m, int width, int height, int angle); - -extern void -matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip); - -extern void -matrix23Multiply(struct matrix23 *result, - const struct matrix23 *a, const struct matrix23 *b); - - -#endif /* INTEL_ROTATE_H */ diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c deleted file mode 100644 index ca8610b496..0000000000 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ /dev/null @@ -1,690 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "context.h" -#include "framebuffer.h" -#include "matrix.h" -#include "renderbuffer.h" -#include "simple_list.h" -#include "utils.h" -#include "vblank.h" -#include "xmlpool.h" - - -#include "intel_screen.h" - -#include "intel_tex.h" -#include "intel_span.h" -#include "intel_tris.h" -#include "intel_ioctl.h" - -#include "i830_dri.h" - -PUBLIC const char __driConfigOptions[] = -DRI_CONF_BEGIN - DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) - DRI_CONF_SECTION_END - DRI_CONF_SECTION_QUALITY - DRI_CONF_FORCE_S3TC_ENABLE(false) - DRI_CONF_ALLOW_LARGE_TEXTURES(1) - DRI_CONF_SECTION_END -DRI_CONF_END; -const GLuint __driNConfigOptions = 4; - -#ifdef USE_NEW_INTERFACE -static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -#endif /*USE_NEW_INTERFACE*/ - -extern const struct dri_extension card_extensions[]; - -/** - * Map all the memory regions described by the screen. - * \return GL_TRUE if success, GL_FALSE if error. - */ -GLboolean -intelMapScreenRegions(__DRIscreenPrivate *sPriv) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - - if (intelScreen->front.handle) { - if (drmMap(sPriv->fd, - intelScreen->front.handle, - intelScreen->front.size, - (drmAddress *)&intelScreen->front.map) != 0) { - _mesa_problem(NULL, "drmMap(frontbuffer) failed!"); - return GL_FALSE; - } - } - else { - _mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!"); - } - - if (drmMap(sPriv->fd, - intelScreen->back.handle, - intelScreen->back.size, - (drmAddress *)&intelScreen->back.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - - if (drmMap(sPriv->fd, - intelScreen->depth.handle, - intelScreen->depth.size, - (drmAddress *)&intelScreen->depth.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *)&intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - - if (0) - printf("Mappings: front: %p back: %p depth: %p tex: %p\n", - intelScreen->front.map, - intelScreen->back.map, - intelScreen->depth.map, - intelScreen->tex.map); - return GL_TRUE; -} - - -void -intelUnmapScreenRegions(intelScreenPrivate *intelScreen) -{ -#define REALLY_UNMAP 1 - if (intelScreen->front.map) { -#if REALLY_UNMAP - if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0) - printf("drmUnmap front failed!\n"); -#endif - intelScreen->front.map = NULL; - } - if (intelScreen->back.map) { -#if REALLY_UNMAP - if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0) - printf("drmUnmap back failed!\n"); -#endif - intelScreen->back.map = NULL; - } - if (intelScreen->depth.map) { -#if REALLY_UNMAP - drmUnmap(intelScreen->depth.map, intelScreen->depth.size); - intelScreen->depth.map = NULL; -#endif - } - if (intelScreen->tex.map) { -#if REALLY_UNMAP - drmUnmap(intelScreen->tex.map, intelScreen->tex.size); - intelScreen->tex.map = NULL; -#endif - } -} - - -static void -intelPrintDRIInfo(intelScreenPrivate *intelScreen, - __DRIscreenPrivate *sPriv, - I830DRIPtr gDRIPriv) -{ - fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->front.size, intelScreen->front.offset, - intelScreen->front.pitch); - fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->back.size, intelScreen->back.offset, - intelScreen->back.pitch); - fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->depth.size, intelScreen->depth.offset, - intelScreen->depth.pitch); - fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->rotated.size, intelScreen->rotated.offset, - intelScreen->rotated.pitch); - fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", - intelScreen->tex.size, intelScreen->tex.offset); - fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); -} - - -static void -intelPrintSAREA(const drmI830Sarea *sarea) -{ - fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, sarea->height); - fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); - fprintf(stderr, - "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->front_offset, sarea->front_size, - (unsigned) sarea->front_handle); - fprintf(stderr, - "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->back_offset, sarea->back_size, - (unsigned) sarea->back_handle); - fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->depth_offset, sarea->depth_size, - (unsigned) sarea->depth_handle); - fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->tex_offset, sarea->tex_size, - (unsigned) sarea->tex_handle); - fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); - fprintf(stderr, - "SAREA: rotated offset: 0x%08x size: 0x%x\n", - sarea->rotated_offset, sarea->rotated_size); - fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); -} - - -/** - * A number of the screen parameters are obtained/computed from - * information in the SAREA. This function updates those parameters. - */ -void -intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, - drmI830Sarea *sarea) -{ - intelScreen->width = sarea->width; - intelScreen->height = sarea->height; - - intelScreen->front.offset = sarea->front_offset; - intelScreen->front.pitch = sarea->pitch * intelScreen->cpp; - intelScreen->front.handle = sarea->front_handle; - intelScreen->front.size = sarea->front_size; - - intelScreen->back.offset = sarea->back_offset; - intelScreen->back.pitch = sarea->pitch * intelScreen->cpp; - intelScreen->back.handle = sarea->back_handle; - intelScreen->back.size = sarea->back_size; - - intelScreen->depth.offset = sarea->depth_offset; - intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp; - intelScreen->depth.handle = sarea->depth_handle; - intelScreen->depth.size = sarea->depth_size; - - intelScreen->tex.offset = sarea->tex_offset; - intelScreen->logTextureGranularity = sarea->log_tex_granularity; - intelScreen->tex.handle = sarea->tex_handle; - intelScreen->tex.size = sarea->tex_size; - - intelScreen->rotated.offset = sarea->rotated_offset; - intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; - intelScreen->rotated.size = sarea->rotated_size; - intelScreen->current_rotation = sarea->rotation; - matrix23Rotate(&intelScreen->rotMatrix, - sarea->width, sarea->height, sarea->rotation); - intelScreen->rotatedWidth = sarea->virtualX; - intelScreen->rotatedHeight = sarea->virtualY; - - if (0) - intelPrintSAREA(sarea); -} - - -static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) -{ - intelScreenPrivate *intelScreen; - I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv; - drmI830Sarea *sarea; - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); - void * const psc = sPriv->psc->screenConfigs; - - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { - fprintf(stderr,"\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); - return GL_FALSE; - } - - /* Allocate the private area */ - intelScreen = (intelScreenPrivate *)CALLOC(sizeof(intelScreenPrivate)); - if (!intelScreen) { - fprintf(stderr,"\nERROR! Allocating private area failed\n"); - return GL_FALSE; - } - /* parse information in __driConfigOptions */ - driParseOptionInfo (&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - intelScreen->driScrnPriv = sPriv; - sPriv->private = (void *)intelScreen; - intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; - sarea = (drmI830Sarea *) - (((GLubyte *)sPriv->pSAREA)+intelScreen->sarea_priv_offset); - - intelScreen->deviceID = gDRIPriv->deviceID; - intelScreen->mem = gDRIPriv->mem; - intelScreen->cpp = gDRIPriv->cpp; - - switch (gDRIPriv->bitsPerPixel) { - case 15: intelScreen->fbFormat = DV_PF_555; break; - case 16: intelScreen->fbFormat = DV_PF_565; break; - case 32: intelScreen->fbFormat = DV_PF_8888; break; - } - - intelUpdateScreenFromSAREA(intelScreen, sarea); - - if (0) - intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - - if (!intelMapScreenRegions(sPriv)) { - fprintf(stderr,"\nERROR! mapping regions\n"); - _mesa_free(intelScreen); - sPriv->private = NULL; - return GL_FALSE; - } - - intelScreen->drmMinor = sPriv->drmMinor; - - /* Determine if IRQs are active? */ - { - int ret; - drmI830GetParam gp; - - gp.param = I830_PARAM_IRQ_ACTIVE; - gp.value = &intelScreen->irq_active; - - ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drmI830GetParam: %d\n", ret); - return GL_FALSE; - } - } - - /* Determine if batchbuffers are allowed */ - { - int ret; - drmI830GetParam gp; - - gp.param = I830_PARAM_ALLOW_BATCHBUFFER; - gp.value = &intelScreen->allow_batchbuffer; - - ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret); - return GL_FALSE; - } - } - - if (glx_enable_extension != NULL) { - (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); - (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); - (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); - (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); - (*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" ); - (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" ); - } - - sPriv->psc->allocateMemory = (void *) intelAllocateMemoryMESA; - sPriv->psc->freeMemory = (void *) intelFreeMemoryMESA; - sPriv->psc->memoryOffset = (void *) intelGetMemoryOffsetMESA; - - return GL_TRUE; -} - - -static void intelDestroyScreen(__DRIscreenPrivate *sPriv) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - - intelUnmapScreenRegions(intelScreen); - - driDestroyOptionInfo (&intelScreen->optionCache); - - FREE(intelScreen); - sPriv->private = NULL; -} - - -static GLboolean intelCreateBuffer( __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - const __GLcontextModes *mesaVis, - GLboolean isPixmap ) -{ - intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private; - - if (isPixmap) { - return GL_FALSE; /* not implemented */ - } else { - GLboolean swStencil = (mesaVis->stencilBits > 0 && - mesaVis->depthBits != 24); - - struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); - - { - driRenderbuffer *frontRb - = driNewRenderbuffer(GL_RGBA, - screen->front.map, - screen->cpp, - screen->front.offset, screen->front.pitch, - driDrawPriv); - intelSetSpanFunctions(frontRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); - } - - if (mesaVis->doubleBufferMode) { - driRenderbuffer *backRb - = driNewRenderbuffer(GL_RGBA, - screen->back.map, - screen->cpp, - screen->back.offset, screen->back.pitch, - driDrawPriv); - intelSetSpanFunctions(backRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); - } - - if (mesaVis->depthBits == 16) { - driRenderbuffer *depthRb - = driNewRenderbuffer(GL_DEPTH_COMPONENT16, - screen->depth.map, - screen->cpp, - screen->depth.offset, screen->depth.pitch, - driDrawPriv); - intelSetSpanFunctions(depthRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); - } - else if (mesaVis->depthBits == 24) { - driRenderbuffer *depthRb - = driNewRenderbuffer(GL_DEPTH_COMPONENT24, - screen->depth.map, - screen->cpp, - screen->depth.offset, screen->depth.pitch, - driDrawPriv); - intelSetSpanFunctions(depthRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); - } - - if (mesaVis->stencilBits > 0 && !swStencil) { - driRenderbuffer *stencilRb - = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, - screen->depth.map, - screen->cpp, - screen->depth.offset, screen->depth.pitch, - driDrawPriv); - intelSetSpanFunctions(stencilRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); - } - - _mesa_add_soft_renderbuffers(fb, - GL_FALSE, /* color */ - GL_FALSE, /* depth */ - swStencil, - mesaVis->accumRedBits > 0, - GL_FALSE, /* alpha */ - GL_FALSE /* aux */); - driDrawPriv->driverPrivate = (void *) fb; - - return (driDrawPriv->driverPrivate != NULL); - } -} - -static void intelDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) -{ - _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); -} - - -/** - * Get information about previous buffer swaps. - */ -static int -intelGetSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo ) -{ - intelContextPtr intel; - - if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL) - || (dPriv->driContextPriv->driverPrivate == NULL) - || (sInfo == NULL) ) { - return -1; - } - - intel = dPriv->driContextPriv->driverPrivate; - sInfo->swap_count = intel->swap_count; - sInfo->swap_ust = intel->swap_ust; - sInfo->swap_missed_count = intel->swap_missed_count; - - sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) - ? driCalculateSwapUsage( dPriv, 0, intel->swap_missed_ust ) - : 0.0; - - return 0; -} - - -/* There are probably better ways to do this, such as an - * init-designated function to register chipids and createcontext - * functions. - */ -extern GLboolean i830CreateContext( const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate); - -extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate); - - - - -static GLboolean intelCreateContext( const __GLcontextModes *mesaVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate) -{ - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; - - switch (intelScreen->deviceID) { - case PCI_CHIP_845_G: - case PCI_CHIP_I830_M: - case PCI_CHIP_I855_GM: - case PCI_CHIP_I865_G: - return i830CreateContext( mesaVis, driContextPriv, - sharedContextPrivate ); - - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q35_G: - case PCI_CHIP_Q33_G: - return i915CreateContext( mesaVis, driContextPriv, - sharedContextPrivate ); - - default: - fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID); - return GL_FALSE; - } -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer -}; - - -static __GLcontextModes * -intelFillInModes( unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer ) -{ - __GLcontextModes * modes; - __GLcontextModes * m; - unsigned num_modes; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML - }; - - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; - - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = depth_buffer_factor * back_buffer_factor * 4; - - if ( pixel_bits == 16 ) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) ); - m = modes; - if ( ! driFillInModes( & m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_TRUE_COLOR ) ) { - fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__ ); - return NULL; - } - if ( ! driFillInModes( & m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_DIRECT_COLOR ) ) { - fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__ ); - return NULL; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for ( m = modes ; m != NULL ; m = m->next ) { - if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) { - m->visualRating = GLX_SLOW_CONFIG; - } - } - - return modes; -} - - -/** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. - */ -PUBLIC -void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes ) - -{ - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 5, 0 }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 4, 0 }; - - dri_interface = interface; - - if ( ! driCheckDriDdxDrmVersions2( "i915", - dri_version, & dri_expected, - ddx_version, & ddx_expected, - drm_version, & drm_expected ) ) { - return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - if ( psp != NULL ) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes( dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, - 1 ); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); - } - - return (void *) psp; -} diff --git a/src/mesa/drivers/dri/i915/intel_screen.h b/src/mesa/drivers/dri/i915/intel_screen.h deleted file mode 100644 index 24cfd9bf8b..0000000000 --- a/src/mesa/drivers/dri/i915/intel_screen.h +++ /dev/null @@ -1,112 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _INTEL_INIT_H_ -#define _INTEL_INIT_H_ - -#include -#include "xmlconfig.h" -#include "dri_util.h" -#include "intel_rotate.h" -#include "i830_common.h" - - -/* This roughly corresponds to a gl_renderbuffer (Mesa 6.4) */ -typedef struct { - drm_handle_t handle; - drmSize size; /* region size in bytes */ - char *map; /* memory map */ - int offset; /* from start of video mem, in bytes */ - int pitch; /* row stride, in bytes */ -} intelRegion; - -typedef struct -{ - intelRegion front; - intelRegion back; - intelRegion rotated; - intelRegion depth; - intelRegion tex; - - int deviceID; - int width; - int height; - int mem; /* unused */ - - int cpp; /* for front and back buffers */ - int fbFormat; - - int logTextureGranularity; - - __DRIscreenPrivate *driScrnPriv; - unsigned int sarea_priv_offset; - - int drmMinor; - - int irq_active; - int allow_batchbuffer; - - struct matrix23 rotMatrix; - - int current_rotation; /* 0, 90, 180 or 270 */ - int rotatedWidth, rotatedHeight; - - /** - * Configuration cache with default values for all contexts - */ - driOptionCache optionCache; -} intelScreenPrivate; - - -extern GLboolean -intelMapScreenRegions(__DRIscreenPrivate *sPriv); - -extern void -intelUnmapScreenRegions(intelScreenPrivate *intelScreen); - -extern void -intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, - drmI830Sarea *sarea); - -extern void -intelDestroyContext(__DRIcontextPrivate *driContextPriv); - -extern GLboolean -intelUnbindContext(__DRIcontextPrivate *driContextPriv); - -extern GLboolean -intelMakeCurrent(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv); - -extern void -intelSwapBuffers(__DRIdrawablePrivate *dPriv); - -extern void -intelCopySubBuffer( __DRIdrawablePrivate *dPriv, int x, int y, int w, int h ); - -#endif diff --git a/src/mesa/drivers/dri/i915/intel_span.c b/src/mesa/drivers/dri/i915/intel_span.c deleted file mode 100644 index c3ffc4b2ac..0000000000 --- a/src/mesa/drivers/dri/i915/intel_span.c +++ /dev/null @@ -1,258 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "colormac.h" - -#include "intel_screen.h" - -#include "intel_span.h" -#include "intel_ioctl.h" -#include "swrast/swrast.h" - - -#define DBG 0 - -#define LOCAL_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = intel->driDrawable; \ - driRenderbuffer *drb = (driRenderbuffer *) rb; \ - GLuint pitch = drb->pitch; \ - GLuint height = dPriv->h; \ - char *buf = (char *) drb->Base.Data + \ - dPriv->x * drb->cpp + \ - dPriv->y * pitch; \ - GLushort p; \ - (void) buf; (void) p - -#define LOCAL_DEPTH_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = intel->driDrawable; \ - driRenderbuffer *drb = (driRenderbuffer *) rb; \ - GLuint pitch = drb->pitch; \ - GLuint height = dPriv->h; \ - char *buf = (char *) drb->Base.Data + \ - dPriv->x * drb->cpp + \ - dPriv->y * pitch - -#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS - -#define INIT_MONO_PIXEL(p,color)\ - p = INTEL_PACKCOLOR565(color[0],color[1],color[2]) - -#define Y_FLIP(_y) (height - _y - 1) - -#define HW_LOCK() - -#define HW_UNLOCK() - -/* 16 bit, 565 rgb color spanline and pixel functions - */ -#define WRITE_RGBA( _x, _y, r, g, b, a ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \ - (((int)g & 0xfc) << 3) | \ - (((int)b & 0xf8) >> 3)) -#define WRITE_PIXEL( _x, _y, p ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = p - -#define READ_RGBA( rgba, _x, _y ) \ -do { \ - GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \ - rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \ - rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \ - rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \ - rgba[3] = 255; \ -} while(0) - -#define TAG(x) intel##x##_565 -#include "spantmp.h" - -/* 15 bit, 555 rgb color spanline and pixel functions - */ -#define WRITE_RGBA( _x, _y, r, g, b, a ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \ - ((g & 0xf8) << 3) | \ - ((b & 0xf8) >> 3)) - -#define WRITE_PIXEL( _x, _y, p ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = p - -#define READ_RGBA( rgba, _x, _y ) \ -do { \ - GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 7) & 0xf8; \ - rgba[1] = (p >> 3) & 0xf8; \ - rgba[2] = (p << 3) & 0xf8; \ - rgba[3] = 255; \ -} while(0) - -#define TAG(x) intel##x##_555 -#include "spantmp.h" - -/* 16 bit depthbuffer functions. - */ -#define WRITE_DEPTH( _x, _y, d ) \ - *(GLushort *)(buf + (_x)*2 + (_y)*pitch) = d; - -#define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + (_x)*2 + (_y)*pitch); - - -#define TAG(x) intel##x##_z16 -#include "depthtmp.h" - - -#undef LOCAL_VARS -#define LOCAL_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = intel->driDrawable; \ - driRenderbuffer *drb = (driRenderbuffer *) rb; \ - GLuint pitch = drb->pitch; \ - GLuint height = dPriv->h; \ - char *buf = (char *)drb->Base.Data + \ - dPriv->x * drb->cpp + \ - dPriv->y * pitch; \ - GLuint p; \ - (void) buf; (void) p - -#undef INIT_MONO_PIXEL -#define INIT_MONO_PIXEL(p,color)\ - p = INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]) - -/* 32 bit, 8888 argb color spanline and pixel functions - */ -#define WRITE_RGBA(_x, _y, r, g, b, a) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \ - (g << 8) | \ - (b << 0) | \ - (a << 24) ) - -#define WRITE_PIXEL(_x, _y, p) \ - *(GLuint *)(buf + _x*4 + _y*pitch) = p - - -#define READ_RGBA(rgba, _x, _y) \ - do { \ - GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \ - rgba[0] = (p >> 16) & 0xff; \ - rgba[1] = (p >> 8) & 0xff; \ - rgba[2] = (p >> 0) & 0xff; \ - rgba[3] = (p >> 24) & 0xff; \ - } while (0) - -#define TAG(x) intel##x##_8888 -#include "spantmp.h" - - -/* 24/8 bit interleaved depth/stencil functions - */ -#define WRITE_DEPTH( _x, _y, d ) { \ - GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \ - tmp &= 0xff000000; \ - tmp |= (d) & 0xffffff; \ - *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \ -} - -#define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) & 0xffffff; - - -#define TAG(x) intel##x##_z24_s8 -#include "depthtmp.h" - -#define WRITE_STENCIL( _x, _y, d ) { \ - GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*pitch); \ - tmp &= 0xffffff; \ - tmp |= ((d)<<24); \ - *(GLuint *)(buf + (_x)*4 + (_y)*pitch) = tmp; \ -} - -#define READ_STENCIL( d, _x, _y ) \ - d = *(GLuint *)(buf + (_x)*4 + (_y)*pitch) >> 24; - -#define TAG(x) intel##x##_z24_s8 -#include "stenciltmp.h" - - -/* Move locking out to get reasonable span performance. - */ -void intelSpanRenderStart( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - - intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - intelWaitForIdle(intel); -} - -void intelSpanRenderFinish( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - _swrast_flush( ctx ); - UNLOCK_HARDWARE( intel ); -} - -void intelInitSpanFuncs( GLcontext *ctx ) -{ - struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); - swdd->SpanRenderStart = intelSpanRenderStart; - swdd->SpanRenderFinish = intelSpanRenderFinish; -} - - -/** - * Plug in the Get/Put routines for the given driRenderbuffer. - */ -void -intelSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis) -{ - if (drb->Base.InternalFormat == GL_RGBA) { - if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) { - intelInitPointers_555(&drb->Base); - } - else if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { - intelInitPointers_565(&drb->Base); - } - else { - assert(vis->redBits == 8); - assert(vis->greenBits == 8); - assert(vis->blueBits == 8); - intelInitPointers_8888(&drb->Base); - } - } - else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) { - intelInitDepthPointers_z16(&drb->Base); - } - else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) { - intelInitDepthPointers_z24_s8(&drb->Base); - } - else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) { - intelInitStencilPointers_z24_s8(&drb->Base); - } -} diff --git a/src/mesa/drivers/dri/i915/intel_span.h b/src/mesa/drivers/dri/i915/intel_span.h deleted file mode 100644 index 2d4f8589d0..0000000000 --- a/src/mesa/drivers/dri/i915/intel_span.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _INTEL_SPAN_H -#define _INTEL_SPAN_H - -#include "drirenderbuffer.h" - -extern void intelInitSpanFuncs( GLcontext *ctx ); - -extern void intelSpanRenderFinish( GLcontext *ctx ); -extern void intelSpanRenderStart( GLcontext *ctx ); - -extern void -intelSetSpanFunctions(driRenderbuffer *rb, const GLvisual *vis); - -#endif diff --git a/src/mesa/drivers/dri/i915/intel_state.c b/src/mesa/drivers/dri/i915/intel_state.c deleted file mode 100644 index e5988a5ed6..0000000000 --- a/src/mesa/drivers/dri/i915/intel_state.c +++ /dev/null @@ -1,281 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "swrast/swrast.h" - -int intel_translate_compare_func( GLenum func ) -{ - switch(func) { - case GL_NEVER: - return COMPAREFUNC_NEVER; - case GL_LESS: - return COMPAREFUNC_LESS; - case GL_LEQUAL: - return COMPAREFUNC_LEQUAL; - case GL_GREATER: - return COMPAREFUNC_GREATER; - case GL_GEQUAL: - return COMPAREFUNC_GEQUAL; - case GL_NOTEQUAL: - return COMPAREFUNC_NOTEQUAL; - case GL_EQUAL: - return COMPAREFUNC_EQUAL; - case GL_ALWAYS: - return COMPAREFUNC_ALWAYS; - } - - fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); - return COMPAREFUNC_ALWAYS; -} - -int intel_translate_stencil_op( GLenum op ) -{ - switch(op) { - case GL_KEEP: - return STENCILOP_KEEP; - case GL_ZERO: - return STENCILOP_ZERO; - case GL_REPLACE: - return STENCILOP_REPLACE; - case GL_INCR: - return STENCILOP_INCRSAT; - case GL_DECR: - return STENCILOP_DECRSAT; - case GL_INCR_WRAP: - return STENCILOP_INCR; - case GL_DECR_WRAP: - return STENCILOP_DECR; - case GL_INVERT: - return STENCILOP_INVERT; - default: - return STENCILOP_ZERO; - } -} - -int intel_translate_blend_factor( GLenum factor ) -{ - switch(factor) { - case GL_ZERO: - return BLENDFACT_ZERO; - case GL_SRC_ALPHA: - return BLENDFACT_SRC_ALPHA; - case GL_ONE: - return BLENDFACT_ONE; - case GL_SRC_COLOR: - return BLENDFACT_SRC_COLR; - case GL_ONE_MINUS_SRC_COLOR: - return BLENDFACT_INV_SRC_COLR; - case GL_DST_COLOR: - return BLENDFACT_DST_COLR; - case GL_ONE_MINUS_DST_COLOR: - return BLENDFACT_INV_DST_COLR; - case GL_ONE_MINUS_SRC_ALPHA: - return BLENDFACT_INV_SRC_ALPHA; - case GL_DST_ALPHA: - return BLENDFACT_DST_ALPHA; - case GL_ONE_MINUS_DST_ALPHA: - return BLENDFACT_INV_DST_ALPHA; - case GL_SRC_ALPHA_SATURATE: - return BLENDFACT_SRC_ALPHA_SATURATE; - case GL_CONSTANT_COLOR: - return BLENDFACT_CONST_COLOR; - case GL_ONE_MINUS_CONSTANT_COLOR: - return BLENDFACT_INV_CONST_COLOR; - case GL_CONSTANT_ALPHA: - return BLENDFACT_CONST_ALPHA; - case GL_ONE_MINUS_CONSTANT_ALPHA: - return BLENDFACT_INV_CONST_ALPHA; - } - - fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor); - return BLENDFACT_ZERO; -} - -int intel_translate_logic_op( GLenum opcode ) -{ - switch(opcode) { - case GL_CLEAR: - return LOGICOP_CLEAR; - case GL_AND: - return LOGICOP_AND; - case GL_AND_REVERSE: - return LOGICOP_AND_RVRSE; - case GL_COPY: - return LOGICOP_COPY; - case GL_COPY_INVERTED: - return LOGICOP_COPY_INV; - case GL_AND_INVERTED: - return LOGICOP_AND_INV; - case GL_NOOP: - return LOGICOP_NOOP; - case GL_XOR: - return LOGICOP_XOR; - case GL_OR: - return LOGICOP_OR; - case GL_OR_INVERTED: - return LOGICOP_OR_INV; - case GL_NOR: - return LOGICOP_NOR; - case GL_EQUIV: - return LOGICOP_EQUIV; - case GL_INVERT: - return LOGICOP_INV; - case GL_OR_REVERSE: - return LOGICOP_OR_RVRSE; - case GL_NAND: - return LOGICOP_NAND; - case GL_SET: - return LOGICOP_SET; - default: - return LOGICOP_SET; - } -} - -static void intelDrawBuffer(GLcontext *ctx, GLenum mode ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - int front = 0; - - if (!ctx->DrawBuffer) - return; - - switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { - case BUFFER_BIT_FRONT_LEFT: - front = 1; - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - case BUFFER_BIT_BACK_LEFT: - front = 0; - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - if ( intel->sarea->pf_current_page == 1 ) - front ^= 1; - - intelSetFrontClipRects( intel ); - - if (front) { - intel->drawRegion = &intel->intelScreen->front; - intel->readRegion = &intel->intelScreen->front; - } else { - intel->drawRegion = &intel->intelScreen->back; - intel->readRegion = &intel->intelScreen->back; - } - - intel->vtbl.set_color_region( intel, intel->drawRegion ); -} - -static void intelReadBuffer( GLcontext *ctx, GLenum mode ) -{ - /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ -} - - -static void intelClearColor(GLcontext *ctx, const GLfloat color[4]) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - intelScreenPrivate *screen = intel->intelScreen; - - CLAMPED_FLOAT_TO_UBYTE(intel->clear_red, color[0]); - CLAMPED_FLOAT_TO_UBYTE(intel->clear_green, color[1]); - CLAMPED_FLOAT_TO_UBYTE(intel->clear_blue, color[2]); - CLAMPED_FLOAT_TO_UBYTE(intel->clear_alpha, color[3]); - - intel->ClearColor = INTEL_PACKCOLOR(screen->fbFormat, - intel->clear_red, - intel->clear_green, - intel->clear_blue, - intel->clear_alpha); -} - - -static void intelCalcViewport( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - const GLfloat *v = ctx->Viewport._WindowMap.m; - GLfloat *m = intel->ViewportMatrix.m; - GLint h = 0; - - if (intel->driDrawable) - h = intel->driDrawable->h + SUBPIXEL_Y; - - /* See also intel_translate_vertex. SUBPIXEL adjustments can be done - * via state vars, too. - */ - m[MAT_SX] = v[MAT_SX]; - m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; - m[MAT_SY] = - v[MAT_SY]; - m[MAT_TY] = - v[MAT_TY] + h; - m[MAT_SZ] = v[MAT_SZ] * intel->depth_scale; - m[MAT_TZ] = v[MAT_TZ] * intel->depth_scale; -} - -static void intelViewport( GLcontext *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height ) -{ - intelCalcViewport( ctx ); -} - -static void intelDepthRange( GLcontext *ctx, - GLclampd nearval, GLclampd farval ) -{ - intelCalcViewport( ctx ); -} - -/* Fallback to swrast for select and feedback. - */ -static void intelRenderMode( GLcontext *ctx, GLenum mode ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - FALLBACK( intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); -} - - -void intelInitStateFuncs( struct dd_function_table *functions ) -{ - functions->DrawBuffer = intelDrawBuffer; - functions->ReadBuffer = intelReadBuffer; - functions->RenderMode = intelRenderMode; - functions->Viewport = intelViewport; - functions->DepthRange = intelDepthRange; - functions->ClearColor = intelClearColor; -} - diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c deleted file mode 100644 index 978945f26b..0000000000 --- a/src/mesa/drivers/dri/i915/intel_tex.c +++ /dev/null @@ -1,879 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "macros.h" -#include "simple_list.h" -#include "enums.h" -#include "image.h" -#include "texstore.h" -#include "texformat.h" -#include "teximage.h" -#include "texmem.h" -#include "texobj.h" -#include "swrast/swrast.h" - -#include "mm.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_context.h" -#include "intel_tex.h" -#include "intel_ioctl.h" - - - -static GLboolean -intelValidateClientStorage( intelContextPtr intel, GLenum target, - GLint internalFormat, - GLint srcWidth, GLint srcHeight, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) - -{ - GLcontext *ctx = &intel->ctx; - int texelBytes; - - if (0) - fprintf(stderr, "intformat %s format %s type %s\n", - _mesa_lookup_enum_by_nr( internalFormat ), - _mesa_lookup_enum_by_nr( format ), - _mesa_lookup_enum_by_nr( type )); - - if (!ctx->Unpack.ClientStorage) - return 0; - - if (ctx->_ImageTransferState || - texImage->IsCompressed || - texObj->GenerateMipmap) - return 0; - - - /* This list is incomplete - */ - switch ( internalFormat ) { - case GL_RGBA: - if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) { - texImage->TexFormat = &_mesa_texformat_argb8888; - texelBytes = 4; - } - else - return 0; - break; - - case GL_RGB: - if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { - texImage->TexFormat = &_mesa_texformat_rgb565; - texelBytes = 2; - } - else - return 0; - break; - - case GL_YCBCR_MESA: - if ( format == GL_YCBCR_MESA && - type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) { - texImage->TexFormat = &_mesa_texformat_ycbcr_rev; - texelBytes = 2; - } - else if ( format == GL_YCBCR_MESA && - (type == GL_UNSIGNED_SHORT_8_8_APPLE || - type == GL_UNSIGNED_BYTE)) { - texImage->TexFormat = &_mesa_texformat_ycbcr; - texelBytes = 2; - } - else - return 0; - break; - - - default: - return 0; - } - - /* Could deal with these packing issues, but currently don't: - */ - if (packing->SkipPixels || - packing->SkipRows || - packing->SwapBytes || - packing->LsbFirst) { - return 0; - } - - { - GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth, - format, type); - - - if (0) - fprintf(stderr, "%s: srcRowStride %d/%x\n", - __FUNCTION__, srcRowStride, srcRowStride); - - /* Could check this later in upload, pitch restrictions could be - * relaxed, but would need to store the image pitch somewhere, - * as packing details might change before image is uploaded: - */ - if (!intelIsAgpMemory( intel, pixels, srcHeight * srcRowStride ) || - (srcRowStride & 63)) - return 0; - - - /* Have validated that _mesa_transfer_teximage would be a straight - * memcpy at this point. NOTE: future calls to TexSubImage will - * overwrite the client data. This is explicitly mentioned in the - * extension spec. - */ - texImage->Data = (void *)pixels; - texImage->IsClientData = GL_TRUE; - texImage->RowStride = srcRowStride / texelBytes; - return 1; - } -} - - - -static void intelTexImage1D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - - assert(t); - intelFlush( ctx ); - driSwapOutTextureObject( t ); - - texImage->IsClientData = GL_FALSE; - - _mesa_store_teximage1d( ctx, target, level, internalFormat, - width, border, format, type, - pixels, packing, texObj, texImage ); - - t->dirty_images[0] |= (1 << level); -} - -static void intelTexSubImage1D( GLcontext *ctx, - GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - - assert(t); - intelFlush( ctx ); - driSwapOutTextureObject( t ); - - _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, - format, type, pixels, packing, texObj, - texImage); -} - - -/* Handles 2D, CUBE, RECT: - */ -static void intelTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - GLuint face; - - /* which cube face or ordinary 2D image */ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - ASSERT(face < 6); - break; - default: - face = 0; - } - - assert(t); - intelFlush( ctx ); - driSwapOutTextureObject( t ); - texImage->IsClientData = GL_FALSE; - - if (intelValidateClientStorage( INTEL_CONTEXT(ctx), target, - internalFormat, - width, height, - format, type, pixels, - packing, texObj, texImage)) { - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); - } - else { - _mesa_store_teximage2d( ctx, target, level, internalFormat, - width, height, border, format, type, - pixels, packing, texObj, texImage ); - - t->dirty_images[face] |= (1 << level); - } -} - -static void intelTexSubImage2D( GLcontext *ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - GLuint face; - - /* which cube face or ordinary 2D image */ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - ASSERT(face < 6); - break; - default: - face = 0; - } - - if (texImage->IsClientData && - (char *)pixels == (char *)texImage->Data + - ((xoffset + yoffset * texImage->RowStride) * - texImage->TexFormat->TexelBytes)) { - - /* Notification only - no upload required */ - } - else { - assert( t ); /* this _should_ be true */ - intelFlush( ctx ); - driSwapOutTextureObject( t ); - - _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, - height, format, type, pixels, packing, texObj, - texImage); - - t->dirty_images[face] |= (1 << level); - } -} - -static void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - GLuint face; - - /* which cube face or ordinary 2D image */ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - ASSERT(face < 6); - break; - default: - face = 0; - } - - assert(t); - intelFlush( ctx ); - - driSwapOutTextureObject( t ); - texImage->IsClientData = GL_FALSE; - - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); - - _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width, - height, border, imageSize, data, texObj, texImage); - - t->dirty_images[face] |= (1 << level); -} - - -static void intelCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - GLuint face; - - - /* which cube face or ordinary 2D image */ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - ASSERT(face < 6); - break; - default: - face = 0; - } - - assert( t ); /* this _should_ be true */ - intelFlush( ctx ); - driSwapOutTextureObject( t ); - - _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width, - height, format, imageSize, data, texObj, texImage); - - t->dirty_images[face] |= (1 << level); -} - - -static void intelTexImage3D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - - assert(t); - driSwapOutTextureObject( t ); - texImage->IsClientData = GL_FALSE; - - _mesa_store_teximage3d(ctx, target, level, internalFormat, - width, height, depth, border, - format, type, pixels, - &ctx->Unpack, texObj, texImage); - - t->dirty_images[0] |= (1 << level); -} - - -static void -intelTexSubImage3D( GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - driTextureObject * t = (driTextureObject *) texObj->DriverData; - - assert( t ); /* this _should_ be true */ - driSwapOutTextureObject( t ); - - _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, packing, texObj, texImage); - - t->dirty_images[0] |= (1 << level); -} - - - - -static void intelDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) -{ - driTextureObject * t = (driTextureObject *) tObj->DriverData; - - if ( t != NULL ) { - intelFlush( ctx ); - driDestroyTextureObject( t ); - } - - /* Free mipmap images and the texture object itself */ - _mesa_delete_texture_object(ctx, tObj); -} - - -static const struct gl_texture_format * -intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat, - GLenum format, GLenum type ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - const GLboolean do32bpt = ( intel->intelScreen->cpp == 4 && - intel->intelScreen->tex.size > 4*1024*1024); - - switch ( internalFormat ) { - case 4: - case GL_RGBA: - case GL_COMPRESSED_RGBA: - if ( format == GL_BGRA ) { - if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { - return &_mesa_texformat_argb8888; - } - else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { - return &_mesa_texformat_argb4444; - } - else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { - return &_mesa_texformat_argb1555; - } - } - return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; - - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: - if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { - return &_mesa_texformat_rgb565; - } - return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; - - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; - - case GL_RGBA4: - case GL_RGBA2: - return &_mesa_texformat_argb4444; - - case GL_RGB5_A1: - return &_mesa_texformat_argb1555; - - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; - - case GL_RGB5: - case GL_RGB4: - case GL_R3_G3_B2: - return &_mesa_texformat_rgb565; - - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - case GL_COMPRESSED_ALPHA: - return &_mesa_texformat_a8; - - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - case GL_COMPRESSED_LUMINANCE: - return &_mesa_texformat_l8; - - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - case GL_COMPRESSED_LUMINANCE_ALPHA: - return &_mesa_texformat_al88; - - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - case GL_COMPRESSED_INTENSITY: - return &_mesa_texformat_i8; - - case GL_YCBCR_MESA: - if (type == GL_UNSIGNED_SHORT_8_8_MESA || - type == GL_UNSIGNED_BYTE) - return &_mesa_texformat_ycbcr; - else - return &_mesa_texformat_ycbcr_rev; - - case GL_COMPRESSED_RGB_FXT1_3DFX: - return &_mesa_texformat_rgb_fxt1; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return &_mesa_texformat_rgba_fxt1; - - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return &_mesa_texformat_rgb_dxt1; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return &_mesa_texformat_rgba_dxt1; - - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - return &_mesa_texformat_rgba_dxt3; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return &_mesa_texformat_rgba_dxt5; - - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - return &_mesa_texformat_z16; - - default: - fprintf(stderr, "unexpected texture format %s in %s\n", - _mesa_lookup_enum_by_nr(internalFormat), - __FUNCTION__); - return NULL; - } - - return NULL; /* never get here */ -} - - - -void intelDestroyTexObj(intelContextPtr intel, intelTextureObjectPtr t) -{ - unsigned i; - - if ( intel == NULL ) - return; - - if ( t->age > intel->dirtyAge ) - intel->dirtyAge = t->age; - - for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) { - if ( t == intel->CurrentTexObj[ i ] ) - intel->CurrentTexObj[ i ] = NULL; - } -} - - - -/* Upload an image from mesa's internal copy. Image may be 1D, 2D or - * 3D. Cubemaps are expanded elsewhere. - */ -static void intelUploadTexImage( intelContextPtr intel, - intelTextureObjectPtr t, - const struct gl_texture_image *image, - const GLuint offset ) -{ - - if (!image || !image->Data) - return; - - if (image->Depth == 1 && image->IsClientData) { - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "Blit uploading\n"); - - /* Do it with a blit. - */ - intelEmitCopyBlitLocked( intel, - image->TexFormat->TexelBytes, - image->RowStride, /* ? */ - intelGetMemoryOffsetMESA( NULL, 0, image->Data ), - t->Pitch / image->TexFormat->TexelBytes, - intelGetMemoryOffsetMESA( NULL, 0, t->BufAddr + offset ), - 0, 0, - 0, 0, - image->Width, - image->Height); - } - else if (image->IsCompressed) { - GLuint row_len = 0; - GLubyte *dst = (GLubyte *)(t->BufAddr + offset); - GLubyte *src = (GLubyte *)image->Data; - GLuint j; - - /* must always copy whole blocks (8/16 bytes) */ - switch (image->InternalFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - row_len = ((image->Width + 7) & ~7) * 2; - break; - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - row_len = ((image->Width + 3) & ~3) * 2; - break; - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - row_len = ((image->Width + 3) & ~3) * 4; - break; - default: - fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat); - break; - } - - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, - "Upload image %dx%dx%d offset %xm row_len %x " - "pitch %x depth_pitch %x\n", - image->Width, image->Height, image->Depth, offset, - row_len, t->Pitch, t->depth_pitch); - - if (row_len) { - for (j = 0 ; j < (image->Height + 3)/4 ; j++, dst += (t->Pitch)) { - __memcpy(dst, src, row_len ); - src += row_len; - } - } - } - /* Time for another vtbl entry: - */ - else if (intel->intelScreen->deviceID == PCI_CHIP_I945_G || - intel->intelScreen->deviceID == PCI_CHIP_I945_GM || - intel->intelScreen->deviceID == PCI_CHIP_I945_GME || - intel->intelScreen->deviceID == PCI_CHIP_G33_G || - intel->intelScreen->deviceID == PCI_CHIP_Q33_G || - intel->intelScreen->deviceID == PCI_CHIP_Q35_G) { - GLuint row_len = image->Width * image->TexFormat->TexelBytes; - GLubyte *dst = (GLubyte *)(t->BufAddr + offset); - GLubyte *src = (GLubyte *)image->Data; - GLuint d, j; - - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, - "Upload image %dx%dx%d offset %xm row_len %x " - "pitch %x depth_pitch %x\n", - image->Width, image->Height, image->Depth, offset, - row_len, t->Pitch, t->depth_pitch); - - if (row_len == t->Pitch) { - memcpy( dst, src, row_len * image->Height * image->Depth ); - } - else { - GLuint x = 0, y = 0; - - for (d = 0 ; d < image->Depth ; d++) { - GLubyte *dst0 = dst + x + y * t->Pitch; - - for (j = 0 ; j < image->Height ; j++) { - __memcpy(dst0, src, row_len ); - src += row_len; - dst0 += t->Pitch; - } - - x += MIN2(4, row_len); /* Guess: 4 byte minimum alignment */ - if (x > t->Pitch) { - x = 0; - y += image->Height; - } - } - } - - } - else { - GLuint row_len = image->Width * image->TexFormat->TexelBytes; - GLubyte *dst = (GLubyte *)(t->BufAddr + offset); - GLubyte *src = (GLubyte *)image->Data; - GLuint d, j; - - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, - "Upload image %dx%dx%d offset %xm row_len %x " - "pitch %x depth_pitch %x\n", - image->Width, image->Height, image->Depth, offset, - row_len, t->Pitch, t->depth_pitch); - - if (row_len == t->Pitch) { - for (d = 0; d < image->Depth; d++) { - memcpy( dst, src, t->Pitch * image->Height ); - dst += t->depth_pitch; - src += row_len * image->Height; - } - } - else { - for (d = 0 ; d < image->Depth ; d++) { - for (j = 0 ; j < image->Height ; j++) { - __memcpy(dst, src, row_len ); - src += row_len; - dst += t->Pitch; - } - - dst += t->depth_pitch - (t->Pitch * image->Height); - } - } - } -} - - - -int intelUploadTexImages( intelContextPtr intel, - intelTextureObjectPtr t, - GLuint face) -{ - const int numLevels = t->base.lastLevel - t->base.firstLevel + 1; - const struct gl_texture_image *firstImage = t->image[face][t->base.firstLevel].image; - int pitch = firstImage->RowStride * firstImage->TexFormat->TexelBytes; - - /* Can we texture out of the existing client data? */ - if ( numLevels == 1 && - firstImage->IsClientData && - (pitch & 3) == 0) { - - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "AGP texturing from client memory\n"); - - t->TextureOffset = intelAgpOffsetFromVirtual( intel, firstImage->Data ); - t->BufAddr = 0; - t->dirty = ~0; - return GL_TRUE; - } - else { - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "Uploading client data to agp\n"); - - INTEL_FIREVERTICES( intel ); - LOCK_HARDWARE( intel ); - - if ( t->base.memBlock == NULL ) { - int heap; - - heap = driAllocateTexture( intel->texture_heaps, intel->nr_heaps, - (driTextureObject *) t ); - if ( heap == -1 ) { - UNLOCK_HARDWARE( intel ); - return GL_FALSE; - } - - /* Set the base offset of the texture image */ - t->BufAddr = (GLubyte *) (intel->intelScreen->tex.map + - t->base.memBlock->ofs); - t->TextureOffset = intel->intelScreen->tex.offset + t->base.memBlock->ofs; - t->dirty = ~0; - } - - - /* Let the world know we've used this memory recently. - */ - driUpdateTextureLRU( (driTextureObject *) t ); - - - /* Upload any images that are new */ - if (t->base.dirty_images[face]) { - int i; - - intelWaitForIdle( intel ); - - for (i = 0 ; i < numLevels ; i++) { - int level = i + t->base.firstLevel; - - if (t->base.dirty_images[face] & (1<image[face][i].image; - GLuint offset = t->image[face][i].offset; - - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "upload level %d, offset %x\n", - level, offset); - - intelUploadTexImage( intel, t, image, offset ); - } - } - t->base.dirty_images[face] = 0; - intel->perf_boxes |= I830_BOX_TEXTURE_LOAD; - } - - UNLOCK_HARDWARE( intel ); - return GL_TRUE; - } -} - -/** - * Allocate a new texture object. - * Called via ctx->Driver.NewTextureObject. - * Note: this function will be called during context creation to - * allocate the default texture objects. - * Note: we could use containment here to 'derive' the driver-specific - * texture object from the core mesa gl_texture_object. Not done at this time. - */ -static struct gl_texture_object * -intelNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) -{ - struct gl_texture_object *obj = _mesa_new_texture_object(ctx, name, target); - INTEL_CONTEXT(ctx)->vtbl.alloc_tex_obj( obj ); - return obj; -} - - -void intelInitTextureFuncs( struct dd_function_table *functions ) -{ - functions->NewTextureObject = intelNewTextureObject; - functions->ChooseTextureFormat = intelChooseTextureFormat; - functions->TexImage1D = intelTexImage1D; - functions->TexImage2D = intelTexImage2D; - functions->TexImage3D = intelTexImage3D; - functions->TexSubImage1D = intelTexSubImage1D; - functions->TexSubImage2D = intelTexSubImage2D; - functions->TexSubImage3D = intelTexSubImage3D; - functions->CopyTexImage1D = _swrast_copy_teximage1d; - functions->CopyTexImage2D = _swrast_copy_teximage2d; - functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d; - functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d; - functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d; - functions->DeleteTexture = intelDeleteTexture; - functions->UpdateTexturePalette = NULL; - functions->IsTextureResident = driIsTextureResident; - functions->TestProxyTexImage = _mesa_test_proxy_teximage; - functions->DeleteTexture = intelDeleteTexture; - functions->CompressedTexImage2D = intelCompressedTexImage2D; - functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D; -} diff --git a/src/mesa/drivers/dri/i915/intel_tex.h b/src/mesa/drivers/dri/i915/intel_tex.h deleted file mode 100644 index 9b7e550232..0000000000 --- a/src/mesa/drivers/dri/i915/intel_tex.h +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTELTEX_INC -#define INTELTEX_INC - -#include "mtypes.h" -#include "intel_context.h" -#include "texmem.h" - - -void intelInitTextureFuncs( struct dd_function_table *functions ); - -void intelDestroyTexObj( intelContextPtr intel, intelTextureObjectPtr t ); -int intelUploadTexImages( intelContextPtr intel, intelTextureObjectPtr t, - GLuint face ); - -GLboolean -intel_driReinitTextureHeap( driTexHeap *heap, - unsigned size ); -#endif diff --git a/src/mesa/drivers/dri/i915/intel_texmem.c b/src/mesa/drivers/dri/i915/intel_texmem.c deleted file mode 100644 index 09beec95b8..0000000000 --- a/src/mesa/drivers/dri/i915/intel_texmem.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "texmem.h" -#include "simple_list.h" -#include "imports.h" -#include "macros.h" - -#include "intel_tex.h" - -static GLuint -driLog2( GLuint n ) -{ - GLuint log2; - - for ( log2 = 1 ; n > 1 ; log2++ ) { - n >>= 1; - } - - return log2; -} - -static void calculate_heap_size( driTexHeap * heap, unsigned size, - unsigned nr_regions, unsigned alignmentShift ) -{ - unsigned l; - - l = driLog2( (size - 1) / nr_regions ); - if ( l < alignmentShift ) - { - l = alignmentShift; - } - - heap->logGranularity = l; - heap->size = size & ~((1L << l) - 1); -} - - -GLboolean -intel_driReinitTextureHeap( driTexHeap *heap, - unsigned size ) -{ - driTextureObject *t, *tmp; - - /* Kick out everything: - */ - foreach_s ( t, tmp, & heap->texture_objects ) { - if ( t->tObj != NULL ) { - driSwapOutTextureObject( t ); - } - else { - driDestroyTextureObject( t ); - } - } - - /* Destroy the memory manager: - */ - mmDestroy( heap->memory_heap ); - - /* Recreate the memory manager: - */ - calculate_heap_size(heap, size, heap->nrRegions, heap->alignmentShift); - heap->memory_heap = mmInit( 0, heap->size ); - if ( heap->memory_heap == NULL ) { - fprintf(stderr, "driReinitTextureHeap: couldn't recreate memory heap\n"); - FREE( heap ); - return GL_FALSE; - } - - make_empty_list( & heap->texture_objects ); - - return GL_TRUE; -} - - diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c deleted file mode 100644 index b2787ee60a..0000000000 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ /dev/null @@ -1,945 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/t_context.h" -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" - -#include "intel_screen.h" -#include "intel_tris.h" -#include "intel_batchbuffer.h" -#include "intel_reg.h" -#include "intel_span.h" - -/* XXX we shouldn't include these headers in this file, but we need them - * for fallbackStrings, below. - */ -#include "i830_context.h" -#include "i915_context.h" - -static void intelRenderPrimitive( GLcontext *ctx, GLenum prim ); -static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); - -/*********************************************************************** - * Emit primitives as inline vertices * - ***********************************************************************/ - -#ifdef __i386__ -#define COPY_DWORDS( j, vb, vertsize, v ) \ -do { \ - int __tmp; \ - __asm__ __volatile__( "rep ; movsl" \ - : "=%c" (j), "=D" (vb), "=S" (__tmp) \ - : "0" (vertsize), \ - "D" ((long)vb), \ - "S" ((long)v) ); \ -} while (0) -#else -#define COPY_DWORDS( j, vb, vertsize, v ) \ -do { \ - if (0) fprintf(stderr, "\n"); \ - for ( j = 0 ; j < vertsize ; j++ ) { \ - if (0) fprintf(stderr, " -- v(%d): %x/%f\n",j, \ - ((GLuint *)v)[j], \ - ((GLfloat *)v)[j]); \ - vb[j] = ((GLuint *)v)[j]; \ - } \ - vb += vertsize; \ -} while (0) -#endif - -static void __inline__ intel_draw_quad( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1, - intelVertexPtr v2, - intelVertexPtr v3 ) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize ); - int j; - - COPY_DWORDS( j, vb, vertsize, v0 ); - COPY_DWORDS( j, vb, vertsize, v1 ); - COPY_DWORDS( j, vb, vertsize, v3 ); - COPY_DWORDS( j, vb, vertsize, v1 ); - COPY_DWORDS( j, vb, vertsize, v2 ); - COPY_DWORDS( j, vb, vertsize, v3 ); -} - -static void __inline__ intel_draw_triangle( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1, - intelVertexPtr v2 ) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize ); - int j; - - COPY_DWORDS( j, vb, vertsize, v0 ); - COPY_DWORDS( j, vb, vertsize, v1 ); - COPY_DWORDS( j, vb, vertsize, v2 ); -} - - -static __inline__ void intel_draw_line( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1 ) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize ); - int j; - - COPY_DWORDS( j, vb, vertsize, v0 ); - COPY_DWORDS( j, vb, vertsize, v1 ); -} - - -static __inline__ void intel_draw_point( intelContextPtr intel, - intelVertexPtr v0 ) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive( intel, vertsize ); - int j; - - /* Adjust for sub pixel position -- still required for conform. */ - *(float *)&vb[0] = v0->v.x - 0.125; - *(float *)&vb[1] = v0->v.y - 0.125; - for (j = 2 ; j < vertsize ; j++) - vb[j] = v0->ui[j]; -} - - - -/*********************************************************************** - * Fixup for ARB_point_parameters * - ***********************************************************************/ - -static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 ) -{ - GLcontext *ctx = &intel->ctx; - GLfloat psz[4], col[4], restore_psz, restore_alpha; - - _tnl_get_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz ); - _tnl_get_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col ); - - restore_psz = psz[0]; - restore_alpha = col[3]; - - if (psz[0] >= ctx->Point.Threshold) { - psz[0] = MIN2(psz[0], ctx->Point.MaxSize); - } - else { - GLfloat dsize = psz[0] / ctx->Point.Threshold; - psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); - col[3] *= dsize * dsize; - } - - if (psz[0] < 1.0) - psz[0] = 1.0; - - if (restore_psz != psz[0] || restore_alpha != col[3]) { - _tnl_set_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); - _tnl_set_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col); - - intel_draw_point( intel, v0 ); - - psz[0] = restore_psz; - col[3] = restore_alpha; - - _tnl_set_attr( ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); - _tnl_set_attr( ctx, v0, _TNL_ATTRIB_COLOR0, col); - } - else - intel_draw_point( intel, v0 ); -} - - - - - -/*********************************************************************** - * Fixup for I915 WPOS texture coordinate * - ***********************************************************************/ - - - -static void intel_wpos_triangle( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1, - intelVertexPtr v2 ) -{ - GLuint offset = intel->wpos_offset; - GLuint size = intel->wpos_size; - - __memcpy( ((char *)v0) + offset, v0, size ); - __memcpy( ((char *)v1) + offset, v1, size ); - __memcpy( ((char *)v2) + offset, v2, size ); - - intel_draw_triangle( intel, v0, v1, v2 ); -} - - -static void intel_wpos_line( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1 ) -{ - GLuint offset = intel->wpos_offset; - GLuint size = intel->wpos_size; - - __memcpy( ((char *)v0) + offset, v0, size ); - __memcpy( ((char *)v1) + offset, v1, size ); - - intel_draw_line( intel, v0, v1 ); -} - - -static void intel_wpos_point( intelContextPtr intel, - intelVertexPtr v0 ) -{ - GLuint offset = intel->wpos_offset; - GLuint size = intel->wpos_size; - - __memcpy( ((char *)v0) + offset, v0, size ); - - intel_draw_point( intel, v0 ); -} - - - - - - -/*********************************************************************** - * Macros for t_dd_tritmp.h to draw basic primitives * - ***********************************************************************/ - -#define TRI( a, b, c ) \ -do { \ - if (DO_FALLBACK) \ - intel->draw_tri( intel, a, b, c ); \ - else \ - intel_draw_triangle( intel, a, b, c ); \ -} while (0) - -#define QUAD( a, b, c, d ) \ -do { \ - if (DO_FALLBACK) { \ - intel->draw_tri( intel, a, b, d ); \ - intel->draw_tri( intel, b, c, d ); \ - } else \ - intel_draw_quad( intel, a, b, c, d ); \ -} while (0) - -#define LINE( v0, v1 ) \ -do { \ - if (DO_FALLBACK) \ - intel->draw_line( intel, v0, v1 ); \ - else \ - intel_draw_line( intel, v0, v1 ); \ -} while (0) - -#define POINT( v0 ) \ -do { \ - if (DO_FALLBACK) \ - intel->draw_point( intel, v0 ); \ - else \ - intel_draw_point( intel, v0 ); \ -} while (0) - - -/*********************************************************************** - * Build render functions from dd templates * - ***********************************************************************/ - -#define INTEL_OFFSET_BIT 0x01 -#define INTEL_TWOSIDE_BIT 0x02 -#define INTEL_UNFILLED_BIT 0x04 -#define INTEL_FALLBACK_BIT 0x08 -#define INTEL_MAX_TRIFUNC 0x10 - - -static struct { - tnl_points_func points; - tnl_line_func line; - tnl_triangle_func triangle; - tnl_quad_func quad; -} rast_tab[INTEL_MAX_TRIFUNC]; - - -#define DO_FALLBACK (IND & INTEL_FALLBACK_BIT) -#define DO_OFFSET (IND & INTEL_OFFSET_BIT) -#define DO_UNFILLED (IND & INTEL_UNFILLED_BIT) -#define DO_TWOSIDE (IND & INTEL_TWOSIDE_BIT) -#define DO_FLAT 0 -#define DO_TRI 1 -#define DO_QUAD 1 -#define DO_LINE 1 -#define DO_POINTS 1 -#define DO_FULL_QUAD 1 - -#define HAVE_RGBA 1 -#define HAVE_SPEC 1 -#define HAVE_BACK_COLORS 0 -#define HAVE_HW_FLATSHADE 1 -#define VERTEX intelVertex -#define TAB rast_tab - -/* Only used to pull back colors into vertices (ie, we know color is - * floating point). - */ -#define INTEL_COLOR( dst, src ) \ -do { \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \ -} while (0) - -#define INTEL_SPEC( dst, src ) \ -do { \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ -} while (0) - - -#define DEPTH_SCALE intel->polygon_offset_scale -#define UNFILLED_TRI unfilled_tri -#define UNFILLED_QUAD unfilled_quad -#define VERT_X(_v) _v->v.x -#define VERT_Y(_v) _v->v.y -#define VERT_Z(_v) _v->v.z -#define AREA_IS_CCW( a ) (a > 0) -#define GET_VERTEX(e) (intel->verts + (e * intel->vertex_size * sizeof(GLuint))) - -#define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c ) -#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset] -#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset] -#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx] - -#define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c ) -#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset]) -#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset] -#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx] - -#define LOCAL_VARS(n) \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ - GLuint color[n], spec[n]; \ - GLuint coloroffset = intel->coloroffset; \ - GLboolean specoffset = intel->specoffset; \ - (void) color; (void) spec; (void) coloroffset; (void) specoffset; - - -/*********************************************************************** - * Helpers for rendering unfilled primitives * - ***********************************************************************/ - -static const GLuint hw_prim[GL_POLYGON+1] = { - PRIM3D_POINTLIST, - PRIM3D_LINELIST, - PRIM3D_LINELIST, - PRIM3D_LINELIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST -}; - -#define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] ) -#define RENDER_PRIMITIVE intel->render_primitive -#define TAG(x) x -#define IND INTEL_FALLBACK_BIT -#include "tnl_dd/t_dd_unfilled.h" -#undef IND - -/*********************************************************************** - * Generate GL render functions * - ***********************************************************************/ - -#define IND (0) -#define TAG(x) x -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT) -#define TAG(x) x##_offset -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT) -#define TAG(x) x##_twoside -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT) -#define TAG(x) x##_twoside_offset -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_UNFILLED_BIT) -#define TAG(x) x##_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) -#define TAG(x) x##_offset_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT) -#define TAG(x) x##_twoside_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_FALLBACK_BIT) -#define TAG(x) x##_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_offset_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_offset_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_offset_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \ - INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_offset_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - - -static void init_rast_tab( void ) -{ - init(); - init_offset(); - init_twoside(); - init_twoside_offset(); - init_unfilled(); - init_offset_unfilled(); - init_twoside_unfilled(); - init_twoside_offset_unfilled(); - init_fallback(); - init_offset_fallback(); - init_twoside_fallback(); - init_twoside_offset_fallback(); - init_unfilled_fallback(); - init_offset_unfilled_fallback(); - init_twoside_unfilled_fallback(); - init_twoside_offset_unfilled_fallback(); -} - - -/*********************************************************************** - * Rasterization fallback helpers * - ***********************************************************************/ - - -/* This code is hit only when a mix of accelerated and unaccelerated - * primitives are being drawn, and only for the unaccelerated - * primitives. - */ -static void -intel_fallback_tri( intelContextPtr intel, - intelVertex *v0, - intelVertex *v1, - intelVertex *v2 ) -{ - GLcontext *ctx = &intel->ctx; - SWvertex v[3]; - - if (0) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - _swsetup_Translate( ctx, v0, &v[0] ); - _swsetup_Translate( ctx, v1, &v[1] ); - _swsetup_Translate( ctx, v2, &v[2] ); - intelSpanRenderStart( ctx ); - _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); - intelSpanRenderFinish( ctx ); -} - - -static void -intel_fallback_line( intelContextPtr intel, - intelVertex *v0, - intelVertex *v1 ) -{ - GLcontext *ctx = &intel->ctx; - SWvertex v[2]; - - if (0) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - _swsetup_Translate( ctx, v0, &v[0] ); - _swsetup_Translate( ctx, v1, &v[1] ); - intelSpanRenderStart( ctx ); - _swrast_Line( ctx, &v[0], &v[1] ); - intelSpanRenderFinish( ctx ); -} - - -static void -intel_fallback_point( intelContextPtr intel, - intelVertex *v0 ) -{ - GLcontext *ctx = &intel->ctx; - SWvertex v[1]; - - if (0) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - _swsetup_Translate( ctx, v0, &v[0] ); - intelSpanRenderStart( ctx ); - _swrast_Point( ctx, &v[0] ); - intelSpanRenderFinish( ctx ); -} - - - -/**********************************************************************/ -/* Render unclipped begin/end objects */ -/**********************************************************************/ - -#define IND 0 -#define V(x) (intelVertex *)(vertptr + ((x)*vertsize*sizeof(GLuint))) -#define RENDER_POINTS( start, count ) \ - for ( ; start < count ; start++) POINT( V(ELT(start)) ); -#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) -#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) -#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) -#define INIT(x) intelRenderPrimitive( ctx, x ) -#undef LOCAL_VARS -#define LOCAL_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ - GLubyte *vertptr = (GLubyte *)intel->verts; \ - const GLuint vertsize = intel->vertex_size; \ - const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ - (void) elt; -#define RESET_STIPPLE -#define RESET_OCCLUSION -#define PRESERVE_VB_DEFS -#define ELT(x) x -#define TAG(x) intel_##x##_verts -#include "tnl/t_vb_rendertmp.h" -#undef ELT -#undef TAG -#define TAG(x) intel_##x##_elts -#define ELT(x) elt[x] -#include "tnl/t_vb_rendertmp.h" - -/**********************************************************************/ -/* Render clipped primitives */ -/**********************************************************************/ - - - -static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts, - GLuint n ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLuint prim = intel->render_primitive; - - /* Render the new vertices as an unclipped polygon. - */ - { - GLuint *tmp = VB->Elts; - VB->Elts = (GLuint *)elts; - tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, - PRIM_BEGIN|PRIM_END ); - VB->Elts = tmp; - } - - /* Restore the render primitive - */ - if (prim != GL_POLYGON) - tnl->Driver.Render.PrimitiveNotify( ctx, prim ); -} - -static void intelRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - tnl->Driver.Render.Line( ctx, ii, jj ); -} - -static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, - GLuint n ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - const GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive( intel, (n-2) * 3 * vertsize ); - GLubyte *vertptr = (GLubyte *)intel->verts; - const GLuint *start = (const GLuint *)V(elts[0]); - int i,j; - - for (i = 2 ; i < n ; i++) { - COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) ); - COPY_DWORDS( j, vb, vertsize, V(elts[i]) ); - COPY_DWORDS( j, vb, vertsize, start ); - } -} - -/**********************************************************************/ -/* Choose render functions */ -/**********************************************************************/ - - - - -#define POINT_FALLBACK (0) -#define LINE_FALLBACK (DD_LINE_STIPPLE) -#define TRI_FALLBACK (0) -#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\ - DD_TRI_STIPPLE|DD_POINT_ATTEN) -#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) - -void intelChooseRenderState(GLcontext *ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - intelContextPtr intel = INTEL_CONTEXT(ctx); - GLuint flags = ctx->_TriangleCaps; - const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; - GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS)); - GLuint index = 0; - - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr,"\n%s\n",__FUNCTION__); - - if ((flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) || have_wpos) { - - if (flags & ANY_RASTER_FLAGS) { - if (flags & DD_TRI_LIGHT_TWOSIDE) index |= INTEL_TWOSIDE_BIT; - if (flags & DD_TRI_OFFSET) index |= INTEL_OFFSET_BIT; - if (flags & DD_TRI_UNFILLED) index |= INTEL_UNFILLED_BIT; - } - - if (have_wpos) { - intel->draw_point = intel_wpos_point; - intel->draw_line = intel_wpos_line; - intel->draw_tri = intel_wpos_triangle; - - /* Make sure these get called: - */ - index |= INTEL_FALLBACK_BIT; - } - else { - intel->draw_point = intel_draw_point; - intel->draw_line = intel_draw_line; - intel->draw_tri = intel_draw_triangle; - } - - /* Hook in fallbacks for specific primitives. - */ - if (flags & ANY_FALLBACK_FLAGS) - { - if (flags & POINT_FALLBACK) - intel->draw_point = intel_fallback_point; - - if (flags & LINE_FALLBACK) - intel->draw_line = intel_fallback_line; - - if (flags & TRI_FALLBACK) - intel->draw_tri = intel_fallback_tri; - - if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) - intel->draw_tri = intel_fallback_tri; - - if (flags & DD_POINT_ATTEN) - intel->draw_point = intel_atten_point; - - index |= INTEL_FALLBACK_BIT; - } - } - - if (intel->RenderIndex != index) { - intel->RenderIndex = index; - - tnl->Driver.Render.Points = rast_tab[index].points; - tnl->Driver.Render.Line = rast_tab[index].line; - tnl->Driver.Render.Triangle = rast_tab[index].triangle; - tnl->Driver.Render.Quad = rast_tab[index].quad; - - if (index == 0) { - tnl->Driver.Render.PrimTabVerts = intel_render_tab_verts; - tnl->Driver.Render.PrimTabElts = intel_render_tab_elts; - tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ - tnl->Driver.Render.ClippedPolygon = intelFastRenderClippedPoly; - } else { - tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; - tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; - tnl->Driver.Render.ClippedLine = intelRenderClippedLine; - tnl->Driver.Render.ClippedPolygon = intelRenderClippedPoly; - } - } -} - -static const GLenum reduced_prim[GL_POLYGON+1] = { - GL_POINTS, - GL_LINES, - GL_LINES, - GL_LINES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES -}; - - -/**********************************************************************/ -/* High level hooks for t_vb_render.c */ -/**********************************************************************/ - - - - -static void intelRunPipeline( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - - if (intel->NewGLState) { - if (intel->NewGLState & _NEW_TEXTURE) { - intel->vtbl.update_texture_state( intel ); - } - - if (!intel->Fallback) { - if (intel->NewGLState & _INTEL_NEW_RENDERSTATE) - intelChooseRenderState( ctx ); - } - - intel->NewGLState = 0; - } - - _tnl_run_pipeline( ctx ); -} - -static void intelRenderStart( GLcontext *ctx ) -{ - INTEL_CONTEXT(ctx)->vtbl.render_start( INTEL_CONTEXT(ctx) ); -} - -static void intelRenderFinish( GLcontext *ctx ) -{ - if (INTEL_CONTEXT(ctx)->RenderIndex & INTEL_FALLBACK_BIT) - _swrast_flush( ctx ); -} - - - - - /* System to flush dma and emit state changes based on the rasterized - * primitive. - */ -static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - - if (0) - fprintf(stderr, "%s %s %x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(rprim), hwprim); - - intel->vtbl.reduced_primitive_state( intel, rprim ); - - /* Start a new primitive. Arrange to have it flushed later on. - */ - if (hwprim != intel->prim.primitive) - intelStartInlinePrimitive( intel, hwprim ); -} - - -/* - */ -static void intelRenderPrimitive( GLcontext *ctx, GLenum prim ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - - if (0) - fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); - - /* Let some clipping routines know which primitive they're dealing - * with. - */ - intel->render_primitive = prim; - - /* Shortcircuit this when called from t_dd_rendertmp.h for unfilled - * triangles. The rasterized primitive will always be reset by - * lower level functions in that case, potentially pingponging the - * state: - */ - if (reduced_prim[prim] == GL_TRIANGLES && - (ctx->_TriangleCaps & DD_TRI_UNFILLED)) - return; - - /* Set some primitive-dependent state and Start? a new primitive. - */ - intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] ); -} - - -/**********************************************************************/ -/* Transition to/from hardware rasterization. */ -/**********************************************************************/ - -static struct { - GLuint bit; - const char *str; -} fallbackStrings[] = { - { INTEL_FALLBACK_DRAW_BUFFER, "Draw buffer" }, - { INTEL_FALLBACK_READ_BUFFER, "Read buffer" }, - { INTEL_FALLBACK_USER, "User" }, - { INTEL_FALLBACK_NO_BATCHBUFFER, "No Batchbuffer" }, - { INTEL_FALLBACK_NO_TEXMEM, "No Texmem" }, - { INTEL_FALLBACK_RENDERMODE, "Rendermode" }, - - { I830_FALLBACK_TEXTURE, "i830 texture" }, - { I830_FALLBACK_COLORMASK, "i830 colormask" }, - { I830_FALLBACK_STENCIL, "i830 stencil" }, - { I830_FALLBACK_STIPPLE, "i830 stipple" }, - { I830_FALLBACK_LOGICOP, "i830 logicop" }, - - { I915_FALLBACK_TEXTURE, "i915 texture" }, - { I915_FALLBACK_COLORMASK, "i915 colormask" }, - { I915_FALLBACK_STENCIL, "i915 stencil" }, - { I915_FALLBACK_STIPPLE, "i915 stipple" }, - { I915_FALLBACK_PROGRAM, "i915 program" }, - { I915_FALLBACK_LOGICOP, "i915 logicop" }, - { I915_FALLBACK_POLYGON_SMOOTH, "i915 polygon smooth" }, - { I915_FALLBACK_POINT_SMOOTH, "i915 point smooth" }, - - { 0, NULL } -}; - - -static const char * -getFallbackString(GLuint bit) -{ - int i; - for (i = 0; fallbackStrings[i].bit; i++) { - if (fallbackStrings[i].bit == bit) - return fallbackStrings[i].str; - } - return "unknown fallback bit"; -} - - -void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode ) -{ - GLcontext *ctx = &intel->ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldfallback = intel->Fallback; - - if (mode) { - intel->Fallback |= bit; - if (oldfallback == 0) { - intelFlush(ctx); - if (INTEL_DEBUG & DEBUG_FALLBACKS) - fprintf(stderr, "ENTER FALLBACK 0x%x: %s\n", - bit, getFallbackString(bit)); - _swsetup_Wakeup( ctx ); - intel->RenderIndex = ~0; - } - } - else { - intel->Fallback &= ~bit; - if (oldfallback == bit) { - _swrast_flush( ctx ); - if (INTEL_DEBUG & DEBUG_FALLBACKS) - fprintf(stderr, "LEAVE FALLBACK 0x%x: %s\n", - bit, getFallbackString(bit)); - tnl->Driver.Render.Start = intelRenderStart; - tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; - tnl->Driver.Render.Finish = intelRenderFinish; - tnl->Driver.Render.BuildVertices = _tnl_build_vertices; - tnl->Driver.Render.CopyPV = _tnl_copy_pv; - tnl->Driver.Render.Interp = _tnl_interp; - - _tnl_invalidate_vertex_state( ctx, ~0 ); - _tnl_invalidate_vertices( ctx, ~0 ); - _tnl_install_attrs( ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0 ); - - intel->NewGLState |= _INTEL_NEW_RENDERSTATE; - } - } -} - - - - -/**********************************************************************/ -/* Initialization. */ -/**********************************************************************/ - - -void intelInitTriFuncs( GLcontext *ctx ) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - static int firsttime = 1; - - if (firsttime) { - init_rast_tab(); - firsttime = 0; - } - - tnl->Driver.RunPipeline = intelRunPipeline; - tnl->Driver.Render.Start = intelRenderStart; - tnl->Driver.Render.Finish = intelRenderFinish; - tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; - tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; - tnl->Driver.Render.BuildVertices = _tnl_build_vertices; - tnl->Driver.Render.CopyPV = _tnl_copy_pv; - tnl->Driver.Render.Interp = _tnl_interp; -} diff --git a/src/mesa/drivers/dri/i915/intel_tris.h b/src/mesa/drivers/dri/i915/intel_tris.h deleted file mode 100644 index d7e382fdb3..0000000000 --- a/src/mesa/drivers/dri/i915/intel_tris.h +++ /dev/null @@ -1,46 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTELTRIS_INC -#define INTELTRIS_INC - -#include "mtypes.h" - -#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ - _DD_NEW_TRI_UNFILLED | \ - _DD_NEW_TRI_LIGHT_TWOSIDE | \ - _DD_NEW_TRI_OFFSET | \ - _DD_NEW_TRI_STIPPLE | \ - _NEW_PROGRAM | \ - _NEW_POLYGONSTIPPLE) - -extern void intelInitTriFuncs( GLcontext *ctx ); - -extern void intelPrintRenderState( const char *msg, GLuint state ); -extern void intelChooseRenderState( GLcontext *ctx ); - -#endif diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/i915/server/i830_common.h deleted file mode 100644 index 2962ecc68a..0000000000 --- a/src/mesa/drivers/dri/i915/server/i830_common.h +++ /dev/null @@ -1,212 +0,0 @@ -/************************************************************************** - -Copyright 2001 VA Linux Systems Inc., Fremont, California. -Copyright 2002 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 -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 -ATI, VA LINUX SYSTEMS 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. - -**************************************************************************/ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ - -#ifndef _I830_COMMON_H_ -#define _I830_COMMON_H_ - - -#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ -#define I830_LOG_MIN_TEX_REGION_SIZE 14 - - -/* Driver specific DRM command indices - * NOTE: these are not OS specific, but they are driver specific - */ -#define DRM_I830_INIT 0x00 -#define DRM_I830_FLUSH 0x01 -#define DRM_I830_FLIP 0x02 -#define DRM_I830_BATCHBUFFER 0x03 -#define DRM_I830_IRQ_EMIT 0x04 -#define DRM_I830_IRQ_WAIT 0x05 -#define DRM_I830_GETPARAM 0x06 -#define DRM_I830_SETPARAM 0x07 -#define DRM_I830_ALLOC 0x08 -#define DRM_I830_FREE 0x09 -#define DRM_I830_INIT_HEAP 0x0a -#define DRM_I830_CMDBUFFER 0x0b -#define DRM_I830_DESTROY_HEAP 0x0c - -typedef struct { - enum { - I830_INIT_DMA = 0x01, - I830_CLEANUP_DMA = 0x02, - I830_RESUME_DMA = 0x03 - } func; - unsigned int mmio_offset; - int sarea_priv_offset; - unsigned int ring_start; - unsigned int ring_end; - unsigned int ring_size; - unsigned int front_offset; - unsigned int back_offset; - unsigned int depth_offset; - unsigned int w; - unsigned int h; - unsigned int pitch; - unsigned int pitch_bits; - unsigned int back_pitch; - unsigned int depth_pitch; - unsigned int cpp; - unsigned int chipset; -} drmI830Init; - -typedef struct { - drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; - int last_upload; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - int last_dispatch; /* age of the most recently dispatched buffer */ - int ctxOwner; /* last context to upload state */ - int texAge; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - int width, height; /* screen size in pixels */ - - drm_handle_t front_handle; - int front_offset; - int front_size; - - drm_handle_t back_handle; - int back_offset; - int back_size; - - drm_handle_t depth_handle; - int depth_offset; - int depth_size; - - drm_handle_t tex_handle; - int tex_offset; - int tex_size; - int log_tex_granularity; - int pitch; - int rotation; /* 0, 90, 180 or 270 */ - int rotated_offset; - int rotated_size; - int rotated_pitch; - int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; - - int planeA_x; - int planeA_y; - int planeA_w; - int planeA_h; - int planeB_x; - int planeB_y; - int planeB_w; - int planeB_h; -} drmI830Sarea; - -/* Flags for perf_boxes - */ -#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ -#define I830_BOX_FLIP 0x2 /* populated by kernel */ -#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ -#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ -#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ - - -typedef struct { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830BatchBuffer; - -typedef struct { - char *buf; /* agp offset */ - int sz; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830CmdBuffer; - -typedef struct { - int *irq_seq; -} drmI830IrqEmit; - -typedef struct { - int irq_seq; -} drmI830IrqWait; - -typedef struct { - int param; - int *value; -} drmI830GetParam; - -#define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 - -typedef struct { - int param; - int value; -} drmI830SetParam; - -#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 -#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 -#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 - - -/* A memory manager for regions of shared memory: - */ -#define I830_MEM_REGION_AGP 1 - -typedef struct { - int region; - int alignment; - int size; - int *region_offset; /* offset from start of fb or agp */ -} drmI830MemAlloc; - -typedef struct { - int region; - int region_offset; -} drmI830MemFree; - -typedef struct { - int region; - int size; - int start; -} drmI830MemInitHeap; - -typedef struct { - int region; -} drmI830MemDestroyHeap; - - -#endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i915/server/i830_dri.h b/src/mesa/drivers/dri/i915/server/i830_dri.h deleted file mode 100644 index 6c9a709021..0000000000 --- a/src/mesa/drivers/dri/i915/server/i830_dri.h +++ /dev/null @@ -1,73 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ - -#ifndef _I830_DRI_H -#define _I830_DRI_H - -#include "xf86drm.h" -#include "i830_common.h" - -#define I830_MAX_DRAWABLES 256 - -#define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 3 -#define I830_PATCHLEVEL 0 - -#define I830_REG_SIZE 0x80000 - -typedef struct _I830DRIRec { - drm_handle_t regs; - drmSize regsSize; - - drmSize backbufferSize; - drm_handle_t backbuffer; - - drmSize depthbufferSize; - drm_handle_t depthbuffer; - - drmSize rotatedSize; - drm_handle_t rotatedbuffer; - - drm_handle_t textures; - int textureSize; - - drm_handle_t agp_buffers; - drmSize agp_buf_size; - - int deviceID; - int width; - int height; - int mem; - int cpp; - int bitsPerPixel; - - int fbOffset; - int fbStride; - - int backOffset; - int backPitch; - - int depthOffset; - int depthPitch; - - int rotatedOffset; - int rotatedPitch; - - int logTextureGranularity; - int textureOffset; - - int irq; - int sarea_priv_offset; -} I830DRIRec, *I830DRIPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830ConfigPrivRec, *I830ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830DRIContextRec, *I830DRIContextPtr; - - -#endif diff --git a/src/mesa/drivers/dri/i915/server/intel.h b/src/mesa/drivers/dri/i915/server/intel.h deleted file mode 100644 index d7858a20c8..0000000000 --- a/src/mesa/drivers/dri/i915/server/intel.h +++ /dev/null @@ -1,328 +0,0 @@ -#ifndef _INTEL_H_ -#define _INTEL_H_ - -#include "xf86drm.h" /* drm_handle_t, etc */ - -/* Intel */ -#ifndef PCI_CHIP_I810 -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 -#define PCI_CHIP_I810_BRIDGE 0x7120 -#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 -#define PCI_CHIP_I810_E_BRIDGE 0x7124 -#define PCI_CHIP_I815_BRIDGE 0x1130 -#endif - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 - -#ifndef PCI_CHIP_I855_GM -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I855_GM_BRIDGE 0x3580 -#endif - -#ifndef PCI_CHIP_I865_G -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I865_G_BRIDGE 0x2570 -#endif - -#ifndef PCI_CHIP_I915_G -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I915_GM -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I915_GM_BRIDGE 0x2590 -#endif - -#ifndef PCI_CHIP_E7221_G -#define PCI_CHIP_E7221_G 0x258A -/* Same as I915_G_BRIDGE */ -#define PCI_CHIP_E7221_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I945_G -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_G_BRIDGE 0x2770 -#endif - -#ifndef PCI_CHIP_I945_GM -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 -#endif - -#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ - pI810->Chipset == PCI_CHIP_I810_DC100 || \ - pI810->Chipset == PCI_CHIP_I810_E) -#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) -#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) -#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) -#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) -#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) -#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) -#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) - -#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) -#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) -#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) -#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) - -#define I830_GMCH_CTRL 0x52 - - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_DISABLED 0x00 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK (0x7 << 4) -#define I855_GMCH_GMS_DISABLED 0x00 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -typedef unsigned char Bool; -#define TRUE 1 -#define FALSE 0 - -#define PIPE_NONE 0<<0 -#define PIPE_CRT 1<<0 -#define PIPE_TV 1<<1 -#define PIPE_DFP 1<<2 -#define PIPE_LFP 1<<3 -#define PIPE_CRT2 1<<4 -#define PIPE_TV2 1<<5 -#define PIPE_DFP2 1<<6 -#define PIPE_LFP2 1<<7 - -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - drm_handle_t Key; - unsigned long Pitch; // add pitch - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; - -typedef struct { - int tail_mask; - I830MemRange mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -typedef struct _I830Rec { - unsigned char *MMIOBase; - unsigned char *FbBase; - int cpp; - - unsigned int bios_version; - - /* These are set in PreInit and never changed. */ - long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - long BIOSMemorySize; /* min stolen pool size */ - int BIOSMemSizeLoc; - - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; - - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; - - I830RingBuffer *LpRing; - - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; - int TexGranularity; - I830MemRange ContextMem; - int drmMinor; - Bool have3DWindows; - - Bool NeedRingBufferLow; - Bool allowPageFlip; - Bool disableTiling; - - int Chipset; - unsigned long LinearAddr; - unsigned long MMIOAddr; - - drmSize registerSize; /**< \brief MMIO register map size */ - drm_handle_t registerHandle; /**< \brief MMIO register map handle */ - // IOADDRESS ioBase; - int irq; /**< \brief IRQ number */ - int GttBound; - - drm_handle_t ring_map; - unsigned int Fence[8]; - -} I830Rec; - -/* - * 12288 is set as the maximum, chosen because it is enough for - * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. - */ -#define I830_MAXIMUM_VBIOS_MEM 12288 -#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) -#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) - -/* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -#define KB(x) ((x) * 1024) -#define MB(x) ((x) * KB(1024)) - -#define GTT_PAGE_SIZE KB(4) -#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) -#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) -#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) -#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(128) - - -/* Ring buffer registers, p277, overview p19 - */ -#define LP_RING 0x2030 -#define HP_RING 0x2040 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define I830_TAIL_MASK 0x001FFFF8 - -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define I830_HEAD_MASK 0x001FFFFC - -#define RING_START 0x08 -#define START_ADDR 0x03FFFFF8 -#define I830_RING_START_MASK 0xFFFFF000 - -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define I830_RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - - -/* Fence/Tiling ranges [0..7] - */ -#define FENCE 0x2000 -#define FENCE_NR 8 - -#define I915G_FENCE_START_MASK 0x0ff00000 - -#define I830_FENCE_START_MASK 0x07f80000 - -#define FENCE_START_MASK 0x03F80000 -#define FENCE_X_MAJOR 0x00000000 -#define FENCE_Y_MAJOR 0x00001000 -#define FENCE_SIZE_MASK 0x00000700 -#define FENCE_SIZE_512K 0x00000000 -#define FENCE_SIZE_1M 0x00000100 -#define FENCE_SIZE_2M 0x00000200 -#define FENCE_SIZE_4M 0x00000300 -#define FENCE_SIZE_8M 0x00000400 -#define FENCE_SIZE_16M 0x00000500 -#define FENCE_SIZE_32M 0x00000600 -#define FENCE_SIZE_64M 0x00000700 -#define I915G_FENCE_SIZE_1M 0x00000000 -#define I915G_FENCE_SIZE_2M 0x00000100 -#define I915G_FENCE_SIZE_4M 0x00000200 -#define I915G_FENCE_SIZE_8M 0x00000300 -#define I915G_FENCE_SIZE_16M 0x00000400 -#define I915G_FENCE_SIZE_32M 0x00000500 -#define I915G_FENCE_SIZE_64M 0x00000600 -#define I915G_FENCE_SIZE_128M 0x00000700 -#define FENCE_PITCH_1 0x00000000 -#define FENCE_PITCH_2 0x00000010 -#define FENCE_PITCH_4 0x00000020 -#define FENCE_PITCH_8 0x00000030 -#define FENCE_PITCH_16 0x00000040 -#define FENCE_PITCH_32 0x00000050 -#define FENCE_PITCH_64 0x00000060 -#define FENCE_VALID 0x00000001 - -#include - -# define MMIO_IN8(base, offset) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - read_MMIO_LE32(base, offset) -# define MMIO_OUT8(base, offset, val) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) - - - /* Memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(MMIO, addr) -#define INREG(addr) MMIO_IN32(MMIO, addr) -#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) -#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) - -#define DSPABASE 0x70184 - -#endif diff --git a/src/mesa/drivers/dri/i915/server/intel_dri.c b/src/mesa/drivers/dri/i915/server/intel_dri.c deleted file mode 100644 index b6946b75d2..0000000000 --- a/src/mesa/drivers/dri/i915/server/intel_dri.c +++ /dev/null @@ -1,1283 +0,0 @@ -/** - * \file server/intel_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) - - 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 THE COPYRIGHT HOLDERS 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. -*/ - -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "intel.h" -#include "i830_dri.h" - -#include "memops.h" -#include "pciaccess.h" - -static size_t drm_page_size; -static int nextTile = 0; -#define xf86DrvMsg(...) do {} while(0) - -static const int pitches[] = { - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 -}; - -static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); - -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - -static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - unsigned char *MMIO = ctx->MMIOAddress; - - for (i = 0; i < 8; i++) { - OUTREG(FENCE + i * 4, pI830->Fence[i]); - // if (I810_DEBUG & DEBUG_VERBOSE_VGA) - fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); - } -} - -/* Tiled memory is good... really, really good... - * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. - */ -static void -SetFence(const DRIDriverContext *ctx, I830Rec *pI830, - int nr, unsigned int start, unsigned int pitch, - unsigned int size) -{ - unsigned int val; - unsigned int fence_mask = 0; - unsigned int fence_pitch; - - if (nr < 0 || nr > 7) { - fprintf(stderr, - "SetFence: fence %d out of range\n",nr); - return; - } - - pI830->Fence[nr] = 0; - - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (start & fence_mask) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - fprintf(stderr, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } - - if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - pI830->Fence[nr] = val; -} - -static Bool -MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) -{ - int pitch, ntiles, i; - - pitch = pMem->Pitch * ctx->cpp; - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - - /* Clear out */ - for (i = 0; i < 8; i++) - pI830->Fence[i] = 0; - - nextTile = 0; - - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { - fprintf(stderr, - "Activating tiled memory for the back buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { - fprintf(stderr, - "Activating tiled memory for the depth buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the depth buffer.\n"); - } - } - - return; -} - -static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - struct pci_device host_bridge; - uint32_t gmch_ctrl; - int memsize = 0; - int range; - - memset(&host_bridge, 0, sizeof(host_bridge)); - - pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB */ - range = (ctx->shared.fbSize / (1024*1024)) + 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - if (memsize > 0) { - fprintf(stderr, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - fprintf(stderr, - "no video memory detected.\n"); - } - return memsize; -} - -static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) -{ - unsigned long mode = 0x4; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - return 1; -} - -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) -{ - long needed, start, end; - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - start = ROUND_TO(pool->Free.Start, alignment); - end = ROUND_TO(start + size, alignment); - needed = end - pool->Free.Start; - } - if (needed > pool->Free.Size) { - return 0; - } - - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; -} - -static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) -{ - unsigned long start, end; - unsigned long newApStart, newApEnd; - int ret; - if (!result || !size) - return 0; - - if (!alignment) - alignment = 4; - - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - end = ROUND_TO(start + size, alignment); - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - - ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); - - if (ret) - { - fprintf(stderr,"drmAgpAlloc failed %d\n", ret); - return 0; - } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - // pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; -} - -unsigned long -I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, long size, - unsigned long alignment, int flags) -{ - unsigned long ret; - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - if (pool->Free.Size < size) { - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - else { - ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); - if (ret == 0) - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - return ret; -} - -static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); -} - -/* simple memory allocation routines needed */ -/* put ring buffer in low memory */ -/* need to allocate front, back, depth buffers aligned correctly, - allocate ring buffer, -*/ - -/* */ -static Bool -I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long size, ret; - unsigned long lines, lineSize, align; - - /* allocate ring buffer */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - size = PRIMARY_RINGBUFFER_SIZE; - - ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); - - if (ret != size) - { - fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); - return FALSE; - } - - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - - - /* allocate front buffer */ - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; - - align = KB(512); - - lineSize = ctx->shared.virtualWidth * ctx->cpp; - lines = (ctx->shared.virtualHeight + 15) / 16 * 16; - size = lineSize * lines; - size = ROUND_TO_PAGE(size); - - align = GetBestTileAlignment(size); - - ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate front buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate back buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - - ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate context buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - size = 32768 * 1024; - ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); - if (ret < size) - { - fprintf(stderr,"unable to allocate texture memory %ld\n", ret); - return FALSE; - } - - return TRUE; -} - -static Bool -I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - if (!BindAgpRange(ctx, &pI830->LpRing->mem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->FrontBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->BackBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->DepthBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->ContextMem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->TexMem)) - return FALSE; - - return TRUE; -} - -static Bool -I830CleanupDma(const DRIDriverContext *ctx) -{ - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_CLEANUP_DMA; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, "I830 Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) -{ - I830RingBuffer *ring = pI830->LpRing; - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_INIT_DMA; - - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; - - info.mmio_offset = (unsigned int)ctx->MMIOStart; - - info.sarea_priv_offset = sizeof(drm_sarea_t); - - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; - info.w = ctx->shared.virtualWidth; - info.h = ctx->shared.virtualHeight; - info.pitch = ctx->shared.virtualWidth; - info.back_pitch = pI830->BackBuffer.Pitch; - info.depth_pitch = pI830->DepthBuffer.Pitch; - info.cpp = ctx->cpp; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, - "I830 Dma Initialization Failed\n"); - return FALSE; - } - - return TRUE; -} - -static int I830CheckDRMVersion( const DRIDriverContext *ctx, - I830Rec *pI830 ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I830DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i915.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - pI830->drmMinor = version->version_minor; - drmFreeVersion(version); - } - return 1; -} - -static void -I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned int itemp; - unsigned char *MMIO = ctx->MMIOAddress; - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - - pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); - pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); - if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; - - SetFenceRegs(ctx, pI830); - - /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky - hacky hacky */ - OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); - -} - -static Bool -I830SetParam(const DRIDriverContext *ctx, int param, int value) -{ - drmI830SetParam sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { - fprintf(stderr, "I830 SetParam Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - fprintf(stderr, - "[drm] Mapping front buffer\n"); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_FRAME_BUFFER, /*DRM_AGP,*/ - 0, - &sarea->front_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - return FALSE; - } - ctx->shared.hFrameBuffer = sarea->front_handle; - ctx->shared.fbSize = sarea->front_size; - fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", - sarea->front_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->back_offset), - sarea->back_size, DRM_AGP, 0, - &sarea->back_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", - sarea->back_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->depth_offset, - sarea->depth_size, DRM_AGP, 0, - &sarea->depth_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", - sarea->depth_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->tex_offset, - sarea->tex_size, DRM_AGP, 0, - &sarea->tex_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] textures = 0x%08x\n", - sarea->tex_handle); - - return TRUE; -} - - -static void -I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ -#if 1 - if (sarea->front_handle) { - drmRmMap(ctx->drmFD, sarea->front_handle); - sarea->front_handle = 0; - } -#endif - if (sarea->back_handle) { - drmRmMap(ctx->drmFD, sarea->back_handle); - sarea->back_handle = 0; - } - if (sarea->depth_handle) { - drmRmMap(ctx->drmFD, sarea->depth_handle); - sarea->depth_handle = 0; - } - if (sarea->tex_handle) { - drmRmMap(ctx->drmFD, sarea->tex_handle); - sarea->tex_handle = 0; - } -} - -static void -I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* Start up the simple memory manager for agp space */ - drmI830MemInitHeap drmHeap; - drmHeap.region = I830_MEM_REGION_AGP; - drmHeap.start = 0; - drmHeap.size = sarea->tex_size; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT_HEAP, - &drmHeap, sizeof(drmHeap))) { - fprintf(stderr, - "[drm] Failed to initialized agp heap manager\n"); - } else { - fprintf(stderr, - "[drm] Initialized kernel agp heap manager, %d\n", - sarea->tex_size); - - I830SetParam(ctx, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY, - sarea->log_tex_granularity); - } -} - -static Bool -I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)pI830->LpRing->mem.Start, - pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { - fprintf(stderr, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); - - if (I830InitDma(ctx, pI830) == FALSE) { - return FALSE; - } - - /* init to zero to be safe */ - - I830DRIMapScreenRegions(ctx, pI830, sarea); - I830InitTextureHeap(ctx, pI830, sarea); - - if (ctx->pciDevice != PCI_CHIP_845_G && - ctx->pciDevice != PCI_CHIP_I830_M) { - I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); - } - - /* Okay now initialize the dma engine */ - { - pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { - fprintf(stderr, - "[drm] failure adding irq handler\n"); - pI830->irq = 0; - return FALSE; - } - else - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pI830->irq); - } - - fprintf(stderr, "[dri] visual configs initialized\n"); - - return TRUE; -} - -static Bool -I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* need to drmMap front and back buffers and zero them */ - drmAddress map_addr; - int ret; - - ret = drmMap(ctx->drmFD, - sarea->front_handle, - sarea->front_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map front buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->front_size); - drmUnmap(map_addr, sarea->front_size); - - - ret = drmMap(ctx->drmFD, - sarea->back_handle, - sarea->back_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map back buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->back_size); - drmUnmap(map_addr, sarea->back_size); - - return TRUE; -} - -static Bool -I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) - -{ - I830DRIPtr pI830DRI; - drmI830Sarea *pSAREAPriv; - int err; - - drm_page_size = getpagesize(); - - pI830->registerSize = ctx->MMIOSize; - /* This is a hack for now. We have to have more than a 4k page here - * because of the size of the state. However, the state should be - * in a per-context mapping. This will be added in the Mesa 3.5 port - * of the I830 driver. - */ - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i915", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - - } - - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pI830->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", pI830->registerHandle); - - - if (!I830CheckDRMVersion(ctx, pI830)) { - return FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the SAREA private data structure */ - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = KB(40000); - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->StolenPool.Total.Size; - - if (!AgpInit(ctx, pI830)) - return FALSE; - - if (I830AllocateMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - if (I830BindMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - pSAREAPriv->front_offset = pI830->FrontBuffer.Start; - pSAREAPriv->front_size = pI830->FrontBuffer.Size; - pSAREAPriv->width = ctx->shared.virtualWidth; - pSAREAPriv->height = ctx->shared.virtualHeight; - pSAREAPriv->pitch = ctx->shared.virtualWidth; - pSAREAPriv->virtualX = ctx->shared.virtualWidth; - pSAREAPriv->virtualY = ctx->shared.virtualHeight; - pSAREAPriv->back_offset = pI830->BackBuffer.Start; - pSAREAPriv->back_size = pI830->BackBuffer.Size; - pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; - pSAREAPriv->depth_size = pI830->DepthBuffer.Size; - pSAREAPriv->tex_offset = pI830->TexMem.Start; - pSAREAPriv->tex_size = pI830->TexMem.Size; - pSAREAPriv->log_tex_granularity = pI830->TexGranularity; - - ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); - ctx->driverClientMsgSize = sizeof(I830DRIRec); - pI830DRI = (I830DRIPtr)ctx->driverClientMsg; - pI830DRI->deviceID = pI830->Chipset; - pI830DRI->regsSize = I830_REG_SIZE; - pI830DRI->width = ctx->shared.virtualWidth; - pI830DRI->height = ctx->shared.virtualHeight; - pI830DRI->mem = ctx->shared.fbSize; - pI830DRI->cpp = ctx->cpp; - pI830DRI->backOffset = pI830->BackBuffer.Start; - pI830DRI->backPitch = pI830->BackBuffer.Pitch; - - pI830DRI->depthOffset = pI830->DepthBuffer.Start; - pI830DRI->depthPitch = pI830->DepthBuffer.Pitch; - - pI830DRI->fbOffset = pI830->FrontBuffer.Start; - pI830DRI->fbStride = pI830->FrontBuffer.Pitch; - - pI830DRI->bitsPerPixel = ctx->bpp; - pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); - if (err == FALSE) - return FALSE; - - I830SetupMemoryTiling(ctx, pI830); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - I830ClearScreen(ctx, pI830, pSAREAPriv); - - I830SetRingRegs(ctx, pI830); - - return TRUE; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int i830ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i830PostValidateMode( const DRIDriverContext *ctx ) -{ - I830Rec *pI830 = ctx->driverPrivate; - - I830SetRingRegs(ctx, pI830); - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i830InitFBDev( DRIDriverContext *ctx ) -{ - I830Rec *pI830 = calloc(1, sizeof(I830Rec)); - int i; - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = ctx->shared.virtualWidth; - } - - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= ctx->shared.virtualWidth) { - ctx->shared.virtualWidth = pitches[i]; - break; - } - } - - ctx->driverPrivate = (void *)pI830; - - pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); - pI830->Chipset = ctx->chipset; - pI830->LinearAddr = ctx->FBStart; - - if (!I830ScreenInit( ctx, pI830 )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i830HaltFBDev( DRIDriverContext *ctx ) -{ - drmI830Sarea *pSAREAPriv; - I830Rec *pI830 = ctx->driverPrivate; - - if (pI830->irq) { - drmCtlUninstHandler(ctx->drmFD); - pI830->irq = 0; } - - I830CleanupDma(ctx); - - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - - I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i830ValidateMode, - i830PostValidateMode, - i830InitFBDev, - i830HaltFBDev, - NULL,//I830EngineShutdown, - NULL, //I830EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; -- cgit v1.2.3 From 8cf9085bc7b96819d2bec1e749e15af58eefb2f3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Sep 2007 10:03:25 -0700 Subject: Move i915tex driver into place as just i915. --- configs/freebsd-dri | 2 +- configs/linux-dri | 2 +- src/mesa/drivers/dri/i915/Makefile | 71 ++ src/mesa/drivers/dri/i915/i830_context.c | 104 ++ src/mesa/drivers/dri/i915/i830_context.h | 213 ++++ src/mesa/drivers/dri/i915/i830_metaops.c | 457 +++++++ src/mesa/drivers/dri/i915/i830_reg.h | 642 ++++++++++ src/mesa/drivers/dri/i915/i830_state.c | 1116 +++++++++++++++++ src/mesa/drivers/dri/i915/i830_tex.c | 100 ++ src/mesa/drivers/dri/i915/i830_texblend.c | 463 +++++++ src/mesa/drivers/dri/i915/i830_texstate.c | 343 +++++ src/mesa/drivers/dri/i915/i830_vtbl.c | 674 ++++++++++ src/mesa/drivers/dri/i915/i915_context.c | 174 +++ src/mesa/drivers/dri/i915/i915_context.h | 360 ++++++ src/mesa/drivers/dri/i915/i915_debug.c | 843 +++++++++++++ src/mesa/drivers/dri/i915/i915_debug.h | 55 + src/mesa/drivers/dri/i915/i915_debug_fp.c | 333 +++++ src/mesa/drivers/dri/i915/i915_fragprog.c | 1074 ++++++++++++++++ src/mesa/drivers/dri/i915/i915_metaops.c | 509 ++++++++ src/mesa/drivers/dri/i915/i915_program.c | 515 ++++++++ src/mesa/drivers/dri/i915/i915_program.h | 160 +++ src/mesa/drivers/dri/i915/i915_reg.h | 866 +++++++++++++ src/mesa/drivers/dri/i915/i915_state.c | 1014 +++++++++++++++ src/mesa/drivers/dri/i915/i915_tex.c | 78 ++ src/mesa/drivers/dri/i915/i915_tex_layout.c | 343 +++++ src/mesa/drivers/dri/i915/i915_texstate.c | 359 ++++++ src/mesa/drivers/dri/i915/i915_vtbl.c | 571 +++++++++ src/mesa/drivers/dri/i915/intel_batchbuffer.c | 331 +++++ src/mesa/drivers/dri/i915/intel_batchbuffer.h | 122 ++ src/mesa/drivers/dri/i915/intel_blit.c | 493 ++++++++ src/mesa/drivers/dri/i915/intel_blit.h | 62 + src/mesa/drivers/dri/i915/intel_buffer_objects.c | 268 ++++ src/mesa/drivers/dri/i915/intel_buffer_objects.h | 86 ++ src/mesa/drivers/dri/i915/intel_buffers.c | 1193 ++++++++++++++++++ src/mesa/drivers/dri/i915/intel_buffers.h | 59 + src/mesa/drivers/dri/i915/intel_context.c | 797 ++++++++++++ src/mesa/drivers/dri/i915/intel_context.h | 498 ++++++++ src/mesa/drivers/dri/i915/intel_decode.c | 832 +++++++++++++ src/mesa/drivers/dri/i915/intel_decode.h | 29 + src/mesa/drivers/dri/i915/intel_depthstencil.c | 282 +++++ src/mesa/drivers/dri/i915/intel_depthstencil.h | 14 + src/mesa/drivers/dri/i915/intel_fbo.c | 687 ++++++++++ src/mesa/drivers/dri/i915/intel_fbo.h | 115 ++ src/mesa/drivers/dri/i915/intel_ioctl.c | 135 ++ src/mesa/drivers/dri/i915/intel_ioctl.h | 40 + src/mesa/drivers/dri/i915/intel_mipmap_tree.c | 371 ++++++ src/mesa/drivers/dri/i915/intel_mipmap_tree.h | 198 +++ src/mesa/drivers/dri/i915/intel_pixel.c | 120 ++ src/mesa/drivers/dri/i915/intel_pixel.h | 63 + src/mesa/drivers/dri/i915/intel_pixel_bitmap.c | 350 ++++++ src/mesa/drivers/dri/i915/intel_pixel_copy.c | 383 ++++++ src/mesa/drivers/dri/i915/intel_pixel_draw.c | 388 ++++++ src/mesa/drivers/dri/i915/intel_pixel_read.c | 319 +++++ src/mesa/drivers/dri/i915/intel_reg.h | 88 ++ src/mesa/drivers/dri/i915/intel_regions.c | 482 ++++++++ src/mesa/drivers/dri/i915/intel_regions.h | 143 +++ src/mesa/drivers/dri/i915/intel_render.c | 244 ++++ src/mesa/drivers/dri/i915/intel_rotate.c | 237 ++++ src/mesa/drivers/dri/i915/intel_rotate.h | 39 + src/mesa/drivers/dri/i915/intel_screen.c | 955 ++++++++++++++ src/mesa/drivers/dri/i915/intel_screen.h | 134 ++ src/mesa/drivers/dri/i915/intel_span.c | 409 ++++++ src/mesa/drivers/dri/i915/intel_span.h | 38 + src/mesa/drivers/dri/i915/intel_state.c | 269 ++++ src/mesa/drivers/dri/i915/intel_structs.h | 132 ++ src/mesa/drivers/dri/i915/intel_tex.c | 192 +++ src/mesa/drivers/dri/i915/intel_tex.h | 151 +++ src/mesa/drivers/dri/i915/intel_tex_copy.c | 302 +++++ src/mesa/drivers/dri/i915/intel_tex_format.c | 172 +++ src/mesa/drivers/dri/i915/intel_tex_image.c | 690 +++++++++++ src/mesa/drivers/dri/i915/intel_tex_layout.c | 1 + src/mesa/drivers/dri/i915/intel_tex_subimage.c | 182 +++ src/mesa/drivers/dri/i915/intel_tex_validate.c | 272 ++++ src/mesa/drivers/dri/i915/intel_tris.c | 1152 +++++++++++++++++ src/mesa/drivers/dri/i915/intel_tris.h | 69 ++ src/mesa/drivers/dri/i915/server/i830_common.h | 236 ++++ src/mesa/drivers/dri/i915/server/i830_dri.h | 63 + src/mesa/drivers/dri/i915/server/intel.h | 331 +++++ src/mesa/drivers/dri/i915/server/intel_dri.c | 1306 ++++++++++++++++++++ src/mesa/drivers/dri/i915tex/Makefile | 71 -- src/mesa/drivers/dri/i915tex/i830_context.c | 104 -- src/mesa/drivers/dri/i915tex/i830_context.h | 213 ---- src/mesa/drivers/dri/i915tex/i830_metaops.c | 457 ------- src/mesa/drivers/dri/i915tex/i830_reg.h | 642 ---------- src/mesa/drivers/dri/i915tex/i830_state.c | 1116 ----------------- src/mesa/drivers/dri/i915tex/i830_tex.c | 100 -- src/mesa/drivers/dri/i915tex/i830_texblend.c | 463 ------- src/mesa/drivers/dri/i915tex/i830_texstate.c | 343 ----- src/mesa/drivers/dri/i915tex/i830_vtbl.c | 674 ---------- src/mesa/drivers/dri/i915tex/i915_context.c | 174 --- src/mesa/drivers/dri/i915tex/i915_context.h | 360 ------ src/mesa/drivers/dri/i915tex/i915_debug.c | 843 ------------- src/mesa/drivers/dri/i915tex/i915_debug.h | 55 - src/mesa/drivers/dri/i915tex/i915_debug_fp.c | 333 ----- src/mesa/drivers/dri/i915tex/i915_fragprog.c | 1074 ---------------- src/mesa/drivers/dri/i915tex/i915_metaops.c | 509 -------- src/mesa/drivers/dri/i915tex/i915_program.c | 515 -------- src/mesa/drivers/dri/i915tex/i915_program.h | 160 --- src/mesa/drivers/dri/i915tex/i915_reg.h | 866 ------------- src/mesa/drivers/dri/i915tex/i915_state.c | 1014 --------------- src/mesa/drivers/dri/i915tex/i915_tex.c | 78 -- src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 343 ----- src/mesa/drivers/dri/i915tex/i915_texstate.c | 359 ------ src/mesa/drivers/dri/i915tex/i915_vtbl.c | 571 --------- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 331 ----- src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 122 -- src/mesa/drivers/dri/i915tex/intel_blit.c | 493 -------- src/mesa/drivers/dri/i915tex/intel_blit.h | 62 - .../drivers/dri/i915tex/intel_buffer_objects.c | 268 ---- .../drivers/dri/i915tex/intel_buffer_objects.h | 86 -- src/mesa/drivers/dri/i915tex/intel_buffers.c | 1193 ------------------ src/mesa/drivers/dri/i915tex/intel_buffers.h | 59 - src/mesa/drivers/dri/i915tex/intel_context.c | 797 ------------ src/mesa/drivers/dri/i915tex/intel_context.h | 498 -------- src/mesa/drivers/dri/i915tex/intel_decode.c | 832 ------------- src/mesa/drivers/dri/i915tex/intel_decode.h | 29 - src/mesa/drivers/dri/i915tex/intel_depthstencil.c | 282 ----- src/mesa/drivers/dri/i915tex/intel_depthstencil.h | 14 - src/mesa/drivers/dri/i915tex/intel_fbo.c | 687 ---------- src/mesa/drivers/dri/i915tex/intel_fbo.h | 115 -- src/mesa/drivers/dri/i915tex/intel_ioctl.c | 135 -- src/mesa/drivers/dri/i915tex/intel_ioctl.h | 40 - src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 371 ------ src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h | 198 --- src/mesa/drivers/dri/i915tex/intel_pixel.c | 120 -- src/mesa/drivers/dri/i915tex/intel_pixel.h | 63 - src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c | 350 ------ src/mesa/drivers/dri/i915tex/intel_pixel_copy.c | 383 ------ src/mesa/drivers/dri/i915tex/intel_pixel_draw.c | 388 ------ src/mesa/drivers/dri/i915tex/intel_pixel_read.c | 319 ----- src/mesa/drivers/dri/i915tex/intel_reg.h | 88 -- src/mesa/drivers/dri/i915tex/intel_regions.c | 482 -------- src/mesa/drivers/dri/i915tex/intel_regions.h | 143 --- src/mesa/drivers/dri/i915tex/intel_render.c | 244 ---- src/mesa/drivers/dri/i915tex/intel_rotate.c | 237 ---- src/mesa/drivers/dri/i915tex/intel_rotate.h | 39 - src/mesa/drivers/dri/i915tex/intel_screen.c | 955 -------------- src/mesa/drivers/dri/i915tex/intel_screen.h | 134 -- src/mesa/drivers/dri/i915tex/intel_span.c | 409 ------ src/mesa/drivers/dri/i915tex/intel_span.h | 38 - src/mesa/drivers/dri/i915tex/intel_state.c | 269 ---- src/mesa/drivers/dri/i915tex/intel_structs.h | 132 -- src/mesa/drivers/dri/i915tex/intel_tex.c | 192 --- src/mesa/drivers/dri/i915tex/intel_tex.h | 151 --- src/mesa/drivers/dri/i915tex/intel_tex_copy.c | 302 ----- src/mesa/drivers/dri/i915tex/intel_tex_format.c | 172 --- src/mesa/drivers/dri/i915tex/intel_tex_image.c | 690 ----------- src/mesa/drivers/dri/i915tex/intel_tex_layout.c | 1 - src/mesa/drivers/dri/i915tex/intel_tex_subimage.c | 182 --- src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 272 ---- src/mesa/drivers/dri/i915tex/intel_tris.c | 1152 ----------------- src/mesa/drivers/dri/i915tex/intel_tris.h | 69 -- src/mesa/drivers/dri/i915tex/server/i830_common.h | 236 ---- src/mesa/drivers/dri/i915tex/server/i830_dri.h | 63 - src/mesa/drivers/dri/i915tex/server/intel.h | 331 ----- src/mesa/drivers/dri/i915tex/server/intel_dri.c | 1306 -------------------- 156 files changed, 27963 insertions(+), 27963 deletions(-) create mode 100644 src/mesa/drivers/dri/i915/Makefile create mode 100644 src/mesa/drivers/dri/i915/i830_context.c create mode 100644 src/mesa/drivers/dri/i915/i830_context.h create mode 100644 src/mesa/drivers/dri/i915/i830_metaops.c create mode 100644 src/mesa/drivers/dri/i915/i830_reg.h create mode 100644 src/mesa/drivers/dri/i915/i830_state.c create mode 100644 src/mesa/drivers/dri/i915/i830_tex.c create mode 100644 src/mesa/drivers/dri/i915/i830_texblend.c create mode 100644 src/mesa/drivers/dri/i915/i830_texstate.c create mode 100644 src/mesa/drivers/dri/i915/i830_vtbl.c create mode 100644 src/mesa/drivers/dri/i915/i915_context.c create mode 100644 src/mesa/drivers/dri/i915/i915_context.h create mode 100644 src/mesa/drivers/dri/i915/i915_debug.c create mode 100644 src/mesa/drivers/dri/i915/i915_debug.h create mode 100644 src/mesa/drivers/dri/i915/i915_debug_fp.c create mode 100644 src/mesa/drivers/dri/i915/i915_fragprog.c create mode 100644 src/mesa/drivers/dri/i915/i915_metaops.c create mode 100644 src/mesa/drivers/dri/i915/i915_program.c create mode 100644 src/mesa/drivers/dri/i915/i915_program.h create mode 100644 src/mesa/drivers/dri/i915/i915_reg.h create mode 100644 src/mesa/drivers/dri/i915/i915_state.c create mode 100644 src/mesa/drivers/dri/i915/i915_tex.c create mode 100644 src/mesa/drivers/dri/i915/i915_tex_layout.c create mode 100644 src/mesa/drivers/dri/i915/i915_texstate.c create mode 100644 src/mesa/drivers/dri/i915/i915_vtbl.c create mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.c create mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.h create mode 100644 src/mesa/drivers/dri/i915/intel_blit.c create mode 100644 src/mesa/drivers/dri/i915/intel_blit.h create mode 100644 src/mesa/drivers/dri/i915/intel_buffer_objects.c create mode 100644 src/mesa/drivers/dri/i915/intel_buffer_objects.h create mode 100644 src/mesa/drivers/dri/i915/intel_buffers.c create mode 100644 src/mesa/drivers/dri/i915/intel_buffers.h create mode 100644 src/mesa/drivers/dri/i915/intel_context.c create mode 100644 src/mesa/drivers/dri/i915/intel_context.h create mode 100644 src/mesa/drivers/dri/i915/intel_decode.c create mode 100644 src/mesa/drivers/dri/i915/intel_decode.h create mode 100644 src/mesa/drivers/dri/i915/intel_depthstencil.c create mode 100644 src/mesa/drivers/dri/i915/intel_depthstencil.h create mode 100644 src/mesa/drivers/dri/i915/intel_fbo.c create mode 100644 src/mesa/drivers/dri/i915/intel_fbo.h create mode 100644 src/mesa/drivers/dri/i915/intel_ioctl.c create mode 100644 src/mesa/drivers/dri/i915/intel_ioctl.h create mode 100644 src/mesa/drivers/dri/i915/intel_mipmap_tree.c create mode 100644 src/mesa/drivers/dri/i915/intel_mipmap_tree.h create mode 100644 src/mesa/drivers/dri/i915/intel_pixel.c create mode 100644 src/mesa/drivers/dri/i915/intel_pixel.h create mode 100644 src/mesa/drivers/dri/i915/intel_pixel_bitmap.c create mode 100644 src/mesa/drivers/dri/i915/intel_pixel_copy.c create mode 100644 src/mesa/drivers/dri/i915/intel_pixel_draw.c create mode 100644 src/mesa/drivers/dri/i915/intel_pixel_read.c create mode 100644 src/mesa/drivers/dri/i915/intel_reg.h create mode 100644 src/mesa/drivers/dri/i915/intel_regions.c create mode 100644 src/mesa/drivers/dri/i915/intel_regions.h create mode 100644 src/mesa/drivers/dri/i915/intel_render.c create mode 100644 src/mesa/drivers/dri/i915/intel_rotate.c create mode 100644 src/mesa/drivers/dri/i915/intel_rotate.h create mode 100644 src/mesa/drivers/dri/i915/intel_screen.c create mode 100644 src/mesa/drivers/dri/i915/intel_screen.h create mode 100644 src/mesa/drivers/dri/i915/intel_span.c create mode 100644 src/mesa/drivers/dri/i915/intel_span.h create mode 100644 src/mesa/drivers/dri/i915/intel_state.c create mode 100644 src/mesa/drivers/dri/i915/intel_structs.h create mode 100644 src/mesa/drivers/dri/i915/intel_tex.c create mode 100644 src/mesa/drivers/dri/i915/intel_tex.h create mode 100644 src/mesa/drivers/dri/i915/intel_tex_copy.c create mode 100644 src/mesa/drivers/dri/i915/intel_tex_format.c create mode 100644 src/mesa/drivers/dri/i915/intel_tex_image.c create mode 120000 src/mesa/drivers/dri/i915/intel_tex_layout.c create mode 100644 src/mesa/drivers/dri/i915/intel_tex_subimage.c create mode 100644 src/mesa/drivers/dri/i915/intel_tex_validate.c create mode 100644 src/mesa/drivers/dri/i915/intel_tris.c create mode 100644 src/mesa/drivers/dri/i915/intel_tris.h create mode 100644 src/mesa/drivers/dri/i915/server/i830_common.h create mode 100644 src/mesa/drivers/dri/i915/server/i830_dri.h create mode 100644 src/mesa/drivers/dri/i915/server/intel.h create mode 100644 src/mesa/drivers/dri/i915/server/intel_dri.c delete mode 100644 src/mesa/drivers/dri/i915tex/Makefile delete mode 100644 src/mesa/drivers/dri/i915tex/i830_context.c delete mode 100644 src/mesa/drivers/dri/i915tex/i830_context.h delete mode 100644 src/mesa/drivers/dri/i915tex/i830_metaops.c delete mode 100644 src/mesa/drivers/dri/i915tex/i830_reg.h delete mode 100644 src/mesa/drivers/dri/i915tex/i830_state.c delete mode 100644 src/mesa/drivers/dri/i915tex/i830_tex.c delete mode 100644 src/mesa/drivers/dri/i915tex/i830_texblend.c delete mode 100644 src/mesa/drivers/dri/i915tex/i830_texstate.c delete mode 100644 src/mesa/drivers/dri/i915tex/i830_vtbl.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_context.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_context.h delete mode 100644 src/mesa/drivers/dri/i915tex/i915_debug.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_debug.h delete mode 100644 src/mesa/drivers/dri/i915tex/i915_debug_fp.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_fragprog.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_metaops.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_program.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_program.h delete mode 100644 src/mesa/drivers/dri/i915tex/i915_reg.h delete mode 100644 src/mesa/drivers/dri/i915tex/i915_state.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_tex.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_tex_layout.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_texstate.c delete mode 100644 src/mesa/drivers/dri/i915tex/i915_vtbl.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_batchbuffer.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_batchbuffer.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_blit.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_blit.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_buffer_objects.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_buffer_objects.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_buffers.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_buffers.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_context.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_context.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_decode.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_decode.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_depthstencil.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_depthstencil.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_fbo.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_fbo.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_ioctl.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_ioctl.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_copy.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_draw.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_read.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_reg.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_regions.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_regions.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_render.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_rotate.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_rotate.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_screen.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_screen.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_span.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_span.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_state.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_structs.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tex.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tex.h delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_copy.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_format.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_image.c delete mode 120000 src/mesa/drivers/dri/i915tex/intel_tex_layout.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_subimage.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_validate.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tris.c delete mode 100644 src/mesa/drivers/dri/i915tex/intel_tris.h delete mode 100644 src/mesa/drivers/dri/i915tex/server/i830_common.h delete mode 100644 src/mesa/drivers/dri/i915tex/server/i830_dri.h delete mode 100644 src/mesa/drivers/dri/i915tex/server/intel.h delete mode 100644 src/mesa/drivers/dri/i915tex/server/intel_dri.c (limited to 'src') diff --git a/configs/freebsd-dri b/configs/freebsd-dri index e4d6b02bc2..9750017c23 100644 --- a/configs/freebsd-dri +++ b/configs/freebsd-dri @@ -45,6 +45,6 @@ DRM_SOURCE_PATH=$(TOP)/../drm # ffb and gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = i810 i915tex i965 mach64 mga r128 r200 r300 radeon tdfx \ +DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon tdfx \ unichrome savage sis diff --git a/configs/linux-dri b/configs/linux-dri index 3cba192569..afa2d8ca34 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -66,5 +66,5 @@ WINDOW_SYSTEM=dri # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = i810 i915tex i965 mach64 mga r128 r200 r300 radeon s3v \ +DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon s3v \ savage sis tdfx trident unichrome ffb diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile new file mode 100644 index 0000000000..d3d0bd570c --- /dev/null +++ b/src/mesa/drivers/dri/i915/Makefile @@ -0,0 +1,71 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915_dri.so + +MINIGLX_SOURCES = server/intel_dri.c + +DRIVER_SOURCES = \ + i830_context.c \ + i830_metaops.c \ + i830_state.c \ + i830_texblend.c \ + i830_tex.c \ + i830_texstate.c \ + i830_vtbl.c \ + intel_render.c \ + intel_regions.c \ + intel_buffer_objects.c \ + intel_batchbuffer.c \ + intel_mipmap_tree.c \ + i915_tex_layout.c \ + intel_tex_layout.c \ + intel_tex_image.c \ + intel_tex_subimage.c \ + intel_tex_copy.c \ + intel_tex_validate.c \ + intel_tex_format.c \ + intel_tex.c \ + intel_pixel.c \ + intel_pixel_copy.c \ + intel_pixel_read.c \ + intel_pixel_draw.c \ + intel_buffers.c \ + intel_blit.c \ + i915_tex.c \ + i915_texstate.c \ + i915_context.c \ + i915_debug.c \ + i915_debug_fp.c \ + i915_fragprog.c \ + i915_metaops.c \ + i915_program.c \ + i915_state.c \ + i915_vtbl.c \ + intel_context.c \ + intel_decode.c \ + intel_ioctl.c \ + intel_rotate.c \ + intel_screen.c \ + intel_span.c \ + intel_state.c \ + intel_tris.c \ + intel_fbo.c \ + intel_depthstencil.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(COMMON_BM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ + && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") + +include ../Makefile.template + +intel_tex_layout.o: ../intel/intel_tex_layout.c + +symlinks: diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c new file mode 100644 index 0000000000..2ff8621c42 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -0,0 +1,104 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i830_context.h" +#include "imports.h" +#include "texmem.h" +#include "intel_tex.h" +#include "tnl/tnl.h" +#include "tnl/t_vertex.h" +#include "tnl/t_context.h" +#include "utils.h" + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +static const struct dri_extension i830_extensions[] = { + {"GL_ARB_texture_env_crossbar", NULL}, + {NULL, NULL} +}; + + +static void +i830InitDriverFunctions(struct dd_function_table *functions) +{ + intelInitDriverFunctions(functions); + i830InitStateFuncs(functions); + i830InitTextureFuncs(functions); +} + + +GLboolean +i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct dd_function_table functions; + struct i830_context *i830 = CALLOC_STRUCT(i830_context); + struct intel_context *intel = &i830->intel; + GLcontext *ctx = &intel->ctx; + if (!i830) + return GL_FALSE; + + i830InitVtbl(i830); + i830InitDriverFunctions(&functions); + + if (!intelInitContext(intel, mesaVis, driContextPriv, + sharedContextPrivate, &functions)) { + FREE(i830); + return GL_FALSE; + } + + intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; + intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; + intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; + + /* Advertise the full hardware capabilities. The new memory + * manager should cope much better with overload situations: + */ + ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 11; + ctx->Const.MaxTextureRectSize = (1 << 11); + ctx->Const.MaxTextureUnits = I830_TEX_UNITS; + + _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, + 18 * sizeof(GLfloat)); + + intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; + + driInitExtensions(ctx, i830_extensions, GL_FALSE); + + i830InitState(i830); + i830InitMetaFuncs(i830); + + _tnl_allow_vertex_fog(ctx, 1); + _tnl_allow_pixel_fog(ctx, 0); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h new file mode 100644 index 0000000000..9397fa45b5 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_context.h @@ -0,0 +1,213 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef I830CONTEXT_INC +#define I830CONTEXT_INC + +#include "intel_context.h" + +#define I830_FALLBACK_TEXTURE 0x1000 +#define I830_FALLBACK_COLORMASK 0x2000 +#define I830_FALLBACK_STENCIL 0x4000 +#define I830_FALLBACK_STIPPLE 0x8000 +#define I830_FALLBACK_LOGICOP 0x10000 + +#define I830_UPLOAD_CTX 0x1 +#define I830_UPLOAD_BUFFERS 0x2 +#define I830_UPLOAD_STIPPLE 0x4 +#define I830_UPLOAD_INVARIENT 0x8 +#define I830_UPLOAD_TEX(i) (0x10<<(i)) +#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i)) +#define I830_UPLOAD_TEX_ALL (0x0f0) +#define I830_UPLOAD_TEXBLEND_ALL (0xf00) + +/* State structure offsets - these will probably disappear. + */ +#define I830_DESTREG_CBUFADDR0 0 +#define I830_DESTREG_CBUFADDR1 1 +#define I830_DESTREG_DBUFADDR0 2 +#define I830_DESTREG_DBUFADDR1 3 +#define I830_DESTREG_DV0 4 +#define I830_DESTREG_DV1 5 +#define I830_DESTREG_SENABLE 6 +#define I830_DESTREG_SR0 7 +#define I830_DESTREG_SR1 8 +#define I830_DESTREG_SR2 9 +#define I830_DEST_SETUP_SIZE 10 + +#define I830_CTXREG_STATE1 0 +#define I830_CTXREG_STATE2 1 +#define I830_CTXREG_STATE3 2 +#define I830_CTXREG_STATE4 3 +#define I830_CTXREG_STATE5 4 +#define I830_CTXREG_IALPHAB 5 +#define I830_CTXREG_STENCILTST 6 +#define I830_CTXREG_ENABLES_1 7 +#define I830_CTXREG_ENABLES_2 8 +#define I830_CTXREG_AA 9 +#define I830_CTXREG_FOGCOLOR 10 +#define I830_CTXREG_BLENDCOLOR0 11 +#define I830_CTXREG_BLENDCOLOR1 12 +#define I830_CTXREG_VF 13 +#define I830_CTXREG_VF2 14 +#define I830_CTXREG_MCSB0 15 +#define I830_CTXREG_MCSB1 16 +#define I830_CTX_SETUP_SIZE 17 + +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S1 1 +#define I830_TEXREG_TM0S2 2 +#define I830_TEXREG_TM0S3 3 +#define I830_TEXREG_TM0S4 4 +#define I830_TEXREG_MCS 5 /* _3DSTATE_MAP_COORD_SETS */ +#define I830_TEXREG_CUBE 6 /* _3DSTATE_MAP_SUBE */ +#define I830_TEX_SETUP_SIZE 7 + +#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ + +struct i830_texture_object +{ + struct intel_texture_object intel; + GLuint Setup[I830_TEX_SETUP_SIZE]; +}; + +#define I830_TEX_UNITS 4 + +struct i830_hw_state +{ + GLuint Ctx[I830_CTX_SETUP_SIZE]; + GLuint Buffer[I830_DEST_SETUP_SIZE]; + GLuint Stipple[I830_STP_SETUP_SIZE]; + GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE]; + GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE]; + GLuint TexBlendWordsUsed[I830_TEX_UNITS]; + + struct intel_region *draw_region; + struct intel_region *depth_region; + + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Will have to do this for draw and depth for + * FBO's... + */ + dri_bo *tex_buffer[I830_TEX_UNITS]; + GLuint tex_offset[I830_TEX_UNITS]; + + GLuint emitted; /* I810_UPLOAD_* */ + GLuint active; +}; + +struct i830_context +{ + struct intel_context intel; + + GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; + DECLARE_RENDERINPUTS(last_index_bitset); + + struct i830_hw_state meta, initial, state, *current; +}; + + + + +#define I830_STATECHANGE(i830, flag) \ +do { \ + INTEL_FIREVERTICES( &i830->intel ); \ + i830->state.emitted &= ~flag; \ +} while (0) + +#define I830_ACTIVESTATE(i830, flag, mode) \ +do { \ + INTEL_FIREVERTICES( &i830->intel ); \ + if (mode) \ + i830->state.active |= flag; \ + else \ + i830->state.active &= ~flag; \ +} while (0) + +/* i830_vtbl.c + */ +extern void i830InitVtbl(struct i830_context *i830); + +extern void +i830_state_draw_region(struct intel_context *intel, + struct i830_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region); +/* i830_context.c + */ +extern GLboolean +i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +/* i830_tex.c, i830_texstate.c + */ +extern void i830UpdateTextureState(struct intel_context *intel); + +extern void i830InitTextureFuncs(struct dd_function_table *functions); + +/* i830_texblend.c + */ +extern GLuint i830SetTexEnvCombine(struct i830_context *i830, + const struct gl_tex_env_combine_state + *combine, GLint blendUnit, GLuint texel_op, + GLuint * state, const GLfloat * factor); + +extern void i830EmitTextureBlend(struct i830_context *i830); + + +/* i830_state.c + */ +extern void i830InitStateFuncs(struct dd_function_table *functions); + +extern void i830EmitState(struct i830_context *i830); + +extern void i830InitState(struct i830_context *i830); + +/* i830_metaops.c + */ +extern void i830InitMetaFuncs(struct i830_context *i830); + +extern void +i830RotateWindow(struct intel_context *intel, __DRIdrawablePrivate * dPriv, + GLuint srcBuf); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static INLINE struct i830_context * +i830_context(GLcontext * ctx) +{ + return (struct i830_context *) ctx; +} + +#endif diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c new file mode 100644 index 0000000000..13e4ab3aac --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_metaops.c @@ -0,0 +1,457 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "utils.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_regions.h" + +#include "i830_context.h" +#include "i830_reg.h" + +/* A large amount of state doesn't need to be uploaded. + */ +#define ACTIVE (I830_UPLOAD_INVARIENT | \ + I830_UPLOAD_CTX | \ + I830_UPLOAD_BUFFERS | \ + I830_UPLOAD_STIPPLE | \ + I830_UPLOAD_TEXBLEND(0) | \ + I830_UPLOAD_TEX(0)) + + +#define SET_STATE( i830, STATE ) \ +do { \ + i830->current->emitted &= ~ACTIVE; \ + i830->current = &i830->STATE; \ + i830->current->emitted &= ~ACTIVE; \ +} while (0) + + +static void +set_no_stencil_write(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +static void +set_no_depth_write(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Set depth unit to replace. + */ +static void +set_depth_replace(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + * ctx->Driver.DepthMask( ctx, GL_TRUE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; + + /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) + */ + i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; + i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC + (COMPAREFUNC_ALWAYS)); + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +/* Set stencil unit to replace always with the reference value. + */ +static void +set_stencil_replace(struct intel_context *intel, + GLuint s_mask, GLuint s_clear) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + + /* ctx->Driver.StencilMask( ctx, s_mask ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK((s_mask & + 0xff))); + + /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) + */ + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); + + /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff)); + + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE((s_clear & 0xff)) | + STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); + + + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void +set_color_mask(struct intel_context *intel, GLboolean state) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | + (1 << WRITEMASK_GREEN_SHIFT) | + (1 << WRITEMASK_BLUE_SHIFT) | + (1 << WRITEMASK_ALPHA_SHIFT)); + + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; + + if (state) { + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= + (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); + } + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Installs a one-stage passthrough texture blend pipeline. Is there + * more that can be done to turn off texturing? + */ +static void +set_no_texture(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + static const struct gl_tex_env_combine_state comb = { + GL_NONE, GL_NONE, + {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,}, + {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0}, + 0, 0, 0, 0 + }; + + i830->meta.TexBlendWordsUsed[0] = + i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], NULL); + + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); +} + +/* Set up a single element blend stage for 'replace' texturing with no + * funny ops. + */ +static void +set_texture_blend_replace(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + static const struct gl_tex_env_combine_state comb = { + GL_REPLACE, GL_REPLACE, + {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE, + GL_TEXTURE,}, + {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA, + GL_SRC_ALPHA}, + 0, 0, 1, 1 + }; + + i830->meta.TexBlendWordsUsed[0] = + i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], NULL); + + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); + +/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ +/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ +} + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +static GLboolean +set_tex_rect_source(struct intel_context *intel, + dri_bo *buffer, + GLuint offset, + GLuint pitch, GLuint height, GLenum format, GLenum type) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint *setup = i830->meta.Tex[0]; + GLint numLevels = 1; + GLuint textureFormat; + GLuint cpp; + + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + i830->meta.tex_buffer[0] = buffer; + i830->meta.tex_offset[0] = offset; + + setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << 0) | 4); + setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | + ((pitch - 1) << TM0S1_WIDTH_SHIFT) | + textureFormat); + setup[I830_TEXREG_TM0S2] = + (((((pitch * cpp) / 4) - + 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); + + setup[I830_TEXREG_TM0S3] = + ((((numLevels - + 1) * + 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST << + TM0S3_MIN_FILTER_SHIFT) | + (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST << + TM0S3_MAG_FILTER_SHIFT)); + + setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0)); + + setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | + MAP_UNIT(0) | + ENABLE_TEXCOORD_PARAMS | + TEXCOORDS_ARE_IN_TEXELUNITS | + TEXCOORDTYPE_CARTESIAN | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | + ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); + + i830->meta.emitted &= ~I830_UPLOAD_TEX(0); + return GL_TRUE; +} + + +static void +set_vertex_format(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | + VFT0_TEX_COUNT(1) | + VFT0_DIFFUSE | VFT0_XYZ); + i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | + VFT1_TEX0_FMT(TEXCOORDFMT_2D) | + VFT1_TEX1_FMT(TEXCOORDFMT_2D) | + VFT1_TEX2_FMT(TEXCOORDFMT_2D) | + VFT1_TEX3_FMT(TEXCOORDFMT_2D)); + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void +meta_import_pixel_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1]; + i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2]; + i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3]; + i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; + i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5]; + i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB]; + i830->meta.Ctx[I830_CTXREG_STENCILTST] = + i830->state.Ctx[I830_CTXREG_STENCILTST]; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] = + i830->state.Ctx[I830_CTXREG_ENABLES_1]; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] = + i830->state.Ctx[I830_CTXREG_ENABLES_2]; + i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA]; + i830->meta.Ctx[I830_CTXREG_FOGCOLOR] = + i830->state.Ctx[I830_CTXREG_FOGCOLOR]; + i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] = + i830->state.Ctx[I830_CTXREG_BLENDCOLOR0]; + i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; + i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0]; + i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1]; + + + i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + i830->meta.emitted &= ~I830_UPLOAD_CTX; + + + i830->meta.Buffer[I830_DESTREG_SENABLE] = + i830->state.Buffer[I830_DESTREG_SENABLE]; + i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; + i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; +} + + + +/* Select between front and back draw buffers. + */ +static void +meta_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + i830_state_draw_region(intel, &i830->meta, color_region, depth_region); +} + + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void +install_meta_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + memcpy(&i830->meta, &i830->initial, sizeof(i830->meta)); + + i830->meta.active = ACTIVE; + i830->meta.emitted = 0; + + SET_STATE(i830, meta); + set_vertex_format(intel); + set_no_texture(intel); +} + +static void +leave_meta_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + intel_region_release(&i830->meta.draw_region); + intel_region_release(&i830->meta.depth_region); +/* intel_region_release(intel, &i830->meta.tex_region[0]); */ + SET_STATE(i830, state); +} + + + +void +i830InitMetaFuncs(struct i830_context *i830) +{ + i830->intel.vtbl.install_meta_state = install_meta_state; + i830->intel.vtbl.leave_meta_state = leave_meta_state; + i830->intel.vtbl.meta_no_depth_write = set_no_depth_write; + i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write; + i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; + i830->intel.vtbl.meta_depth_replace = set_depth_replace; + i830->intel.vtbl.meta_color_mask = set_color_mask; + i830->intel.vtbl.meta_no_texture = set_no_texture; + i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; + i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; + i830->intel.vtbl.meta_draw_region = meta_draw_region; + i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; +} diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h new file mode 100644 index 0000000000..41280bca7c --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_reg.h @@ -0,0 +1,642 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef _I830_REG_H_ +#define _I830_REG_H_ + + +#include "intel_reg.h" + +#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) +#define AA_LINE_ENABLE ((1<<1) | 1) +#define AA_LINE_DISABLE (1<<1) + +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) + +#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ + ((0x90+(stage))<<16)) + +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_IS_Z 0 +#define DEPTH_IS_W (1<<6) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 0 +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + + +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +#define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) +#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) +#define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) +#define DISABLE_LOGIC_OP (1<<23) +#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_TEST (1<<21) +#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) +#define DISABLE_DEPTH_BIAS (1<<11) +#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) +#define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) +#define DISABLE_SPEC_ADD (1<<9) +#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) +#define ENABLE_FOG ((1<<7)|(1<<6)) +#define DISABLE_FOG (1<<7) +#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) +#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) +#define DISABLE_ALPHA_TEST (1<<5) +#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) +#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) +#define DISABLE_COLOR_BLEND (1<<3) +#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) +#define ENABLE_DEPTH_TEST ((1<<1)|1) +#define DISABLE_DEPTH_TEST (1<<1) + +/* _3DSTATE_ENABLES_2, p138 */ +#define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) +#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_WRITE (1<<21) +#define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) +#define DISABLE_TEX_CACHE (1<<17) +#define ENABLE_DITHER ((1<<9)|(1<<8)) +#define DISABLE_DITHER (1<<9) +#define ENABLE_COLOR_MASK (1<<10) +#define WRITEMASK_ALPHA (1<<7) +#define WRITEMASK_ALPHA_SHIFT 7 +#define WRITEMASK_RED (1<<6) +#define WRITEMASK_RED_SHIFT 6 +#define WRITEMASK_GREEN (1<<5) +#define WRITEMASK_GREEN_SHIFT 5 +#define WRITEMASK_BLUE (1<<4) +#define WRITEMASK_BLUE_SHIFT 4 +#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) +#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) +#define DISABLE_COLOR_WRITE (1<<3) +#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 +#define ENABLE_DEPTH_WRITE ((1<<1)|1) +#define DISABLE_DEPTH_WRITE (1<<1) + +/* _3DSTATE_FOG_COLOR, p139 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p140 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FOGFUNC_ENABLE (1<<31) +#define FOGFUNC_VERTEX 0 +#define FOGFUNC_PIXEL_EXP (1<<28) +#define FOGFUNC_PIXEL_EXP2 (2<<28) +#define FOGFUNC_PIXEL_LINEAR (3<<28) +#define FOGSRC_INDEX_Z (1<<27) +#define FOGSRC_INDEX_W ((1<<27)|(1<<25)) +#define FOG_LINEAR_CONST (1<<24) +#define FOG_CONST_1(x) ((x)<<4) +#define ENABLE_FOG_DENSITY (1<<23) +/* Dword 2 */ +#define FOG_CONST_2(x) (x) +/* Dword 3 */ +#define FOG_DENSITY(x) (x) + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ +#define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) +#define DISABLE_INDPT_ALPHA_BLEND (1<<23) +#define ALPHA_BLENDFUNC_MASK 0x3f0000 +#define ENABLE_ALPHA_BLENDFUNC (1<<21) +#define ABLENDFUNC_ADD 0 +#define ABLENDFUNC_SUB (1<<16) +#define ABLENDFUNC_RVSE_SUB (2<<16) +#define ABLENDFUNC_MIN (3<<16) +#define ABLENDFUNC_MAX (4<<16) +#define SRC_DST_ABLEND_MASK 0xfff +#define ENABLE_SRC_ABLEND_FACTOR (1<<11) +#define SRC_ABLEND_FACT(x) ((x)<<6) +#define ENABLE_DST_ABLEND_FACTOR (1<<5) +#define DST_ABLEND_FACT(x) (x) + + +/* _3DSTATE_MAP_BLEND_ARG, p152 */ +#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) + +#define TEXPIPE_COLOR 0 +#define TEXPIPE_ALPHA (1<<18) +#define TEXPIPE_KILL (2<<18) +#define TEXBLEND_ARG0 0 +#define TEXBLEND_ARG1 (1<<15) +#define TEXBLEND_ARG2 (2<<15) +#define TEXBLEND_ARG3 (3<<15) +#define TEXBLENDARG_MODIFY_PARMS (1<<6) +#define TEXBLENDARG_REPLICATE_ALPHA (1<<5) +#define TEXBLENDARG_INV_ARG (1<<4) +#define TEXBLENDARG_ONE 0 +#define TEXBLENDARG_FACTOR 0x01 +#define TEXBLENDARG_ACCUM 0x02 +#define TEXBLENDARG_DIFFUSE 0x03 +#define TEXBLENDARG_SPEC 0x04 +#define TEXBLENDARG_CURRENT 0x05 +#define TEXBLENDARG_TEXEL0 0x06 +#define TEXBLENDARG_TEXEL1 0x07 +#define TEXBLENDARG_TEXEL2 0x08 +#define TEXBLENDARG_TEXEL3 0x09 +#define TEXBLENDARG_FACTOR_N 0x0e + +/* _3DSTATE_MAP_BLEND_OP, p155 */ +#define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) +#if 0 +# define TEXPIPE_COLOR 0 +# define TEXPIPE_ALPHA (1<<18) +# define TEXPIPE_KILL (2<<18) +#endif +#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) +#define TEXOP_OUTPUT_CURRENT 0 +#define TEXOP_OUTPUT_ACCUM (1<<15) +#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) +#define DISABLE_TEX_CNTRL_STAGE (1<<12) +#define TEXOP_SCALE_SHIFT 9 +#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) +#define TEXOP_MODIFY_PARMS (1<<8) +#define TEXOP_LAST_STAGE (1<<7) +#define TEXBLENDOP_KILLPIXEL 0x02 +#define TEXBLENDOP_ARG1 0x01 +#define TEXBLENDOP_ARG2 0x02 +#define TEXBLENDOP_MODULATE 0x03 +#define TEXBLENDOP_ADD 0x06 +#define TEXBLENDOP_ADDSIGNED 0x07 +#define TEXBLENDOP_BLEND 0x08 +#define TEXBLENDOP_BLEND_AND_ADD 0x09 +#define TEXBLENDOP_SUBTRACT 0x0a +#define TEXBLENDOP_DOT3 0x0b +#define TEXBLENDOP_DOT4 0x0c +#define TEXBLENDOP_MODULATE_AND_ADD 0x0d +#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e +#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f + +/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ +/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ + +#define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) +#define DISABLE_TEX_TRANSFORM (1<<28) +#define TEXTURE_SET(x) (x<<29) + +#define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define DISABLE_PERSPECTIVE_DIVIDE (1<<29) + + +/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ +#define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) +#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) +#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) +#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) + +#define TEXBIND_SET3(x) ((x)<<12) +#define TEXBIND_SET2(x) ((x)<<8) +#define TEXBIND_SET1(x) ((x)<<4) +#define TEXBIND_SET0(x) (x) + +#define TEXCOORDSRC_KEEP 0 +#define TEXCOORDSRC_DEFAULT 0x01 +#define TEXCOORDSRC_VTXSET_0 0x08 +#define TEXCOORDSRC_VTXSET_1 0x09 +#define TEXCOORDSRC_VTXSET_2 0x0a +#define TEXCOORDSRC_VTXSET_3 0x0b +#define TEXCOORDSRC_VTXSET_4 0x0c +#define TEXCOORDSRC_VTXSET_5 0x0d +#define TEXCOORDSRC_VTXSET_6 0x0e +#define TEXCOORDSRC_VTXSET_7 0x0f + +#define MAP_UNIT(unit) ((unit)<<16) +#define MAP_UNIT_MASK (0x7<<16) + +/* _3DSTATE_MAP_COORD_SETS, p164 */ +#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) +#define ENABLE_TEXCOORD_PARAMS (1<<15) +#define TEXCOORDS_ARE_NORMAL (1<<14) +#define TEXCOORDS_ARE_IN_TEXELUNITS 0 +#define TEXCOORDTYPE_CARTESIAN 0 +#define TEXCOORDTYPE_HOMOGENEOUS (1<<11) +#define TEXCOORDTYPE_VECTOR (2<<11) +#define TEXCOORDTYPE_MASK (0x7<<11) +#define ENABLE_ADDR_V_CNTL (1<<7) +#define ENABLE_ADDR_U_CNTL (1<<3) +#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) +#define TEXCOORD_ADDR_U_MODE(x) (x) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP 2 +#define TEXCOORDMODE_WRAP_SHORTEST 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORD_ADDR_V_MASK 0x70 +#define TEXCOORD_ADDR_U_MASK 0x7 + +/* _3DSTATE_MAP_CUBE, p168 TODO */ +#define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) +#define CUBE_NEGX_ENABLE (1<<5) +#define CUBE_POSX_ENABLE (1<<4) +#define CUBE_NEGY_ENABLE (1<<3) +#define CUBE_POSY_ENABLE (1<<2) +#define CUBE_NEGZ_ENABLE (1<<1) +#define CUBE_POSZ_ENABLE (1<<0) + + +/* _3DSTATE_MODES_1, p190 */ +#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) +#define BLENDFUNC_MASK 0x3f0000 +#define ENABLE_COLR_BLND_FUNC (1<<21) +#define BLENDFUNC_ADD 0 +#define BLENDFUNC_SUB (1<<16) +#define BLENDFUNC_RVRSE_SUB (2<<16) +#define BLENDFUNC_MIN (3<<16) +#define BLENDFUNC_MAX (4<<16) +#define SRC_DST_BLND_MASK 0xfff +#define ENABLE_SRC_BLND_FACTOR (1<<11) +#define ENABLE_DST_BLND_FACTOR (1<<5) +#define SRC_BLND_FACT(x) ((x)<<6) +#define DST_BLND_FACT(x) (x) + + +/* _3DSTATE_MODES_2, p192 */ +#define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) +#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) +#define GLOBAL_DEPTH_BIAS(x) ((x)<<14) +#define ENABLE_ALPHA_TEST_FUNC (1<<13) +#define ENABLE_ALPHA_REF_VALUE (1<<8) +#define ALPHA_TEST_FUNC(x) ((x)<<9) +#define ALPHA_REF_VALUE(x) (x) + +#define ALPHA_TEST_REF_MASK 0x3fff + +/* _3DSTATE_MODES_3, p193 */ +#define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) +#define DEPTH_TEST_FUNC_MASK 0x1f0000 +#define ENABLE_DEPTH_TEST_FUNC (1<<20) +/* Uses COMPAREFUNC */ +#define DEPTH_TEST_FUNC(x) ((x)<<16) +#define ENABLE_ALPHA_SHADE_MODE (1<<11) +#define ENABLE_FOG_SHADE_MODE (1<<9) +#define ENABLE_SPEC_SHADE_MODE (1<<7) +#define ENABLE_COLOR_SHADE_MODE (1<<5) +#define ALPHA_SHADE_MODE(x) ((x)<<10) +#define FOG_SHADE_MODE(x) ((x)<<8) +#define SPEC_SHADE_MODE(x) ((x)<<6) +#define COLOR_SHADE_MODE(x) ((x)<<4) +#define CULLMODE_MASK 0xf +#define ENABLE_CULL_MODE (1<<3) +#define CULLMODE_BOTH 0 +#define CULLMODE_NONE 1 +#define CULLMODE_CW 2 +#define CULLMODE_CCW 3 + +#define SHADE_MODE_LINEAR 0 +#define SHADE_MODE_FLAT 0x1 + +/* _3DSTATE_MODES_4, p195 */ +#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) + +/* _3DSTATE_MODES_5, p196 */ +#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define ENABLE_SPRITE_POINT_TEX (1<<23) +#define SPRITE_POINT_TEX_ON (1<<22) +#define SPRITE_POINT_TEX_OFF 0 +#define FLUSH_RENDER_CACHE (1<<18) +#define FLUSH_TEXTURE_CACHE (1<<16) +#define FIXED_LINE_WIDTH_MASK 0xfc00 +#define ENABLE_FIXED_LINE_WIDTH (1<<15) +#define FIXED_LINE_WIDTH(x) ((x)<<10) +#define FIXED_POINT_WIDTH_MASK 0x3ff +#define ENABLE_FIXED_POINT_WIDTH (1<<9) +#define FIXED_POINT_WIDTH(x) (x) + +/* _3DSTATE_RASTERIZATION_RULES, p198 */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) +#define TRI_STRIP_PROVOKE_VRTX(x) (x) + +/* _3DSTATE_SCISSOR_ENABLE, p200 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* _3DSTATE_STENCIL_TEST, p202 */ +#define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) +#define ENABLE_STENCIL_PARMS (1<<23) +#define STENCIL_OPS_MASK (0xffc000) +#define STENCIL_FAIL_OP(x) ((x)<<20) +#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) +#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) + +#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) +#define ENABLE_STENCIL_TEST_FUNC (1<<13) +/* Uses COMPAREFUNC */ +#define STENCIL_TEST_FUNC(x) ((x)<<9) +#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) +#define ENABLE_STENCIL_REF_VALUE (1<<8) +#define STENCIL_REF_VALUE(x) (x) + +/* _3DSTATE_VERTEX_FORMAT, p204 */ +#define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) +#define VFT0_POINT_WIDTH (1<<12) +#define VFT0_TEX_COUNT_MASK (7<<8) +#define VFT0_TEX_COUNT_SHIFT 8 +#define VFT0_TEX_COUNT(x) ((x)<<8) +#define VFT0_SPEC (1<<7) +#define VFT0_DIFFUSE (1<<6) +#define VFT0_DEPTH_OFFSET (1<<5) +#define VFT0_XYZ (1<<1) +#define VFT0_XYZW (2<<1) +#define VFT0_XY (3<<1) +#define VFT0_XYW (4<<1) +#define VFT0_XYZW_MASK (7<<1) + +/* _3DSTATE_VERTEX_FORMAT_2, p206 */ +#define _3DSTATE_VFT1_CMD (CMD_3D|(0x0a<<24)) +#define VFT1_TEX7_FMT(x) ((x)<<14) +#define VFT1_TEX6_FMT(x) ((x)<<12) +#define VFT1_TEX5_FMT(x) ((x)<<10) +#define VFT1_TEX4_FMT(x) ((x)<<8) +#define VFT1_TEX3_FMT(x) ((x)<<6) +#define VFT1_TEX2_FMT(x) ((x)<<4) +#define VFT1_TEX1_FMT(x) ((x)<<2) +#define VFT1_TEX0_FMT(x) (x) +#define VFT1_TEX0_MASK 3 +#define VFT1_TEX1_SHIFT 2 +#define TEXCOORDFMT_2D 0 +#define TEXCOORDFMT_3D 1 +#define TEXCOORDFMT_4D 2 +#define TEXCOORDFMT_1D 3 + +/*New stuff picked up along the way */ + +#define MLC_LOD_BIAS_MASK ((1<<7)-1) + + +/* _3DSTATE_VERTEX_TRANSFORM, p207 */ +#define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) +#define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) +/* Dword 1 */ +#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) +#define DISABLE_PERSP_DIVIDE (1<<29) +#define VRTX_TRANS_LOAD_MATRICES 0x7421 +#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 +/* Dword 2 -> 7 are matrix elements */ + +/* _3DSTATE_W_STATE, p209 */ +#define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) +/* Dword 1 */ +#define MAGIC_W_STATE_DWORD1 0x00000008 +/* Dword 2 */ +#define WFAR_VALUE(x) (x) + + +/* Stipple command, carried over from the i810, apparently: + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + + +#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) +#define LOAD_GLOBAL_COLOR_FACTOR (1<<6) + +#define TM0S0_ADDRESS_MASK 0xfffffffc +#define TM0S0_USE_FENCE (1<<1) + +#define TM0S1_HEIGHT_SHIFT 21 +#define TM0S1_WIDTH_SHIFT 10 +#define TM0S1_PALETTE_SELECT (1<<9) +#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) +#define TM0S1_MAPSURF_FORMAT_SHIFT 6 +#define MAPSURF_8BIT_INDEXED (0<<6) +#define MAPSURF_8BIT (1<<6) +#define MAPSURF_16BIT (2<<6) +#define MAPSURF_32BIT (3<<6) +#define MAPSURF_411 (4<<6) +#define MAPSURF_422 (5<<6) +#define MAPSURF_COMPRESSED (6<<6) +#define MAPSURF_4BIT_INDEXED (7<<6) +#define TM0S1_MT_FORMAT_MASK (0x7 << 3) +#define TM0S1_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ +#define MT_8BIT_IDX_ARGB1555 (1<<3) +#define MT_8BIT_IDX_ARGB4444 (2<<3) +#define MT_8BIT_IDX_AY88 (3<<3) +#define MT_8BIT_IDX_ABGR8888 (4<<3) +#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) +#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) +#define MT_8BIT_IDX_ARGB8888 (7<<3) +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) +#define MT_16BIT_BUMP_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_DIB_RGB565_8888 (7<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_XRGB8888 (2<<3) /* XXX: Guess from i915_reg.h */ +#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) +#define MT_32BIT_DIB_8888 (7<<3) +#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define TM0S1_COLORSPACE_CONVERSION (1 << 2) +#define TM0S1_TILED_SURFACE (1 << 1) +#define TM0S1_TILE_WALK (1 << 0) + +#define TM0S2_PITCH_SHIFT 21 +#define TM0S2_CUBE_FACE_ENA_SHIFT 15 +#define TM0S2_CUBE_FACE_ENA_MASK (1<<15) +#define TM0S2_MAP_FORMAT (1<<14) +#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) +#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) +#define TM0S2_OUTPUT_CHAN_SHIFT 10 +#define TM0S2_OUTPUT_CHAN_MASK (3<<10) + +#define TM0S3_MIP_FILTER_MASK (0x3<<30) +#define TM0S3_MIP_FILTER_SHIFT 30 +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define TM0S3_MAG_FILTER_MASK (0x3<<28) +#define TM0S3_MAG_FILTER_SHIFT 28 +#define TM0S3_MIN_FILTER_MASK (0x3<<26) +#define TM0S3_MIN_FILTER_SHIFT 26 +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 + +#define TM0S3_LOD_BIAS_SHIFT 17 +#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) +#define TM0S3_MAX_MIP_SHIFT 9 +#define TM0S3_MAX_MIP_MASK (0xff<<9) +#define TM0S3_MIN_MIP_SHIFT 3 +#define TM0S3_MIN_MIP_MASK (0x3f<<3) +#define TM0S3_KILL_PIXEL (1<<2) +#define TM0S3_KEYED_FILTER (1<<1) +#define TM0S3_CHROMA_KEY (1<<0) + + +/* _3DSTATE_MAP_TEXEL_STREAM, p188 */ +#define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) +#define DISABLE_TEX_STREAM_BUMP (1<<12) +#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) +#define TEX_MODIFY_UNIT_0 0 +#define TEX_MODIFY_UNIT_1 (1<<8) +#define ENABLE_TEX_STREAM_COORD_SET (1<<7) +#define TEX_STREAM_COORD_SET(x) ((x)<<4) +#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) +#define TEX_STREAM_MAP_IDX(x) (x) + + +#define MI_FLUSH ((0<<29)|(4<<23)) +#define FLUSH_MAP_CACHE (1<<0) + +#endif diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c new file mode 100644 index 0000000000..3c149e6905 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -0,0 +1,1116 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "texmem.h" + +#include "drivers/common/driverfuncs.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_fbo.h" + +#include "i830_context.h" +#include "i830_reg.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static void +i830StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, + GLuint mask) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + + mask = mask & 0xff; + + DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(func), ref, mask); + + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(mask)); + i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE(ref) | + STENCIL_TEST_FUNC(test)); +} + +static void +i830StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s : mask 0x%x\n", __FUNCTION__, mask); + + mask = mask & 0xff; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(mask)); +} + +static void +i830StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) +{ + struct i830_context *i830 = i830_context(ctx); + int fop, dfop, dpop; + + DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), + _mesa_lookup_enum_by_nr(zpass)); + + fop = 0; + dfop = 0; + dpop = 0; + + switch (fail) { + case GL_KEEP: + fop = STENCILOP_KEEP; + break; + case GL_ZERO: + fop = STENCILOP_ZERO; + break; + case GL_REPLACE: + fop = STENCILOP_REPLACE; + break; + case GL_INCR: + fop = STENCILOP_INCRSAT; + break; + case GL_DECR: + fop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + fop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + fop = STENCILOP_DECR; + break; + case GL_INVERT: + fop = STENCILOP_INVERT; + break; + default: + break; + } + switch (zfail) { + case GL_KEEP: + dfop = STENCILOP_KEEP; + break; + case GL_ZERO: + dfop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dfop = STENCILOP_REPLACE; + break; + case GL_INCR: + dfop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dfop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dfop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dfop = STENCILOP_DECR; + break; + case GL_INVERT: + dfop = STENCILOP_INVERT; + break; + default: + break; + } + switch (zpass) { + case GL_KEEP: + dpop = STENCILOP_KEEP; + break; + case GL_ZERO: + dpop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dpop = STENCILOP_REPLACE; + break; + case GL_INCR: + dpop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dpop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dpop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dpop = STENCILOP_DECR; + break; + case GL_INVERT: + dpop = STENCILOP_INVERT; + break; + default: + break; + } + + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(fop) | + STENCIL_PASS_DEPTH_FAIL_OP + (dfop) | + STENCIL_PASS_DEPTH_PASS_OP + (dpop)); +} + +static void +i830AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + GLubyte refByte; + GLuint refInt; + + UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); + refInt = (GLuint) refByte; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; + i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | + ENABLE_ALPHA_REF_VALUE | + ALPHA_TEST_FUNC(test) | + ALPHA_REF_VALUE(refInt)); +} + +/** + * Makes sure that the proper enables are set for LogicOp, Independant Alpha + * Blend, and Blending. It needs to be called from numerous places where we + * could change the LogicOp or Independant Alpha Blend without subsequent + * calls to glEnable. + * + * \todo + * This function is substantially different from the old i830-specific driver. + * I'm not sure which is correct. + */ +static void +i830EvalLogicOpBlendState(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + if (RGBA_LOGICOP_ENABLED(ctx)) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + ENABLE_LOGIC_OP); + } + else if (ctx->Color.BlendEnabled) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + } + else { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + } +} + +static void +i830BlendColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct i830_context *i830 = i830_context(ctx); + GLubyte r, g, b, a; + + DBG("%s\n", __FUNCTION__); + + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = + (a << 24) | (r << 16) | (g << 8) | b; +} + +/** + * Sets both the blend equation (called "function" in i830 docs) and the + * blend function (called "factor" in i830 docs). This is done in a single + * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) + * change the interpretation of the blend function. + */ +static void +i830_set_blend_state(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + int funcA; + int funcRGB; + int eqnA; + int eqnRGB; + int iab; + int s1; + + + funcRGB = + SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcRGB)) + | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstRGB)); + + switch (ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: + eqnRGB = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnRGB = BLENDFUNC_MIN; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnRGB = BLENDFUNC_MAX; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnRGB = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnRGB = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", + __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB); + return; + } + + + funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcA)) + | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstA)); + + switch (ctx->Color.BlendEquationA) { + case GL_FUNC_ADD: + eqnA = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnA = BLENDFUNC_MIN; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnA = BLENDFUNC_MAX; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnA = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnA = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", + __FUNCTION__, __LINE__, ctx->Color.BlendEquationA); + return; + } + + iab = eqnA | funcA + | _3DSTATE_INDPT_ALPHA_BLEND_CMD + | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR + | ENABLE_ALPHA_BLENDFUNC; + s1 = eqnRGB | funcRGB + | _3DSTATE_MODES_1_CMD + | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR + | ENABLE_COLR_BLND_FUNC; + + if ((eqnA | funcA) != (eqnRGB | funcRGB)) + iab |= ENABLE_INDPT_ALPHA_BLEND; + else + iab |= DISABLE_INDPT_ALPHA_BLEND; + + if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] || + s1 != i830->state.Ctx[I830_CTXREG_STATE1]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_IALPHAB] = iab; + i830->state.Ctx[I830_CTXREG_STATE1] = s1; + } + + /* This will catch a logicop blend equation. It will also ensure + * independant alpha blend is really in the correct state (either enabled + * or disabled) if blending is already enabled. + */ + + i830EvalLogicOpBlendState(ctx); + + if (0) { + fprintf(stderr, + "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n", + __FUNCTION__, __LINE__, i830->state.Ctx[I830_CTXREG_STATE1], + i830->state.Ctx[I830_CTXREG_IALPHAB], + (ctx->Color.BlendEnabled) ? "en" : "dis"); + } +} + + +static void +i830BlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA) +{ + DBG("%s -> %s, %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(modeRGB), + _mesa_lookup_enum_by_nr(modeA)); + + (void) modeRGB; + (void) modeA; + i830_set_blend_state(ctx); +} + + +static void +i830BlendFuncSeparate(GLcontext * ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) +{ + DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(sfactorRGB), + _mesa_lookup_enum_by_nr(dfactorRGB), + _mesa_lookup_enum_by_nr(sfactorA), + _mesa_lookup_enum_by_nr(dfactorA)); + + (void) sfactorRGB; + (void) dfactorRGB; + (void) sfactorA; + (void) dfactorA; + i830_set_blend_state(ctx); +} + + + +static void +i830DepthFunc(GLcontext * ctx, GLenum func) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + + DBG("%s\n", __FUNCTION__); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; + i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(test)); +} + +static void +i830DepthMask(GLcontext * ctx, GLboolean flag) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s flag (%d)\n", __FUNCTION__, flag); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + + if (flag && ctx->Depth.Test) + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; + else + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; +} + +/* ============================================================= + * Polygon stipple + * + * The i830 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void +i830PolygonStipple(GLcontext * ctx, const GLubyte * mask) +{ + struct i830_context *i830 = i830_context(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i, j, k; + int active = (ctx->Polygon.StippleFlag && + i830->intel.reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + for (k = 0; k < 8; k++) + for (j = 3; j >= 0; j--) + for (i = 0; i < 4; i++, m++) + if (*m != p[j]) { + i830->intel.hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + i830->intel.hw_stipple = 0; + return; + } + + i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff; + i830->state.Stipple[I830_STPREG_ST1] |= newMask; + i830->intel.hw_stipple = 1; + + if (active) + i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; +} + + +/* ============================================================= + * Hardware clipping + */ +static void +i830Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + struct i830_context *i830 = i830_context(ctx); + int x1, y1, x2, y2; + + if (!ctx->DrawBuffer) + return; + + DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + if (ctx->DrawBuffer->Name == 0) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + + x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); + + DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); + + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); + i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); +} + +static void +i830LogicOp(GLcontext * ctx, GLenum opcode) +{ + struct i830_context *i830 = i830_context(ctx); + int tmp = intel_translate_logic_op(opcode); + + DBG("%s\n", __FUNCTION__); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); +} + + + +static void +i830CullFaceFrontFace(GLcontext * ctx, GLenum unused) +{ + struct i830_context *i830 = i830_context(ctx); + GLuint mode; + + DBG("%s\n", __FUNCTION__); + + if (!ctx->Polygon.CullFlag) { + mode = CULLMODE_NONE; + } + else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = CULLMODE_CW; + + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + } + else { + mode = CULLMODE_BOTH; + } + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; +} + +static void +i830LineWidth(GLcontext * ctx, GLfloat widthf) +{ + struct i830_context *i830 = i830_context(ctx); + int width; + int state5; + + DBG("%s\n", __FUNCTION__); + + width = (int) (widthf * 2); + CLAMP_SELF(width, 1, 15); + + state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK; + state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width)); + + if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE5] = state5; + } +} + +static void +i830PointSize(GLcontext * ctx, GLfloat size) +{ + struct i830_context *i830 = i830_context(ctx); + GLint point_size = (int) size; + + DBG("%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 256); + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; + i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(point_size)); +} + + +/* ============================================================= + * Color masks + */ + +static void +i830ColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + struct i830_context *i830 = i830_context(ctx); + GLuint tmp = 0; + + DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); + + tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) | + ENABLE_COLOR_MASK | + ENABLE_COLOR_WRITE | + ((!r) << WRITEMASK_RED_SHIFT) | + ((!g) << WRITEMASK_GREEN_SHIFT) | + ((!b) << WRITEMASK_BLUE_SHIFT) | ((!a) << WRITEMASK_ALPHA_SHIFT)); + + if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp; + } +} + +static void +update_specular(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; + + if (NEED_SECONDARY_COLOR(ctx)) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; +} + +static void +i830LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + DBG("%s\n", __FUNCTION__); + + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + update_specular(ctx); + } +} + +/* In Mesa 3.5 we can reliably do native flatshading. + */ +static void +i830ShadeModel(GLcontext * ctx, GLenum mode) +{ + struct i830_context *i830 = i830_context(ctx); + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + +#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) + + i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; + + if (mode == GL_FLAT) { + i830->state.Ctx[I830_CTXREG_STATE3] |= + (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | FOG_SHADE_MODE(SHADE_MODE_FLAT) + | SPEC_SHADE_MODE(SHADE_MODE_FLAT) | + COLOR_SHADE_MODE(SHADE_MODE_FLAT)); + } + else { + i830->state.Ctx[I830_CTXREG_STATE3] |= + (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); + } +} + +/* ============================================================= + * Fog + */ +static void +i830Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s\n", __FUNCTION__); + + if (pname == GL_FOG_COLOR) { + GLuint color = (((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | + ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | + ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_FOGCOLOR] = + (_3DSTATE_FOG_COLOR_CMD | color); + } +} + +/* ============================================================= + */ + +static void +i830Enable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + struct i830_context *i830 = i830_context(ctx); + + switch (cap) { + case GL_LIGHTING: + case GL_COLOR_SUM: + update_specular(ctx); + break; + + case GL_ALPHA_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; + + break; + + case GL_BLEND: + i830EvalLogicOpBlendState(ctx); + break; + + case GL_COLOR_LOGIC_OP: + i830EvalLogicOpBlendState(ctx); + + /* Logicop doesn't seem to work at 16bpp: + */ + if (i830->intel.intelScreen->cpp == 2) + FALLBACK(&i830->intel, I830_FALLBACK_LOGICOP, state); + break; + + case GL_DITHER: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; + + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; + else + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; + break; + + case GL_DEPTH_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + + /* Also turn off depth writes when GL_DEPTH_TEST is disabled: + */ + i830DepthMask(ctx, ctx->Depth.Mask); + break; + + case GL_SCISSOR_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + + if (state) + i830->state.Buffer[I830_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); + else + i830->state.Buffer[I830_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + break; + + case GL_LINE_SMOOTH: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; + if (state) + i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE; + else + i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE; + break; + + case GL_FOG: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG; + break; + + case GL_CULL_FACE: + i830CullFaceFrontFace(ctx, 0); + break; + + case GL_TEXTURE_2D: + break; + + case GL_STENCIL_TEST: + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (irbStencil && irbStencil->region); + } + if (hw_stencil) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + if (state) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + } + else { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= + ~ENABLE_STENCIL_WRITE; + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= + DISABLE_STENCIL_WRITE; + } + } + else { + FALLBACK(&i830->intel, I830_FALLBACK_STENCIL, state); + } + } + break; + + case GL_POLYGON_STIPPLE: + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (i830->intel.hw_stipple && + i830->intel.reduced_primitive == GL_TRIANGLES) { + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + if (state) + i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; + } + break; + + default: + ; + } +} + + +static void +i830_init_packets(struct i830_context *i830) +{ + intelScreenPrivate *screen = i830->intel.intelScreen; + + /* Zero all state */ + memset(&i830->state, 0, sizeof(i830->state)); + + /* Set default blend state */ + i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | TEXBLENDOP_ARG1); + i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + + i830->state.TexBlendWordsUsed[0] = 4; + + + i830->state.Ctx[I830_CTXREG_VF] = 0; + i830->state.Ctx[I830_CTXREG_VF2] = 0; + + i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | + AA_LINE_REGION_WIDTH_1_0 | + AA_LINE_DISABLE); + + i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD | + DISABLE_LOGIC_OP | + DISABLE_STENCIL_TEST | + DISABLE_DEPTH_BIAS | + DISABLE_SPEC_ADD | + DISABLE_FOG | + DISABLE_ALPHA_TEST | + DISABLE_COLOR_BLEND | + DISABLE_DEPTH_TEST); + +#if 000 /* XXX all the stencil enable state is set in i830Enable(), right? */ + if (i830->intel.hw_stencil) { + i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | + ENABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } + else +#endif + { + i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | + DISABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } + + i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD | + ENABLE_COLR_BLND_FUNC | + BLENDFUNC_ADD | + ENABLE_SRC_BLND_FACTOR | + SRC_BLND_FACT(BLENDFACT_ONE) | + ENABLE_DST_BLND_FACTOR | + DST_BLND_FACT(BLENDFACT_ZERO)); + + i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD | + ENABLE_GLOBAL_DEPTH_BIAS | + GLOBAL_DEPTH_BIAS(0) | + ENABLE_ALPHA_TEST_FUNC | + ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) + | ALPHA_REF_VALUE(0)); + + i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD | + ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | + ENABLE_ALPHA_SHADE_MODE | + ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) + | ENABLE_FOG_SHADE_MODE | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_SPEC_SHADE_MODE | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_COLOR_SHADE_MODE | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR) + | ENABLE_CULL_MODE | CULLMODE_NONE); + + i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD | + ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_KEEP) + | + STENCIL_PASS_DEPTH_FAIL_OP + (STENCILOP_KEEP) | + STENCIL_PASS_DEPTH_PASS_OP + (STENCILOP_KEEP) | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_TEST_FUNC + (COMPAREFUNC_ALWAYS) | + ENABLE_STENCIL_REF_VALUE | + STENCIL_REF_VALUE(0)); + + i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD | FLUSH_TEXTURE_CACHE | ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF | ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */ + ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(1)); + + i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD | + DISABLE_INDPT_ALPHA_BLEND | + ENABLE_ALPHA_BLENDFUNC | + ABLENDFUNC_ADD); + + i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | + FOG_COLOR_RED(0) | + FOG_COLOR_GREEN(0) | + FOG_COLOR_BLUE(0)); + + i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0; + + i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD; + i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | + TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | + TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | + TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); + + + i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE; + + i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + + i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; + +#if 0 + switch (screen->fbFormat) { + case DV_PF_565: + i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_16_FIXED); + break; + case DV_PF_8888: + i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_24_FIXED_8_OTHER); + break; + } +#endif + i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; + i830->state.Buffer[I830_DESTREG_SR1] = 0; + i830->state.Buffer[I830_DESTREG_SR2] = 0; +} + + +void +i830InitStateFuncs(struct dd_function_table *functions) +{ + functions->AlphaFunc = i830AlphaFunc; + functions->BlendColor = i830BlendColor; + functions->BlendEquationSeparate = i830BlendEquationSeparate; + functions->BlendFuncSeparate = i830BlendFuncSeparate; + functions->ColorMask = i830ColorMask; + functions->CullFace = i830CullFaceFrontFace; + functions->DepthFunc = i830DepthFunc; + functions->DepthMask = i830DepthMask; + functions->Enable = i830Enable; + functions->Fogfv = i830Fogfv; + functions->FrontFace = i830CullFaceFrontFace; + functions->LightModelfv = i830LightModelfv; + functions->LineWidth = i830LineWidth; + functions->LogicOpcode = i830LogicOp; + functions->PointSize = i830PointSize; + functions->PolygonStipple = i830PolygonStipple; + functions->Scissor = i830Scissor; + functions->ShadeModel = i830ShadeModel; + functions->StencilFuncSeparate = i830StencilFuncSeparate; + functions->StencilMaskSeparate = i830StencilMaskSeparate; + functions->StencilOpSeparate = i830StencilOpSeparate; +} + +void +i830InitState(struct i830_context *i830) +{ + GLcontext *ctx = &i830->intel.ctx; + + i830_init_packets(i830); + + _mesa_init_driver_state(ctx); + + memcpy(&i830->initial, &i830->state, sizeof(i830->state)); + + i830->current = &i830->state; + i830->state.emitted = 0; + i830->state.active = (I830_UPLOAD_INVARIENT | + I830_UPLOAD_TEXBLEND(0) | + I830_UPLOAD_STIPPLE | + I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS); +} diff --git a/src/mesa/drivers/dri/i915/i830_tex.c b/src/mesa/drivers/dri/i915/i830_tex.c new file mode 100644 index 0000000000..fed464d1aa --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_tex.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "image.h" +#include "texstore.h" +#include "texformat.h" +#include "texmem.h" +#include "swrast/swrast.h" + +#include "mm.h" + +#include "intel_ioctl.h" + +#include "i830_context.h" +#include "i830_reg.h" + + + +static void +i830TexEnv(GLcontext * ctx, GLenum target, + GLenum pname, const GLfloat * param) +{ + + switch (pname) { + case GL_TEXTURE_ENV_COLOR: + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB: + case GL_COMBINE_ALPHA: + case GL_SOURCE0_RGB: + case GL_SOURCE1_RGB: + case GL_SOURCE2_RGB: + case GL_SOURCE0_ALPHA: + case GL_SOURCE1_ALPHA: + case GL_SOURCE2_ALPHA: + case GL_OPERAND0_RGB: + case GL_OPERAND1_RGB: + case GL_OPERAND2_RGB: + case GL_OPERAND0_ALPHA: + case GL_OPERAND1_ALPHA: + case GL_OPERAND2_ALPHA: + case GL_RGB_SCALE: + case GL_ALPHA_SCALE: + break; + + case GL_TEXTURE_LOD_BIAS:{ + struct i830_context *i830 = i830_context(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + int b = (int) ((*param) * 16.0); + if (b > 63) + b = 63; + if (b < -64) + b = -64; + I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); + i830->lodbias_tm0s3[unit] = + ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); + break; + } + + default: + break; + } +} + + + + +void +i830InitTextureFuncs(struct dd_function_table *functions) +{ + functions->TexEnv = i830TexEnv; +} diff --git a/src/mesa/drivers/dri/i915/i830_texblend.c b/src/mesa/drivers/dri/i915/i830_texblend.c new file mode 100644 index 0000000000..58f220eb7c --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_texblend.c @@ -0,0 +1,463 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" + +#include "mm.h" + +#include "intel_screen.h" +#include "intel_ioctl.h" +#include "intel_tex.h" + +#include "i830_context.h" +#include "i830_reg.h" + + +/* ================================================================ + * Texture combine functions + */ +static GLuint +pass_through(GLuint * state, GLuint blendUnit) +{ + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); + + return 4; +} + +static GLuint +emit_factor(GLuint blendUnit, GLuint * state, GLuint count, + const GLfloat * factor) +{ + GLubyte r, g, b, a; + GLuint col; + + if (0) + fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n", + blendUnit, factor[0], factor[1], factor[2], factor[3]); + + UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]); + + col = ((a << 24) | (r << 16) | (g << 8) | b); + + state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit); + state[count++] = col; + + return count; +} + + +static INLINE GLuint +GetTexelOp(GLint unit) +{ + switch (unit) { + case 0: + return TEXBLENDARG_TEXEL0; + case 1: + return TEXBLENDARG_TEXEL1; + case 2: + return TEXBLENDARG_TEXEL2; + case 3: + return TEXBLENDARG_TEXEL3; + default: + return TEXBLENDARG_TEXEL0; + } +} + + +/** + * Calculate the hardware instuctions to setup the current texture enviromnemt + * settings. Since \c gl_texture_unit::_CurrentCombine is used, both + * "classic" texture enviroments and GL_ARB_texture_env_combine type texture + * environments are treated identically. + * + * \todo + * This function should return \c GLboolean. When \c GL_FALSE is returned, + * it means that an environment is selected that the hardware cannot do. This + * is the way the Radeon and R200 drivers work. + * + * \todo + * Looking at i830_3d_regs.h, it seems the i830 can do part of + * GL_ATI_texture_env_combine3. It can handle using \c GL_ONE and + * \c GL_ZERO as combine inputs (which the code already supports). It can + * also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating + * partial support for the extension? + */ +GLuint +i830SetTexEnvCombine(struct i830_context * i830, + const struct gl_tex_env_combine_state * combine, + GLint blendUnit, + GLuint texel_op, GLuint * state, const GLfloat * factor) +{ + const GLuint numColorArgs = combine->_NumArgsRGB; + const GLuint numAlphaArgs = combine->_NumArgsA; + + GLuint blendop; + GLuint ablendop; + GLuint args_RGB[3]; + GLuint args_A[3]; + GLuint rgb_shift; + GLuint alpha_shift; + GLboolean need_factor = 0; + int i; + unsigned used; + static const GLuint tex_blend_rgb[3] = { + TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + static const GLuint tex_blend_a[3] = { + TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + + if (INTEL_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s\n", __FUNCTION__); + + + /* The EXT version of the DOT3 extension does not support the + * scale factor, but the ARB version (and the version in OpenGL + * 1.3) does. + */ + switch (combine->ModeRGB) { + case GL_DOT3_RGB_EXT: + alpha_shift = combine->ScaleShiftA; + rgb_shift = 0; + break; + + case GL_DOT3_RGBA_EXT: + alpha_shift = 0; + rgb_shift = 0; + break; + + default: + rgb_shift = combine->ScaleShiftRGB; + alpha_shift = combine->ScaleShiftA; + break; + } + + + switch (combine->ModeRGB) { + case GL_REPLACE: + blendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + blendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + blendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + blendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + blendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + blendop = TEXBLENDOP_SUBTRACT; + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGB: + blendop = TEXBLENDOP_DOT3; + break; + case GL_DOT3_RGBA_EXT: + case GL_DOT3_RGBA: + blendop = TEXBLENDOP_DOT3; + break; + default: + return pass_through(state, blendUnit); + } + + blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); + + + /* Handle RGB args */ + for (i = 0; i < 3; i++) { + switch (combine->SourceRGB[i]) { + case GL_TEXTURE: + args_RGB[i] = texel_op; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_RGB[i] = GetTexelOp(combine->SourceRGB[i] - GL_TEXTURE0); + break; + case GL_CONSTANT: + args_RGB[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_RGB[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_RGB[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through(state, blendUnit); + } + + switch (combine->OperandRGB[i]) { + case GL_SRC_COLOR: + args_RGB[i] |= 0; + break; + case GL_ONE_MINUS_SRC_COLOR: + args_RGB[i] |= TEXBLENDARG_INV_ARG; + break; + case GL_SRC_ALPHA: + args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | TEXBLENDARG_INV_ARG); + break; + default: + return pass_through(state, blendUnit); + } + } + + + /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to + * match the spec. Can't use DOT3 as it won't propogate values + * into alpha as required: + * + * Note - the global factor is set up with alpha == .5, so + * the alpha part of the DOT4 calculation should be zero. + */ + if (combine->ModeRGB == GL_DOT3_RGBA_EXT || + combine->ModeRGB == GL_DOT3_RGBA) { + ablendop = TEXBLENDOP_DOT4; + args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */ + args_A[1] = TEXBLENDARG_FACTOR; + args_A[2] = TEXBLENDARG_FACTOR; + } + else { + switch (combine->ModeA) { + case GL_REPLACE: + ablendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + ablendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + ablendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + ablendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + ablendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + ablendop = TEXBLENDOP_SUBTRACT; + break; + default: + return pass_through(state, blendUnit); + } + + + ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); + + /* Handle A args */ + for (i = 0; i < 3; i++) { + switch (combine->SourceA[i]) { + case GL_TEXTURE: + args_A[i] = texel_op; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_A[i] = GetTexelOp(combine->SourceA[i] - GL_TEXTURE0); + break; + case GL_CONSTANT: + args_A[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_A[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_A[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through(state, blendUnit); + } + + switch (combine->OperandA[i]) { + case GL_SRC_ALPHA: + args_A[i] |= 0; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_A[i] |= TEXBLENDARG_INV_ARG; + break; + default: + return pass_through(state, blendUnit); + } + } + } + + + + /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ + /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ + /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ + + /* When we render we need to figure out which is the last really enabled + * tex unit, and put last stage on it + */ + + + /* Build color & alpha pipelines */ + + used = 0; + state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | TEXOP_MODIFY_PARMS | blendop); + state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | TEXOP_MODIFY_PARMS | ablendop); + + for (i = 0; i < numColorArgs; i++) { + state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + tex_blend_rgb[i] | args_RGB[i]); + } + + for (i = 0; i < numAlphaArgs; i++) { + state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + tex_blend_a[i] | args_A[i]); + } + + + if (need_factor) + return emit_factor(blendUnit, state, used, factor); + else + return used; +} + + +static void +emit_texblend(struct i830_context *i830, GLuint unit, GLuint blendUnit, + GLboolean last_stage) +{ + struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + + + if (0) + fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); + + /* Update i830->state.TexBlend + */ + tmp_sz = i830SetTexEnvCombine(i830, texUnit->_CurrentCombine, blendUnit, + GetTexelOp(unit), tmp, texUnit->EnvColor); + + if (last_stage) + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] || + memcmp(tmp, i830->state.TexBlend[blendUnit], + tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(blendUnit)); + memcpy(i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); +} + +static void +emit_passthrough(struct i830_context *i830) +{ + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + GLuint unit = 0; + + tmp_sz = pass_through(tmp, unit); + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[unit] || + memcmp(tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(unit)); + memcpy(i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[unit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); +} + +void +i830EmitTextureBlend(struct i830_context *i830) +{ + GLcontext *ctx = &i830->intel.ctx; + GLuint unit, last_stage = 0, blendunit = 0; + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE); + + if (ctx->Texture._EnabledUnits) { + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + last_stage = unit; + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + emit_texblend(i830, unit, blendunit++, last_stage == unit); + } + else { + emit_passthrough(i830); + } +} diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c new file mode 100644 index 0000000000..7613b9d2a6 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -0,0 +1,343 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "mtypes.h" +#include "enums.h" +#include "texformat.h" +#include "dri_bufmgr.h" + +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#include "i830_context.h" +#include "i830_reg.h" + + + +static GLuint +translate_texture_format(GLuint mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case MESA_FORMAT_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case MESA_FORMAT_A8: + return MAPSURF_8BIT | MT_8BIT_I8; /* Kludge! */ + case MESA_FORMAT_AL88: + return MAPSURF_16BIT | MT_16BIT_AY88; + case MESA_FORMAT_RGB565: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case MESA_FORMAT_ARGB1555: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case MESA_FORMAT_ARGB4444: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case MESA_FORMAT_ARGB8888: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case MESA_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case MESA_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case MESA_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case MESA_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + default: + fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); + abort(); + return 0; + } +} + + + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static GLuint +translate_wrap_mode(GLenum wrap) +{ + switch (wrap) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP; /* not really correct */ + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + + +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static GLboolean +i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) +{ + GLcontext *ctx = &intel->ctx; + struct i830_context *i830 = i830_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage; + GLuint *state = i830->state.Tex[unit], format, pitch; + + memset(state, 0, sizeof(state)); + + /*We need to refcount these. */ + + if (i830->state.tex_buffer[unit] != NULL) { + dri_bo_unreference(i830->state.tex_buffer[unit]); + i830->state.tex_buffer[unit] = NULL; + } + + if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + /* Get first image here, since intelObj->firstLevel will get set in + * the intel_finalize_mipmap_tree() call above. + */ + firstImage = tObj->Image[0][intelObj->firstLevel]; + + if (intelObj->imageOverride) { + i830->state.tex_buffer[unit] = NULL; + i830->state.tex_offset[unit] = intelObj->textureOffset; + + switch (intelObj->depthOverride) { + case 32: + format = MAPSURF_32BIT | MT_32BIT_ARGB8888; + break; + case 24: + default: + format = MAPSURF_32BIT | MT_32BIT_XRGB8888; + break; + case 16: + format = MAPSURF_16BIT | MT_16BIT_RGB565; + break; + } + + pitch = intelObj->pitchOverride; + } else { + dri_bo_reference(intelObj->mt->region->buffer); + i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, + 0, intelObj-> + firstLevel); + + format = translate_texture_format(firstImage->TexFormat->MesaFormat); + pitch = intelObj->mt->pitch * intelObj->mt->cpp; + } + + state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << unit) | 4); + +/* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */ +/* t->intel.TextureOffset); */ + + + state[I830_TEXREG_TM0S1] = + (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format); + + state[I830_TEXREG_TM0S2] = + ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); + + { + if (tObj->Target == GL_TEXTURE_CUBE_MAP) + state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit) | + CUBE_NEGX_ENABLE | + CUBE_POSX_ENABLE | + CUBE_NEGY_ENABLE | + CUBE_POSY_ENABLE | + CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE); + else + state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit)); + } + + + + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + return GL_FALSE; + } + + if (tObj->MaxAnisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + return GL_FALSE; + } + } + + state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit]; + +#if 0 + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION; +#endif + + state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - + intelObj->firstLevel) * + 4) << TM0S3_MIN_MIP_SHIFT; + + state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | + (mipFilt << TM0S3_MIP_FILTER_SHIFT) | + (magFilt << TM0S3_MAG_FILTER_SHIFT)); + } + + { + GLenum ws = tObj->WrapS; + GLenum wt = tObj->WrapT; + + + /* 3D textures not available on i830 + */ + if (tObj->Target == GL_TEXTURE_3D) + return GL_FALSE; + + state[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | + MAP_UNIT(unit) | + ENABLE_TEXCOORD_PARAMS | + ss3 | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt)) + | ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(translate_wrap_mode + (ws))); + } + + + state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); + + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: + */ + I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); + return GL_TRUE; +} + + + + +void +i830UpdateTextureState(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLboolean ok = GL_TRUE; + GLuint i; + + for (i = 0; i < I830_TEX_UNITS && ok; i++) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: + case TEXTURE_CUBE_BIT: + ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_NORMAL); + break; + case TEXTURE_RECT_BIT: + ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_IN_TEXELUNITS); + break; + case 0:{ + struct i830_context *i830 = i830_context(&intel->ctx); + if (i830->state.active & I830_UPLOAD_TEX(i)) + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); + + if (i830->state.tex_buffer[i] != NULL) { + dri_bo_unreference(i830->state.tex_buffer[i]); + i830->state.tex_buffer[i] = NULL; + } + break; + } + case TEXTURE_3D_BIT: + default: + ok = GL_FALSE; + break; + } + } + + FALLBACK(intel, I830_FALLBACK_TEXTURE, !ok); + + if (ok) + i830EmitTextureBlend(i830); +} diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c new file mode 100644 index 0000000000..eecff2729f --- /dev/null +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -0,0 +1,674 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "i830_context.h" +#include "i830_reg.h" +#include "intel_batchbuffer.h" +#include "intel_regions.h" +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static GLboolean i830_check_vertex_size(struct intel_context *intel, + GLuint expected); + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, V0 ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ + intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ + intel->vertex_attr_count++; \ + v0 |= V0; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ + intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ + intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ + intel->vertex_attr_count++; \ +} while (0) + + +#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) +#define TEXBIND_SET(n, x) ((x)<<((n)*4)) + +static void +i830_render_prevalidate(struct intel_context *intel) +{ +} + +static void +i830_render_start(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + struct i830_context *i830 = i830_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + DECLARE_RENDERINPUTS(index_bitset); + GLuint v0 = _3DSTATE_VFT0_CMD; + GLuint v2 = _3DSTATE_VFT1_CMD; + GLuint mcsb1 = 0; + + RENDERINPUTS_COPY(index_bitset, tnl->render_inputs_bitset); + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + intel->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW); + intel->coloroffset = 4; + } + else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ); + intel->coloroffset = 3; + } + + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_POINTSIZE)) { + EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH); + } + + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE); + + intel->specoffset = 0; + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1) || + RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) { + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1)) { + intel->specoffset = intel->coloroffset + 1; + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC); + } + else + EMIT_PAD(3); + + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC); + else + EMIT_PAD(1); + } + + if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { + int i, count = 0; + + for (i = 0; i < I830_TEX_UNITS; i++) { + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_TEX(i))) { + GLuint sz = VB->TexCoordPtr[i]->size; + GLuint emit; + GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] & + ~TEXCOORDTYPE_MASK); + + switch (sz) { + case 1: + case 2: + emit = EMIT_2F; + sz = 2; + mcs |= TEXCOORDTYPE_CARTESIAN; + break; + case 3: + emit = EMIT_3F; + sz = 3; + mcs |= TEXCOORDTYPE_VECTOR; + break; + case 4: + emit = EMIT_3F_XYW; + sz = 3; + mcs |= TEXCOORDTYPE_HOMOGENEOUS; + break; + default: + continue; + }; + + + EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, emit, 0); + v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz)); + mcsb1 |= (count + 8) << (i * 4); + + if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) { + I830_STATECHANGE(i830, I830_UPLOAD_TEX(i)); + i830->state.Tex[i][I830_TEXREG_MCS] = mcs; + } + + count++; + } + } + + v0 |= VFT0_TEX_COUNT(count); + } + + /* Only need to change the vertex emit code if there has been a + * statechange to a new hardware vertex format: + */ + if (v0 != i830->state.Ctx[I830_CTXREG_VF] || + v2 != i830->state.Ctx[I830_CTXREG_VF2] || + mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] || + !RENDERINPUTS_EQUAL(index_bitset, i830->last_index_bitset)) { + int k; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + /* Must do this *after* statechange, so as not to affect + * buffered vertices reliant on the old state: + */ + intel->vertex_size = + _tnl_install_attrs(ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->vertex_size >>= 2; + + i830->state.Ctx[I830_CTXREG_VF] = v0; + i830->state.Ctx[I830_CTXREG_VF2] = v2; + i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1; + RENDERINPUTS_COPY(i830->last_index_bitset, index_bitset); + + k = i830_check_vertex_size(intel, intel->vertex_size); + assert(k); + } +} + +static void +i830_reduced_primitive_state(struct intel_context *intel, GLenum rprim) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint st1 = i830->state.Stipple[I830_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i830->intel.reduced_primitive = rprim; + + if (st1 != i830->state.Stipple[I830_STPREG_ST1]) { + INTEL_FIREVERTICES(intel); + + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] = st1; + } +} + +/* Pull apart the vertex format registers and figure out how large a + * vertex is supposed to be. + */ +static GLboolean +i830_check_vertex_size(struct intel_context *intel, GLuint expected) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + int vft0 = i830->current->Ctx[I830_CTXREG_VF]; + int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; + int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; + int i, sz = 0; + + switch (vft0 & VFT0_XYZW_MASK) { + case VFT0_XY: + sz = 2; + break; + case VFT0_XYZ: + sz = 3; + break; + case VFT0_XYW: + sz = 3; + break; + case VFT0_XYZW: + sz = 4; + break; + default: + fprintf(stderr, "no xyzw specified\n"); + return 0; + } + + if (vft0 & VFT0_SPEC) + sz++; + if (vft0 & VFT0_DIFFUSE) + sz++; + if (vft0 & VFT0_DEPTH_OFFSET) + sz++; + if (vft0 & VFT0_POINT_WIDTH) + sz++; + + for (i = 0; i < nrtex; i++) { + switch (vft1 & VFT1_TEX0_MASK) { + case TEXCOORDFMT_2D: + sz += 2; + break; + case TEXCOORDFMT_3D: + sz += 3; + break; + case TEXCOORDFMT_4D: + sz += 4; + break; + case TEXCOORDFMT_1D: + sz += 1; + break; + } + vft1 >>= VFT1_TEX1_SHIFT; + } + + if (sz != expected) + fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); + + return sz == expected; +} + +static void +i830_emit_invarient_state(struct intel_context *intel) +{ + BATCH_LOCALS; + + BEGIN_BATCH(40, 0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_FOG_MODE_CMD); + OUT_BATCH(FOGFUNC_ENABLE | + FOG_LINEAR_CONST | FOGSRC_INDEX_Z | ENABLE_FOG_DENSITY); + OUT_BATCH(0); + OUT_BATCH(0); + + + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(0) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(0) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(1) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(1) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(2) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(2) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(3) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(3) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); + + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + ENABLE_TRI_STRIP_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2)); + + OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM); + OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); + + OUT_BATCH(_3DSTATE_W_STATE_CMD); + OUT_BATCH(MAGIC_W_STATE_DWORD1); + OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ ); + + + OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD); + OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */ + + ADVANCE_BATCH(); +} + + +#define emit( intel, state, size ) \ +do { \ + int k; \ + BEGIN_BATCH(size / sizeof(GLuint), 0); \ + for (k = 0 ; k < size / sizeof(GLuint) ; k++) { \ + if (0) _mesa_printf(" 0x%08x\n", state[k]); \ + OUT_BATCH(state[k]); \ + } \ + ADVANCE_BATCH(); \ +} while (0) + +static GLuint +get_state_size(struct i830_hw_state *state) +{ + GLuint dirty = state->active & ~state->emitted; + GLuint sz = 0; + GLuint i; + + if (dirty & I830_UPLOAD_INVARIENT) + sz += 40 * sizeof(int); + + if (dirty & I830_UPLOAD_CTX) + sz += sizeof(state->Ctx); + + if (dirty & I830_UPLOAD_BUFFERS) + sz += sizeof(state->Buffer); + + if (dirty & I830_UPLOAD_STIPPLE) + sz += sizeof(state->Stipple); + + for (i = 0; i < I830_TEX_UNITS; i++) { + if ((dirty & I830_UPLOAD_TEX(i))) + sz += sizeof(state->Tex[i]); + + if (dirty & I830_UPLOAD_TEXBLEND(i)) + sz += state->TexBlendWordsUsed[i] * 4; + } + + return sz; +} + + +/* Push the state into the sarea and/or texture memory. + */ +static void +i830_emit_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + struct i830_hw_state *state = i830->current; + int i; + GLuint dirty; + BATCH_LOCALS; + + /* We don't hold the lock at this point, so want to make sure that + * there won't be a buffer wrap. + * + * It might be better to talk about explicit places where + * scheduling is allowed, rather than assume that it is whenever a + * batchbuffer fills up. + */ + intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); + + /* Do this here as we may have flushed the batchbuffer above, + * causing more state to be dirty! + */ + dirty = state->active & ~state->emitted; + + if (dirty & I830_UPLOAD_INVARIENT) { + DBG("I830_UPLOAD_INVARIENT:\n"); + i830_emit_invarient_state(intel); + } + + if (dirty & I830_UPLOAD_CTX) { + DBG("I830_UPLOAD_CTX:\n"); + emit(i830, state->Ctx, sizeof(state->Ctx)); + + } + + if (dirty & I830_UPLOAD_BUFFERS) { + DBG("I830_UPLOAD_BUFFERS:\n"); + BEGIN_BATCH(I830_DEST_SETUP_SIZE + 2, 0); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + state->draw_region->draw_offset); + + if (state->depth_region) { + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + state->depth_region->draw_offset); + } + + OUT_BATCH(state->Buffer[I830_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR2]); + ADVANCE_BATCH(); + } + + if (dirty & I830_UPLOAD_STIPPLE) { + DBG("I830_UPLOAD_STIPPLE:\n"); + emit(i830, state->Stipple, sizeof(state->Stipple)); + } + + for (i = 0; i < I830_TEX_UNITS; i++) { + if ((dirty & I830_UPLOAD_TEX(i))) { + DBG("I830_UPLOAD_TEX(%d):\n", i); + + BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, 0); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]); + + if (state->tex_buffer[i]) { + OUT_RELOC(state->tex_buffer[i], + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + state->tex_offset[i] | TM0S0_USE_FENCE); + } + else if (state == &i830->meta) { + assert(i == 0); + OUT_BATCH(0); + } + else { + OUT_BATCH(state->tex_offset[i]); + } + + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S3]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]); + OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]); + OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]); + } + + if (dirty & I830_UPLOAD_TEXBLEND(i)) { + DBG("I830_UPLOAD_TEXBLEND(%d): %d words\n", i, + state->TexBlendWordsUsed[i]); + emit(i830, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4); + } + } + + state->emitted |= dirty; +} + +static void +i830_destroy_context(struct intel_context *intel) +{ + GLuint i; + struct i830_context *i830 = i830_context(&intel->ctx); + + for (i = 0; i < I830_TEX_UNITS; i++) { + if (i830->state.tex_buffer[i] != NULL) { + dri_bo_unreference(i830->state.tex_buffer[i]); + i830->state.tex_buffer[i] = NULL; + } + } + + _tnl_free_vertices(&intel->ctx); +} + + +void +i830_state_draw_region(struct intel_context *intel, + struct i830_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint value; + + ASSERT(state == &i830->state || state == &i830->meta); + + if (state->draw_region != color_region) { + intel_region_release(&state->draw_region); + intel_region_reference(&state->draw_region, color_region); + } + if (state->depth_region != depth_region) { + intel_region_release(&state->depth_region); + intel_region_reference(&state->depth_region, depth_region); + } + + /* + * Set stride/cpp values + */ + if (color_region) { + state->Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I830_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(color_region->pitch * color_region->cpp) | + BUF_3D_USE_FENCE); + } + + if (depth_region) { + state->Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I830_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | + BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | + BUF_3D_USE_FENCE); + } + + /* + * Compute/set I830_DESTREG_DV1 value + */ + value = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z); /* .5 */ + + if (color_region && color_region->cpp == 4) { + value |= DV_PF_8888; + } + else { + value |= DV_PF_565; + } + if (depth_region && depth_region->cpp == 4) { + value |= DEPTH_FRMT_24_FIXED_8_OTHER; + } + else { + value |= DEPTH_FRMT_16_FIXED; + } + state->Buffer[I830_DESTREG_DV1] = value; + + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + + +} + + +static void +i830_set_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + i830_state_draw_region(intel, &i830->state, color_region, depth_region); +} + +#if 0 +static void +i830_update_color_z_regions(intelContextPtr intel, + const intelRegion * colorRegion, + const intelRegion * depthRegion) +{ + i830ContextPtr i830 = I830_CONTEXT(intel); + + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | + BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset; + + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset; +} +#endif + + +/* This isn't really handled at the moment. + */ +static void +i830_lost_hardware(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + i830->state.emitted = 0; +} + + + +static GLuint +i830_flush_cmd(void) +{ + return MI_FLUSH | FLUSH_MAP_CACHE; +} + + +static void +i830_assert_not_dirty( struct intel_context *intel ) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + struct i830_hw_state *state = i830->current; + GLuint dirty = state->active & ~state->emitted; + assert(!dirty); +} + + +void +i830InitVtbl(struct i830_context *i830) +{ + i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; + i830->intel.vtbl.destroy = i830_destroy_context; + i830->intel.vtbl.emit_state = i830_emit_state; + i830->intel.vtbl.lost_hardware = i830_lost_hardware; + i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state; + i830->intel.vtbl.set_draw_region = i830_set_draw_region; + i830->intel.vtbl.update_texture_state = i830UpdateTextureState; + i830->intel.vtbl.flush_cmd = i830_flush_cmd; + i830->intel.vtbl.render_start = i830_render_start; + i830->intel.vtbl.render_prevalidate = i830_render_prevalidate; + i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; +} diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c new file mode 100644 index 0000000000..49e30141e4 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -0,0 +1,174 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "i915_context.h" +#include "imports.h" +#include "intel_tex.h" +#include "intel_tris.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" + +#include "utils.h" +#include "i915_reg.h" + +#include "intel_regions.h" +#include "intel_batchbuffer.h" + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +static const struct dri_extension i915_extensions[] = { + {"GL_ARB_depth_texture", NULL}, + {"GL_ARB_fragment_program", NULL}, + {"GL_ARB_shadow", NULL}, + {"GL_ARB_texture_env_crossbar", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL}, + {"GL_EXT_shadow_funcs", NULL}, + /* ARB extn won't work if not enabled */ + {"GL_SGIX_depth_texture", NULL}, + {NULL, NULL} +}; + +/* Override intel default. + */ +static void +i915InvalidateState(GLcontext * ctx, GLuint new_state) +{ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); + intel_context(ctx)->NewGLState |= new_state; + + /* Todo: gather state values under which tracked parameters become + * invalidated, add callbacks for things like + * ProgramLocalParameters, etc. + */ + { + struct i915_fragment_program *p = + (struct i915_fragment_program *) ctx->FragmentProgram._Current; + if (p && p->nr_params) + p->params_uptodate = 0; + } + + if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM)) + i915_update_fog(ctx); +} + + +static void +i915InitDriverFunctions(struct dd_function_table *functions) +{ + intelInitDriverFunctions(functions); + i915InitStateFunctions(functions); + i915InitTextureFuncs(functions); + i915InitFragProgFuncs(functions); + functions->UpdateState = i915InvalidateState; +} + + + +GLboolean +i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct dd_function_table functions; + struct i915_context *i915 = + (struct i915_context *) CALLOC_STRUCT(i915_context); + struct intel_context *intel = &i915->intel; + GLcontext *ctx = &intel->ctx; + + if (!i915) + return GL_FALSE; + + if (0) + _mesa_printf("\ntexmem-0-3 branch\n\n"); + + i915InitVtbl(i915); + i915InitMetaFuncs(i915); + + i915InitDriverFunctions(&functions); + + if (!intelInitContext(intel, mesaVis, driContextPriv, + sharedContextPrivate, &functions)) { + FREE(i915); + return GL_FALSE; + } + + ctx->Const.MaxTextureUnits = I915_TEX_UNITS; + ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS; + ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS; + + + /* Advertise the full hardware capabilities. The new memory + * manager should cope much better with overload situations: + */ + ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = (1 << 11); + ctx->Const.MaxTextureUnits = I915_TEX_UNITS; + + /* GL_ARB_fragment_program limits - don't think Mesa actually + * validates programs against these, and in any case one ARB + * instruction can translate to more than one HW instruction, so + * we'll still have to check and fallback each time. + */ + ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY; + ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */ + ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT; + ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN; + ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN; + ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN + + I915_MAX_TEX_INSN); + ctx->Const.FragmentProgram.MaxNativeTexIndirections = + I915_MAX_TEX_INDIRECT; + ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ + + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; + + driInitExtensions(ctx, i915_extensions, GL_FALSE); + + + _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, + 36 * sizeof(GLfloat)); + + intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; + + i915InitState(i915); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h new file mode 100644 index 0000000000..0be2b3cc8b --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -0,0 +1,360 @@ + /************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef I915CONTEXT_INC +#define I915CONTEXT_INC + +#include "intel_context.h" + +#define I915_FALLBACK_TEXTURE 0x1000 +#define I915_FALLBACK_COLORMASK 0x2000 +#define I915_FALLBACK_STENCIL 0x4000 +#define I915_FALLBACK_STIPPLE 0x8000 +#define I915_FALLBACK_PROGRAM 0x10000 +#define I915_FALLBACK_LOGICOP 0x20000 +#define I915_FALLBACK_POLYGON_SMOOTH 0x40000 +#define I915_FALLBACK_POINT_SMOOTH 0x80000 + +#define I915_UPLOAD_CTX 0x1 +#define I915_UPLOAD_BUFFERS 0x2 +#define I915_UPLOAD_STIPPLE 0x4 +#define I915_UPLOAD_PROGRAM 0x8 +#define I915_UPLOAD_CONSTANTS 0x10 +#define I915_UPLOAD_FOG 0x20 +#define I915_UPLOAD_INVARIENT 0x40 +#define I915_UPLOAD_DEFAULTS 0x80 +#define I915_UPLOAD_TEX(i) (0x00010000<<(i)) +#define I915_UPLOAD_TEX_ALL (0x00ff0000) +#define I915_UPLOAD_TEX_0_SHIFT 16 + + +/* State structure offsets - these will probably disappear. + */ +#define I915_DESTREG_CBUFADDR0 0 +#define I915_DESTREG_CBUFADDR1 1 +#define I915_DESTREG_DBUFADDR0 3 +#define I915_DESTREG_DBUFADDR1 4 +#define I915_DESTREG_DV0 6 +#define I915_DESTREG_DV1 7 +#define I915_DESTREG_SENABLE 8 +#define I915_DESTREG_SR0 9 +#define I915_DESTREG_SR1 10 +#define I915_DESTREG_SR2 11 +#define I915_DEST_SETUP_SIZE 12 + +#define I915_CTXREG_STATE4 0 +#define I915_CTXREG_LI 1 +#define I915_CTXREG_LIS2 2 +#define I915_CTXREG_LIS4 3 +#define I915_CTXREG_LIS5 4 +#define I915_CTXREG_LIS6 5 +#define I915_CTXREG_IAB 6 +#define I915_CTXREG_BLENDCOLOR0 7 +#define I915_CTXREG_BLENDCOLOR1 8 +#define I915_CTX_SETUP_SIZE 9 + +#define I915_FOGREG_COLOR 0 +#define I915_FOGREG_MODE0 1 +#define I915_FOGREG_MODE1 2 +#define I915_FOGREG_MODE2 3 +#define I915_FOGREG_MODE3 4 +#define I915_FOG_SETUP_SIZE 5 + +#define I915_STPREG_ST0 0 +#define I915_STPREG_ST1 1 +#define I915_STP_SETUP_SIZE 2 + +#define I915_TEXREG_MS3 1 +#define I915_TEXREG_MS4 2 +#define I915_TEXREG_SS2 3 +#define I915_TEXREG_SS3 4 +#define I915_TEXREG_SS4 5 +#define I915_TEX_SETUP_SIZE 6 + +#define I915_DEFREG_C0 0 +#define I915_DEFREG_C1 1 +#define I915_DEFREG_S0 2 +#define I915_DEFREG_S1 3 +#define I915_DEFREG_Z0 4 +#define I915_DEFREG_Z1 5 +#define I915_DEF_SETUP_SIZE 6 + + +#define I915_MAX_CONSTANT 32 +#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) + + +#define I915_PROGRAM_SIZE 192 + + +/* Hardware version of a parsed fragment program. "Derived" from the + * mesa fragment_program struct. + */ +struct i915_fragment_program +{ + struct gl_fragment_program FragProg; + + GLboolean translated; + GLboolean params_uptodate; + GLboolean on_hardware; + GLboolean error; /* If program is malformed for any reason. */ + + GLuint nr_tex_indirect; + GLuint nr_tex_insn; + GLuint nr_alu_insn; + GLuint nr_decl_insn; + + + + + /* TODO: split between the stored representation of a program and + * the state used to build that representation. + */ + GLcontext *ctx; + + GLuint declarations[I915_PROGRAM_SIZE]; + GLuint program[I915_PROGRAM_SIZE]; + + GLfloat constant[I915_MAX_CONSTANT][4]; + GLuint constant_flags[I915_MAX_CONSTANT]; + GLuint nr_constants; + + GLuint *csr; /* Cursor, points into program. + */ + + GLuint *decl; /* Cursor, points into declarations. + */ + + GLuint decl_s; /* flags for which s regs need to be decl'd */ + GLuint decl_t; /* flags for which t regs need to be decl'd */ + + GLuint temp_flag; /* Tracks temporary regs which are in + * use. + */ + + GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in + * use. + */ + + + + /* Helpers for i915_fragprog.c: + */ + GLuint wpos_tex; + GLboolean depth_written; + + struct + { + GLuint reg; /* Hardware constant idx */ + const GLfloat *values; /* Pointer to tracked values */ + } param[I915_MAX_CONSTANT]; + GLuint nr_params; + + + /* Helpers for i915_texprog.c: + */ + GLuint src_texture; /* Reg containing sampled texture color, + * else UREG_BAD. + */ + + GLuint src_previous; /* Reg containing color from previous + * stage. May need to be decl'd. + */ + + GLuint last_tex_stage; /* Number of last enabled texture unit */ + + struct vertex_buffer *VB; +}; + + + + + + + +#define I915_TEX_UNITS 8 + + +struct i915_hw_state +{ + GLuint Ctx[I915_CTX_SETUP_SIZE]; + GLuint Buffer[I915_DEST_SETUP_SIZE]; + GLuint Stipple[I915_STP_SETUP_SIZE]; + GLuint Fog[I915_FOG_SETUP_SIZE]; + GLuint Defaults[I915_DEF_SETUP_SIZE]; + GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; + GLuint Constant[I915_CONSTANT_SIZE]; + GLuint ConstantSize; + GLuint Program[I915_PROGRAM_SIZE]; + GLuint ProgramSize; + + /* Region pointers for relocation: + */ + struct intel_region *draw_region; + struct intel_region *depth_region; +/* struct intel_region *tex_region[I915_TEX_UNITS]; */ + + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Will have to do this for draw and depth for + * FBO's... + */ + dri_bo *tex_buffer[I915_TEX_UNITS]; + GLuint tex_offset[I915_TEX_UNITS]; + + + GLuint active; /* I915_UPLOAD_* */ + GLuint emitted; /* I915_UPLOAD_* */ +}; + +#define I915_FOG_PIXEL 2 +#define I915_FOG_VERTEX 1 +#define I915_FOG_NONE 0 + +struct i915_context +{ + struct intel_context intel; + + GLuint last_ReallyEnabled; + GLuint vertex_fog; + GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; + + + struct i915_fragment_program *current_program; + + struct i915_hw_state meta, initial, state, *current; +}; + + +#define I915_STATECHANGE(i915, flag) \ +do { \ + INTEL_FIREVERTICES( &(i915)->intel ); \ + (i915)->state.emitted &= ~(flag); \ +} while (0) + +#define I915_ACTIVESTATE(i915, flag, mode) \ +do { \ + INTEL_FIREVERTICES( &(i915)->intel ); \ + if (mode) \ + (i915)->state.active |= (flag); \ + else \ + (i915)->state.active &= ~(flag); \ +} while (0) + + +/*====================================================================== + * i915_vtbl.c + */ +extern void i915InitVtbl(struct i915_context *i915); + +extern void +i915_state_draw_region(struct intel_context *intel, + struct i915_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region); + + + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ + intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ + s4 |= S4; \ + intel->vertex_attr_count++; \ + offset += (SZ); \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ + intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ + intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ + intel->vertex_attr_count++; \ + offset += (N); \ +} while (0) + + + +/*====================================================================== + * i915_context.c + */ +extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +/*====================================================================== + * i915_debug.c + */ +extern void i915_disassemble_program(const GLuint * program, GLuint sz); +extern void i915_print_ureg(const char *msg, GLuint ureg); + + +/*====================================================================== + * i915_state.c + */ +extern void i915InitStateFunctions(struct dd_function_table *functions); +extern void i915InitState(struct i915_context *i915); +extern void i915_update_fog(GLcontext * ctx); + + +/*====================================================================== + * i915_tex.c + */ +extern void i915UpdateTextureState(struct intel_context *intel); +extern void i915InitTextureFuncs(struct dd_function_table *functions); + +/*====================================================================== + * i915_metaops.c + */ +void i915InitMetaFuncs(struct i915_context *i915); + + +/*====================================================================== + * i915_fragprog.c + */ +extern void i915ValidateFragmentProgram(struct i915_context *i915); +extern void i915InitFragProgFuncs(struct dd_function_table *functions); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static INLINE struct i915_context * +i915_context(GLcontext * ctx) +{ + return (struct i915_context *) ctx; +} + + + +#define I915_CONTEXT(ctx) i915_context(ctx) + + + +#endif diff --git a/src/mesa/drivers/dri/i915/i915_debug.c b/src/mesa/drivers/dri/i915/i915_debug.c new file mode 100644 index 0000000000..c0e1242a0e --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_debug.c @@ -0,0 +1,843 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "imports.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_debug.h" + +#define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) + +static GLboolean debug( struct debug_stream *stream, const char *name, GLuint len ) +{ + GLuint i; + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + + if (len == 0) { + PRINTF("Error - zero length packet (0x%08x)\n", stream->ptr[0]); + assert(0); + return GL_FALSE; + } + + if (stream->print_addresses) + PRINTF("%08x: ", stream->offset); + + + PRINTF("%s (%d dwords):\n", name, len); + for (i = 0; i < len; i++) + PRINTF("\t0x%08x\n", ptr[i]); + PRINTF("\n"); + + stream->offset += len * sizeof(GLuint); + + return GL_TRUE; +} + + +static const char *get_prim_name( GLuint val ) +{ + switch (val & PRIM3D_MASK) { + case PRIM3D_TRILIST: return "TRILIST"; break; + case PRIM3D_TRISTRIP: return "TRISTRIP"; break; + case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break; + case PRIM3D_TRIFAN: return "TRIFAN"; break; + case PRIM3D_POLY: return "POLY"; break; + case PRIM3D_LINELIST: return "LINELIST"; break; + case PRIM3D_LINESTRIP: return "LINESTRIP"; break; + case PRIM3D_RECTLIST: return "RECTLIST"; break; + case PRIM3D_POINTLIST: return "POINTLIST"; break; + case PRIM3D_DIB: return "DIB"; break; + case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break; + case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break; + default: return "????"; break; + } +} + +static GLboolean debug_prim( struct debug_stream *stream, const char *name, + GLboolean dump_floats, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + const char *prim = get_prim_name( ptr[0] ); + GLuint i; + + + + PRINTF("%s %s (%d dwords):\n", name, prim, len); + PRINTF("\t0x%08x\n", ptr[0]); + for (i = 1; i < len; i++) { + if (dump_floats) + PRINTF("\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); + else + PRINTF("\t0x%08x\n", ptr[i]); + } + + + PRINTF("\n"); + + stream->offset += len * sizeof(GLuint); + + return GL_TRUE; +} + + + + +static GLboolean debug_program( struct debug_stream *stream, const char *name, GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + + if (len == 0) { + PRINTF("Error - zero length packet (0x%08x)\n", stream->ptr[0]); + assert(0); + return GL_FALSE; + } + + if (stream->print_addresses) + PRINTF("%08x: ", stream->offset); + + PRINTF("%s (%d dwords):\n", name, len); + i915_disassemble_program( ptr, len ); + + stream->offset += len * sizeof(GLuint); + return GL_TRUE; +} + + +static GLboolean debug_chain( struct debug_stream *stream, const char *name, GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint old_offset = stream->offset + len * sizeof(GLuint); + GLuint i; + + PRINTF("%s (%d dwords):\n", name, len); + for (i = 0; i < len; i++) + PRINTF("\t0x%08x\n", ptr[i]); + + stream->offset = ptr[1] & ~0x3; + + if (stream->offset < old_offset) + PRINTF("\n... skipping backwards from 0x%x --> 0x%x ...\n\n", + old_offset, stream->offset ); + else + PRINTF("\n... skipping from 0x%x --> 0x%x ...\n\n", + old_offset, stream->offset ); + + + return GL_TRUE; +} + + +static GLboolean debug_variable_length_prim( struct debug_stream *stream ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + const char *prim = get_prim_name( ptr[0] ); + GLuint i, len; + + GLushort *idx = (GLushort *)(ptr+1); + for (i = 0; idx[i] != 0xffff; i++) + ; + + len = 1+(i+2)/2; + + PRINTF("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); + for (i = 0; i < len; i++) + PRINTF("\t0x%08x\n", ptr[i]); + PRINTF("\n"); + + stream->offset += len * sizeof(GLuint); + return GL_TRUE; +} + + +#define BITS( dw, hi, lo, ... ) \ +do { \ + unsigned himask = ~0UL >> (31 - (hi)); \ + PRINTF("\t\t "); \ + PRINTF(__VA_ARGS__); \ + PRINTF(": 0x%x\n", ((dw) & himask) >> (lo)); \ +} while (0) + +#define MBZ( dw, hi, lo) do { \ + unsigned x = (dw) >> (lo); \ + unsigned lomask = (1 << (lo)) - 1; \ + unsigned himask; \ + himask = (1UL << (hi)) - 1; \ + assert ((x & himask & ~lomask) == 0); \ +} while (0) + +#define FLAG( dw, bit, ... ) \ +do { \ + if (((dw) >> (bit)) & 1) { \ + PRINTF("\t\t "); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n"); \ + } \ +} while (0) + +static GLboolean debug_load_immediate( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint bits = (ptr[0] >> 4) & 0xff; + GLuint j = 0; + + PRINTF("%s (%d dwords, flags: %x):\n", name, len, bits); + PRINTF("\t0x%08x\n", ptr[j++]); + + if (bits & (1<<0)) { + PRINTF("\t LIS0: 0x%08x\n", ptr[j]); + PRINTF("\t vb address: 0x%08x\n", (ptr[j] & ~0x3)); + BITS(ptr[j], 0, 0, "vb invalidate disable"); + j++; + } + if (bits & (1<<1)) { + PRINTF("\t LIS1: 0x%08x\n", ptr[j]); + BITS(ptr[j], 29, 24, "vb dword width"); + BITS(ptr[j], 21, 16, "vb dword pitch"); + BITS(ptr[j], 15, 0, "vb max index"); + j++; + } + if (bits & (1<<2)) { + int i; + PRINTF("\t LIS2: 0x%08x\n", ptr[j]); + for (i = 0; i < 8; i++) { + unsigned tc = (ptr[j] >> (i * 4)) & 0xf; + if (tc != 0xf) + BITS(tc, 3, 0, "tex coord %d", i); + } + j++; + } + if (bits & (1<<3)) { + PRINTF("\t LIS3: 0x%08x\n", ptr[j]); + j++; + } + if (bits & (1<<4)) { + PRINTF("\t LIS4: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 23, "point width"); + BITS(ptr[j], 22, 19, "line width"); + FLAG(ptr[j], 18, "alpha flatshade"); + FLAG(ptr[j], 17, "fog flatshade"); + FLAG(ptr[j], 16, "spec flatshade"); + FLAG(ptr[j], 15, "rgb flatshade"); + BITS(ptr[j], 14, 13, "cull mode"); + FLAG(ptr[j], 12, "vfmt: point width"); + FLAG(ptr[j], 11, "vfmt: specular/fog"); + FLAG(ptr[j], 10, "vfmt: rgba"); + FLAG(ptr[j], 9, "vfmt: depth offset"); + BITS(ptr[j], 8, 6, "vfmt: position (2==xyzw)"); + FLAG(ptr[j], 5, "force dflt diffuse"); + FLAG(ptr[j], 4, "force dflt specular"); + FLAG(ptr[j], 3, "local depth offset enable"); + FLAG(ptr[j], 2, "vfmt: fp32 fog coord"); + FLAG(ptr[j], 1, "sprite point"); + FLAG(ptr[j], 0, "antialiasing"); + j++; + } + if (bits & (1<<5)) { + PRINTF("\t LIS5: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 28, "rgba write disables"); + FLAG(ptr[j], 27, "force dflt point width"); + FLAG(ptr[j], 26, "last pixel enable"); + FLAG(ptr[j], 25, "global z offset enable"); + FLAG(ptr[j], 24, "fog enable"); + BITS(ptr[j], 23, 16, "stencil ref"); + BITS(ptr[j], 15, 13, "stencil test"); + BITS(ptr[j], 12, 10, "stencil fail op"); + BITS(ptr[j], 9, 7, "stencil pass z fail op"); + BITS(ptr[j], 6, 4, "stencil pass z pass op"); + FLAG(ptr[j], 3, "stencil write enable"); + FLAG(ptr[j], 2, "stencil test enable"); + FLAG(ptr[j], 1, "color dither enable"); + FLAG(ptr[j], 0, "logiop enable"); + j++; + } + if (bits & (1<<6)) { + PRINTF("\t LIS6: 0x%08x\n", ptr[j]); + FLAG(ptr[j], 31, "alpha test enable"); + BITS(ptr[j], 30, 28, "alpha func"); + BITS(ptr[j], 27, 20, "alpha ref"); + FLAG(ptr[j], 19, "depth test enable"); + BITS(ptr[j], 18, 16, "depth func"); + FLAG(ptr[j], 15, "blend enable"); + BITS(ptr[j], 14, 12, "blend func"); + BITS(ptr[j], 11, 8, "blend src factor"); + BITS(ptr[j], 7, 4, "blend dst factor"); + FLAG(ptr[j], 3, "depth write enable"); + FLAG(ptr[j], 2, "color write enable"); + BITS(ptr[j], 1, 0, "provoking vertex"); + j++; + } + + + PRINTF("\n"); + + assert(j == len); + + stream->offset += len * sizeof(GLuint); + + return GL_TRUE; +} + + + +static GLboolean debug_load_indirect( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint bits = (ptr[0] >> 8) & 0x3f; + GLuint i, j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); + + for (i = 0; i < 6; i++) { + if (bits & (1<offset += len * sizeof(GLuint); + + return GL_TRUE; +} + +static void BR13( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x\n", val); + FLAG(val, 30, "clipping enable"); + BITS(val, 25, 24, "color depth (3==32bpp)"); + BITS(val, 23, 16, "raster op"); + BITS(val, 15, 0, "dest pitch"); +} + + +static void BR22( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x\n", val); + BITS(val, 31, 16, "dest y1"); + BITS(val, 15, 0, "dest x1"); +} + +static void BR23( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x\n", val); + BITS(val, 31, 16, "dest y2"); + BITS(val, 15, 0, "dest x2"); +} + +static void BR09( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x -- dest address\n", val); +} + +static void BR26( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x\n", val); + BITS(val, 31, 16, "src y1"); + BITS(val, 15, 0, "src x1"); +} + +static void BR11( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x\n", val); + BITS(val, 15, 0, "src pitch"); +} + +static void BR12( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x -- src address\n", val); +} + +static void BR16( struct debug_stream *stream, + GLuint val ) +{ + PRINTF("\t0x%08x -- color\n", val); +} + +static GLboolean debug_copy_blit( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); + + BR13(stream, ptr[j++]); + BR22(stream, ptr[j++]); + BR23(stream, ptr[j++]); + BR09(stream, ptr[j++]); + BR26(stream, ptr[j++]); + BR11(stream, ptr[j++]); + BR12(stream, ptr[j++]); + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_color_blit( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); + + BR13(stream, ptr[j++]); + BR22(stream, ptr[j++]); + BR23(stream, ptr[j++]); + BR09(stream, ptr[j++]); + BR16(stream, ptr[j++]); + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_modes4( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 21, 18, "logicop func"); + FLAG(ptr[j], 17, "stencil test mask modify-enable"); + FLAG(ptr[j], 16, "stencil write mask modify-enable"); + BITS(ptr[j], 15, 8, "stencil test mask"); + BITS(ptr[j], 7, 0, "stencil write mask"); + j++; + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_map_state( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); + + { + PRINTF("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 15, 0, "map mask"); + j++; + } + + while (j < len) { + { + PRINTF("\t TMn.0: 0x%08x\n", ptr[j]); + PRINTF("\t map address: 0x%08x\n", (ptr[j] & ~0x3)); + FLAG(ptr[j], 1, "vertical line stride"); + FLAG(ptr[j], 0, "vertical line stride offset"); + j++; + } + + { + PRINTF("\t TMn.1: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 21, "height"); + BITS(ptr[j], 20, 10, "width"); + BITS(ptr[j], 9, 7, "surface format"); + BITS(ptr[j], 6, 3, "texel format"); + FLAG(ptr[j], 2, "use fence regs"); + FLAG(ptr[j], 1, "tiled surface"); + FLAG(ptr[j], 0, "tile walk ymajor"); + j++; + } + { + PRINTF("\t TMn.2: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 21, "dword pitch"); + BITS(ptr[j], 20, 15, "cube face enables"); + BITS(ptr[j], 14, 9, "max lod"); + FLAG(ptr[j], 8, "mip layout right"); + BITS(ptr[j], 7, 0, "depth"); + j++; + } + } + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_sampler_state( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); + + { + PRINTF("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 15, 0, "sampler mask"); + j++; + } + + while (j < len) { + { + PRINTF("\t TSn.0: 0x%08x\n", ptr[j]); + FLAG(ptr[j], 31, "reverse gamma"); + FLAG(ptr[j], 30, "planar to packed"); + FLAG(ptr[j], 29, "yuv->rgb"); + BITS(ptr[j], 28, 27, "chromakey index"); + BITS(ptr[j], 26, 22, "base mip level"); + BITS(ptr[j], 21, 20, "mip mode filter"); + BITS(ptr[j], 19, 17, "mag mode filter"); + BITS(ptr[j], 16, 14, "min mode filter"); + BITS(ptr[j], 13, 5, "lod bias (s4.4)"); + FLAG(ptr[j], 4, "shadow enable"); + FLAG(ptr[j], 3, "max-aniso-4"); + BITS(ptr[j], 2, 0, "shadow func"); + j++; + } + + { + PRINTF("\t TSn.1: 0x%08x\n", ptr[j]); + BITS(ptr[j], 31, 24, "min lod"); + MBZ( ptr[j], 23, 18 ); + FLAG(ptr[j], 17, "kill pixel enable"); + FLAG(ptr[j], 16, "keyed tex filter mode"); + FLAG(ptr[j], 15, "chromakey enable"); + BITS(ptr[j], 14, 12, "tcx wrap mode"); + BITS(ptr[j], 11, 9, "tcy wrap mode"); + BITS(ptr[j], 8, 6, "tcz wrap mode"); + FLAG(ptr[j], 5, "normalized coords"); + BITS(ptr[j], 4, 1, "map (surface) index"); + FLAG(ptr[j], 0, "EAST deinterlacer enable"); + j++; + } + { + PRINTF("\t TSn.2: 0x%08x (default color)\n", ptr[j]); + j++; + } + } + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_dest_vars( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); + + { + PRINTF("\t0x%08x\n", ptr[j]); + FLAG(ptr[j], 31, "early classic ztest"); + FLAG(ptr[j], 30, "opengl tex default color"); + FLAG(ptr[j], 29, "bypass iz"); + FLAG(ptr[j], 28, "lod preclamp"); + BITS(ptr[j], 27, 26, "dither pattern"); + FLAG(ptr[j], 25, "linear gamma blend"); + FLAG(ptr[j], 24, "debug dither"); + BITS(ptr[j], 23, 20, "dstorg x"); + BITS(ptr[j], 19, 16, "dstorg y"); + MBZ (ptr[j], 15, 15 ); + BITS(ptr[j], 14, 12, "422 write select"); + BITS(ptr[j], 11, 8, "cbuf format"); + BITS(ptr[j], 3, 2, "zbuf format"); + FLAG(ptr[j], 1, "vert line stride"); + FLAG(ptr[j], 1, "vert line stride offset"); + j++; + } + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean debug_buf_info( struct debug_stream *stream, + const char *name, + GLuint len ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + int j = 0; + + PRINTF("%s (%d dwords):\n", name, len); + PRINTF("\t0x%08x\n", ptr[j++]); + + { + PRINTF("\t0x%08x\n", ptr[j]); + BITS(ptr[j], 28, 28, "aux buffer id"); + BITS(ptr[j], 27, 24, "buffer id (7=depth, 3=back)"); + FLAG(ptr[j], 23, "use fence regs"); + FLAG(ptr[j], 22, "tiled surface"); + FLAG(ptr[j], 21, "tile walk ymajor"); + MBZ (ptr[j], 20, 14); + BITS(ptr[j], 13, 2, "dword pitch"); + MBZ (ptr[j], 2, 0); + j++; + } + + PRINTF("\t0x%08x -- buffer base address\n", ptr[j++]); + + stream->offset += len * sizeof(GLuint); + assert(j == len); + return GL_TRUE; +} + +static GLboolean i915_debug_packet( struct debug_stream *stream ) +{ + GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); + GLuint cmd = *ptr; + + switch (((cmd >> 29) & 0x7)) { + case 0x0: + switch ((cmd >> 23) & 0x3f) { + case 0x0: + return debug(stream, "MI_NOOP", 1); + case 0x3: + return debug(stream, "MI_WAIT_FOR_EVENT", 1); + case 0x4: + return debug(stream, "MI_FLUSH", 1); + case 0xA: + debug(stream, "MI_BATCH_BUFFER_END", 1); + return GL_FALSE; + case 0x22: + return debug(stream, "MI_LOAD_REGISTER_IMM", 3); + case 0x31: + return debug_chain(stream, "MI_BATCH_BUFFER_START", 2); + default: + break; + } + break; + case 0x1: + break; + case 0x2: + switch ((cmd >> 22) & 0xff) { + case 0x50: + return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); + case 0x53: + return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); + default: + return debug(stream, "blit command", (cmd & 0xff) + 2); + } + break; + case 0x3: + switch ((cmd >> 24) & 0x1f) { + case 0x6: + return debug(stream, "3DSTATE_ANTI_ALIASING", 1); + case 0x7: + return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1); + case 0x8: + return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2); + case 0x9: + return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1); + case 0xb: + return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1); + case 0xc: + return debug(stream, "3DSTATE_MODES5", 1); + case 0xd: + return debug_modes4(stream, "3DSTATE_MODES4", 1); + case 0x15: + return debug(stream, "3DSTATE_FOG_COLOR", 1); + case 0x16: + return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1); + case 0x1c: + /* 3DState16NP */ + switch((cmd >> 19) & 0x1f) { + case 0x10: + return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1); + case 0x11: + return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1); + default: + break; + } + break; + case 0x1d: + /* 3DStateMW */ + switch ((cmd >> 16) & 0xff) { + case 0x0: + return debug_map_state(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); + case 0x1: + return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); + case 0x4: + return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2); + case 0x5: + return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2); + case 0x6: + return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2); + case 0x7: + return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2); + case 0x80: + return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2); + case 0x81: + return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2); + case 0x83: + return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2); + case 0x85: + return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); + case 0x88: + return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2); + case 0x89: + return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2); + case 0x8e: + return debug_buf_info(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); + case 0x97: + return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2); + case 0x98: + return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2); + case 0x99: + return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2); + case 0x9a: + return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2); + case 0x9c: + return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2); + default: + assert(0); + return 0; + } + break; + case 0x1e: + if (cmd & (1 << 23)) + return debug(stream, "???", (cmd & 0xffff) + 1); + else + return debug(stream, "", 1); + break; + case 0x1f: + if ((cmd & (1 << 23)) == 0) + return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2); + else if (cmd & (1 << 17)) + { + if ((cmd & 0xffff) == 0) + return debug_variable_length_prim(stream); + else + return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1); + } + else + return debug_prim(stream, "3DPRIM (indirect sequential)", 0, 2); + break; + default: + return debug(stream, "", 0); + } + default: + assert(0); + return 0; + } + + assert(0); + return 0; +} + + + +void +i915_dump_batchbuffer( GLuint *start, + GLuint *end ) +{ + struct debug_stream stream; + GLuint bytes = (end - start) * 4; + GLboolean done = GL_FALSE; + + PRINTF("\n\nBATCH: (%d)\n", bytes / 4); + + stream.offset = 0; + stream.ptr = (char *)start; + stream.print_addresses = 0; + + while (!done && + stream.offset < bytes && + stream.offset >= 0) + { + if (!i915_debug_packet( &stream )) + break; + + assert(stream.offset <= bytes && + stream.offset >= 0); + } + + PRINTF("END-BATCH\n\n\n"); +} + + diff --git a/src/mesa/drivers/dri/i915/i915_debug.h b/src/mesa/drivers/dri/i915/i915_debug.h new file mode 100644 index 0000000000..0643a8c631 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_debug.h @@ -0,0 +1,55 @@ +/************************************************************************** + * + * 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 I915_DEBUG_H +#define I915_DEBUG_H + +struct i915_context; + +struct debug_stream +{ + unsigned offset; /* current gtt offset */ + char *ptr; /* pointer to gtt offset zero */ + char *end; /* pointer to gtt offset zero */ + unsigned print_addresses; +}; + + + +extern void i915_disassemble_program(const unsigned *program, unsigned sz); +extern void i915_print_ureg(const char *msg, unsigned ureg); + + +void +i915_dump_batchbuffer( unsigned *start, + unsigned *end ); + + +#endif diff --git a/src/mesa/drivers/dri/i915/i915_debug_fp.c b/src/mesa/drivers/dri/i915/i915_debug_fp.c new file mode 100644 index 0000000000..84347a01ef --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_debug_fp.c @@ -0,0 +1,333 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "i915_reg.h" +#include "i915_debug.h" +#include "main/imports.h" +#include "shader/program.h" +#include "shader/prog_instruction.h" +#include "shader/prog_print.h" + +#define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) + +static const char *opcodes[0x20] = { + "NOP", + "ADD", + "MOV", + "MUL", + "MAD", + "DP2ADD", + "DP3", + "DP4", + "FRC", + "RCP", + "RSQ", + "EXP", + "LOG", + "CMP", + "MIN", + "MAX", + "FLR", + "MOD", + "TRC", + "SGE", + "SLT", + "TEXLD", + "TEXLDP", + "TEXLDB", + "TEXKILL", + "DCL", + "0x1a", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x1f", +}; + + +static const int args[0x20] = { + 0, /* 0 nop */ + 2, /* 1 add */ + 1, /* 2 mov */ + 2, /* 3 m ul */ + 3, /* 4 mad */ + 3, /* 5 dp2add */ + 2, /* 6 dp3 */ + 2, /* 7 dp4 */ + 1, /* 8 frc */ + 1, /* 9 rcp */ + 1, /* a rsq */ + 1, /* b exp */ + 1, /* c log */ + 3, /* d cmp */ + 2, /* e min */ + 2, /* f max */ + 1, /* 10 flr */ + 1, /* 11 mod */ + 1, /* 12 trc */ + 2, /* 13 sge */ + 2, /* 14 slt */ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + + +static const char *regname[0x8] = { + "R", + "T", + "CONST", + "S", + "OC", + "OD", + "U", + "UNKNOWN", +}; + +static void +print_reg_type_nr(GLuint type, GLuint nr) +{ + switch (type) { + case REG_TYPE_T: + switch (nr) { + case T_DIFFUSE: + PRINTF("T_DIFFUSE"); + return; + case T_SPECULAR: + PRINTF("T_SPECULAR"); + return; + case T_FOG_W: + PRINTF("T_FOG_W"); + return; + default: + PRINTF("T_TEX%d", nr); + return; + } + case REG_TYPE_OC: + if (nr == 0) { + PRINTF("oC"); + return; + } + break; + case REG_TYPE_OD: + if (nr == 0) { + PRINTF("oD"); + return; + } + break; + default: + break; + } + + PRINTF("%s[%d]", regname[type], nr); +} + +#define REG_SWIZZLE_MASK 0x7777 +#define REG_NEGATE_MASK 0x8888 + +#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ + (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ + (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ + (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) + + +static void +print_reg_neg_swizzle(GLuint reg) +{ + int i; + + if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && + (reg & REG_NEGATE_MASK) == 0) + return; + + PRINTF("."); + + for (i = 3; i >= 0; i--) { + if (reg & (1 << ((i * 4) + 3))) + PRINTF("-"); + + switch ((reg >> (i * 4)) & 0x7) { + case 0: + PRINTF("x"); + break; + case 1: + PRINTF("y"); + break; + case 2: + PRINTF("z"); + break; + case 3: + PRINTF("w"); + break; + case 4: + PRINTF("0"); + break; + case 5: + PRINTF("1"); + break; + default: + PRINTF("?"); + break; + } + } +} + + +static void +print_src_reg(GLuint dword) +{ + GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + print_reg_neg_swizzle(dword); +} + + +static void +print_dest_reg(GLuint dword) +{ + GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) + return; + PRINTF("."); + if (dword & A0_DEST_CHANNEL_X) + PRINTF("x"); + if (dword & A0_DEST_CHANNEL_Y) + PRINTF("y"); + if (dword & A0_DEST_CHANNEL_Z) + PRINTF("z"); + if (dword & A0_DEST_CHANNEL_W) + PRINTF("w"); +} + + +#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) +#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) +#define GET_SRC2_REG(r) (r) + + +static void +print_arith_op(GLuint opcode, const GLuint * program) +{ + if (opcode != A0_NOP) { + print_dest_reg(program[0]); + if (program[0] & A0_DEST_SATURATE) + PRINTF(" = SATURATE "); + else + PRINTF(" = "); + } + + PRINTF("%s ", opcodes[opcode]); + + print_src_reg(GET_SRC0_REG(program[0], program[1])); + if (args[opcode] == 1) { + PRINTF("\n"); + return; + } + + PRINTF(", "); + print_src_reg(GET_SRC1_REG(program[1], program[2])); + if (args[opcode] == 2) { + PRINTF("\n"); + return; + } + + PRINTF(", "); + print_src_reg(GET_SRC2_REG(program[2])); + PRINTF("\n"); + return; +} + + +static void +print_tex_op(GLuint opcode, const GLuint * program) +{ + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + PRINTF(" = "); + + PRINTF("%s ", opcodes[opcode]); + + PRINTF("S[%d],", program[0] & T0_SAMPLER_NR_MASK); + + print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & + REG_TYPE_MASK, + (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); + PRINTF("\n"); +} + +static void +print_dcl_op(GLuint opcode, const GLuint * program) +{ + PRINTF("%s ", opcodes[opcode]); + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + PRINTF("\n"); +} + + +void +i915_disassemble_program(const GLuint * program, GLuint sz) +{ + GLuint size = program[0] & 0x1ff; + GLint i; + + PRINTF("\t\tBEGIN\n"); + + assert(size + 2 == sz); + + program++; + for (i = 1; i < sz; i += 3, program += 3) { + GLuint opcode = program[0] & (0x1f << 24); + + PRINTF("\t\t"); + + if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) + print_arith_op(opcode >> 24, program); + else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) + print_tex_op(opcode >> 24, program); + else if (opcode == D0_DCL) + print_dcl_op(opcode >> 24, program); + else + PRINTF("Unknown opcode 0x%x\n", opcode); + } + + PRINTF("\t\tEND\n\n"); +} + + diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c new file mode 100644 index 0000000000..4c3f2236e5 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -0,0 +1,1074 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/program.h" +#include "shader/programopt.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_program.h" + + + +/* 1, -1/3!, 1/5!, -1/7! */ +static const GLfloat sin_constants[4] = { 1.0, + -1.0 / (3 * 2 * 1), + 1.0 / (5 * 4 * 3 * 2 * 1), + -1.0 / (7 * 6 * 5 * 4 * 3 * 2 * 1) +}; + +/* 1, -1/2!, 1/4!, -1/6! */ +static const GLfloat cos_constants[4] = { 1.0, + -1.0 / (2 * 1), + 1.0 / (4 * 3 * 2 * 1), + -1.0 / (6 * 5 * 4 * 3 * 2 * 1) +}; + +/** + * Retrieve a ureg for the given source register. Will emit + * constants, apply swizzling and negation as needed. + */ +static GLuint +src_vector(struct i915_fragment_program *p, + const struct prog_src_register *source, + const struct gl_fragment_program *program) +{ + GLuint src; + + switch (source->File) { + + /* Registers: + */ + case PROGRAM_TEMPORARY: + if (source->Index >= I915_MAX_TEMPORARY) { + i915_program_error(p, "Exceeded max temporary reg"); + return 0; + } + src = UREG(REG_TYPE_R, source->Index); + break; + case PROGRAM_INPUT: + switch (source->Index) { + case FRAG_ATTRIB_WPOS: + src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); + break; + case FRAG_ATTRIB_COL0: + src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); + break; + case FRAG_ATTRIB_COL1: + src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ); + src = swizzle(src, X, Y, Z, ONE); + break; + case FRAG_ATTRIB_FOGC: + src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W); + src = swizzle(src, W, W, W, W); + break; + case FRAG_ATTRIB_TEX0: + case FRAG_ATTRIB_TEX1: + case FRAG_ATTRIB_TEX2: + case FRAG_ATTRIB_TEX3: + case FRAG_ATTRIB_TEX4: + case FRAG_ATTRIB_TEX5: + case FRAG_ATTRIB_TEX6: + case FRAG_ATTRIB_TEX7: + src = i915_emit_decl(p, REG_TYPE_T, + T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0), + D0_CHANNEL_ALL); + break; + + default: + i915_program_error(p, "Bad source->Index"); + return 0; + } + break; + + /* Various paramters and env values. All emitted to + * hardware as program constants. + */ + case PROGRAM_LOCAL_PARAM: + src = i915_emit_param4fv(p, program->Base.LocalParams[source->Index]); + break; + + case PROGRAM_ENV_PARAM: + src = + i915_emit_param4fv(p, + p->ctx->FragmentProgram.Parameters[source-> + Index]); + break; + + case PROGRAM_CONSTANT: + case PROGRAM_STATE_VAR: + case PROGRAM_NAMED_PARAM: + src = + i915_emit_param4fv(p, + program->Base.Parameters->ParameterValues[source-> + Index]); + break; + + default: + i915_program_error(p, "Bad source->File"); + return 0; + } + + src = swizzle(src, + GET_SWZ(source->Swizzle, 0), + GET_SWZ(source->Swizzle, 1), + GET_SWZ(source->Swizzle, 2), GET_SWZ(source->Swizzle, 3)); + + if (source->NegateBase) + src = negate(src, + GET_BIT(source->NegateBase, 0), + GET_BIT(source->NegateBase, 1), + GET_BIT(source->NegateBase, 2), + GET_BIT(source->NegateBase, 3)); + + return src; +} + + +static GLuint +get_result_vector(struct i915_fragment_program *p, + const struct prog_instruction *inst) +{ + switch (inst->DstReg.File) { + case PROGRAM_OUTPUT: + switch (inst->DstReg.Index) { + case FRAG_RESULT_COLR: + return UREG(REG_TYPE_OC, 0); + case FRAG_RESULT_DEPR: + p->depth_written = 1; + return UREG(REG_TYPE_OD, 0); + default: + i915_program_error(p, "Bad inst->DstReg.Index"); + return 0; + } + case PROGRAM_TEMPORARY: + return UREG(REG_TYPE_R, inst->DstReg.Index); + default: + i915_program_error(p, "Bad inst->DstReg.File"); + return 0; + } +} + +static GLuint +get_result_flags(const struct prog_instruction *inst) +{ + GLuint flags = 0; + + if (inst->SaturateMode == SATURATE_ZERO_ONE) + flags |= A0_DEST_SATURATE; + if (inst->DstReg.WriteMask & WRITEMASK_X) + flags |= A0_DEST_CHANNEL_X; + if (inst->DstReg.WriteMask & WRITEMASK_Y) + flags |= A0_DEST_CHANNEL_Y; + if (inst->DstReg.WriteMask & WRITEMASK_Z) + flags |= A0_DEST_CHANNEL_Z; + if (inst->DstReg.WriteMask & WRITEMASK_W) + flags |= A0_DEST_CHANNEL_W; + + return flags; +} + +static GLuint +translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit) +{ + switch (bit) { + case TEXTURE_1D_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_2D_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_RECT_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_3D_INDEX: + return D0_SAMPLE_TYPE_VOLUME; + case TEXTURE_CUBE_INDEX: + return D0_SAMPLE_TYPE_CUBE; + default: + i915_program_error(p, "TexSrcBit"); + return 0; + } +} + +#define EMIT_TEX( OP ) \ +do { \ + GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget ); \ + GLuint sampler = i915_emit_decl(p, REG_TYPE_S, \ + inst->TexSrcUnit, dim); \ + GLuint coord = src_vector( p, &inst->SrcReg[0], program); \ + /* Texel lookup */ \ + \ + i915_emit_texld( p, \ + get_result_vector( p, inst ), \ + get_result_flags( inst ), \ + sampler, \ + coord, \ + OP); \ +} while (0) + +#define EMIT_ARITH( OP, N ) \ +do { \ + i915_emit_arith( p, \ + OP, \ + get_result_vector( p, inst ), \ + get_result_flags( inst ), 0, \ + (N<1)?0:src_vector( p, &inst->SrcReg[0], program), \ + (N<2)?0:src_vector( p, &inst->SrcReg[1], program), \ + (N<3)?0:src_vector( p, &inst->SrcReg[2], program)); \ +} while (0) + +#define EMIT_1ARG_ARITH( OP ) EMIT_ARITH( OP, 1 ) +#define EMIT_2ARG_ARITH( OP ) EMIT_ARITH( OP, 2 ) +#define EMIT_3ARG_ARITH( OP ) EMIT_ARITH( OP, 3 ) + + +/* Possible concerns: + * + * SIN, COS -- could use another taylor step? + * LIT -- results seem a little different to sw mesa + * LOG -- different to mesa on negative numbers, but this is conformant. + * + * Parse failures -- Mesa doesn't currently give a good indication + * internally whether a particular program string parsed or not. This + * can lead to confusion -- hopefully we cope with it ok now. + * + */ +static void +upload_program(struct i915_fragment_program *p) +{ + const struct gl_fragment_program *program = + p->ctx->FragmentProgram._Current; + const struct prog_instruction *inst = program->Base.Instructions; + +/* _mesa_debug_fp_inst(program->Base.NumInstructions, inst); */ + + /* Is this a parse-failed program? Ensure a valid program is + * loaded, as the flagging of an error isn't sufficient to stop + * this being uploaded to hardware. + */ + if (inst[0].Opcode == OPCODE_END) { + GLuint tmp = i915_get_utemp(p); + i915_emit_arith(p, + A0_MOV, + UREG(REG_TYPE_OC, 0), + A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, ONE, ZERO, ONE, ONE), 0, 0); + return; + } + + while (1) { + GLuint src0, src1, src2, flags; + GLuint tmp = 0; + + switch (inst->Opcode) { + case OPCODE_ABS: + src0 = src_vector(p, &inst->SrcReg[0], program); + i915_emit_arith(p, + A0_MAX, + get_result_vector(p, inst), + get_result_flags(inst), 0, + src0, negate(src0, 1, 1, 1, 1), 0); + break; + + case OPCODE_ADD: + EMIT_2ARG_ARITH(A0_ADD); + break; + + case OPCODE_CMP: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + src2 = src_vector(p, &inst->SrcReg[2], program); + i915_emit_arith(p, A0_CMP, get_result_vector(p, inst), get_result_flags(inst), 0, src0, src2, src1); /* NOTE: order of src2, src1 */ + break; + + case OPCODE_COS: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0 / (M_PI)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (M_PI)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 + * t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * result = DP4 t0, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, Y, X, ONE), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + + break; + + case OPCODE_DP3: + EMIT_2ARG_ARITH(A0_DP3); + break; + + case OPCODE_DP4: + EMIT_2ARG_ARITH(A0_DP4); + break; + + case OPCODE_DPH: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, Y, Z, ONE), src1, 0); + break; + + case OPCODE_DST: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + /* result[0] = 1 * 1; + * result[1] = a[1] * b[1]; + * result[2] = a[2] * 1; + * result[3] = 1 * b[3]; + */ + i915_emit_arith(p, + A0_MUL, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, ONE, Y, Z, ONE), + swizzle(src1, ONE, Y, ONE, W), 0); + break; + + case OPCODE_EX2: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_FLR: + EMIT_1ARG_ARITH(A0_FLR); + break; + + case OPCODE_FRC: + EMIT_1ARG_ARITH(A0_FRC); + break; + + case OPCODE_KIL: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ + 0, src0, T0_TEXKILL); + break; + + case OPCODE_LG2: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_LOG, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_LIT: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + /* tmp = max( a.xyzw, a.00zw ) + * XXX: Clamp tmp.w to -128..128 + * tmp.y = log(tmp.y) + * tmp.y = tmp.w * tmp.y + * tmp.y = exp(tmp.y) + * result = cmp (a.11-x1, a.1x01, a.1xy1 ) + */ + i915_emit_arith(p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0, + src0, swizzle(src0, ZERO, ZERO, Z, W), 0); + + i915_emit_arith(p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, ZERO, Y, ZERO, ZERO), + swizzle(tmp, ZERO, W, ZERO, ZERO), 0); + + i915_emit_arith(p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_CMP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0), + swizzle(tmp, ONE, X, ZERO, ONE), + swizzle(tmp, ONE, X, Y, ONE)); + + break; + + case OPCODE_LRP: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + src2 = src_vector(p, &inst->SrcReg[2], program); + flags = get_result_flags(inst); + tmp = i915_get_utemp(p); + + /* b*a + c*(1-a) + * + * b*a + c - ca + * + * tmp = b*a + c, + * result = (-c)*a + tmp + */ + i915_emit_arith(p, A0_MAD, tmp, + flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2); + + i915_emit_arith(p, A0_MAD, + get_result_vector(p, inst), + flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp); + break; + + case OPCODE_MAD: + EMIT_3ARG_ARITH(A0_MAD); + break; + + case OPCODE_MAX: + EMIT_2ARG_ARITH(A0_MAX); + break; + + case OPCODE_MIN: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + i915_emit_arith(p, + A0_MAX, + tmp, flags & A0_DEST_CHANNEL_ALL, 0, + negate(src0, 1, 1, 1, 1), + negate(src1, 1, 1, 1, 1), 0); + + i915_emit_arith(p, + A0_MOV, + get_result_vector(p, inst), + flags, 0, negate(tmp, 1, 1, 1, 1), 0, 0); + break; + + case OPCODE_MOV: + EMIT_1ARG_ARITH(A0_MOV); + break; + + case OPCODE_MUL: + EMIT_2ARG_ARITH(A0_MUL); + break; + + case OPCODE_POW: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + /* XXX: masking on intermediate values, here and elsewhere. + */ + i915_emit_arith(p, + A0_LOG, + tmp, A0_DEST_CHANNEL_X, 0, + swizzle(src0, X, X, X, X), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, src1, 0); + + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, inst), + flags, 0, swizzle(tmp, X, X, X, X), 0, 0); + + break; + + case OPCODE_RCP: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_RCP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_RSQ: + + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_RSQ, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_SCS: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * scs.x = DP4 t1, sin_constants + * t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * scs.y = DP4 t1, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(src0, X, X, ONE, ONE), + swizzle(src0, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + if (inst->DstReg.WriteMask & WRITEMASK_Y) { + GLuint tmp1; + + if (inst->DstReg.WriteMask & WRITEMASK_X) + tmp1 = i915_get_utemp(p); + else + tmp1 = tmp; + + i915_emit_arith(p, + A0_MUL, + tmp1, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + A0_DEST_CHANNEL_Y, 0, + swizzle(tmp1, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + } + + if (inst->DstReg.WriteMask & WRITEMASK_X) { + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + A0_DEST_CHANNEL_X, 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + } + break; + + case OPCODE_SGE: + EMIT_2ARG_ARITH(A0_SGE); + break; + + case OPCODE_SIN: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0 / (M_PI)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (M_PI)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * result = DP4 t1.wzyx, sin_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(tmp, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + break; + + case OPCODE_SLT: + EMIT_2ARG_ARITH(A0_SLT); + break; + + case OPCODE_SUB: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + i915_emit_arith(p, + A0_ADD, + get_result_vector(p, inst), + get_result_flags(inst), 0, + src0, negate(src1, 1, 1, 1, 1), 0); + break; + + case OPCODE_SWZ: + EMIT_1ARG_ARITH(A0_MOV); /* extended swizzle handled natively */ + break; + + case OPCODE_TEX: + EMIT_TEX(T0_TEXLD); + break; + + case OPCODE_TXB: + EMIT_TEX(T0_TEXLDB); + break; + + case OPCODE_TXP: + EMIT_TEX(T0_TEXLDP); + break; + + case OPCODE_XPD: + /* Cross product: + * result.x = src0.y * src1.z - src0.z * src1.y; + * result.y = src0.z * src1.x - src0.x * src1.z; + * result.z = src0.x * src1.y - src0.y * src1.x; + * result.w = undef; + */ + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(src0, Z, X, Y, ONE), + swizzle(src1, Y, Z, X, ONE), 0); + + i915_emit_arith(p, + A0_MAD, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, Y, Z, X, ONE), + swizzle(src1, Z, X, Y, ONE), + negate(tmp, 1, 1, 1, 0)); + break; + + case OPCODE_END: + return; + + default: + i915_program_error(p, "bad opcode"); + return; + } + + inst++; + i915_release_utemps(p); + } +} + +/* Rather than trying to intercept and jiggle depth writes during + * emit, just move the value into its correct position at the end of + * the program: + */ +static void +fixup_depth_write(struct i915_fragment_program *p) +{ + if (p->depth_written) { + GLuint depth = UREG(REG_TYPE_OD, 0); + + i915_emit_arith(p, + A0_MOV, + depth, A0_DEST_CHANNEL_W, 0, + swizzle(depth, X, Y, Z, Z), 0, 0); + } +} + + +static void +check_wpos(struct i915_fragment_program *p) +{ + GLuint inputs = p->FragProg.Base.InputsRead; + GLint i; + + p->wpos_tex = -1; + + for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { + if (inputs & FRAG_BIT_TEX(i)) + continue; + else if (inputs & FRAG_BIT_WPOS) { + p->wpos_tex = i; + inputs &= ~FRAG_BIT_WPOS; + } + } + + if (inputs & FRAG_BIT_WPOS) { + i915_program_error(p, "No free texcoord for wpos value"); + } +} + + +static void +translate_program(struct i915_fragment_program *p) +{ + struct i915_context *i915 = I915_CONTEXT(p->ctx); + + i915_init_program(i915, p); + check_wpos(p); + upload_program(p); + fixup_depth_write(p); + i915_fini_program(p); + + p->translated = 1; +} + + +static void +track_params(struct i915_fragment_program *p) +{ + GLint i; + + if (p->nr_params) + _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters); + + for (i = 0; i < p->nr_params; i++) { + GLint reg = p->param[i].reg; + COPY_4V(p->constant[reg], p->param[i].values); + } + + p->params_uptodate = 1; + p->on_hardware = 0; /* overkill */ +} + + +static void +i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + return; + + if (i915->current_program) { + i915->current_program->on_hardware = 0; + i915->current_program->params_uptodate = 0; + } + + i915->current_program = p; + + assert(p->on_hardware == 0); + assert(p->params_uptodate == 0); + + } +} + +static struct gl_program * +i915NewProgram(GLcontext * ctx, GLenum target, GLuint id) +{ + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), + target, id); + + case GL_FRAGMENT_PROGRAM_ARB:{ + struct i915_fragment_program *prog = + CALLOC_STRUCT(i915_fragment_program); + if (prog) { + i915_init_program(I915_CONTEXT(ctx), prog); + + return _mesa_init_fragment_program(ctx, &prog->FragProg, + target, id); + } + else + return NULL; + } + + default: + /* Just fallback: + */ + return _mesa_new_program(ctx, target, id); + } +} + +static void +i915DeleteProgram(GLcontext * ctx, struct gl_program *prog) +{ + if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + i915->current_program = 0; + } + + _mesa_delete_program(ctx, prog); +} + + +static GLboolean +i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (!p->translated) + translate_program(p); + + return !p->error; + } + else + return GL_TRUE; +} + +static void +i915ProgramStringNotify(GLcontext * ctx, + GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + p->translated = 0; + + /* Hack: make sure fog is correctly enabled according to this + * fragment program's fog options. + */ + if (p->FragProg.FogOption) { + /* add extra instructions to do fog, then turn off FogOption field */ + _mesa_append_fog_code(ctx, &p->FragProg); + p->FragProg.FogOption = GL_NONE; + } + } + + _tnl_program_string(ctx, target, prog); +} + + +void +i915ValidateFragmentProgram(struct i915_context *i915) +{ + GLcontext *ctx = &i915->intel.ctx; + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + struct i915_fragment_program *p = + (struct i915_fragment_program *) ctx->FragmentProgram._Current; + + const GLuint inputsRead = p->FragProg.Base.InputsRead; + GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; + GLuint s2 = S2_TEXCOORD_NONE; + int i, offset = 0; + + if (i915->current_program != p) { + if (i915->current_program) { + i915->current_program->on_hardware = 0; + i915->current_program->params_uptodate = 0; + } + + i915->current_program = p; + } + + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + + if (!p->translated) + translate_program(p); + + intel->vertex_attr_count = 0; + intel->wpos_offset = 0; + intel->wpos_size = 0; + intel->coloroffset = 0; + intel->specoffset = 0; + + if (inputsRead & FRAG_BITS_TEX_ANY) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); + } + else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); + } + + if (inputsRead & FRAG_BIT_COL0) { + intel->coloroffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); + } + + if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) || + i915->vertex_fog != I915_FOG_NONE) { + + if (inputsRead & FRAG_BIT_COL1) { + intel->specoffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); + } + else + EMIT_PAD(3); + + if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); + else + EMIT_PAD(1); + } + + /* XXX this was disabled, but enabling this code helped fix the Glean + * tfragprog1 fog tests. + */ +#if 1 + if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); + } +#endif + + for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { + if (inputsRead & FRAG_BIT_TEX(i)) { + int sz = VB->TexCoordPtr[i]->size; + + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); + + EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); + } + else if (i == p->wpos_tex) { + + /* If WPOS is required, duplicate the XYZ position data in an + * unused texture coordinate: + */ + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); + + intel->wpos_offset = offset; + intel->wpos_size = 3 * sizeof(GLuint); + + EMIT_PAD(intel->wpos_size); + } + } + + if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || + s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + int k; + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + /* Must do this *after* statechange, so as not to affect + * buffered vertices reliant on the old state: + */ + intel->vertex_size = _tnl_install_attrs(&intel->ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->vertex_size >>= 2; + + i915->state.Ctx[I915_CTXREG_LIS2] = s2; + i915->state.Ctx[I915_CTXREG_LIS4] = s4; + + k = intel->vtbl.check_vertex_size(intel, intel->vertex_size); + assert(k); + } + + if (!p->params_uptodate) + track_params(p); + + if (!p->on_hardware) + i915_upload_program(i915, p); +} + +void +i915InitFragProgFuncs(struct dd_function_table *functions) +{ + functions->BindProgram = i915BindProgram; + functions->NewProgram = i915NewProgram; + functions->DeleteProgram = i915DeleteProgram; + functions->IsProgramNative = i915IsProgramNative; + functions->ProgramStringNotify = i915ProgramStringNotify; +} diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c new file mode 100644 index 0000000000..a739bd6581 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_metaops.c @@ -0,0 +1,509 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "utils.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_regions.h" +#include "intel_rotate.h" + +#include "i915_context.h" +#include "i915_reg.h" + +/* We touch almost everything: + */ +#define ACTIVE (I915_UPLOAD_INVARIENT | \ + I915_UPLOAD_CTX | \ + I915_UPLOAD_BUFFERS | \ + I915_UPLOAD_STIPPLE | \ + I915_UPLOAD_PROGRAM | \ + I915_UPLOAD_FOG | \ + I915_UPLOAD_TEX(0)) + +#define SET_STATE( i915, STATE ) \ +do { \ + i915->current->emitted &= ~ACTIVE; \ + i915->current = &i915->STATE; \ + i915->current->emitted &= ~ACTIVE; \ +} while (0) + + +static void +meta_no_stencil_write(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + +static void +meta_no_depth_write(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | + S6_DEPTH_WRITE_ENABLE); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + +static void +meta_depth_replace(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) + * ctx->Driver.DepthMask( ctx, GL_TRUE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | + S6_DEPTH_WRITE_ENABLE); + + /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; + i915->meta.Ctx[I915_CTXREG_LIS6] |= + COMPAREFUNC_ALWAYS << S6_DEPTH_TEST_FUNC_SHIFT; + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + +/* Set stencil unit to replace always with the reference value. + */ +static void +meta_stencil_replace(struct intel_context *intel, + GLuint s_mask, GLuint s_clear) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint op = STENCILOP_REPLACE; + GLuint func = COMPAREFUNC_ALWAYS; + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + + /* ctx->Driver.StencilMask( ctx, s_mask ) + */ + i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + + i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(s_mask)); + + /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK); + + i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | + (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); + + + /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) + */ + i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff)); + + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | + S5_STENCIL_TEST_FUNC_MASK); + + i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | + (func << S5_STENCIL_TEST_FUNC_SHIFT)); + + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + +static void +meta_color_mask(struct intel_context *intel, GLboolean state) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + const GLuint mask = (S5_WRITEDISABLE_RED | + S5_WRITEDISABLE_GREEN | + S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA); + + /* Copy colormask state from "regular" hw context. + */ + if (state) { + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; + i915->meta.Ctx[I915_CTXREG_LIS5] |= + (i915->state.Ctx[I915_CTXREG_LIS5] & mask); + } + else + i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + +static void +meta_import_pixel_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + memcpy(i915->meta.Fog, i915->state.Fog, I915_FOG_SETUP_SIZE * 4); + + i915->meta.Ctx[I915_CTXREG_LIS5] = i915->state.Ctx[I915_CTXREG_LIS5]; + i915->meta.Ctx[I915_CTXREG_LIS6] = i915->state.Ctx[I915_CTXREG_LIS6]; + i915->meta.Ctx[I915_CTXREG_STATE4] = i915->state.Ctx[I915_CTXREG_STATE4]; + i915->meta.Ctx[I915_CTXREG_BLENDCOLOR1] = + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]; + i915->meta.Ctx[I915_CTXREG_IAB] = i915->state.Ctx[I915_CTXREG_IAB]; + + i915->meta.Buffer[I915_DESTREG_SENABLE] = + i915->state.Buffer[I915_DESTREG_SENABLE]; + i915->meta.Buffer[I915_DESTREG_SR1] = i915->state.Buffer[I915_DESTREG_SR1]; + i915->meta.Buffer[I915_DESTREG_SR2] = i915->state.Buffer[I915_DESTREG_SR2]; + + i915->meta.emitted &= ~I915_UPLOAD_FOG; + i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + + +#define REG( type, nr ) (((type)<<5)|(nr)) + +#define REG_R(x) REG(REG_TYPE_R, x) +#define REG_T(x) REG(REG_TYPE_T, x) +#define REG_CONST(x) REG(REG_TYPE_CONST, x) +#define REG_S(x) REG(REG_TYPE_S, x) +#define REG_OC REG(REG_TYPE_OC, 0) +#define REG_OD REG(REG_TYPE_OD, 0) +#define REG_U(x) REG(REG_TYPE_U, x) + +#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) +#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) +#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) +#define REG_T_TEX(x) REG(REG_TYPE_T, x) + + +#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) +#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) +#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) +#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) +#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) +#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) +#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) + +#define T0_SAMPLER( unit ) ((unit)<ctx); + + static const GLuint prog[] = { + _3DSTATE_PIXEL_SHADER_PROGRAM, + + /* Declare incoming diffuse color: + */ + (D0_DCL | D0_DECL_REG(REG_T_DIFFUSE) | D0_CHANNEL_ALL), + D1_MBZ, + D2_MBZ, + + /* output-color = mov(t_diffuse) + */ + (A0_MOV | + A0_DEST_REG(REG_OC) | + A0_DEST_CHANNEL_ALL | A0_SRC0_REG(REG_T_DIFFUSE)), + (A1_SRC0_XYZW), + 0, + }; + + + memcpy(i915->meta.Program, prog, sizeof(prog)); + i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); + i915->meta.Program[0] |= i915->meta.ProgramSize - 2; + i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; +} + +static void +meta_texture_blend_replace(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + static const GLuint prog[] = { + _3DSTATE_PIXEL_SHADER_PROGRAM, + + /* Declare the sampler: + */ + (D0_DCL | D0_DECL_REG(REG_S(0)) | D0_SAMPLE_TYPE_2D | D0_CHANNEL_NONE), + D1_MBZ, + D2_MBZ, + + /* Declare the interpolated texture coordinate: + */ + (D0_DCL | D0_DECL_REG(REG_T_TEX(0)) | D0_CHANNEL_ALL), + D1_MBZ, + D2_MBZ, + + /* output-color = texld(sample0, texcoord0) + */ + (T0_TEXLD | T0_DEST_REG(REG_OC) | T0_SAMPLER(0)), + T1_ADDRESS_REG(REG_TYPE_T, 0), + T2_MBZ + }; + + memcpy(i915->meta.Program, prog, sizeof(prog)); + i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); + i915->meta.Program[0] |= i915->meta.ProgramSize - 2; + i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; +} + + + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +static GLboolean +meta_tex_rect_source(struct intel_context *intel, + dri_bo *buffer, + GLuint offset, + GLuint pitch, GLuint height, GLenum format, GLenum type) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint unit = 0; + GLint numLevels = 1; + GLuint *state = i915->meta.Tex[0]; + GLuint textureFormat; + GLuint cpp; + + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + + if ((pitch * cpp) & 3) { + _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); + return GL_FALSE; + } + +/* intel_region_release(&i915->meta.tex_region[0]); */ +/* intel_region_reference(&i915->meta.tex_region[0], region); */ + i915->meta.tex_buffer[0] = buffer; + i915->meta.tex_offset[0] = offset; + + state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | + ((pitch - 1) << MS3_WIDTH_SHIFT) | + textureFormat | MS3_USE_FENCE_REGS); + + state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | + MS4_CUBE_FACE_ENA_MASK | + ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); + + state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | + (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | + (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); + + state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | + (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); + + state[I915_TEXREG_SS4] = 0; + + i915->meta.emitted &= ~I915_UPLOAD_TEX(0); + return GL_TRUE; +} + + +/** + * Set the color and depth drawing region for meta ops. + */ +static void +meta_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915_state_draw_region(intel, &i915->meta, color_region, depth_region); +} + + +static void +set_vertex_format(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + i915->meta.Ctx[I915_CTXREG_LIS2] = + (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | + S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); + + i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; + + i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | S4_VFMT_XYZ); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void +install_meta_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + memcpy(&i915->meta, &i915->initial, sizeof(i915->meta)); + i915->meta.active = ACTIVE; + i915->meta.emitted = 0; + + SET_STATE(i915, meta); + set_vertex_format(intel); + meta_no_texture(intel); +} + +static void +leave_meta_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + intel_region_release(&i915->meta.draw_region); + intel_region_release(&i915->meta.depth_region); +/* intel_region_release(&i915->meta.tex_region[0]); */ + SET_STATE(i915, state); +} + + + +void +i915InitMetaFuncs(struct i915_context *i915) +{ + i915->intel.vtbl.install_meta_state = install_meta_state; + i915->intel.vtbl.leave_meta_state = leave_meta_state; + i915->intel.vtbl.meta_no_depth_write = meta_no_depth_write; + i915->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; + i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; + i915->intel.vtbl.meta_depth_replace = meta_depth_replace; + i915->intel.vtbl.meta_color_mask = meta_color_mask; + i915->intel.vtbl.meta_no_texture = meta_no_texture; + i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; + i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; + i915->intel.vtbl.meta_draw_region = meta_draw_region; + i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; +} diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c new file mode 100644 index 0000000000..ed45e4f806 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_program.c @@ -0,0 +1,515 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "tnl/t_context.h" +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_program.h" + + +#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) +#define A1_SRC0( reg ) (((reg)&UREG_MASK)<>UREG_A1_SRC1_SHIFT_LEFT) +#define A2_SRC1( reg ) (((reg)&UREG_MASK)<>UREG_A2_SRC2_SHIFT_LEFT) + +/* These are special, and don't have swizzle/negate bits. + */ +#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<temp_flag); + if (!bit) { + fprintf(stderr, "%s: out of temporaries\n", __FILE__); + exit(1); + } + + p->temp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_R, (bit - 1)); +} + + +GLuint +i915_get_utemp(struct i915_fragment_program * p) +{ + int bit = ffs(~p->utemp_flag); + if (!bit) { + fprintf(stderr, "%s: out of temporaries\n", __FILE__); + exit(1); + } + + p->utemp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_U, (bit - 1)); +} + +void +i915_release_utemps(struct i915_fragment_program *p) +{ + p->utemp_flag = ~0x7; +} + + +GLuint +i915_emit_decl(struct i915_fragment_program *p, + GLuint type, GLuint nr, GLuint d0_flags) +{ + GLuint reg = UREG(type, nr); + + if (type == REG_TYPE_T) { + if (p->decl_t & (1 << nr)) + return reg; + + p->decl_t |= (1 << nr); + } + else if (type == REG_TYPE_S) { + if (p->decl_s & (1 << nr)) + return reg; + + p->decl_s |= (1 << nr); + } + else + return reg; + + *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); + *(p->decl++) = D1_MBZ; + *(p->decl++) = D2_MBZ; + + p->nr_decl_insn++; + return reg; +} + +GLuint +i915_emit_arith(struct i915_fragment_program * p, + GLuint op, + GLuint dest, + GLuint mask, + GLuint saturate, GLuint src0, GLuint src1, GLuint src2) +{ + GLuint c[3]; + GLuint nr_const = 0; + + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); + assert(dest); + + if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) + c[nr_const++] = 0; + if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) + c[nr_const++] = 1; + if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) + c[nr_const++] = 2; + + /* Recursively call this function to MOV additional const values + * into temporary registers. Use utemp registers for this - + * currently shouldn't be possible to run out, but keep an eye on + * this. + */ + if (nr_const > 1) { + GLuint s[3], first, i, old_utemp_flag; + + s[0] = src0; + s[1] = src1; + s[2] = src2; + old_utemp_flag = p->utemp_flag; + + first = GET_UREG_NR(s[c[0]]); + for (i = 1; i < nr_const; i++) { + if (GET_UREG_NR(s[c[i]]) != first) { + GLuint tmp = i915_get_utemp(p); + + i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, + s[c[i]], 0, 0); + s[c[i]] = tmp; + } + } + + src0 = s[0]; + src1 = s[1]; + src2 = s[2]; + p->utemp_flag = old_utemp_flag; /* restore */ + } + + *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); + *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); + *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); + + p->nr_alu_insn++; + return dest; +} + +GLuint i915_emit_texld( struct i915_fragment_program *p, + GLuint dest, + GLuint destmask, + GLuint sampler, + GLuint coord, + GLuint op ) +{ + if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { + /* No real way to work around this in the general case - need to + * allocate and declare a new temporary register (a utemp won't + * do). Will fallback for now. + */ + i915_program_error(p, "Can't (yet) swizzle TEX arguments"); + return 0; + } + + /* Don't worry about saturate as we only support + */ + if (destmask != A0_DEST_CHANNEL_ALL) { + GLuint tmp = i915_get_utemp(p); + i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); + i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); + return dest; + } + else { + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); + + if (GET_UREG_TYPE(coord) != REG_TYPE_T) { + p->nr_tex_indirect++; + } + + *(p->csr++) = (op | + T0_DEST( dest ) | + T0_SAMPLER( sampler )); + + *(p->csr++) = T1_ADDRESS_REG( coord ); + *(p->csr++) = T2_MBZ; + + p->nr_tex_insn++; + return dest; + } +} + + +GLuint +i915_emit_const1f(struct i915_fragment_program * p, GLfloat c0) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); + if (c0 == 1.0) + return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 4; idx++) { + if (!(p->constant_flags[reg] & (1 << idx)) || + p->constant[reg][idx] == c0) { + p->constant[reg][idx] = c0; + p->constant_flags[reg] |= 1 << idx; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); + } + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + +GLuint +i915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); + if (c0 == 1.0) + return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); + + if (c1 == 0.0) + return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); + if (c1 == 1.0) + return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf || + p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 3; idx++) { + if (!(p->constant_flags[reg] & (3 << idx))) { + p->constant[reg][idx] = c0; + p->constant[reg][idx + 1] = c1; + p->constant_flags[reg] |= 3 << idx; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, + ONE); + } + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + + +GLuint +i915_emit_const4f(struct i915_fragment_program * p, + GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3) +{ + GLint reg; + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf && + p->constant[reg][0] == c0 && + p->constant[reg][1] == c1 && + p->constant[reg][2] == c2 && p->constant[reg][3] == c3) { + return UREG(REG_TYPE_CONST, reg); + } + else if (p->constant_flags[reg] == 0) { + p->constant[reg][0] = c0; + p->constant[reg][1] = c1; + p->constant[reg][2] = c2; + p->constant[reg][3] = c3; + p->constant_flags[reg] = 0xf; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + +GLuint +i915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c) +{ + return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); +} + + +GLuint +i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values) +{ + GLint reg, i; + + for (i = 0; i < p->nr_params; i++) { + if (p->param[i].values == values) + return UREG(REG_TYPE_CONST, p->param[i].reg); + } + + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0) { + p->constant_flags[reg] = I915_CONSTFLAG_PARAM; + i = p->nr_params++; + + p->param[i].values = values; + p->param[i].reg = reg; + p->params_uptodate = 0; + + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + + +void +i915_program_error(struct i915_fragment_program *p, const char *msg) +{ + _mesa_problem(NULL, "i915_program_error: %s", msg); + p->error = 1; +} + + +void +i915_init_program(struct i915_context *i915, struct i915_fragment_program *p) +{ + GLcontext *ctx = &i915->intel.ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + + p->translated = 0; + p->params_uptodate = 0; + p->on_hardware = 0; + p->error = 0; + + p->nr_tex_indirect = 1; /* correct? */ + p->nr_tex_insn = 0; + p->nr_alu_insn = 0; + p->nr_decl_insn = 0; + + p->ctx = ctx; + memset(p->constant_flags, 0, sizeof(p->constant_flags)); + + p->nr_constants = 0; + p->csr = p->program; + p->decl = p->declarations; + p->decl_s = 0; + p->decl_t = 0; + p->temp_flag = 0xffff000; + p->utemp_flag = ~0x7; + p->wpos_tex = -1; + p->depth_written = 0; + p->nr_params = 0; + + p->src_texture = UREG_BAD; + p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE); + p->last_tex_stage = 0; + p->VB = &tnl->vb; + + *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; +} + + +void +i915_fini_program(struct i915_fragment_program *p) +{ + GLuint program_size = p->csr - p->program; + GLuint decl_size = p->decl - p->declarations; + + if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) + i915_program_error(p, "Exceeded max nr indirect texture lookups"); + + if (p->nr_tex_insn > I915_MAX_TEX_INSN) + i915_program_error(p, "Exceeded max TEX instructions"); + + if (p->nr_alu_insn > I915_MAX_ALU_INSN) + i915_program_error(p, "Exceeded max ALU instructions"); + + if (p->nr_decl_insn > I915_MAX_DECL_INSN) + i915_program_error(p, "Exceeded max DECL instructions"); + + if (p->error) { + p->FragProg.Base.NumNativeInstructions = 0; + p->FragProg.Base.NumNativeAluInstructions = 0; + p->FragProg.Base.NumNativeTexInstructions = 0; + p->FragProg.Base.NumNativeTexIndirections = 0; + } + else { + p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + + p->nr_tex_insn + + p->nr_decl_insn); + p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn; + p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn; + p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect; + } + + p->declarations[0] |= program_size + decl_size - 2; +} + +void +i915_upload_program(struct i915_context *i915, + struct i915_fragment_program *p) +{ + GLuint program_size = p->csr - p->program; + GLuint decl_size = p->decl - p->declarations; + + FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error); + + /* Could just go straight to the batchbuffer from here: + */ + if (i915->state.ProgramSize != (program_size + decl_size) || + memcmp(i915->state.Program + decl_size, p->program, + program_size * sizeof(int)) != 0) { + I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM); + memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int)); + memcpy(i915->state.Program + decl_size, p->program, + program_size * sizeof(int)); + i915->state.ProgramSize = decl_size + program_size; + } + + /* Always seemed to get a failure if I used memcmp() to + * shortcircuit this state upload. Needs further investigation? + */ + if (p->nr_constants) { + GLuint nr = p->nr_constants; + + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); + I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); + + i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); + i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1); + + memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr)); + i915->state.ConstantSize = 2 + (nr) * 4; + + if (0) { + GLuint i; + for (i = 0; i < nr; i++) { + fprintf(stderr, "const[%d]: %f %f %f %f\n", i, + p->constant[i][0], + p->constant[i][1], p->constant[i][2], p->constant[i][3]); + } + } + } + else { + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); + } + + p->on_hardware = 1; +} diff --git a/src/mesa/drivers/dri/i915/i915_program.h b/src/mesa/drivers/dri/i915/i915_program.h new file mode 100644 index 0000000000..3c12b34f16 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_program.h @@ -0,0 +1,160 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef I915_PROGRAM_H +#define I915_PROGRAM_H + +#include "i915_context.h" +#include "i915_reg.h" + + + +/* Having zero and one in here makes the definition of swizzle a lot + * easier. + */ +#define UREG_TYPE_SHIFT 29 +#define UREG_NR_SHIFT 24 +#define UREG_CHANNEL_X_NEGATE_SHIFT 23 +#define UREG_CHANNEL_X_SHIFT 20 +#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 +#define UREG_CHANNEL_Y_SHIFT 16 +#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 +#define UREG_CHANNEL_Z_SHIFT 12 +#define UREG_CHANNEL_W_NEGATE_SHIFT 11 +#define UREG_CHANNEL_W_SHIFT 8 +#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 +#define UREG_CHANNEL_ZERO_SHIFT 4 +#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 +#define UREG_CHANNEL_ONE_SHIFT 0 + +#define UREG_BAD 0xffffffff /* not a valid ureg */ + +#define X SRC_X +#define Y SRC_Y +#define Z SRC_Z +#define W SRC_W +#define ZERO SRC_ZERO +#define ONE SRC_ONE + +/* Construct a ureg: + */ +#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ + ((nr) << UREG_NR_SHIFT) | \ + (X << UREG_CHANNEL_X_SHIFT) | \ + (Y << UREG_CHANNEL_Y_SHIFT) | \ + (Z << UREG_CHANNEL_Z_SHIFT) | \ + (W << UREG_CHANNEL_W_SHIFT) | \ + (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ + (ONE << UREG_CHANNEL_ONE_SHIFT)) + +#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) +#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) + +#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) +#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) + + + +#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 + +/* One neat thing about the UREG representation: + */ +static INLINE int +swizzle(int reg, int x, int y, int z, int w) +{ + return ((reg & ~UREG_XYZW_CHANNEL_MASK) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); +} + +/* Another neat thing about the UREG representation: + */ +static INLINE int +negate(int reg, int x, int y, int z, int w) +{ + return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) | + ((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) | + ((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) | + ((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT)); +} + + +extern GLuint i915_get_temp(struct i915_fragment_program *p); +extern GLuint i915_get_utemp(struct i915_fragment_program *p); +extern void i915_release_utemps(struct i915_fragment_program *p); + + +extern GLuint i915_emit_texld(struct i915_fragment_program *p, + GLuint dest, + GLuint destmask, + GLuint sampler, GLuint coord, GLuint op); + +extern GLuint i915_emit_arith(struct i915_fragment_program *p, + GLuint op, + GLuint dest, + GLuint mask, + GLuint saturate, + GLuint src0, GLuint src1, GLuint src2); + +extern GLuint i915_emit_decl(struct i915_fragment_program *p, + GLuint type, GLuint nr, GLuint d0_flags); + + +extern GLuint i915_emit_const1f(struct i915_fragment_program *p, GLfloat c0); + +extern GLuint i915_emit_const2f(struct i915_fragment_program *p, + GLfloat c0, GLfloat c1); + +extern GLuint i915_emit_const4fv(struct i915_fragment_program *p, + const GLfloat * c); + +extern GLuint i915_emit_const4f(struct i915_fragment_program *p, + GLfloat c0, GLfloat c1, + GLfloat c2, GLfloat c3); + + +extern GLuint i915_emit_param4fv(struct i915_fragment_program *p, + const GLfloat * values); + +extern void i915_program_error(struct i915_fragment_program *p, + const char *msg); + +extern void i915_init_program(struct i915_context *i915, + struct i915_fragment_program *p); + +extern void i915_upload_program(struct i915_context *i915, + struct i915_fragment_program *p); + +extern void i915_fini_program(struct i915_fragment_program *p); + + + + +#endif diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h new file mode 100644 index 0000000000..a9fa56e8a6 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_reg.h @@ -0,0 +1,866 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef _I915_REG_H_ +#define _I915_REG_H_ + + +#include "intel_reg.h" + +#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define CMD_3D (0x3<<29) + +#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_CLEAR_RECT (0xa<<18) +#define PRIM3D_ZONE_INIT (0xd<<18) +#define PRIM3D_MASK (0x1f<<18) + +/* p137 */ +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) + +/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ +#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) +#define BFO_ENABLE_STENCIL_REF (1<<23) +#define BFO_STENCIL_REF_SHIFT 15 +#define BFO_STENCIL_REF_MASK (0xff<<15) +#define BFO_ENABLE_STENCIL_FUNCS (1<<14) +#define BFO_STENCIL_TEST_SHIFT 11 +#define BFO_STENCIL_TEST_MASK (0x7<<11) +#define BFO_STENCIL_FAIL_SHIFT 8 +#define BFO_STENCIL_FAIL_MASK (0x7<<8) +#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 +#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) +#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 +#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) +#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) +#define BFO_STENCIL_TWO_SIDE (1<<0) + + +/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ +#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) +#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) +#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) +#define BFM_STENCIL_TEST_MASK_SHIFT 8 +#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) +#define BFM_STENCIL_WRITE_MASK_SHIFT 0 +#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) + + + +/* 3DSTATE_BIN_CONTROL p141 */ + +/* p143 */ +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +/* 3DSTATE_CHROMA_KEY */ + +/* 3DSTATE_CLEAR_PARAMETERS, p150 */ +/* + * Sets the color, depth and stencil clear values used by the + * CLEAR_RECT and ZONE_INIT primitive types, respectively. These + * primitives set override most 3d state and only take a minimal x/y + * vertex. The color/z/stencil information is supplied here and + * therefore cannot vary per vertex. + */ +#define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) +/* Dword 1 */ +#define CLEARPARAM_CLEAR_RECT (1 << 16) +#define CLEARPARAM_ZONE_INIT (0 << 16) +#define CLEARPARAM_WRITE_COLOR (1 << 2) +#define CLEARPARAM_WRITE_DEPTH (1 << 1) +#define CLEARPARAM_WRITE_STENCIL (1 << 0) + +/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + + + +/* 3DSTATE_COORD_SET_BINDINGS, p154 */ +#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) +#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) + +/* p156 */ +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +/* p157 */ +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +/* p158 */ +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ +#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) +/* scale in dword 1 */ + + +/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ +#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | 0x2) + +/* p161 */ +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define TEX_DEFAULT_COLOR_OGL (0<<30) +#define TEX_DEFAULT_COLOR_D3D (1<<30) +#define ZR_EARLY_DEPTH (1<<29) +#define LOD_PRECLAMP_OGL (1<<28) +#define LOD_PRECLAMP_D3D (0<<28) +#define DITHER_FULL_ALWAYS (0<<26) +#define DITHER_FULL_ON_FB_BLEND (1<<26) +#define DITHER_CLAMPED_ALWAYS (2<<26) +#define LINEAR_GAMMA_BLEND_32BPP (1<<25) +#define DEBUG_DISABLE_ENH_DITHER (1<<24) +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 (0<<1) +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + +/* p166 */ +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ + +/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ + + +/* _3DSTATE_FOG_COLOR, p173 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p174 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) +#define FMC1_FOGFUNC_VERTEX (0<<28) +#define FMC1_FOGFUNC_PIXEL_EXP (1<<28) +#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) +#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) +#define FMC1_FOGFUNC_MASK (3<<28) +#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) +#define FMC1_FOGINDEX_Z (0<<25) +#define FMC1_FOGINDEX_W (1<<25) +#define FMC1_C1_C2_MODIFY_ENABLE (1<<24) +#define FMC1_DENSITY_MODIFY_ENABLE (1<<23) +#define FMC1_C1_ONE (1<<13) +#define FMC1_C1_MASK (0xffff<<4) +/* Dword 2 */ +#define FMC2_C2_ONE (1<<16) +/* Dword 3 */ +#define FMC3_D_ONE (1<<16) + + + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ +#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define IAB_MODIFY_ENABLE (1<<23) +#define IAB_ENABLE (1<<22) +#define IAB_MODIFY_FUNC (1<<21) +#define IAB_FUNC_SHIFT 16 +#define IAB_MODIFY_SRC_FACTOR (1<<11) +#define IAB_SRC_FACTOR_SHIFT 6 +#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) +#define IAB_MODIFY_DST_FACTOR (1<<5) +#define IAB_DST_FACTOR_SHIFT 0 +#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) + + +#define BLENDFUNC_ADD 0x0 +#define BLENDFUNC_SUBTRACT 0x1 +#define BLENDFUNC_REVERSE_SUBTRACT 0x2 +#define BLENDFUNC_MIN 0x3 +#define BLENDFUNC_MAX 0x4 +#define BLENDFUNC_MASK 0x7 + +/* 3DSTATE_LOAD_INDIRECT, p180 */ + +#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) +#define LI0_STATE_STATIC_INDIRECT (0x01<<8) +#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) +#define LI0_STATE_SAMPLER (0x04<<8) +#define LI0_STATE_MAP (0x08<<8) +#define LI0_STATE_PROGRAM (0x10<<8) +#define LI0_STATE_CONSTANTS (0x20<<8) + +#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SIS0_FORCE_LOAD (1<<1) +#define SIS0_BUFFER_VALID (1<<0) +#define SIS1_BUFFER_LENGTH(x) ((x)&0xff) + +#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define DIS0_BUFFER_RESET (1<<1) +#define DIS0_BUFFER_VALID (1<<0) + +#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SSB0_FORCE_LOAD (1<<1) +#define SSB0_BUFFER_VALID (1<<0) +#define SSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define MSB0_FORCE_LOAD (1<<1) +#define MSB0_BUFFER_VALID (1<<0) +#define MSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSP0_FORCE_LOAD (1<<1) +#define PSP0_BUFFER_VALID (1<<0) +#define PSP1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSC0_FORCE_LOAD (1<<1) +#define PSC0_BUFFER_VALID (1<<0) +#define PSC1_BUFFER_LENGTH(x) ((x)&0xff) + + + + + +/* _3DSTATE_RASTERIZATION_RULES */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_TEXKILL_3D_4D (1<<10) +#define TEXKILL_3D (0<<9) +#define TEXKILL_4D (1<<9) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) + +/* _3DSTATE_SCISSOR_ENABLE, p256 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* p189 */ +#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) +#define I1_LOAD_S(n) (1<<(4+n)) + +#define S0_VB_OFFSET_MASK 0xffffffc +#define S0_AUTO_CACHE_INV_DISABLE (1<<0) + +#define S1_VERTEX_WIDTH_SHIFT 24 +#define S1_VERTEX_WIDTH_MASK (0x3f<<24) +#define S1_VERTEX_PITCH_SHIFT 16 +#define S1_VERTEX_PITCH_MASK (0x3f<<16) + +#define TEXCOORDFMT_2D 0x0 +#define TEXCOORDFMT_3D 0x1 +#define TEXCOORDFMT_4D 0x2 +#define TEXCOORDFMT_1D 0x3 +#define TEXCOORDFMT_2D_16 0x4 +#define TEXCOORDFMT_4D_16 0x5 +#define TEXCOORDFMT_NOT_PRESENT 0xf +#define S2_TEXCOORD_FMT0_MASK 0xf +#define S2_TEXCOORD_FMT1_SHIFT 4 +#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) +#define S2_TEXCOORD_NONE (~0) + +/* S3 not interesting */ + +#define S4_POINT_WIDTH_SHIFT 23 +#define S4_POINT_WIDTH_MASK (0x1ff<<23) +#define S4_LINE_WIDTH_SHIFT 19 +#define S4_LINE_WIDTH_ONE (0x2<<19) +#define S4_LINE_WIDTH_MASK (0xf<<19) +#define S4_FLATSHADE_ALPHA (1<<18) +#define S4_FLATSHADE_FOG (1<<17) +#define S4_FLATSHADE_SPECULAR (1<<16) +#define S4_FLATSHADE_COLOR (1<<15) +#define S4_CULLMODE_BOTH (0<<13) +#define S4_CULLMODE_NONE (1<<13) +#define S4_CULLMODE_CW (2<<13) +#define S4_CULLMODE_CCW (3<<13) +#define S4_CULLMODE_MASK (3<<13) +#define S4_VFMT_POINT_WIDTH (1<<12) +#define S4_VFMT_SPEC_FOG (1<<11) +#define S4_VFMT_COLOR (1<<10) +#define S4_VFMT_DEPTH_OFFSET (1<<9) +#define S4_VFMT_XYZ (1<<6) +#define S4_VFMT_XYZW (2<<6) +#define S4_VFMT_XY (3<<6) +#define S4_VFMT_XYW (4<<6) +#define S4_VFMT_XYZW_MASK (7<<6) +#define S4_FORCE_DEFAULT_DIFFUSE (1<<5) +#define S4_FORCE_DEFAULT_SPECULAR (1<<4) +#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) +#define S4_VFMT_FOG_PARAM (1<<2) +#define S4_SPRITE_POINT_ENABLE (1<<1) +#define S4_LINE_ANTIALIAS_ENABLE (1<<0) + +#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ + S4_VFMT_SPEC_FOG | \ + S4_VFMT_COLOR | \ + S4_VFMT_DEPTH_OFFSET | \ + S4_VFMT_XYZW_MASK | \ + S4_VFMT_FOG_PARAM) + + +#define S5_WRITEDISABLE_ALPHA (1<<31) +#define S5_WRITEDISABLE_RED (1<<30) +#define S5_WRITEDISABLE_GREEN (1<<29) +#define S5_WRITEDISABLE_BLUE (1<<28) +#define S5_WRITEDISABLE_MASK (0xf<<28) +#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) +#define S5_LAST_PIXEL_ENABLE (1<<26) +#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) +#define S5_FOG_ENABLE (1<<24) +#define S5_STENCIL_REF_SHIFT 16 +#define S5_STENCIL_REF_MASK (0xff<<16) +#define S5_STENCIL_TEST_FUNC_SHIFT 13 +#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) +#define S5_STENCIL_FAIL_SHIFT 10 +#define S5_STENCIL_FAIL_MASK (0x7<<10) +#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 +#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) +#define S5_STENCIL_PASS_Z_PASS_SHIFT 4 +#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) +#define S5_STENCIL_WRITE_ENABLE (1<<3) +#define S5_STENCIL_TEST_ENABLE (1<<2) +#define S5_COLOR_DITHER_ENABLE (1<<1) +#define S5_LOGICOP_ENABLE (1<<0) + + +#define S6_ALPHA_TEST_ENABLE (1<<31) +#define S6_ALPHA_TEST_FUNC_SHIFT 28 +#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) +#define S6_ALPHA_REF_SHIFT 20 +#define S6_ALPHA_REF_MASK (0xff<<20) +#define S6_DEPTH_TEST_ENABLE (1<<19) +#define S6_DEPTH_TEST_FUNC_SHIFT 16 +#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) +#define S6_CBUF_BLEND_ENABLE (1<<15) +#define S6_CBUF_BLEND_FUNC_SHIFT 12 +#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) +#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 +#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) +#define S6_CBUF_DST_BLEND_FACT_SHIFT 4 +#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) +#define S6_DEPTH_WRITE_ENABLE (1<<3) +#define S6_COLOR_WRITE_ENABLE (1<<2) +#define S6_TRISTRIP_PV_SHIFT 0 +#define S6_TRISTRIP_PV_MASK (0x3<<0) + +#define S7_DEPTH_OFFSET_CONST_MASK ~0 + + +/* Helper macros for blend factors + */ +#define DST_BLND_FACT(f) ((f)<= 0.0) ? src1 : src2 */ +#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ +#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ +#define A0_FLR (0x10<<24) /* dst = floor(src0) */ +#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ +#define A0_TRC (0x12<<24) /* dst = int(src0) */ +#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ +#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ +#define A0_DEST_SATURATE (1<<22) +#define A0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +#define A0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define A0_DEST_CHANNEL_X (1<<10) +#define A0_DEST_CHANNEL_Y (2<<10) +#define A0_DEST_CHANNEL_Z (4<<10) +#define A0_DEST_CHANNEL_W (8<<10) +#define A0_DEST_CHANNEL_ALL (0xf<<10) +#define A0_DEST_CHANNEL_SHIFT 10 +#define A0_SRC0_TYPE_SHIFT 7 +#define A0_SRC0_NR_SHIFT 2 + +#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) +#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) + + +#define SRC_X 0 +#define SRC_Y 1 +#define SRC_Z 2 +#define SRC_W 3 +#define SRC_ZERO 4 +#define SRC_ONE 5 + +#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) +#define A1_SRC0_CHANNEL_X_SHIFT 28 +#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) +#define A1_SRC0_CHANNEL_Y_SHIFT 24 +#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) +#define A1_SRC0_CHANNEL_Z_SHIFT 20 +#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) +#define A1_SRC0_CHANNEL_W_SHIFT 16 +#define A1_SRC1_TYPE_SHIFT 13 +#define A1_SRC1_NR_SHIFT 8 +#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) +#define A1_SRC1_CHANNEL_X_SHIFT 4 +#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) +#define A1_SRC1_CHANNEL_Y_SHIFT 0 + +#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) +#define A2_SRC1_CHANNEL_Z_SHIFT 28 +#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) +#define A2_SRC1_CHANNEL_W_SHIFT 24 +#define A2_SRC2_TYPE_SHIFT 21 +#define A2_SRC2_NR_SHIFT 16 +#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) +#define A2_SRC2_CHANNEL_X_SHIFT 12 +#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) +#define A2_SRC2_CHANNEL_Y_SHIFT 8 +#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) +#define A2_SRC2_CHANNEL_Z_SHIFT 4 +#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) +#define A2_SRC2_CHANNEL_W_SHIFT 0 + + + +/* Texture instructions */ +#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared + * sampler and address, and output + * filtered texel data to destination + * register */ +#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a + * perspective divide of the texture + * coordinate .xyz values by .w before + * sampling. */ +#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the + * computed LOD by w. Only S4.6 two's + * comp is used. This implies that a + * float to fixed conversion is + * done. */ +#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling + * operation. Simply kills the pixel + * if any channel of the address + * register is < 0.0. */ +#define T0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +/* Note: U (unpreserved) regs do not retain their values between + * phases (cannot be used for feedback) + * + * Note: oC and OD registers can only be used as the destination of a + * texture instruction once per phase (this is an implementation + * restriction). + */ +#define T0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ +#define T0_SAMPLER_NR_MASK (0xf<<0) + +#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ +/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ +#define T1_ADDRESS_REG_NR_SHIFT 17 +#define T2_MBZ 0 + +/* Declaration instructions */ +#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) + * register or an s (sampler) + * register. */ +#define D0_SAMPLE_TYPE_SHIFT 22 +#define D0_SAMPLE_TYPE_2D (0x0<<22) +#define D0_SAMPLE_TYPE_CUBE (0x1<<22) +#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) +#define D0_SAMPLE_TYPE_MASK (0x3<<22) + +#define D0_TYPE_SHIFT 19 +/* Allow: T, S */ +#define D0_NR_SHIFT 14 +/* Allow T: 0..10, S: 0..15 */ +#define D0_CHANNEL_X (1<<10) +#define D0_CHANNEL_Y (2<<10) +#define D0_CHANNEL_Z (4<<10) +#define D0_CHANNEL_W (8<<10) +#define D0_CHANNEL_ALL (0xf<<10) +#define D0_CHANNEL_NONE (0<<10) + +#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) +#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) + +/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse + * or specular declarations. + * + * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) + * + * Must be zero for S (sampler) dcls + */ +#define D1_MBZ 0 +#define D2_MBZ 0 + + + +/* p207 */ +#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) + +#define MS1_MAPMASK_SHIFT 0 +#define MS1_MAPMASK_MASK (0x8fff<<0) + +#define MS2_UNTRUSTED_SURFACE (1<<31) +#define MS2_ADDRESS_MASK 0xfffffffc +#define MS2_VERTICAL_LINE_STRIDE (1<<1) +#define MS2_VERTICAL_OFFSET (1<<1) + +#define MS3_HEIGHT_SHIFT 21 +#define MS3_WIDTH_SHIFT 10 +#define MS3_PALETTE_SELECT (1<<9) +#define MS3_MAPSURF_FORMAT_SHIFT 7 +#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) +#define MAPSURF_8BIT (1<<7) +#define MAPSURF_16BIT (2<<7) +#define MAPSURF_32BIT (3<<7) +#define MAPSURF_422 (5<<7) +#define MAPSURF_COMPRESSED (6<<7) +#define MAPSURF_4BIT_INDEXED (7<<7) +#define MS3_MT_FORMAT_MASK (0x7 << 3) +#define MS3_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_8BIT_A8 (4<<3) +#define MT_8BIT_MONO8 (5<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_I16 (7<<3) +#define MT_16BIT_L16 (8<<3) +#define MT_16BIT_A16 (9<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_XRGB8888 (2<<3) +#define MT_32BIT_XBGR8888 (3<<3) +#define MT_32BIT_QWVU8888 (4<<3) +#define MT_32BIT_AXVU8888 (5<<3) +#define MT_32BIT_LXVU8888 (6<<3) +#define MT_32BIT_XLVU8888 (7<<3) +#define MT_32BIT_ARGB2101010 (8<<3) +#define MT_32BIT_ABGR2101010 (9<<3) +#define MT_32BIT_AWVU2101010 (0xA<<3) +#define MT_32BIT_GR1616 (0xB<<3) +#define MT_32BIT_VU1616 (0xC<<3) +#define MT_32BIT_xI824 (0xD<<3) +#define MT_32BIT_xA824 (0xE<<3) +#define MT_32BIT_xL824 (0xF<<3) +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define MT_COMPRESS_DXT1_RGB (4<<3) +#define MS3_USE_FENCE_REGS (1<<2) +#define MS3_TILED_SURFACE (1<<1) +#define MS3_TILE_WALK (1<<0) + +#define MS4_PITCH_SHIFT 21 +#define MS4_CUBE_FACE_ENA_NEGX (1<<20) +#define MS4_CUBE_FACE_ENA_POSX (1<<19) +#define MS4_CUBE_FACE_ENA_NEGY (1<<18) +#define MS4_CUBE_FACE_ENA_POSY (1<<17) +#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) +#define MS4_CUBE_FACE_ENA_POSZ (1<<15) +#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) +#define MS4_MAX_LOD_SHIFT 9 +#define MS4_MAX_LOD_MASK (0x3f<<9) +#define MS4_MIP_LAYOUT_LEGACY (0<<8) +#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) +#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) +#define MS4_VOLUME_DEPTH_SHIFT 0 +#define MS4_VOLUME_DEPTH_MASK (0xff<<0) + +/* p244 */ +#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) + +#define SS1_MAPMASK_SHIFT 0 +#define SS1_MAPMASK_MASK (0x8fff<<0) + +#define SS2_REVERSE_GAMMA_ENABLE (1<<31) +#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) +#define SS2_COLORSPACE_CONVERSION (1<<29) +#define SS2_CHROMAKEY_SHIFT 27 +#define SS2_BASE_MIP_LEVEL_SHIFT 22 +#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) +#define SS2_MIP_FILTER_SHIFT 20 +#define SS2_MIP_FILTER_MASK (0x3<<20) +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define SS2_MAG_FILTER_SHIFT 17 +#define SS2_MAG_FILTER_MASK (0x7<<17) +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 +#define FILTER_4X4_1 3 +#define FILTER_4X4_2 4 +#define FILTER_4X4_FLAT 5 +#define FILTER_6X5_MONO 6 /* XXX - check */ +#define SS2_MIN_FILTER_SHIFT 14 +#define SS2_MIN_FILTER_MASK (0x7<<14) +#define SS2_LOD_BIAS_SHIFT 5 +#define SS2_LOD_BIAS_ONE (0x10<<5) +#define SS2_LOD_BIAS_MASK (0x1ff<<5) +/* Shadow requires: + * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format + * FILTER_4X4_x MIN and MAG filters + */ +#define SS2_SHADOW_ENABLE (1<<4) +#define SS2_MAX_ANISO_MASK (1<<3) +#define SS2_MAX_ANISO_2 (0<<3) +#define SS2_MAX_ANISO_4 (1<<3) +#define SS2_SHADOW_FUNC_SHIFT 0 +#define SS2_SHADOW_FUNC_MASK (0x7<<0) +/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ + +#define SS3_MIN_LOD_SHIFT 24 +#define SS3_MIN_LOD_ONE (0x10<<24) +#define SS3_MIN_LOD_MASK (0xff<<24) +#define SS3_KILL_PIXEL_ENABLE (1<<17) +#define SS3_TCX_ADDR_MODE_SHIFT 12 +#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP_EDGE 2 +#define TEXCOORDMODE_CUBE 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORDMODE_MIRROR_ONCE 5 +#define SS3_TCY_ADDR_MODE_SHIFT 9 +#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) +#define SS3_TCZ_ADDR_MODE_SHIFT 6 +#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) +#define SS3_NORMALIZED_COORDS (1<<5) +#define SS3_TEXTUREMAP_INDEX_SHIFT 1 +#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) +#define SS3_DEINTERLACER_ENABLE (1<<0) + +#define SS4_BORDER_COLOR_MASK (~0) + +/* 3DSTATE_SPAN_STIPPLE, p258 + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + +#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) +#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) +#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) + + +#define MI_FLUSH ((0<<29)|(4<<23)) +#define FLUSH_MAP_CACHE (1<<0) +#define INHIBIT_FLUSH_RENDER_CACHE (1<<2) + + +#endif diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c new file mode 100644 index 0000000000..e5d8d27993 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -0,0 +1,1014 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +#include "texmem.h" + +#include "drivers/common/driverfuncs.h" + +#include "intel_fbo.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" + +#include "i915_context.h" +#include "i915_reg.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static void +i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, + GLuint mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + + mask = mask & 0xff; + + DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(func), ref, mask); + + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(mask)); + + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | + S5_STENCIL_TEST_FUNC_MASK); + + i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | + (test << + S5_STENCIL_TEST_FUNC_SHIFT)); +} + +static void +i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + DBG("%s : mask 0x%x\n", __FUNCTION__, mask); + + mask = mask & 0xff; + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(mask)); +} + + +static void +i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int fop = intel_translate_stencil_op(fail); + int dfop = intel_translate_stencil_op(zfail); + int dpop = intel_translate_stencil_op(zpass); + + + DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK); + + i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | + (dfop << + S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (dpop << + S5_STENCIL_PASS_Z_PASS_SHIFT)); +} + +static void +i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + GLubyte refByte; + + UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | + S6_ALPHA_REF_MASK); + i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | + (((GLuint) refByte) << + S6_ALPHA_REF_SHIFT)); +} + +/* This function makes sure that the proper enables are + * set for LogicOp, Independant Alpha Blend, and Blending. + * It needs to be called from numerous places where we + * could change the LogicOp or Independant Alpha Blend without subsequent + * calls to glEnable. + */ +static void +i915EvalLogicOpBlendState(GLcontext * ctx) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (RGBA_LOGICOP_ENABLED(ctx)) { + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + } + else { + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; + + if (ctx->Color.BlendEnabled) { + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; + } + else { + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + } + } +} + +static void +i915BlendColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLubyte r, g, b, a; + + DBG("%s\n", __FUNCTION__); + + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = + (a << 24) | (r << 16) | (g << 8) | b; +} + + +#define DST_BLND_FACT(f) ((f)<state.Ctx[I915_CTXREG_IAB] & + ~(IAB_SRC_FACTOR_MASK | + IAB_DST_FACTOR_MASK | + (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); + + GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & + ~(S6_CBUF_SRC_BLEND_FACT_MASK | + S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); + + GLuint eqRGB = ctx->Color.BlendEquationRGB; + GLuint eqA = ctx->Color.BlendEquationA; + GLuint srcRGB = ctx->Color.BlendSrcRGB; + GLuint dstRGB = ctx->Color.BlendDstRGB; + GLuint srcA = ctx->Color.BlendSrcA; + GLuint dstA = ctx->Color.BlendDstA; + + if (eqRGB == GL_MIN || eqRGB == GL_MAX) { + srcRGB = dstRGB = GL_ONE; + } + + if (eqA == GL_MIN || eqA == GL_MAX) { + srcA = dstA = GL_ONE; + } + + lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); + lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); + lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; + + iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); + iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); + iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; + + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) + iab |= IAB_ENABLE; + + if (iab != i915->state.Ctx[I915_CTXREG_IAB] || + lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_IAB] = iab; + i915->state.Ctx[I915_CTXREG_LIS6] = lis6; + } + + /* This will catch a logicop blend equation */ + i915EvalLogicOpBlendState(ctx); +} + + +static void +i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB, + GLenum dstRGB, GLenum srcA, GLenum dstA) +{ + i915UpdateBlendState(ctx); +} + + +static void +i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA) +{ + i915UpdateBlendState(ctx); +} + + +static void +i915DepthFunc(GLcontext * ctx, GLenum func) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + + DBG("%s\n", __FUNCTION__); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; + i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; +} + +static void +i915DepthMask(GLcontext * ctx, GLboolean flag) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + DBG("%s flag (%d)\n", __FUNCTION__, flag); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (flag && ctx->Depth.Test) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; +} + +/* ============================================================= + * Polygon stipple + * + * The i915 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void +i915PolygonStipple(GLcontext * ctx, const GLubyte * mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i, j, k; + int active = (ctx->Polygon.StippleFlag && + i915->intel.reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + for (k = 0; k < 8; k++) + for (j = 3; j >= 0; j--) + for (i = 0; i < 4; i++, m++) + if (*m != p[j]) { + i915->intel.hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + i915->intel.hw_stipple = 0; + return; + } + + i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; + i915->state.Stipple[I915_STPREG_ST1] |= newMask; + i915->intel.hw_stipple = 1; + + if (active) + i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; +} + + +/* ============================================================= + * Hardware clipping + */ +static void +i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int x1, y1, x2, y2; + + if (!ctx->DrawBuffer) + return; + + DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + if (ctx->DrawBuffer->Name == 0) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + + x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); + + DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); + + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); + i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); +} + +static void +i915LogicOp(GLcontext * ctx, GLenum opcode) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int tmp = intel_translate_logic_op(opcode); + + DBG("%s\n", __FUNCTION__); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); +} + + + +static void +i915CullFaceFrontFace(GLcontext * ctx, GLenum unused) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint mode; + + DBG("%s %d\n", __FUNCTION__, + ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); + + if (!ctx->Polygon.CullFlag) { + mode = S4_CULLMODE_NONE; + } + else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = S4_CULLMODE_CW; + + if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + } + else { + mode = S4_CULLMODE_BOTH; + } + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; + i915->state.Ctx[I915_CTXREG_LIS4] |= mode; +} + +static void +i915LineWidth(GLcontext * ctx, GLfloat widthf) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; + int width; + + DBG("%s\n", __FUNCTION__); + + width = (int) (widthf * 2); + CLAMP_SELF(width, 1, 0xf); + lis4 |= width << S4_LINE_WIDTH_SHIFT; + + if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] = lis4; + } +} + +static void +i915PointSize(GLcontext * ctx, GLfloat size) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; + GLint point_size = (int) size; + + DBG("%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 255); + lis4 |= point_size << S4_POINT_WIDTH_SHIFT; + + if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] = lis4; + } +} + + +/* ============================================================= + * Color masks + */ + +static void +i915ColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; + + DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, + a); + + if (!r) + tmp |= S5_WRITEDISABLE_RED; + if (!g) + tmp |= S5_WRITEDISABLE_GREEN; + if (!b) + tmp |= S5_WRITEDISABLE_BLUE; + if (!a) + tmp |= S5_WRITEDISABLE_ALPHA; + + if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS5] = tmp; + } +} + +static void +update_specular(GLcontext * ctx) +{ + /* A hack to trigger the rebuild of the fragment program. + */ + intel_context(ctx)->NewGLState |= _NEW_TEXTURE; +} + +static void +i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + DBG("%s\n", __FUNCTION__); + + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + update_specular(ctx); + } +} + +static void +i915ShadeModel(GLcontext * ctx, GLenum mode) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (mode == GL_SMOOTH) { + i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } + else { + i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } +} + +/* ============================================================= + * Fog + */ +void +i915_update_fog(GLcontext * ctx) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLenum mode; + GLboolean enabled; + GLboolean try_pixel_fog; + + if (ctx->FragmentProgram._Active) { + /* Pull in static fog state from program */ + mode = ctx->FragmentProgram._Current->FogOption; + enabled = (mode != GL_NONE); + try_pixel_fog = 0; + } + else { + enabled = ctx->Fog.Enabled; + mode = ctx->Fog.Mode; +#if 0 + /* XXX - DISABLED -- Need ortho fallback */ + try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT + && ctx->Hint.Fog == GL_NICEST); +#else + try_pixel_fog = 0; +#endif + } + + if (!enabled) { + i915->vertex_fog = I915_FOG_NONE; + } + else if (try_pixel_fog) { + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; + i915->vertex_fog = I915_FOG_PIXEL; + + switch (mode) { + case GL_LINEAR: + if (ctx->Fog.End <= ctx->Fog.Start) { + /* XXX - this won't work with fragment programs. Need to + * either fallback or append fog instructions to end of + * program in the case of linear fog. + */ + printf("vertex fog!\n"); + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; + i915->vertex_fog = I915_FOG_VERTEX; + } + else { + GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); + GLfloat c1 = ctx->Fog.End * c2; + + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; + i915->state.Fog[I915_FOGREG_MODE1] |= + ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; + + if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { + i915->state.Fog[I915_FOGREG_MODE2] + = (GLuint) (c2 * FMC2_C2_ONE); + } + else { + fi_type fi; + fi.f = c2; + i915->state.Fog[I915_FOGREG_MODE2] = fi.i; + } + } + break; + case GL_EXP: + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; + break; + case GL_EXP2: + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; + break; + default: + break; + } + } + else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; + i915->vertex_fog = I915_FOG_VERTEX; + } + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); + if (enabled) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; + + /* Always enable pixel fog. Vertex fog using fog coord will conflict + * with fog code appended onto fragment program. + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); +} + +static void +i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_FOG_COORDINATE_SOURCE_EXT: + case GL_FOG_MODE: + case GL_FOG_START: + case GL_FOG_END: + break; + + case GL_FOG_DENSITY: + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + + if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { + i915->state.Fog[I915_FOGREG_MODE3] = + (GLuint) (ctx->Fog.Density * FMC3_D_ONE); + } + else { + fi_type fi; + fi.f = ctx->Fog.Density; + i915->state.Fog[I915_FOGREG_MODE3] = fi.i; + } + break; + + case GL_FOG_COLOR: + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_COLOR] = + (_3DSTATE_FOG_COLOR_CMD | + ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | + ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | + ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); + break; + + default: + break; + } +} + +static void +i915Hint(GLcontext * ctx, GLenum target, GLenum state) +{ + switch (target) { + case GL_FOG_HINT: + break; + default: + break; + } +} + +/* ============================================================= + */ + +static void +i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (cap) { + case GL_TEXTURE_2D: + break; + + case GL_LIGHTING: + case GL_COLOR_SUM: + update_specular(ctx); + break; + + case GL_ALPHA_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; + break; + + case GL_BLEND: + i915EvalLogicOpBlendState(ctx); + break; + + case GL_COLOR_LOGIC_OP: + i915EvalLogicOpBlendState(ctx); + + /* Logicop doesn't seem to work at 16bpp: + */ + if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ + FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); + break; + + case GL_FRAGMENT_PROGRAM_ARB: + break; + + case GL_DITHER: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; + break; + + case GL_DEPTH_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; + + i915DepthMask(ctx, ctx->Depth.Mask); + break; + + case GL_SCISSOR_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + if (state) + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); + else + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + break; + + case GL_LINE_SMOOTH: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; + break; + + case GL_FOG: + break; + + case GL_CULL_FACE: + i915CullFaceFrontFace(ctx, 0); + break; + + case GL_STENCIL_TEST: + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (irbStencil && irbStencil->region); + } + if (hw_stencil) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + } + else { + FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); + } + } + break; + + case GL_POLYGON_STIPPLE: + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (i915->intel.hw_stipple && + i915->intel.reduced_primitive == GL_TRIANGLES) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + if (state) + i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; + else + i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; + } + break; + + case GL_POLYGON_SMOOTH: + break; + + case GL_POINT_SMOOTH: + break; + + default: + ; + } +} + + +static void +i915_init_packets(struct i915_context *i915) +{ + intelScreenPrivate *screen = i915->intel.intelScreen; + + /* Zero all state */ + memset(&i915->state, 0, sizeof(i915->state)); + + + { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + /* Probably don't want to upload all this stuff every time one + * piece changes. + */ + i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(2) | + I1_LOAD_S(4) | + I1_LOAD_S(5) | I1_LOAD_S(6) | (3)); + i915->state.Ctx[I915_CTXREG_LIS2] = 0; + i915->state.Ctx[I915_CTXREG_LIS4] = 0; + i915->state.Ctx[I915_CTXREG_LIS5] = 0; + + if (screen->cpp == 2) /* XXX FBO fix */ + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + + + i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | + (2 << S6_TRISTRIP_PV_SHIFT)); + + i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + i915->state.Ctx[I915_CTXREG_IAB] = + (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | + IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); + + i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = + _3DSTATE_CONST_BLEND_COLOR_CMD; + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; + + } + + { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; + } + + + { + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; + i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | + FMC1_FOGFUNC_VERTEX | + FMC1_FOGINDEX_MODIFY_ENABLE | + FMC1_FOGINDEX_W | + FMC1_C1_C2_MODIFY_ENABLE | + FMC1_DENSITY_MODIFY_ENABLE); + i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; + } + + + { + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + /* color buffer offset/stride */ + i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ + i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ + i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; + + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ +#if 0 /* seems we don't need this */ + switch (screen->fbFormat) { + case DV_PF_565: + i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + DITHER_FULL_ALWAYS | + screen->fbFormat | + DEPTH_FRMT_16_FIXED); + break; + case DV_PF_8888: + i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + screen->fbFormat | + DEPTH_FRMT_24_FIXED_8_OTHER); + break; + } +#endif + + + /* scissor */ + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; + i915->state.Buffer[I915_DESTREG_SR1] = 0; + i915->state.Buffer[I915_DESTREG_SR2] = 0; + } + + +#if 0 + { + I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); + i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; + i915->state.Default[I915_DEFREG_C1] = 0; + i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; + i915->state.Default[I915_DEFREG_S1] = 0; + i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; + i915->state.Default[I915_DEFREG_Z1] = 0; + } +#endif + + + /* These will be emitted every at the head of every buffer, unless + * we get hardware contexts working. + */ + i915->state.active = (I915_UPLOAD_PROGRAM | + I915_UPLOAD_STIPPLE | + I915_UPLOAD_CTX | + I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT); +} + +void +i915InitStateFunctions(struct dd_function_table *functions) +{ + functions->AlphaFunc = i915AlphaFunc; + functions->BlendColor = i915BlendColor; + functions->BlendEquationSeparate = i915BlendEquationSeparate; + functions->BlendFuncSeparate = i915BlendFuncSeparate; + functions->ColorMask = i915ColorMask; + functions->CullFace = i915CullFaceFrontFace; + functions->DepthFunc = i915DepthFunc; + functions->DepthMask = i915DepthMask; + functions->Enable = i915Enable; + functions->Fogfv = i915Fogfv; + functions->FrontFace = i915CullFaceFrontFace; + functions->Hint = i915Hint; + functions->LightModelfv = i915LightModelfv; + functions->LineWidth = i915LineWidth; + functions->LogicOpcode = i915LogicOp; + functions->PointSize = i915PointSize; + functions->PolygonStipple = i915PolygonStipple; + functions->Scissor = i915Scissor; + functions->ShadeModel = i915ShadeModel; + functions->StencilFuncSeparate = i915StencilFuncSeparate; + functions->StencilMaskSeparate = i915StencilMaskSeparate; + functions->StencilOpSeparate = i915StencilOpSeparate; +} + + +void +i915InitState(struct i915_context *i915) +{ + GLcontext *ctx = &i915->intel.ctx; + + i915_init_packets(i915); + + _mesa_init_driver_state(ctx); + + memcpy(&i915->initial, &i915->state, sizeof(i915->state)); + i915->current = &i915->state; +} diff --git a/src/mesa/drivers/dri/i915/i915_tex.c b/src/mesa/drivers/dri/i915/i915_tex.c new file mode 100644 index 0000000000..59e148ca04 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_tex.c @@ -0,0 +1,78 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "image.h" +#include "texstore.h" +#include "texformat.h" +#include "texmem.h" +#include "swrast/swrast.h" + +#include "mm.h" + +#include "intel_ioctl.h" + +#include "i915_context.h" +#include "i915_reg.h" + + + +static void +i915TexEnv(GLcontext * ctx, GLenum target, + GLenum pname, const GLfloat * param) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_TEXTURE_LOD_BIAS:{ + GLuint unit = ctx->Texture.CurrentUnit; + GLint b = (int) ((*param) * 16.0); + if (b > 255) + b = 255; + if (b < -256) + b = -256; + I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); + i915->lodbias_ss2[unit] = + ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); + break; + } + + default: + break; + } +} + + +void +i915InitTextureFuncs(struct dd_function_table *functions) +{ + functions->TexEnv = i915TexEnv; +} diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c new file mode 100644 index 0000000000..7b761a7b22 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c @@ -0,0 +1,343 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Code to layout images in a mipmap tree for i915 and i945 + * respectively. + */ + +#include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" +#include "macros.h" +#include "intel_context.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static GLint initial_offsets[6][2] = { {0, 0}, +{0, 2}, +{1, 0}, +{1, 2}, +{1, 1}, +{1, 3} +}; + + +static GLint step_offsets[6][2] = { {0, 2}, +{0, 2}, +{-1, 2}, +{-1, 2}, +{-1, 1}, +{-1, 1} +}; + +GLboolean +i915_miptree_layout(struct intel_mipmap_tree * mt) +{ + GLint level; + + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP:{ + const GLuint dim = mt->width0; + GLuint face; + GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; + + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* double pitch for cube layouts */ + mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + mt->total_height = dim * 4; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + /*OLD: mt->pitch, mt->total_height,*/ + lvlWidth, lvlHeight, + 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + if (d == 0) + _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", + face, level, mt->first_level, mt->last_level); + + d >>= 1; + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + } + } + break; + } + case GL_TEXTURE_3D:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint stack_height = 0; + + /* Calculate the size of a single slice. + */ + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + + /* XXX: hardware expects/requires 9 levels at minimum. + */ + for (level = mt->first_level; level <= MAX2(8, mt->last_level); + level++) { + intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height, + width, height, depth); + + + stack_height += MAX2(2, height); + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + + /* Fixup depth image_offsets: + */ + depth = mt->depth0; + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint i; + for (i = 0; i < depth; i++) + intel_miptree_set_image_offset(mt, level, i, + 0, i * stack_height); + + depth = minify(depth); + } + + + /* Multiply slice size by texture depth for total size. It's + * remarkable how wasteful of memory the i915 texture layouts + * are. They are largely fixed in the i945. + */ + mt->total_height = stack_height * mt->depth0; + break; + } + + default:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint img_height; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 1, + 0, mt->total_height, + width, height, 1); + + if (mt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = (MAX2(2, height) + 1) & ~1; + + mt->total_height += img_height; + + width = minify(width); + height = minify(height); + } + break; + } + } + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + mt->pitch, + mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + + return GL_TRUE; +} + + +GLboolean +i945_miptree_layout(struct intel_mipmap_tree * mt) +{ + GLint level; + + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP:{ + const GLuint dim = mt->width0; + GLuint face; + GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; + + assert(lvlWidth == lvlHeight); /* cubemap images are square */ + + /* Depending on the size of the largest images, pitch can be + * determined either by the old-style packing of cubemap faces, + * or the final row of 4x4, 2x2 and 1x1 faces below this. + */ + if (dim > 32) + mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + else + mt->pitch = 14 * 8; + + mt->total_height = dim * 4 + 4; + + /* Set all the levels to effectively occupy the whole rectangular region. + */ + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + lvlWidth, lvlHeight, 1); + lvlWidth /= 2; + lvlHeight /= 2; + } + + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + if (dim == 4 && face >= 4) { + y = mt->total_height - 4; + x = (face - 4) * 8; + } + else if (dim < 4 && (face > 0 || mt->first_level > 0)) { + y = mt->total_height - 4; + x = face * 8; + } + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + d >>= 1; + + switch (d) { + case 4: + switch (face) { + case FACE_POS_X: + case FACE_NEG_X: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + case FACE_POS_Y: + case FACE_NEG_Y: + y += 12; + x -= 8; + break; + case FACE_POS_Z: + case FACE_NEG_Z: + y = mt->total_height - 4; + x = (face - 4) * 8; + break; + } + + case 2: + y = mt->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + } + } + } + break; + } + case GL_TEXTURE_3D:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint pack_x_pitch, pack_x_nr; + GLuint pack_y_pitch; + GLuint level; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + pack_y_pitch = MAX2(mt->height0, 2); + pack_x_pitch = mt->pitch; + pack_x_nr = 1; + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6; + GLint x = 0; + GLint y = 0; + GLint q, j; + + intel_miptree_set_level_info(mt, level, nr_images, + 0, mt->total_height, + width, height, depth); + + for (q = 0; q < nr_images;) { + for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { + intel_miptree_set_image_offset(mt, level, q, x, y); + x += pack_x_pitch; + } + + x = 0; + y += pack_y_pitch; + } + + + mt->total_height += y; + + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= mt->pitch); + } + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; + } + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + break; + } + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE_ARB: + i945_miptree_layout_2d(mt); + break; + default: + _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); + } + + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + mt->pitch, + mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c new file mode 100644 index 0000000000..09684e87b4 --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -0,0 +1,359 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "mtypes.h" +#include "enums.h" +#include "texformat.h" +#include "dri_bufmgr.h" + +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#include "i915_context.h" +#include "i915_reg.h" + + +static GLuint +translate_texture_format(GLuint mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case MESA_FORMAT_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case MESA_FORMAT_A8: + return MAPSURF_8BIT | MT_8BIT_A8; + case MESA_FORMAT_AL88: + return MAPSURF_16BIT | MT_16BIT_AY88; + case MESA_FORMAT_RGB565: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case MESA_FORMAT_ARGB1555: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case MESA_FORMAT_ARGB4444: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case MESA_FORMAT_ARGB8888: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case MESA_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case MESA_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + case MESA_FORMAT_Z16: + return (MAPSURF_16BIT | MT_16BIT_L16); + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case MESA_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case MESA_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + case MESA_FORMAT_Z24_S8: + return (MAPSURF_32BIT | MT_32BIT_xL824); + default: + fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); + abort(); + return 0; + } +} + + + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static GLuint +translate_wrap_mode(GLenum wrap) +{ + switch (wrap) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP_EDGE; + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + + + +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static GLboolean +i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) +{ + GLcontext *ctx = &intel->ctx; + struct i915_context *i915 = i915_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage; + GLuint *state = i915->state.Tex[unit], format, pitch; + + memset(state, 0, sizeof(state)); + + /*We need to refcount these. */ + + if (i915->state.tex_buffer[unit] != NULL) { + dri_bo_unreference(i915->state.tex_buffer[unit]); + i915->state.tex_buffer[unit] = NULL; + } + + if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + /* Get first image here, since intelObj->firstLevel will get set in + * the intel_finalize_mipmap_tree() call above. + */ + firstImage = tObj->Image[0][intelObj->firstLevel]; + + if (intelObj->imageOverride) { + i915->state.tex_buffer[unit] = NULL; + i915->state.tex_offset[unit] = intelObj->textureOffset; + + switch (intelObj->depthOverride) { + case 32: + format = MAPSURF_32BIT | MT_32BIT_ARGB8888; + break; + case 24: + default: + format = MAPSURF_32BIT | MT_32BIT_XRGB8888; + break; + case 16: + format = MAPSURF_16BIT | MT_16BIT_RGB565; + break; + } + + pitch = intelObj->pitchOverride; + } else { + dri_bo_reference(intelObj->mt->region->buffer); + i915->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, + 0, intelObj-> + firstLevel); + + format = translate_texture_format(firstImage->TexFormat->MesaFormat); + pitch = intelObj->mt->pitch * intelObj->mt->cpp; + } + + state[I915_TEXREG_MS3] = + (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format | + MS3_USE_FENCE_REGS); + + state[I915_TEXREG_MS4] = + ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK | + ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) << + MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - 1) << + MS4_VOLUME_DEPTH_SHIFT)); + + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + return GL_FALSE; + } + + if (tObj->MaxAnisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + return GL_FALSE; + } + } + + state[I915_TEXREG_SS2] = i915->lodbias_ss2[unit]; + + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION; + + /* Shadow: + */ + if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && + tObj->Target != GL_TEXTURE_3D) { + + state[I915_TEXREG_SS2] |= + (SS2_SHADOW_ENABLE | + intel_translate_compare_func(tObj->CompareFunc)); + + minFilt = FILTER_4X4_FLAT; + magFilt = FILTER_4X4_FLAT; + } + + state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | + (mipFilt << SS2_MIP_FILTER_SHIFT) | + (magFilt << SS2_MAG_FILTER_SHIFT)); + } + + { + GLenum ws = tObj->WrapS; + GLenum wt = tObj->WrapT; + GLenum wr = tObj->WrapR; + + + /* 3D textures don't seem to respect the border color. + * Fallback if there's ever a danger that they might refer to + * it. + * + * Effectively this means fallback on 3D clamp or + * clamp_to_border. + */ + if (tObj->Target == GL_TEXTURE_3D && + (tObj->MinFilter != GL_NEAREST || + tObj->MagFilter != GL_NEAREST) && + (ws == GL_CLAMP || + wt == GL_CLAMP || + wr == GL_CLAMP || + ws == GL_CLAMP_TO_BORDER || + wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER)) + return GL_FALSE; + + + state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */ + + state[I915_TEXREG_SS3] |= + ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); + + state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); + } + + + state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); + + + I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: + */ + I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); + + +#if 0 + DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]); + DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]); + DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]); + DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]); + DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]); + DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]); +#endif + + return GL_TRUE; +} + + + + +void +i915UpdateTextureState(struct intel_context *intel) +{ + GLboolean ok = GL_TRUE; + GLuint i; + + for (i = 0; i < I915_TEX_UNITS && ok; i++) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: + case TEXTURE_CUBE_BIT: + case TEXTURE_3D_BIT: + ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS); + break; + case TEXTURE_RECT_BIT: + ok = i915_update_tex_unit(intel, i, 0); + break; + case 0:{ + struct i915_context *i915 = i915_context(&intel->ctx); + if (i915->state.active & I915_UPLOAD_TEX(i)) + I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); + + if (i915->state.tex_buffer[i] != NULL) { + dri_bo_unreference(i915->state.tex_buffer[i]); + i915->state.tex_buffer[i] = NULL; + } + + break; + } + default: + ok = GL_FALSE; + break; + } + } + + FALLBACK(intel, I915_FALLBACK_TEXTURE, !ok); +} diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c new file mode 100644 index 0000000000..35757e17eb --- /dev/null +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -0,0 +1,571 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#include "intel_batchbuffer.h" +#include "intel_tex.h" +#include "intel_regions.h" + +#include "i915_reg.h" +#include "i915_context.h" + +static void +i915_render_prevalidate(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + i915ValidateFragmentProgram(i915); +} + +static void +i915_render_start(struct intel_context *intel) +{ +} + + +static void +i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */ + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i915->intel.reduced_primitive = rprim; + + if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { + INTEL_FIREVERTICES(intel); + + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] = st1; + } +} + + +/* Pull apart the vertex format registers and figure out how large a + * vertex is supposed to be. + */ +static GLboolean +i915_check_vertex_size(struct intel_context *intel, GLuint expected) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; + int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; + int i, sz = 0; + + switch (lis4 & S4_VFMT_XYZW_MASK) { + case S4_VFMT_XY: + sz = 2; + break; + case S4_VFMT_XYZ: + sz = 3; + break; + case S4_VFMT_XYW: + sz = 3; + break; + case S4_VFMT_XYZW: + sz = 4; + break; + default: + fprintf(stderr, "no xyzw specified\n"); + return 0; + } + + if (lis4 & S4_VFMT_SPEC_FOG) + sz++; + if (lis4 & S4_VFMT_COLOR) + sz++; + if (lis4 & S4_VFMT_DEPTH_OFFSET) + sz++; + if (lis4 & S4_VFMT_POINT_WIDTH) + sz++; + if (lis4 & S4_VFMT_FOG_PARAM) + sz++; + + for (i = 0; i < 8; i++) { + switch (lis2 & S2_TEXCOORD_FMT0_MASK) { + case TEXCOORDFMT_2D: + sz += 2; + break; + case TEXCOORDFMT_3D: + sz += 3; + break; + case TEXCOORDFMT_4D: + sz += 4; + break; + case TEXCOORDFMT_1D: + sz += 1; + break; + case TEXCOORDFMT_2D_16: + sz += 1; + break; + case TEXCOORDFMT_4D_16: + sz += 2; + break; + case TEXCOORDFMT_NOT_PRESENT: + break; + default: + fprintf(stderr, "bad texcoord fmt %d\n", i); + return GL_FALSE; + } + lis2 >>= S2_TEXCOORD_FMT1_SHIFT; + } + + if (sz != expected) + fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); + + return sz == expected; +} + + +static void +i915_emit_invarient_state(struct intel_context *intel) +{ + BATCH_LOCALS; + + BEGIN_BATCH(200, 0); + + OUT_BATCH(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + /* Don't support texture crossbar yet */ + OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); + + /* Need to initialize this to zero. + */ + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0)); + OUT_BATCH(0); + + /* XXX: Use this */ + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_BATCH(0); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); + + OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ + OUT_BATCH(0); + + + /* Don't support twosided stencil yet */ + OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); + OUT_BATCH(0); + + ADVANCE_BATCH(); +} + + +#define emit(intel, state, size ) \ + intel_batchbuffer_data(intel->batch, state, size, 0 ) + +static GLuint +get_dirty(struct i915_hw_state *state) +{ + GLuint dirty; + + /* Workaround the multitex hang - if one texture unit state is + * modified, emit all texture units. + */ + dirty = state->active & ~state->emitted; + if (dirty & I915_UPLOAD_TEX_ALL) + state->emitted &= ~I915_UPLOAD_TEX_ALL; + dirty = state->active & ~state->emitted; + return dirty; +} + + +static GLuint +get_state_size(struct i915_hw_state *state) +{ + GLuint dirty = get_dirty(state); + GLuint i; + GLuint sz = 0; + + if (dirty & I915_UPLOAD_INVARIENT) + sz += 30 * 4; + + if (dirty & I915_UPLOAD_CTX) + sz += sizeof(state->Ctx); + + if (dirty & I915_UPLOAD_BUFFERS) + sz += sizeof(state->Buffer); + + if (dirty & I915_UPLOAD_STIPPLE) + sz += sizeof(state->Stipple); + + if (dirty & I915_UPLOAD_FOG) + sz += sizeof(state->Fog); + + if (dirty & I915_UPLOAD_TEX_ALL) { + int nr = 0; + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) + nr++; + + sz += (2 + nr * 3) * sizeof(GLuint) * 2; + } + + if (dirty & I915_UPLOAD_CONSTANTS) + sz += state->ConstantSize * sizeof(GLuint); + + if (dirty & I915_UPLOAD_PROGRAM) + sz += state->ProgramSize * sizeof(GLuint); + + return sz; +} + + +/* Push the state into the sarea and/or texture memory. + */ +static void +i915_emit_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + struct i915_hw_state *state = i915->current; + int i; + GLuint dirty; + BATCH_LOCALS; + + /* We don't hold the lock at this point, so want to make sure that + * there won't be a buffer wrap. + * + * It might be better to talk about explicit places where + * scheduling is allowed, rather than assume that it is whenever a + * batchbuffer fills up. + */ + intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); + + /* Do this here as we may have flushed the batchbuffer above, + * causing more state to be dirty! + */ + dirty = get_dirty(state); + state->emitted |= dirty; + + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); + + if (dirty & I915_UPLOAD_INVARIENT) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); + i915_emit_invarient_state(intel); + } + + if (dirty & I915_UPLOAD_CTX) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_CTX:\n"); + + emit(intel, state->Ctx, sizeof(state->Ctx)); + } + + if (dirty & I915_UPLOAD_BUFFERS) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); + BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, 0); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + state->draw_region->draw_offset); + + if (state->depth_region) { + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + state->depth_region->draw_offset); + } + + OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR2]); + ADVANCE_BATCH(); + } + + if (dirty & I915_UPLOAD_STIPPLE) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); + emit(intel, state->Stipple, sizeof(state->Stipple)); + } + + if (dirty & I915_UPLOAD_FOG) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_FOG:\n"); + emit(intel, state->Fog, sizeof(state->Fog)); + } + + /* Combine all the dirty texture state into a single command to + * avoid lockups on I915 hardware. + */ + if (dirty & I915_UPLOAD_TEX_ALL) { + int nr = 0; + + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) + nr++; + + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); + OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) { + + if (state->tex_buffer[i]) { + OUT_RELOC(state->tex_buffer[i], + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + state->tex_offset[i]); + } + else if (state == &i915->meta) { + assert(i == 0); + OUT_BATCH(0); + } + else { + OUT_BATCH(state->tex_offset[i]); + } + + OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); + } + ADVANCE_BATCH(); + + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); + OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) { + OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); + } + ADVANCE_BATCH(); + } + + if (dirty & I915_UPLOAD_CONSTANTS) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); + emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint)); + } + + if (dirty & I915_UPLOAD_PROGRAM) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); + + assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize); + + emit(intel, state->Program, state->ProgramSize * sizeof(GLuint)); + if (INTEL_DEBUG & DEBUG_STATE) + i915_disassemble_program(state->Program, state->ProgramSize); + } + + assert(get_dirty(state) == 0); +} + +static void +i915_destroy_context(struct intel_context *intel) +{ + GLuint i; + struct i915_context *i915 = i915_context(&intel->ctx); + + for (i = 0; i < I915_TEX_UNITS; i++) { + if (i915->state.tex_buffer[i] != NULL) { + dri_bo_unreference(i915->state.tex_buffer[i]); + i915->state.tex_buffer[i] = NULL; + } + } + + _tnl_free_vertices(&intel->ctx); +} + + +/** + * Set the drawing regions for the color and depth/stencil buffers. + * This involves setting the pitch, cpp and buffer ID/location. + * Also set pixel format for color and Z rendering + * Used for setting both regular and meta state. + */ +void +i915_state_draw_region(struct intel_context *intel, + struct i915_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint value; + + ASSERT(state == &i915->state || state == &i915->meta); + + if (state->draw_region != color_region) { + intel_region_release(&state->draw_region); + intel_region_reference(&state->draw_region, color_region); + } + if (state->depth_region != depth_region) { + intel_region_release(&state->depth_region); + intel_region_reference(&state->depth_region, depth_region); + } + + /* + * Set stride/cpp values + */ + if (color_region) { + state->Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I915_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(color_region->pitch * color_region->cpp) | + BUF_3D_USE_FENCE); + } + + if (depth_region) { + state->Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I915_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | + BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | + BUF_3D_USE_FENCE); + } + + /* + * Compute/set I915_DESTREG_DV1 value + */ + value = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); + if (color_region && color_region->cpp == 4) { + value |= DV_PF_8888; + } + else { + value |= (DITHER_FULL_ALWAYS | DV_PF_565); + } + if (depth_region && depth_region->cpp == 4) { + value |= DEPTH_FRMT_24_FIXED_8_OTHER; + } + else { + value |= DEPTH_FRMT_16_FIXED; + } + state->Buffer[I915_DESTREG_DV1] = value; + + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); +} + + +static void +i915_set_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915_state_draw_region(intel, &i915->state, color_region, depth_region); +} + + + +static void +i915_lost_hardware(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915->state.emitted = 0; +} + +static GLuint +i915_flush_cmd(void) +{ + return MI_FLUSH | FLUSH_MAP_CACHE; +} + +static void +i915_assert_not_dirty( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + struct i915_hw_state *state = i915->current; + GLuint dirty = get_dirty(state); + assert(!dirty); +} + + +void +i915InitVtbl(struct i915_context *i915) +{ + i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; + i915->intel.vtbl.destroy = i915_destroy_context; + i915->intel.vtbl.emit_state = i915_emit_state; + i915->intel.vtbl.lost_hardware = i915_lost_hardware; + i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; + i915->intel.vtbl.render_start = i915_render_start; + i915->intel.vtbl.render_prevalidate = i915_render_prevalidate; + i915->intel.vtbl.set_draw_region = i915_set_draw_region; + i915->intel.vtbl.update_texture_state = i915UpdateTextureState; + i915->intel.vtbl.flush_cmd = i915_flush_cmd; + i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; +} diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c new file mode 100644 index 0000000000..8ee48b5a68 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -0,0 +1,331 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_decode.h" +#include "i915_debug.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } + + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->size = intel->intelScreen->maxBatchSize; + batch->ptr = batch->map; +} + +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->last_fence = NULL; + intel_batchbuffer_reset(batch); + + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + dri_fence_wait(batch->last_fence); + dri_fence_unreference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + dri_bo_unmap(batch->buf); + batch->map = NULL; + } + dri_bo_unreference(batch->buf); + batch->buf = NULL; + free(batch); +} + +static int +relocation_sort(const void *a_in, const void *b_in) { + const struct buffer_reloc *a = a_in, *b = b_in; + + return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; +} + + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + GLuint *ptr; + GLuint i; + struct intel_context *intel = batch->intel; + dri_fence *fo; + GLboolean performed_rendering = GL_FALSE; + + assert(batch->buf->virtual != NULL); + ptr = batch->buf->virtual; + + /* Sort our relocation list in terms of referenced buffer pointer. + * This lets us uniquely validate the buffers with the sum of all the flags, + * while avoiding O(n^2) on number of relocations. + */ + qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), + relocation_sort); + + /* Perform the necessary validations of buffers, and enter the relocations + * in the batchbuffer. + */ + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + if (r->validate_flags & DRM_BO_FLAG_WRITE) + performed_rendering = GL_TRUE; + + /* If this is the first time we've seen this buffer in the relocation + * list, figure out our flags and validate it. + */ + if (i == 0 || batch->reloc[i - 1].buf != r->buf) { + uint32_t validate_flags; + int j, ret; + + /* Accumulate the flags we need for validating this buffer. */ + validate_flags = r->validate_flags; + for (j = i + 1; j < batch->nr_relocs; j++) { + if (batch->reloc[j].buf != r->buf) + break; + validate_flags |= batch->reloc[j].validate_flags; + } + + /* Validate. If we fail, fence to clear the unfenced list and bail + * out. + */ + ret = dri_bo_validate(r->buf, validate_flags); + if (ret != 0) { + dri_bo_unmap(batch->buf); + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "batchbuffer failure fence", GL_TRUE); + dri_fence_unreference(fo); + goto done; + } + } + ptr[r->offset / 4] = r->buf->offset + r->delta; + dri_bo_unreference(r->buf); + } + + dri_bo_unmap(batch->buf); + batch->map = NULL; + batch->ptr = NULL; + + dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { + intel_batch_ioctl(batch->intel, + batch->buf->offset, + used, ignore_cliprects, allow_unlock); + } + + /* Associate a fence with the validated buffers, and note that we included + * a flush at the end. + */ + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "Batch fence", GL_TRUE); + + if (performed_rendering) { + dri_fence_unreference(batch->last_fence); + batch->last_fence = fo; + } else { + /* If we didn't validate any buffers for writing by the card, we don't + * need to track the fence for glFinish(). + */ + dri_fence_unreference(fo); + } + + if (intel->numClipRects == 0 && !ignore_cliprects) { + if (allow_unlock) { + /* If we are not doing any actual user-visible rendering, + * do a sched_yield to keep the app from pegging the cpu while + * achieving nothing. + */ + UNLOCK_HARDWARE(intel); + sched_yield(); + LOCK_HARDWARE(intel); + } + intel->vtbl.lost_hardware(intel); + } + +done: + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + intel_decode(ptr, used / 4, batch->buf->offset); + dri_bo_unmap(batch->buf); + } +} + + +void +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; + + if (used == 0) + return; + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + LOCK_HARDWARE(intel); + + do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + + if (!was_locked) + UNLOCK_HARDWARE(intel); + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + intel_batchbuffer_flush(batch); + if (batch->last_fence != NULL) + dri_fence_wait(batch->last_fence); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint delta) +{ + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + + assert(batch->nr_relocs <= MAX_RELOCS); + + dri_bo_reference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->validate_flags = flags; + + batch->ptr += 4; + return GL_TRUE; +} + + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h new file mode 100644 index 0000000000..850a91e1c9 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h @@ -0,0 +1,122 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 4096 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + dri_bo *buf; + GLuint offset; + GLuint delta; /* not needed? */ + GLuint validate_flags; +}; + +struct intel_batchbuffer +{ + struct intel_context *intel; + + dri_bo *buf; + dri_fence *last_fence; + GLuint flags; + + drmBOList list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; + GLuint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +void intel_batchbuffer_flush(struct intel_batchbuffer *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf, flags, delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c new file mode 100644 index 0000000000..5d97f08434 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -0,0 +1,493 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include +#include + +#include "mtypes.h" +#include "context.h" +#include "enums.h" + +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_reg.h" +#include "intel_regions.h" +#include "vblank.h" + +#define FILE_DEBUG_FLAG DEBUG_BLIT + +/** + * Copy the back color buffer to the front color buffer. + * Used for SwapBuffers(). + */ +void +intelCopyBuffer(const __DRIdrawablePrivate * dPriv, + const drm_clip_rect_t * rect) +{ + + struct intel_context *intel; + const intelScreenPrivate *intelScreen; + + DBG("%s\n", __FUNCTION__); + + assert(dPriv); + + intel = intelScreenContext(dPriv->driScreenPriv->private); + if (!intel) + return; + + intelScreen = intel->intelScreen; + + if (intel->last_swap_fence) { + dri_fence_wait(intel->last_swap_fence); + dri_fence_unreference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + + if (dPriv && dPriv->numClipRects) { + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + const struct intel_region *frontRegion + = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT); + const struct intel_region *backRegion + = intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT); + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = frontRegion->pitch; + const int cpp = frontRegion->cpp; + int BR13, CMD; + int i; + + ASSERT(intel_fb); + ASSERT(intel_fb->Base.Name == 0); /* Not a user-created FBO */ + ASSERT(frontRegion); + ASSERT(backRegion); + ASSERT(frontRegion->pitch == backRegion->pitch); + ASSERT(frontRegion->cpp == backRegion->cpp); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height) + continue; + + box = *pbox; + + if (rect) { + if (rect->x1 > box.x1) + box.x1 = rect->x1; + if (rect->y1 > box.y1) + box.y1 = rect->y1; + if (rect->x2 < box.x2) + box.x2 = rect->x2; + if (rect->y2 < box.y2) + box.y2 = rect->y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((pbox->y1 << 16) | pbox->x1); + OUT_BATCH((pbox->y2 << 16) | pbox->x2); + + OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + 0); + OUT_BATCH((pbox->y1 << 16) | pbox->x1); + OUT_BATCH(BR13 & 0xffff); + OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + 0); + + ADVANCE_BATCH(); + } + + if (intel->first_swap_fence) + dri_fence_unreference(intel->first_swap_fence); + intel_batchbuffer_flush(intel->batch); + intel->first_swap_fence = intel->batch->last_fence; + dri_fence_reference(intel->first_swap_fence); + } + + UNLOCK_HARDWARE(intel); +} + + + + +void +intelEmitFillBlit(struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + dri_bo *dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, GLshort w, GLshort h, GLuint color) +{ + GLuint BR13, CMD; + BATCH_LOCALS; + + dst_pitch *= cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24); + CMD = XY_COLOR_BLT_CMD; + break; + case 4: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25); + CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + break; + default: + return; + } + + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); + + + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y << 16) | x); + OUT_BATCH(((y + h) << 16) | (x + w)); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); + OUT_BATCH(color); + ADVANCE_BATCH(); +} + + +static GLuint translate_raster_op(GLenum logicop) +{ + switch(logicop) { + case GL_CLEAR: return 0x00; + case GL_AND: return 0x88; + case GL_AND_REVERSE: return 0x44; + case GL_COPY: return 0xCC; + case GL_AND_INVERTED: return 0x22; + case GL_NOOP: return 0xAA; + case GL_XOR: return 0x66; + case GL_OR: return 0xEE; + case GL_NOR: return 0x11; + case GL_EQUIV: return 0x99; + case GL_INVERT: return 0x55; + case GL_OR_REVERSE: return 0xDD; + case GL_COPY_INVERTED: return 0x33; + case GL_OR_INVERTED: return 0xBB; + case GL_NAND: return 0x77; + case GL_SET: return 0xFF; + default: return 0; + } +} + + +/* Copy BitBlt + */ +void +intelEmitCopyBlit(struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + dri_bo *src_buffer, + GLuint src_offset, + GLshort dst_pitch, + dri_bo *dst_buffer, + GLuint dst_offset, + GLshort src_x, GLshort src_y, + GLshort dst_x, GLshort dst_y, + GLshort w, GLshort h, + GLenum logic_op) +{ + GLuint CMD, BR13; + int dst_y2 = dst_y + h; + int dst_x2 = dst_x + w; + BATCH_LOCALS; + + + DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + src_buffer, src_pitch, src_offset, src_x, src_y, + dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); + + src_pitch *= cpp; + dst_pitch *= cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = (((GLint) dst_pitch) & 0xffff) | + (translate_raster_op(logic_op) << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + BR13 = + (((GLint) dst_pitch) & 0xffff) | + (translate_raster_op(logic_op) << 16) | (1 << 24) | (1 << 25); + CMD = + (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + break; + default: + return; + } + + if (dst_y2 < dst_y || dst_x2 < dst_x) { + return; + } + + /* Initial y values don't seem to work with negative pitches. If + * we adjust the offsets manually (below), it seems to work fine. + * + * On the other hand, if we always adjust, the hardware doesn't + * know which blit directions to use, so overlapping copypixels get + * the wrong result. + */ + if (dst_pitch > 0 && src_pitch > 0) { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((dst_y << 16) | dst_x); + OUT_BATCH((dst_y2 << 16) | dst_x2); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); + OUT_BATCH((src_y << 16) | src_x); + OUT_BATCH(((GLint) src_pitch & 0xffff)); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, src_offset); + ADVANCE_BATCH(); + } + else { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((0 << 16) | dst_x); + OUT_BATCH((h << 16) | dst_x2); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + dst_offset + dst_y * dst_pitch); + OUT_BATCH((0 << 16) | src_x); + OUT_BATCH(((GLint) src_pitch & 0xffff)); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + src_offset + src_y * src_pitch); + ADVANCE_BATCH(); + } +} + + +/** + * Use blitting to clear the renderbuffers named by 'flags'. + * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferMask field + * since that might include software renderbuffers or renderbuffers + * which we're clearing with triangles. + * \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear + */ +void +intelClearWithBlit(GLcontext * ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + GLuint clear_depth; + GLbitfield skipBuffers = 0; + BATCH_LOCALS; + + DBG("%s %x\n", __FUNCTION__, mask); + + /* + * Compute values for clearing the buffers. + */ + clear_depth = 0; + if (mask & BUFFER_BIT_DEPTH) { + clear_depth = (GLuint) (fb->_DepthMax * ctx->Depth.Clear); + } + if (mask & BUFFER_BIT_STENCIL) { + clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; + } + + /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in + * the loop below. + */ + if ((mask & BUFFER_BIT_DEPTH) && (mask & BUFFER_BIT_STENCIL)) { + skipBuffers = BUFFER_BIT_STENCIL; + } + + /* XXX Move this flush/lock into the following conditional? */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->numClipRects) { + GLint cx, cy, cw, ch; + drm_clip_rect_t clear; + int i; + + /* Get clear bounds after locking */ + cx = fb->_Xmin; + cy = fb->_Ymin; + cw = fb->_Xmax - cx; + ch = fb->_Ymax - cy; + + if (fb->Name == 0) { + /* clearing a window */ + + /* flip top to bottom */ + clear.x1 = cx + intel->drawX; + clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; + clear.x2 = clear.x1 + cw; + clear.y2 = clear.y1 + ch; + } + else { + /* clearing FBO */ + assert(intel->numClipRects == 1); + assert(intel->pClipRects == &intel->fboRect); + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = clear.x1 + cw; + clear.y2 = clear.y1 + ch; + /* no change to mask */ + } + + for (i = 0; i < intel->numClipRects; i++) { + const drm_clip_rect_t *box = &intel->pClipRects[i]; + drm_clip_rect_t b; + GLuint buf; + GLuint clearMask = mask; /* use copy, since we modify it below */ + GLboolean all = (cw == fb->Width && ch == fb->Height); + + if (!all) { + intel_intersect_cliprects(&b, &clear, box); + } + else { + b = *box; + } + + if (0) + _mesa_printf("clear %d,%d..%d,%d, mask %x\n", + b.x1, b.y1, b.x2, b.y2, mask); + + /* Loop over all renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && clearMask; buf++) { + const GLbitfield bufBit = 1 << buf; + if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { + /* OK, clear this renderbuffer */ + struct intel_region *irb_region = + intel_get_rb_region(fb, buf); + dri_bo *write_buffer = + intel_region_buffer(intel->intelScreen, irb_region, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + + GLuint clearVal; + GLint pitch, cpp; + GLuint BR13, CMD; + + ASSERT(irb_region); + + pitch = irb_region->pitch; + cpp = irb_region->cpp; + + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + irb_region->buffer, (pitch * cpp), + irb_region->draw_offset, + b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1); + + + /* Setup the blit command */ + if (cpp == 4) { + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25); + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + CMD = XY_COLOR_BLT_CMD; + if (clearMask & BUFFER_BIT_DEPTH) + CMD |= XY_COLOR_BLT_WRITE_RGB; + if (clearMask & BUFFER_BIT_STENCIL) + CMD |= XY_COLOR_BLT_WRITE_ALPHA; + } + else { + /* clearing RGBA */ + CMD = (XY_COLOR_BLT_CMD | + XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + } + } + else { + ASSERT(cpp == 2 || cpp == 0); + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); + CMD = XY_COLOR_BLT_CMD; + } + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + clearVal = clear_depth; + } + else { + clearVal = (cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + } + /* + _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", + buf, irb->Base.Name); + */ + intel_wait_flips(intel, INTEL_BATCH_NO_CLIPRECTS); + + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((b.y1 << 16) | b.x1); + OUT_BATCH((b.y2 << 16) | b.x2); + OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + irb_region->draw_offset); + OUT_BATCH(clearVal); + ADVANCE_BATCH(); + clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ + } + } + } + intel_batchbuffer_flush(intel->batch); + } + + UNLOCK_HARDWARE(intel); +} diff --git a/src/mesa/drivers/dri/i915/intel_blit.h b/src/mesa/drivers/dri/i915/intel_blit.h new file mode 100644 index 0000000000..a66af86359 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_blit.h @@ -0,0 +1,62 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_BLIT_H +#define INTEL_BLIT_H + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "dri_bufmgr.h" + +extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv, + const drm_clip_rect_t * rect); + +extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); + +extern void intelEmitCopyBlit(struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + dri_bo *src_buffer, + GLuint src_offset, + GLshort dst_pitch, + dri_bo *dst_buffer, + GLuint dst_offset, + GLshort srcx, GLshort srcy, + GLshort dstx, GLshort dsty, + GLshort w, GLshort h, + GLenum logicop ); + +extern void intelEmitFillBlit(struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + dri_bo *dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, + GLshort w, GLshort h, GLuint color); + + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_buffer_objects.c b/src/mesa/drivers/dri/i915/intel_buffer_objects.c new file mode 100644 index 0000000000..3c73c402d9 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_buffer_objects.c @@ -0,0 +1,268 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "imports.h" +#include "mtypes.h" +#include "bufferobj.h" + +#include "intel_context.h" +#include "intel_buffer_objects.h" +#include "intel_regions.h" +#include "dri_bufmgr.h" + +/** Allocates a new dri_bo to store the data for the buffer object. */ +static void +intel_bufferobj_alloc_buffer(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + intel_obj->buffer = dri_bo_alloc(intel->intelScreen->bufmgr, "bufferobj", + intel_obj->Base.Size, 64, + DRM_BO_FLAG_MEM_TT); +} + +/** + * There is some duplication between mesa's bufferobjects and our + * bufmgr buffers. Both have an integer handle and a hashtable to + * lookup an opaque structure. It would be nice if the handles and + * internal structure where somehow shared. + */ +static struct gl_buffer_object * +intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) +{ + struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object); + + _mesa_initialize_buffer_object(&obj->Base, name, target); + + obj->buffer = NULL; + + return &obj->Base; +} + +/* Break the COW tie to the region. The region gets to keep the data. + */ +void +intel_bufferobj_release_region(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + assert(intel_obj->region->buffer == intel_obj->buffer); + intel_obj->region->pbo = NULL; + intel_obj->region = NULL; + + dri_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; +} + +/* Break the COW tie to the region. Both the pbo and the region end + * up with a copy of the data. + */ +void +intel_bufferobj_cow(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + assert(intel_obj->region); + intel_region_cow(intel->intelScreen, intel_obj->region); +} + + +/** + * Deallocate/free a vertex/pixel buffer object. + * Called via glDeleteBuffersARB(). + */ +static void +intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + + if (intel_obj->region) { + intel_bufferobj_release_region(intel, intel_obj); + } + else if (intel_obj->buffer) { + dri_bo_unreference(intel_obj->buffer); + } + + _mesa_free(intel_obj); +} + + + +/** + * Allocate space for and store data in a buffer object. Any data that was + * previously stored in the buffer object is lost. If data is NULL, + * memory will be allocated, but no copy will occur. + * Called via glBufferDataARB(). + */ +static void +intel_bufferobj_data(GLcontext * ctx, + GLenum target, + GLsizeiptrARB size, + const GLvoid * data, + GLenum usage, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + intel_obj->Base.Size = size; + intel_obj->Base.Usage = usage; + + if (intel_obj->region) + intel_bufferobj_release_region(intel, intel_obj); + + if (intel_obj->buffer != NULL && intel_obj->buffer->size != size) { + dri_bo_unreference(intel_obj->buffer); + intel_obj->buffer = NULL; + } + + intel_bufferobj_alloc_buffer(intel, intel_obj); + + if (data != NULL) + dri_bo_subdata(intel_obj->buffer, 0, size, data); +} + + +/** + * Replace data in a subrange of buffer object. If the data range + * specified by size + offset extends beyond the end of the buffer or + * if data is NULL, no copy is performed. + * Called via glBufferSubDataARB(). + */ +static void +intel_bufferobj_subdata(GLcontext * ctx, + GLenum target, + GLintptrARB offset, + GLsizeiptrARB size, + const GLvoid * data, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + + if (intel_obj->region) + intel_bufferobj_cow(intel, intel_obj); + + dri_bo_subdata(intel_obj->buffer, offset, size, data); +} + + +/** + * Called via glGetBufferSubDataARB(). + */ +static void +intel_bufferobj_get_subdata(GLcontext * ctx, + GLenum target, + GLintptrARB offset, + GLsizeiptrARB size, + GLvoid * data, struct gl_buffer_object *obj) +{ + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + dri_bo_get_subdata(intel_obj->buffer, offset, size, data); +} + + + +/** + * Called via glMapBufferARB(). + */ +static void * +intel_bufferobj_map(GLcontext * ctx, + GLenum target, + GLenum access, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + /* XXX: Translate access to flags arg below: + */ + assert(intel_obj); + + if (intel_obj->region) + intel_bufferobj_cow(intel, intel_obj); + + if (intel_obj->buffer == NULL) { + obj->Pointer = NULL; + return NULL; + } + + dri_bo_map(intel_obj->buffer, GL_TRUE); + obj->Pointer = intel_obj->buffer->virtual; + return obj->Pointer; +} + + +/** + * Called via glMapBufferARB(). + */ +static GLboolean +intel_bufferobj_unmap(GLcontext * ctx, + GLenum target, struct gl_buffer_object *obj) +{ + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + if (intel_obj->buffer != NULL) { + assert(obj->Pointer); + dri_bo_unmap(intel_obj->buffer); + obj->Pointer = NULL; + } + return GL_TRUE; +} + +dri_bo * +intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object *intel_obj, GLuint flag) +{ + if (intel_obj->region) { + if (flag == INTEL_WRITE_PART) + intel_bufferobj_cow(intel, intel_obj); + else if (flag == INTEL_WRITE_FULL) { + intel_bufferobj_release_region(intel, intel_obj); + intel_bufferobj_alloc_buffer(intel, intel_obj); + } + } + + return intel_obj->buffer; +} + +void +intel_bufferobj_init(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + + ctx->Driver.NewBufferObject = intel_bufferobj_alloc; + ctx->Driver.DeleteBuffer = intel_bufferobj_free; + ctx->Driver.BufferData = intel_bufferobj_data; + ctx->Driver.BufferSubData = intel_bufferobj_subdata; + ctx->Driver.GetBufferSubData = intel_bufferobj_get_subdata; + ctx->Driver.MapBuffer = intel_bufferobj_map; + ctx->Driver.UnmapBuffer = intel_bufferobj_unmap; +} diff --git a/src/mesa/drivers/dri/i915/intel_buffer_objects.h b/src/mesa/drivers/dri/i915/intel_buffer_objects.h new file mode 100644 index 0000000000..db579a8ae4 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_buffer_objects.h @@ -0,0 +1,86 @@ + /************************************************************************** + * + * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_BUFFEROBJ_H +#define INTEL_BUFFEROBJ_H + +#include "mtypes.h" + +struct intel_context; +struct intel_region; +struct gl_buffer_object; + + +/** + * Intel vertex/pixel buffer object, derived from Mesa's gl_buffer_object. + */ +struct intel_buffer_object +{ + struct gl_buffer_object Base; + dri_bo *buffer; /* the low-level buffer manager's buffer handle */ + + struct intel_region *region; /* Is there a zero-copy texture + associated with this (pixel) + buffer object? */ +}; + + +/* Get the bm buffer associated with a GL bufferobject: + */ +dri_bo *intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object + *obj, GLuint flag); + +/* Hook the bufferobject implementation into mesa: + */ +void intel_bufferobj_init(struct intel_context *intel); + + + +/* Are the obj->Name tests necessary? Unfortunately yes, mesa + * allocates a couple of gl_buffer_object structs statically, and + * the Name == 0 test is the only way to identify them and avoid + * casting them erroneously to our structs. + */ +static INLINE struct intel_buffer_object * +intel_buffer_object(struct gl_buffer_object *obj) +{ + if (obj->Name) + return (struct intel_buffer_object *) obj; + else + return NULL; +} + +/* Helpers for zerocopy image uploads. See also intel_regions.h: + */ +void intel_bufferobj_cow(struct intel_context *intel, + struct intel_buffer_object *intel_obj); +void intel_bufferobj_release_region(struct intel_context *intel, + struct intel_buffer_object *intel_obj); + + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c new file mode 100644 index 0000000000..cb151ab94d --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -0,0 +1,1193 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_depthstencil.h" +#include "intel_fbo.h" +#include "intel_tris.h" +#include "intel_regions.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" +#include "context.h" +#include "utils.h" +#include "drirenderbuffer.h" +#include "framebuffer.h" +#include "swrast/swrast.h" +#include "vblank.h" + + +/* This block can be removed when libdrm >= 2.3.1 is required */ + +#ifndef DRM_VBLANK_FLIP + +#define DRM_VBLANK_FLIP 0x8000000 + +typedef struct drm_i915_flip { + int planes; +} drm_i915_flip_t; + +#undef DRM_IOCTL_I915_FLIP +#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \ + drm_i915_flip_t) + +#endif + + +/** + * XXX move this into a new dri/common/cliprects.c file. + */ +GLboolean +intel_intersect_cliprects(drm_clip_rect_t * dst, + const drm_clip_rect_t * a, + const drm_clip_rect_t * b) +{ + GLint bx = b->x1; + GLint by = b->y1; + GLint bw = b->x2 - bx; + GLint bh = b->y2 - by; + + if (bx < a->x1) + bw -= a->x1 - bx, bx = a->x1; + if (by < a->y1) + bh -= a->y1 - by, by = a->y1; + if (bx + bw > a->x2) + bw = a->x2 - bx; + if (by + bh > a->y2) + bh = a->y2 - by; + if (bw <= 0) + return GL_FALSE; + if (bh <= 0) + return GL_FALSE; + + dst->x1 = bx; + dst->y1 = by; + dst->x2 = bx + bw; + dst->y2 = by + bh; + + return GL_TRUE; +} + +/** + * Return pointer to current color drawing region, or NULL. + */ +struct intel_region * +intel_drawbuf_region(struct intel_context *intel) +{ + struct intel_renderbuffer *irbColor = + intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]); + if (irbColor) + return irbColor->region; + else + return NULL; +} + +/** + * Return pointer to current color reading region, or NULL. + */ +struct intel_region * +intel_readbuf_region(struct intel_context *intel) +{ + struct intel_renderbuffer *irb + = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer); + if (irb) + return irb->region; + else + return NULL; +} + + + +/** + * Update the following fields for rendering to a user-created FBO: + * intel->numClipRects + * intel->pClipRects + * intel->drawX + * intel->drawY + */ +static void +intelSetRenderbufferClipRects(struct intel_context *intel) +{ + assert(intel->ctx.DrawBuffer->Width > 0); + assert(intel->ctx.DrawBuffer->Height > 0); + intel->fboRect.x1 = 0; + intel->fboRect.y1 = 0; + intel->fboRect.x2 = intel->ctx.DrawBuffer->Width; + intel->fboRect.y2 = intel->ctx.DrawBuffer->Height; + intel->numClipRects = 1; + intel->pClipRects = &intel->fboRect; + intel->drawX = 0; + intel->drawY = 0; +} + + +/** + * As above, but for rendering to front buffer of a window. + * \sa intelSetRenderbufferClipRects + */ +static void +intelSetFrontClipRects(struct intel_context *intel) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + if (!dPriv) + return; + + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; +} + + +/** + * As above, but for rendering to back buffer of a window. + */ +static void +intelSetBackClipRects(struct intel_context *intel) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + struct intel_framebuffer *intel_fb; + + if (!dPriv) + return; + + intel_fb = dPriv->driverPrivate; + + if (intel_fb->pf_active || dPriv->numBackClipRects == 0) { + /* use the front clip rects */ + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; + } + else { + /* use the back clip rects */ + intel->numClipRects = dPriv->numBackClipRects; + intel->pClipRects = dPriv->pBackClipRects; + intel->drawX = dPriv->backX; + intel->drawY = dPriv->backY; + } +} + + +/** + * This will be called whenever the currently bound window is moved/resized. + * XXX: actually, it seems to NOT be called when the window is only moved (BP). + */ +void +intelWindowMoved(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + + if (!intel->ctx.DrawBuffer) { + /* when would this happen? -BP */ + intelSetFrontClipRects(intel); + } + else if (intel->ctx.DrawBuffer->Name != 0) { + /* drawing to user-created FBO - do nothing */ + /* Cliprects would be set from intelDrawBuffer() */ + } + else { + /* drawing to a window */ + switch (intel_fb->Base._ColorDrawBufferMask[0]) { + case BUFFER_BIT_FRONT_LEFT: + intelSetFrontClipRects(intel); + break; + case BUFFER_BIT_BACK_LEFT: + intelSetBackClipRects(intel); + break; + default: + /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ + intelSetFrontClipRects(intel); + } + } + + if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) { + drmI830Sarea *sarea = intel->sarea; + drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, + .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; + drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, + .x2 = sarea->planeA_x + sarea->planeA_w, + .y2 = sarea->planeA_y + sarea->planeA_h }; + drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, + .x2 = sarea->planeB_x + sarea->planeB_w, + .y2 = sarea->planeB_y + sarea->planeB_h }; + GLint areaA = driIntersectArea( drw_rect, planeA_rect ); + GLint areaB = driIntersectArea( drw_rect, planeB_rect ); + GLuint flags = intel_fb->vblank_flags; + GLboolean pf_active; + GLint pf_planes; + + /* Update page flipping info + */ + pf_planes = 0; + + if (areaA > 0) + pf_planes |= 1; + + if (areaB > 0) + pf_planes |= 2; + + intel_fb->pf_current_page = (intel->sarea->pf_current_page >> + (intel_fb->pf_planes & 0x2)) & 0x3; + + intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2; + + pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes; + + if (INTEL_DEBUG & DEBUG_LOCK) + if (pf_active != intel_fb->pf_active) + _mesa_printf("%s - Page flipping %sactive\n", __progname, + pf_active ? "" : "in"); + + if (pf_active) { + /* Sync pages between planes if flipping on both at the same time */ + if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes && + (intel->sarea->pf_current_page & 0x3) != + (((intel->sarea->pf_current_page) >> 2) & 0x3)) { + drm_i915_flip_t flip; + + if (intel_fb->pf_current_page == + (intel->sarea->pf_current_page & 0x3)) { + /* XXX: This is ugly, but emitting two flips 'in a row' can cause + * lockups for unknown reasons. + */ + intel->sarea->pf_current_page = + intel->sarea->pf_current_page & 0x3; + intel->sarea->pf_current_page |= + ((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % + intel_fb->pf_num_pages) << 2; + + flip.planes = 0x2; + } else { + intel->sarea->pf_current_page = + intel->sarea->pf_current_page & (0x3 << 2); + intel->sarea->pf_current_page |= + (intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % + intel_fb->pf_num_pages; + + flip.planes = 0x1; + } + + drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); + } + + intel_fb->pf_planes = pf_planes; + } + + intel_fb->pf_active = pf_active; + intel_flip_renderbuffers(intel_fb); + intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); + + /* Update vblank info + */ + if (areaB > areaA || (areaA == areaB && areaB > 0)) { + flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY; + } else { + flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY; + } + + if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags && + !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) { + drmVBlank vbl; + int i; + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + + if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + + for (i = 0; i < intel_fb->pf_num_pages; i++) { + if (!intel_fb->color_rb[i] || + (intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <= + (1<<23)) + continue; + + vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending; + drmWaitVBlank(intel->driFd, &vbl); + } + + intel_fb->vblank_flags = flags; + driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq); + intel_fb->vbl_waited = intel_fb->vbl_seq; + + for (i = 0; i < intel_fb->pf_num_pages; i++) { + if (intel_fb->color_rb[i]) + intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited; + } + } + } else { + intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY; + } + + /* Update Mesa's notion of window size */ + driUpdateFramebufferSize(ctx, dPriv); + intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ + + /* Update hardware scissor */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + + /* Re-calculate viewport related state */ + ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); +} + + + +/* A true meta version of this would be very simple and additionally + * machine independent. Maybe we'll get there one day. + */ +static void +intelClearWithTris(struct intel_context *intel, GLbitfield mask) +{ + GLcontext *ctx = &intel->ctx; + struct gl_framebuffer *fb = ctx->DrawBuffer; + drm_clip_rect_t clear; + + if (INTEL_DEBUG & DEBUG_BLIT) + _mesa_printf("%s 0x%x\n", __FUNCTION__, mask); + + LOCK_HARDWARE(intel); + + /* XXX FBO: was: intel->driDrawable->numClipRects */ + if (intel->numClipRects) { + GLint cx, cy, cw, ch; + GLuint buf; + + intel->vtbl.install_meta_state(intel); + + /* Get clear bounds after locking */ + cx = fb->_Xmin; + cy = fb->_Ymin; + ch = fb->_Ymax - cx; + cw = fb->_Xmax - cy; + + /* note: regardless of 'all', cx, cy, cw, ch are now correct */ + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = cx + cw; + clear.y2 = cy + ch; + + /* Back and stencil cliprects are the same. Try and do both + * buffers at once: + */ + if (mask & + (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { + struct intel_region *backRegion = + intel_get_rb_region(fb, BUFFER_BACK_LEFT); + struct intel_region *depthRegion = + intel_get_rb_region(fb, BUFFER_DEPTH); + const GLuint clearColor = (backRegion && backRegion->cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + + intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); + + if (mask & BUFFER_BIT_BACK_LEFT) + intel->vtbl.meta_color_mask(intel, GL_TRUE); + else + intel->vtbl.meta_color_mask(intel, GL_FALSE); + + if (mask & BUFFER_BIT_STENCIL) + intel->vtbl.meta_stencil_replace(intel, + intel->ctx.Stencil.WriteMask[0], + intel->ctx.Stencil.Clear); + else + intel->vtbl.meta_no_stencil_write(intel); + + if (mask & BUFFER_BIT_DEPTH) + intel->vtbl.meta_depth_replace(intel); + else + intel->vtbl.meta_no_depth_write(intel); + + /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the + * drawing origin may not be correctly emitted. + */ + intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, intel->ctx.Depth.Clear, clearColor, 0, 0, 0, 0); /* texcoords */ + + mask &= + ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); + } + + /* clear the remaining (color) renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { + const GLuint bufBit = 1 << buf; + if (mask & bufBit) { + struct intel_renderbuffer *irbColor = + intel_renderbuffer(fb->Attachment[buf].Renderbuffer); + GLuint color = (irbColor->region->cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + + ASSERT(irbColor); + + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_TRUE); + intel->vtbl.meta_draw_region(intel, irbColor->region, NULL); + + /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the + * drawing origin may not be correctly emitted. + */ + intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, 0, /* depth clear val */ + color, 0, 0, 0, 0); /* texcoords */ + + mask &= ~bufBit; + } + } + + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); +} + + + + +/** + * Copy the window contents named by dPriv to the rotated (or reflected) + * color buffer. + * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source. + */ +void +intelRotateWindow(struct intel_context *intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf) +{ + intelScreenPrivate *screen = intel->intelScreen; + drm_clip_rect_t fullRect; + struct intel_framebuffer *intel_fb; + struct intel_region *src; + const drm_clip_rect_t *clipRects; + int numClipRects; + int i; + GLenum format, type; + + int xOrig, yOrig; + int origNumClipRects; + drm_clip_rect_t *origRects; + + /* + * set up hardware state + */ + intelFlush(&intel->ctx); + + LOCK_HARDWARE(intel); + + if (!intel->numClipRects) { + UNLOCK_HARDWARE(intel); + return; + } + + intel->vtbl.install_meta_state(intel); + + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_FALSE); + + + /* save current drawing origin and cliprects (restored at end) */ + xOrig = intel->drawX; + yOrig = intel->drawY; + origNumClipRects = intel->numClipRects; + origRects = intel->pClipRects; + + /* + * set drawing origin, cliprects for full-screen access to rotated screen + */ + fullRect.x1 = 0; + fullRect.y1 = 0; + fullRect.x2 = screen->rotatedWidth; + fullRect.y2 = screen->rotatedHeight; + intel->drawX = 0; + intel->drawY = 0; + intel->numClipRects = 1; + intel->pClipRects = &fullRect; + + intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ + + intel_fb = dPriv->driverPrivate; + + if ((srcBuf == BUFFER_BIT_BACK_LEFT && !intel_fb->pf_active)) { + src = intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT); + clipRects = dPriv->pBackClipRects; + numClipRects = dPriv->numBackClipRects; + } + else { + src = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT); + clipRects = dPriv->pClipRects; + numClipRects = dPriv->numClipRects; + } + + if (src->cpp == 4) { + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; + } + else { + format = GL_BGR; + type = GL_UNSIGNED_SHORT_5_6_5_REV; + } + + /* set the whole screen up as a texture to avoid alignment issues */ + intel->vtbl.meta_tex_rect_source(intel, + src->buffer, + screen->width, + screen->height, src->pitch, format, type); + + intel->vtbl.meta_texture_blend_replace(intel); + + /* + * loop over the source window's cliprects + */ + for (i = 0; i < numClipRects; i++) { + int srcX0 = clipRects[i].x1; + int srcY0 = clipRects[i].y1; + int srcX1 = clipRects[i].x2; + int srcY1 = clipRects[i].y2; + GLfloat verts[4][2], tex[4][2]; + int j; + + /* build vertices for four corners of clip rect */ + verts[0][0] = srcX0; + verts[0][1] = srcY0; + verts[1][0] = srcX1; + verts[1][1] = srcY0; + verts[2][0] = srcX1; + verts[2][1] = srcY1; + verts[3][0] = srcX0; + verts[3][1] = srcY1; + + /* .. and texcoords */ + tex[0][0] = srcX0; + tex[0][1] = srcY0; + tex[1][0] = srcX1; + tex[1][1] = srcY0; + tex[2][0] = srcX1; + tex[2][1] = srcY1; + tex[3][0] = srcX0; + tex[3][1] = srcY1; + + /* transform coords to rotated screen coords */ + + for (j = 0; j < 4; j++) { + matrix23TransformCoordf(&screen->rotMatrix, + &verts[j][0], &verts[j][1]); + } + + /* draw polygon to map source image to dest region */ + intel_meta_draw_poly(intel, 4, verts, 0, 0, tex); + + } /* cliprect loop */ + + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + + /* restore original drawing origin and cliprects */ + intel->drawX = xOrig; + intel->drawY = yOrig; + intel->numClipRects = origNumClipRects; + intel->pClipRects = origRects; + + UNLOCK_HARDWARE(intel); +} + + +/** + * Called by ctx->Driver.Clear. + */ +static void +intelClear(GLcontext *ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); + GLbitfield tri_mask = 0; + GLbitfield blit_mask = 0; + GLbitfield swrast_mask = 0; + struct gl_framebuffer *fb = ctx->DrawBuffer; + GLuint i; + + if (0) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* HW color buffers (front, back, aux, generic FBO, etc) */ + if (colorMask == ~0) { + /* clear all R,G,B,A */ + /* XXX FBO: need to check if colorbuffers are software RBOs! */ + blit_mask |= (mask & BUFFER_BITS_COLOR); + } + else { + /* glColorMask in effect */ + tri_mask |= (mask & BUFFER_BITS_COLOR); + } + + /* HW stencil */ + if (mask & BUFFER_BIT_STENCIL) { + const struct intel_region *stencilRegion + = intel_get_rb_region(fb, BUFFER_STENCIL); + if (stencilRegion) { + /* have hw stencil */ + if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { + /* not clearing all stencil bits, so use triangle clearing */ + tri_mask |= BUFFER_BIT_STENCIL; + } + else { + /* clearing all stencil bits, use blitting */ + blit_mask |= BUFFER_BIT_STENCIL; + } + } + } + + /* HW depth */ + if (mask & BUFFER_BIT_DEPTH) { + /* clear depth with whatever method is used for stencil (see above) */ + if (tri_mask & BUFFER_BIT_STENCIL) + tri_mask |= BUFFER_BIT_DEPTH; + else + blit_mask |= BUFFER_BIT_DEPTH; + } + + /* SW fallback clearing */ + swrast_mask = mask & ~tri_mask & ~blit_mask; + + for (i = 0; i < BUFFER_COUNT; i++) { + GLuint bufBit = 1 << i; + if ((blit_mask | tri_mask) & bufBit) { + if (!fb->Attachment[i].Renderbuffer->ClassID) { + blit_mask &= ~bufBit; + tri_mask &= ~bufBit; + swrast_mask |= bufBit; + } + } + } + + + intelFlush(ctx); /* XXX intelClearWithBlit also does this */ + + if (blit_mask) + intelClearWithBlit(ctx, blit_mask); + + if (tri_mask) + intelClearWithTris(intel, tri_mask); + + if (swrast_mask) + _swrast_Clear(ctx, swrast_mask); +} + + +/* Emit wait for pending flips */ +void +intel_wait_flips(struct intel_context *intel, GLuint batch_flags) +{ + struct intel_framebuffer *intel_fb = + (struct intel_framebuffer *) intel->ctx.DrawBuffer; + struct intel_renderbuffer *intel_rb = + intel_get_renderbuffer(&intel_fb->Base, + intel_fb->Base._ColorDrawBufferMask[0] == + BUFFER_BIT_FRONT_LEFT ? BUFFER_FRONT_LEFT : + BUFFER_BACK_LEFT); + + if (intel_fb->Base.Name == 0 && intel_rb->pf_pending == intel_fb->pf_seq) { + GLint pf_planes = intel_fb->pf_planes; + BATCH_LOCALS; + + /* Wait for pending flips to take effect */ + BEGIN_BATCH(2, batch_flags); + OUT_BATCH(pf_planes & 0x1 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP) + : 0); + OUT_BATCH(pf_planes & 0x2 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_B_FLIP) + : 0); + ADVANCE_BATCH(); + + intel_rb->pf_pending--; + } +} + + +/* Flip the front & back buffers + */ +static GLboolean +intelPageFlip(const __DRIdrawablePrivate * dPriv) +{ + struct intel_context *intel; + int ret; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + + if (INTEL_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; + + if (intel->intelScreen->drmMinor < 9) + return GL_FALSE; + + intelFlush(&intel->ctx); + + ret = 0; + + LOCK_HARDWARE(intel); + + if (dPriv->numClipRects && intel_fb->pf_active) { + drm_i915_flip_t flip; + + flip.planes = intel_fb->pf_planes; + + ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); + } + + UNLOCK_HARDWARE(intel); + + if (ret || !intel_fb->pf_active) + return GL_FALSE; + + if (!dPriv->numClipRects) { + usleep(10000); /* throttle invisible client 10ms */ + } + + intel_fb->pf_current_page = (intel->sarea->pf_current_page >> + (intel_fb->pf_planes & 0x2)) & 0x3; + + if (dPriv->numClipRects != 0) { + intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->pf_pending = + intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->pf_pending = + ++intel_fb->pf_seq; + } + + intel_flip_renderbuffers(intel_fb); + intel_draw_buffer(&intel->ctx, &intel_fb->Base); + + return GL_TRUE; +} + +#if 0 +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driverPrivate) { + const struct gl_framebuffer *fb + = (struct gl_framebuffer *) dPriv->driverPrivate; + if (fb->Visual.doubleBufferMode) { + GET_CURRENT_CONTEXT(ctx); + if (ctx && ctx->DrawBuffer == fb) { + _mesa_notifySwapBuffers(ctx); /* flush pending rendering */ + } + if (intel->doPageFlip) { + intelPageFlip(dPriv); + } + else { + intelCopyBuffer(dPriv); + } + } + } + else { + _mesa_problem(NULL, + "dPriv has no gl_framebuffer pointer in intelSwapBuffers"); + } +} +#else +/* Trunk version: + */ + +static GLboolean +intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) +{ + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags); + struct intel_context *intel = + intelScreenContext(dPriv->driScreenPriv->private); + const intelScreenPrivate *intelScreen = intel->intelScreen; + unsigned int target; + drm_i915_vblank_swap_t swap; + GLboolean ret; + + if (!intel_fb->vblank_flags || + (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) || + intelScreen->current_rotation != 0 || + intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6)) + return GL_FALSE; + + swap.seqtype = DRM_VBLANK_ABSOLUTE; + + if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) { + swap.seqtype |= DRM_VBLANK_NEXTONMISS; + } else if (interval == 0) { + return GL_FALSE; + } + + swap.drawable = dPriv->hHWDrawable; + target = swap.sequence = intel_fb->vbl_seq + interval; + + if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + swap.seqtype |= DRM_VBLANK_SECONDARY; + } + + LOCK_HARDWARE(intel); + + intel_batchbuffer_flush(intel->batch); + + if ( intel_fb->pf_active ) { + swap.seqtype |= DRM_VBLANK_FLIP; + + intel_fb->pf_current_page = (((intel->sarea->pf_current_page >> + (intel_fb->pf_planes & 0x2)) & 0x3) + 1) % + intel_fb->pf_num_pages; + } + + if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, + sizeof(swap))) { + intel_fb->vbl_seq = swap.sequence; + swap.sequence -= target; + *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); + + intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending = + intel_get_renderbuffer(&intel_fb->Base, + BUFFER_FRONT_LEFT)->vbl_pending = + intel_fb->vbl_seq; + + if (swap.seqtype & DRM_VBLANK_FLIP) { + intel_flip_renderbuffers(intel_fb); + intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); + } + + ret = GL_TRUE; + } else { + if (swap.seqtype & DRM_VBLANK_FLIP) { + intel_fb->pf_current_page = ((intel->sarea->pf_current_page >> + (intel_fb->pf_planes & 0x2)) & 0x3) % + intel_fb->pf_num_pages; + } + + ret = GL_FALSE; + } + + UNLOCK_HARDWARE(intel); + + return ret; +} + +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel; + + if (ctx == NULL) + return; + + intel = intel_context(ctx); + + if (ctx->Visual.doubleBufferMode) { + intelScreenPrivate *screen = intel->intelScreen; + GLboolean missed_target; + struct intel_framebuffer *intel_fb = dPriv->driverPrivate; + int64_t ust; + + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + + if (screen->current_rotation != 0 || + !intelScheduleSwap(dPriv, &missed_target)) { + driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags, + &missed_target); + + if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) { + intelCopyBuffer(dPriv, NULL); + } + + if (screen->current_rotation != 0) { + intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); + } + } + + intel_fb->swap_count++; + (*dri_interface->getUST) (&ust); + if (missed_target) { + intel_fb->swap_missed_count++; + intel_fb->swap_missed_ust = ust - intel_fb->swap_ust; + } + + intel_fb->swap_ust = ust; + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} +#endif + +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + struct intel_context *intel = + (struct intel_context *) dPriv->driContextPriv->driverPrivate; + GLcontext *ctx = &intel->ctx; + + if (ctx->Visual.doubleBufferMode) { + drm_clip_rect_t rect; + rect.x1 = x + dPriv->x; + rect.y1 = (dPriv->h - y - h) + dPriv->y; + rect.x2 = rect.x1 + w; + rect.y2 = rect.y1 + h; + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + intelCopyBuffer(dPriv, &rect); + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} + + +/** + * Update the hardware state for drawing into a window or framebuffer object. + * + * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other + * places within the driver. + * + * Basically, this needs to be called any time the current framebuffer + * changes, the renderbuffers change, or we need to draw into different + * color buffers. + */ +void +intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *colorRegion, *depthRegion = NULL; + struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; + int front = 0; /* drawing to front color buffer? */ + + if (!fb) { + /* this can happen during the initial context initialization */ + return; + } + + /* Do this here, note core Mesa, since this function is called from + * many places within the driver. + */ + if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + } + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + /* this may occur when we're called by glBindFrameBuffer() during + * the process of someone setting up renderbuffers, etc. + */ + /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ + return; + } + + if (fb->Name) + intel_validate_paired_depth_stencil(ctx, fb); + + /* + * How many color buffers are we drawing into? + */ + if (fb->_NumColorDrawBuffers[0] != 1 +#if 0 + /* XXX FBO temporary - always use software rendering */ + || 1 +#endif + ) { + /* writing to 0 or 2 or 4 color buffers */ + /*_mesa_debug(ctx, "Software rendering\n");*/ + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); + front = 1; /* might not have back color buffer */ + } + else { + /* draw to exactly one color buffer */ + /*_mesa_debug(ctx, "Hardware rendering\n");*/ + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { + front = 1; + } + } + + /* + * Get the intel_renderbuffer for the colorbuffer we're drawing into. + * And set up cliprects. + */ + if (fb->Name == 0) { + /* drawing to window system buffer */ + if (front) { + intelSetFrontClipRects(intel); + colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + } + else { + intelSetBackClipRects(intel); + colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); + } + } + else { + /* drawing to user-created FBO */ + struct intel_renderbuffer *irb; + intelSetRenderbufferClipRects(intel); + irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]); + colorRegion = (irb && irb->region) ? irb->region : NULL; + } + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; + + if (!colorRegion) { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); + } + else { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + } + + /*** + *** Get depth buffer region and check if we need a software fallback. + *** Note that the depth buffer is usually a DEPTH_STENCIL buffer. + ***/ + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { + irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped); + if (irbDepth && irbDepth->region) { + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); + depthRegion = irbDepth->region; + } + else { + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE); + depthRegion = NULL; + } + } + else { + /* not using depth buffer */ + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); + depthRegion = NULL; + } + + /*** + *** Stencil buffer + *** This can only be hardware accelerated if we're using a + *** combined DEPTH_STENCIL buffer (for now anyway). + ***/ + if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { + irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); + if (irbStencil && irbStencil->region) { + ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + if (!depthRegion) + depthRegion = irbStencil->region; + } + else { + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); + } + } + else { + /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + } + + /* + * Update depth test state + */ + if (ctx->Depth.Test && fb->Visual.depthBits > 0) { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); + } + else { + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); + } + + /** + ** Release old regions, reference new regions + **/ +#if 0 /* XXX FBO: this seems to be redundant with i915_state_draw_region() */ + if (intel->draw_region != colorRegion) { + intel_region_release(&intel->draw_region); + intel_region_reference(&intel->draw_region, colorRegion); + } + if (intel->intelScreen->depth_region != depthRegion) { + intel_region_release(&intel->intelScreen->depth_region); + intel_region_reference(&intel->intelScreen->depth_region, depthRegion); + } +#endif + + intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); + + /* update viewport since it depends on window size */ + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + + /* Update hardware scissor */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + + +static void +intelDrawBuffer(GLcontext * ctx, GLenum mode) +{ + intel_draw_buffer(ctx, ctx->DrawBuffer); +} + + +static void +intelReadBuffer(GLcontext * ctx, GLenum mode) +{ + if (ctx->ReadBuffer == ctx->DrawBuffer) { + /* This will update FBO completeness status. + * A framebuffer will be incomplete if the GL_READ_BUFFER setting + * refers to a missing renderbuffer. Calling glReadBuffer can set + * that straight and can make the drawing buffer complete. + */ + intel_draw_buffer(ctx, ctx->DrawBuffer); + } + /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc) + * reference ctx->ReadBuffer and do appropriate state checks. + */ +} + + +void +intelInitBufferFuncs(struct dd_function_table *functions) +{ + functions->Clear = intelClear; + functions->DrawBuffer = intelDrawBuffer; + functions->ReadBuffer = intelReadBuffer; +} diff --git a/src/mesa/drivers/dri/i915/intel_buffers.h b/src/mesa/drivers/dri/i915/intel_buffers.h new file mode 100644 index 0000000000..3b686cb5c1 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_buffers.h @@ -0,0 +1,59 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_BUFFERS_H +#define INTEL_BUFFERS_H + + +struct intel_context; +struct intel_framebuffer; + + +extern GLboolean +intel_intersect_cliprects(drm_clip_rect_t * dest, + const drm_clip_rect_t * a, + const drm_clip_rect_t * b); + +extern struct intel_region *intel_readbuf_region(struct intel_context *intel); + +extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); + +extern void intel_wait_flips(struct intel_context *intel, GLuint batch_flags); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelWindowMoved(struct intel_context *intel); + +extern void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb); + +extern void intelInitBufferFuncs(struct dd_function_table *functions); + +extern void +intelRotateWindow(struct intel_context *intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf); + +#endif /* INTEL_BUFFERS_H */ diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c new file mode 100644 index 0000000000..16fbe38e64 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -0,0 +1,797 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" +#include "extensions.h" +#include "framebuffer.h" +#include "imports.h" +#include "points.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" + +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "drivers/common/driverfuncs.h" + +#include "intel_screen.h" + +#include "i830_dri.h" + +#include "intel_buffers.h" +#include "intel_tex.h" +#include "intel_span.h" +#include "intel_tris.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_pixel.h" +#include "intel_regions.h" +#include "intel_buffer_objects.h" +#include "intel_fbo.h" +#include "intel_decode.h" + +#include "drirenderbuffer.h" +#include "vblank.h" +#include "utils.h" +#include "xmlpool.h" /* for symbolic values of enum-type options */ +#ifndef INTEL_DEBUG +int INTEL_DEBUG = (0); +#endif + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +#define DRIVER_DATE "20061102" + +_glthread_Mutex lockMutex; +static GLboolean lockMutexInit = GL_FALSE; + + +static const GLubyte * +intelGetString(GLcontext * ctx, GLenum name) +{ + const char *chipset; + static char buffer[128]; + + switch (name) { + case GL_VENDOR: + return (GLubyte *) "Tungsten Graphics, Inc"; + break; + + case GL_RENDERER: + switch (intel_context(ctx)->intelScreen->deviceID) { + case PCI_CHIP_845_G: + chipset = "Intel(R) 845G"; + break; + case PCI_CHIP_I830_M: + chipset = "Intel(R) 830M"; + break; + case PCI_CHIP_I855_GM: + chipset = "Intel(R) 852GM/855GM"; + break; + case PCI_CHIP_I865_G: + chipset = "Intel(R) 865G"; + break; + case PCI_CHIP_I915_G: + chipset = "Intel(R) 915G"; + break; + case PCI_CHIP_I915_GM: + chipset = "Intel(R) 915GM"; + break; + case PCI_CHIP_I945_G: + chipset = "Intel(R) 945G"; + break; + case PCI_CHIP_I945_GM: + chipset = "Intel(R) 945GM"; + break; + case PCI_CHIP_I945_GME: + chipset = "Intel(R) 945GME"; + break; + case PCI_CHIP_G33_G: + chipset = "Intel(R) G33"; + break; + case PCI_CHIP_Q35_G: + chipset = "Intel(R) Q35"; + break; + case PCI_CHIP_Q33_G: + chipset = "Intel(R) Q33"; + break; + default: + chipset = "Unknown Intel Chipset"; + break; + } + + (void) driGetRendererString(buffer, chipset, DRIVER_DATE, 0); + return (GLubyte *) buffer; + + default: + return NULL; + } +} + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", + GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, +#if 1 /* XXX FBO temporary? */ + {"GL_EXT_packed_depth_stencil", NULL}, +#endif + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, +/* { "GL_SGIS_generate_mipmap", NULL }, */ + {NULL, NULL} +}; + +const struct dri_extension ttm_extensions[] = { + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {NULL, NULL} +}; + +extern const struct tnl_pipeline_stage _intel_render_stage; + +static const struct tnl_pipeline_stage *intel_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_vertex_cull_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, + &_tnl_vertex_program_stage, +#if 1 + &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */ +#endif + &_tnl_render_stage, + 0, +}; + + +static const struct dri_debug_control debug_control[] = { + {"tex", DEBUG_TEXTURE}, + {"state", DEBUG_STATE}, + {"ioctl", DEBUG_IOCTL}, + {"blit", DEBUG_BLIT}, + {"mip", DEBUG_MIPTREE}, + {"fall", DEBUG_FALLBACKS}, + {"verb", DEBUG_VERBOSE}, + {"bat", DEBUG_BATCH}, + {"pix", DEBUG_PIXEL}, + {"buf", DEBUG_BUFMGR}, + {"reg", DEBUG_REGION}, + {"fbo", DEBUG_FBO}, + {"lock", DEBUG_LOCK}, + {NULL, 0} +}; + + +static void +intelInvalidateState(GLcontext * ctx, GLuint new_state) +{ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); + intel_context(ctx)->NewGLState |= new_state; +} + + +void +intelFlush(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + if (intel->Fallback) + _swrast_flush(ctx); + + INTEL_FIREVERTICES(intel); + + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); + + /* XXX: Need to do an MI_FLUSH here. + */ +} + + +/** + * Check if we need to rotate/warp the front color buffer to the + * rotated screen. We generally need to do this when we get a glFlush + * or glFinish after drawing to the front color buffer. + */ +static void +intelCheckFrontRotate(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == + BUFFER_BIT_FRONT_LEFT) { + intelScreenPrivate *screen = intel->intelScreen; + if (screen->current_rotation != 0) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); + } + } +} + + +/** + * Called via glFlush. + */ +static void +intelglFlush(GLcontext * ctx) +{ + intelFlush(ctx); + intelCheckFrontRotate(ctx); +} + +void +intelFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + intelFlush(ctx); + if (intel->batch->last_fence) { + dri_fence_wait(intel->batch->last_fence); + dri_fence_unreference(intel->batch->last_fence); + intel->batch->last_fence = NULL; + } + intelCheckFrontRotate(ctx); +} + + +void +intelInitDriverFunctions(struct dd_function_table *functions) +{ + _mesa_init_driver_functions(functions); + + functions->Flush = intelglFlush; + functions->Finish = intelFinish; + functions->GetString = intelGetString; + functions->UpdateState = intelInvalidateState; + functions->CopyColorTable = _swrast_CopyColorTable; + functions->CopyColorSubTable = _swrast_CopyColorSubTable; + functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + intelInitTextureFuncs(functions); + intelInitPixelFuncs(functions); + intelInitStateFuncs(functions); + intelInitBufferFuncs(functions); +} + + +GLboolean +intelInitContext(struct intel_context *intel, + const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate, + struct dd_function_table *functions) +{ + GLcontext *ctx = &intel->ctx; + GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + drmI830Sarea *saPriv = (drmI830Sarea *) + (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); + int fthrottle_mode; + + if (!_mesa_initialize_context(&intel->ctx, + mesaVis, shareCtx, + functions, (void *) intel)) + return GL_FALSE; + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + intel->width = intelScreen->width; + intel->height = intelScreen->height; + intel->current_rotation = intelScreen->current_rotation; + + if (!lockMutexInit) { + lockMutexInit = GL_TRUE; + _glthread_INIT_MUTEX(lockMutex); + } + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + ctx->Const.MaxTextureMaxAnisotropy = 2.0; + + /* This doesn't yet catch all non-conformant rendering, but it's a + * start. + */ + if (getenv("INTEL_STRICT_CONFORMANCE")) { + intel->strict_conformance = 1; + } + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 3.0; + ctx->Const.MaxLineWidthAA = 3.0; + ctx->Const.LineWidthGranularity = 1.0; + + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 255.0; + ctx->Const.MaxPointSizeAA = 3.0; + ctx->Const.PointSizeGranularity = 1.0; + + /* reinitialize the context point state. + * It depend on constants in __GLcontextRec::Const + */ + _mesa_init_point(ctx); + + ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ + + /* Initialize the software rasterizer and helper modules. */ + _swrast_CreateContext(ctx); + _vbo_CreateContext(ctx); + _tnl_CreateContext(ctx); + _swsetup_CreateContext(ctx); + + /* Install the customized pipeline: */ + _tnl_destroy_pipeline(ctx); + _tnl_install_pipeline(ctx, intel_pipeline); + + /* Configure swrast to match hardware characteristics: */ + _swrast_allow_pixel_fog(ctx, GL_FALSE); + _swrast_allow_vertex_fog(ctx, GL_TRUE); + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + intel->hw_stipple = 1; + + /* XXX FBO: this doesn't seem to be used anywhere */ + switch (mesaVis->depthBits) { + case 0: /* what to do in this case? */ + case 16: + intel->polygon_offset_scale = 1.0 / 0xffff; + break; + case 24: + intel->polygon_offset_scale = 2.0 / 0xffffff; /* req'd to pass glean */ + break; + default: + assert(0); + break; + } + + /* Initialize swrast, tnl driver tables: */ + intelInitSpanFuncs(ctx); + intelInitTriFuncs(ctx); + + + intel->RenderIndex = ~0; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->irqsEmitted = 0; + + intel->do_irqs = (intel->intelScreen->irq_active && + fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); + + intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); + + _math_matrix_ctr(&intel->ViewportMatrix); + + /* Disable imaging extension until convolution is working in + * teximage paths: + */ + driInitExtensions(ctx, card_extensions, +/* GL_TRUE, */ + GL_FALSE); + + if (intelScreen->ttm) + driInitExtensions(ctx, ttm_extensions, GL_FALSE); + + + intel->batch = intel_batchbuffer_alloc(intel); + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + + intel_bufferobj_init(intel); + intel_fbo_init(intel); + + if (intel->ctx.Mesa_DXTn) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(ctx, "GL_S3_s3tc"); + } + else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + } + + intel->prim.primitive = ~0; + + +#if DO_DEBUG + INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + + if (getenv("INTEL_NO_RAST")) { + fprintf(stderr, "disabling 3D rasterization\n"); + FALLBACK(intel, INTEL_FALLBACK_USER, 1); + } + + return GL_TRUE; +} + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = + (struct intel_context *) driContextPriv->driverPrivate; + + assert(intel); /* should never be null */ + if (intel) { + GLboolean release_texture_heaps; + + INTEL_FIREVERTICES(intel); + + intel->vtbl.destroy(intel); + + release_texture_heaps = (intel->ctx.Shared->RefCount == 1); + _swsetup_DestroyContext(&intel->ctx); + _tnl_DestroyContext(&intel->ctx); + _vbo_DestroyContext(&intel->ctx); + + _swrast_DestroyContext(&intel->ctx); + intel->Fallback = 0; /* don't call _swrast_Flush later */ + + intel_batchbuffer_free(intel->batch); + + if (intel->last_swap_fence) { + dri_fence_wait(intel->last_swap_fence); + dri_fence_unreference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + dri_fence_wait(intel->first_swap_fence); + dri_fence_unreference(intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + + if (release_texture_heaps) { + /* This share group is about to go away, free our private + * texture object data. + */ + if (INTEL_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "do something to free texture heaps\n"); + } + + /* free the Mesa context */ + _mesa_free_context_data(&intel->ctx); + } +} + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + return GL_TRUE; +} + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + + if (driContextPriv) { + struct intel_context *intel = + (struct intel_context *) driContextPriv->driverPrivate; + struct intel_framebuffer *intel_fb = + (struct intel_framebuffer *) driDrawPriv->driverPrivate; + GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate; + + + /* XXX FBO temporary fix-ups! */ + /* if the renderbuffers don't have regions, init them from the context */ + { + struct intel_renderbuffer *irbDepth + = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); + + if (intel_fb->color_rb[0] && !intel_fb->color_rb[0]->region) { + intel_region_reference(&intel_fb->color_rb[0]->region, + intel->intelScreen->front_region); + } + if (intel_fb->color_rb[1] && !intel_fb->color_rb[1]->region) { + intel_region_reference(&intel_fb->color_rb[1]->region, + intel->intelScreen->back_region); + } + if (intel_fb->color_rb[2] && !intel_fb->color_rb[2]->region) { + intel_region_reference(&intel_fb->color_rb[2]->region, + intel->intelScreen->third_region); + } + if (irbDepth && !irbDepth->region) { + intel_region_reference(&irbDepth->region, intel->intelScreen->depth_region); + } + if (irbStencil && !irbStencil->region) { + intel_region_reference(&irbStencil->region, intel->intelScreen->depth_region); + } + } + + /* set GLframebuffer size to match window, if needed */ + driUpdateFramebufferSize(&intel->ctx, driDrawPriv); + + if (driReadPriv != driDrawPriv) { + driUpdateFramebufferSize(&intel->ctx, driReadPriv); + } + + _mesa_make_current(&intel->ctx, &intel_fb->Base, readFb); + + /* The drawbuffer won't always be updated by _mesa_make_current: + */ + if (intel->ctx.DrawBuffer == &intel_fb->Base) { + + if (intel->driDrawable != driDrawPriv) { + if (driDrawPriv->pdraw->swap_interval == (unsigned)-1) { + int i; + + intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) + : VBLANK_FLAG_NO_IRQ; + + (*dri_interface->getUST) (&intel_fb->swap_ust); + driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags, + &intel_fb->vbl_seq); + intel_fb->vbl_waited = intel_fb->vbl_seq; + + for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) { + if (intel_fb->color_rb[i]) + intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq; + } + } + intel->driDrawable = driDrawPriv; + intelWindowMoved(intel); + } + + intel_draw_buffer(&intel->ctx, &intel_fb->Base); + } + } + else { + _mesa_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +static void +intelContendedLock(struct intel_context *intel, GLuint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - got contended lock\n", __progname); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dPriv) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + + /* If the last consumer of the texture memory wasn't us, notify the fake + * bufmgr and record the new owner. We should have the memory shared + * between contexts of a single fake bufmgr, but this will at least make + * things correct for now. + */ + if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) { + sarea->texAge = intel->hHWContext; + dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + if (INTEL_DEBUG & DEBUG_BATCH) + intel_decode_context_reset(); + } + + if (sarea->width != intelScreen->width || + sarea->height != intelScreen->height || + sarea->rotation != intelScreen->current_rotation) { + + intelUpdateScreenRotation(sPriv, sarea); + } + + if (sarea->width != intel->width || + sarea->height != intel->height || + sarea->rotation != intel->current_rotation) { + int numClipRects = intel->numClipRects; + + /* + * FIXME: Really only need to do this when drawing to a + * common back- or front buffer. + */ + + /* + * This will essentially drop the outstanding batchbuffer on the floor. + */ + intel->numClipRects = 0; + + if (intel->Fallback) + _swrast_flush(&intel->ctx); + + INTEL_FIREVERTICES(intel); + + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); + + intel->numClipRects = numClipRects; + + /* force window update */ + intel->lastStamp = 0; + + intel->width = sarea->width; + intel->height = sarea->height; + intel->current_rotation = sarea->rotation; + } + + /* Drawable changed? + */ + if (dPriv && intel->lastStamp != dPriv->lastStamp) { + intelWindowMoved(intel); + intel->lastStamp = dPriv->lastStamp; + } +} + + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret=0; + struct intel_framebuffer *intel_fb = NULL; + struct intel_renderbuffer *intel_rb = NULL; + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + if (intel->driDrawable) { + intel_fb = intel->driDrawable->driverPrivate; + + if (intel_fb) + intel_rb = + intel_get_renderbuffer(&intel_fb->Base, + intel_fb->Base._ColorDrawBufferMask[0] == + BUFFER_BIT_FRONT_LEFT ? BUFFER_FRONT_LEFT : + BUFFER_BACK_LEFT); + } + + if (intel_rb && intel_fb->vblank_flags && + !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) && + (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) { + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + + if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + + vbl.request.sequence = intel_rb->vbl_pending; + drmWaitVBlank(intel->driFd, &vbl); + intel_fb->vbl_waited = vbl.reply.sequence; + } + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - locked\n", __progname); + + intel->locked = 1; +} + + + /* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - unlocked\n", __progname); +} + diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h new file mode 100644 index 0000000000..1e9ccd5cdc --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -0,0 +1,498 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTELCONTEXT_INC +#define INTELCONTEXT_INC + + + +#include "mtypes.h" +#include "drm.h" +#include "mm.h" +#include "texmem.h" + +#include "intel_screen.h" +#include "i915_drm.h" +#include "i830_common.h" +#include "tnl/t_vertex.h" + +#define TAG(x) intel##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +#define DV_PF_555 (1<<8) +#define DV_PF_565 (2<<8) +#define DV_PF_8888 (3<<8) + +struct intel_region; +struct intel_context; + +typedef void (*intel_tri_func) (struct intel_context *, intelVertex *, + intelVertex *, intelVertex *); +typedef void (*intel_line_func) (struct intel_context *, intelVertex *, + intelVertex *); +typedef void (*intel_point_func) (struct intel_context *, intelVertex *); + +#define INTEL_FALLBACK_DRAW_BUFFER 0x1 +#define INTEL_FALLBACK_READ_BUFFER 0x2 +#define INTEL_FALLBACK_DEPTH_BUFFER 0x4 +#define INTEL_FALLBACK_STENCIL_BUFFER 0x8 +#define INTEL_FALLBACK_USER 0x10 +#define INTEL_FALLBACK_RENDERMODE 0x20 + +extern void intelFallback(struct intel_context *intel, GLuint bit, + GLboolean mode); +#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode ) + + +#define INTEL_WRITE_PART 0x1 +#define INTEL_WRITE_FULL 0x2 +#define INTEL_READ 0x4 + +struct intel_texture_object +{ + struct gl_texture_object base; /* The "parent" object */ + + /* The mipmap tree must include at least these levels once + * validated: + */ + GLuint firstLevel; + GLuint lastLevel; + + /* Offset for firstLevel image: + */ + GLuint textureOffset; + + /* On validation any active images held in main memory or in other + * regions will be copied to this region and the old storage freed. + */ + struct intel_mipmap_tree *mt; + + GLboolean imageOverride; + GLint depthOverride; + GLuint pitchOverride; +}; + + + +struct intel_texture_image +{ + struct gl_texture_image base; + + /* These aren't stored in gl_texture_image + */ + GLuint level; + GLuint face; + + /* If intelImage->mt != NULL, image data is stored here. + * Else if intelImage->base.Data != NULL, image is stored there. + * Else there is no image data. + */ + struct intel_mipmap_tree *mt; +}; + + +#define INTEL_MAX_FIXUP 64 + +struct intel_context +{ + GLcontext ctx; /* the parent class */ + + struct + { + void (*destroy) (struct intel_context * intel); + void (*emit_state) (struct intel_context * intel); + void (*lost_hardware) (struct intel_context * intel); + void (*update_texture_state) (struct intel_context * intel); + + void (*render_start) (struct intel_context * intel); + void (*render_prevalidate) (struct intel_context * intel); + void (*set_draw_region) (struct intel_context * intel, + struct intel_region * draw_region, + struct intel_region * depth_region); + + GLuint(*flush_cmd) (void); + + void (*reduced_primitive_state) (struct intel_context * intel, + GLenum rprim); + + GLboolean(*check_vertex_size) (struct intel_context * intel, + GLuint expected); + + + /* Metaops: + */ + void (*install_meta_state) (struct intel_context * intel); + void (*leave_meta_state) (struct intel_context * intel); + + void (*meta_draw_region) (struct intel_context * intel, + struct intel_region * draw_region, + struct intel_region * depth_region); + + void (*meta_color_mask) (struct intel_context * intel, GLboolean); + + void (*meta_stencil_replace) (struct intel_context * intel, + GLuint mask, GLuint clear); + + void (*meta_depth_replace) (struct intel_context * intel); + + void (*meta_texture_blend_replace) (struct intel_context * intel); + + void (*meta_no_stencil_write) (struct intel_context * intel); + void (*meta_no_depth_write) (struct intel_context * intel); + void (*meta_no_texture) (struct intel_context * intel); + + void (*meta_import_pixel_state) (struct intel_context * intel); + + GLboolean(*meta_tex_rect_source) (struct intel_context * intel, + dri_bo * buffer, + GLuint offset, + GLuint pitch, + GLuint height, + GLenum format, GLenum type); + void (*rotate_window) (struct intel_context * intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf); + + void (*assert_not_dirty) (struct intel_context *intel); + + } vtbl; + + GLint refcount; + GLuint Fallback; + GLuint NewGLState; + + dri_fence *last_swap_fence; + dri_fence *first_swap_fence; + + struct intel_batchbuffer *batch; + + struct + { + GLuint id; + GLuint primitive; + GLubyte *start_ptr; + void (*flush) (struct intel_context *); + } prim; + + GLboolean locked; + char *prevLockFile; + int prevLockLine; + + GLuint ClearColor565; + GLuint ClearColor8888; + + /* Offsets of fields within the current vertex: + */ + GLuint coloroffset; + GLuint specoffset; + GLuint wpos_offset; + GLuint wpos_size; + + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + + GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */ + + GLboolean hw_stipple; + GLboolean strict_conformance; + + /* State for intelvb.c and inteltris.c. + */ + GLuint RenderIndex; + GLmatrix ViewportMatrix; + GLenum render_primitive; + GLenum reduced_primitive; + GLuint vertex_size; + GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ + +#if 0 + struct intel_region *front_region; /* XXX FBO: obsolete */ + struct intel_region *rotated_region; /* XXX FBO: obsolete */ + struct intel_region *back_region; /* XXX FBO: obsolete */ + struct intel_region *draw_region; /* XXX FBO: rename to color_region */ + struct intel_region *depth_region; /**< currently bound depth/Z region */ +#endif + + /* Fallback rasterization functions + */ + intel_point_func draw_point; + intel_line_func draw_line; + intel_tri_func draw_tri; + + /* These refer to the current drawing buffer: + */ + int drawX, drawY; /**< origin of drawing area within region */ + GLuint numClipRects; /**< cliprects for drawing */ + drm_clip_rect_t *pClipRects; + drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ + + int perf_boxes; + + GLuint do_usleeps; + int do_irqs; + GLuint irqsEmitted; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + intelScreenPrivate *intelScreen; + drmI830Sarea *sarea; + + GLuint lastStamp; + + /** + * Configuration cache + */ + driOptionCache optionCache; + + /* Rotation. Need to match that of the + * current screen. + */ + + int width; + int height; + int current_rotation; +}; + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + +#define SUBPIXEL_X 0.125 +#define SUBPIXEL_Y 0.125 + +#define INTEL_FIREVERTICES(intel) \ +do { \ + if ((intel)->prim.flush) \ + (intel)->prim.flush(intel); \ +} while (0) + +/* ================================================================ + * Color packing: + */ + +#define INTEL_PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define INTEL_PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define INTEL_PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define INTEL_PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + + +/* ================================================================ + * From linux kernel i386 header files, copes with odd sizes better + * than COPY_DWORDS would: + * XXX Put this in src/mesa/main/imports.h ??? + */ +#if defined(i386) || defined(__i386__) +static INLINE void * +__memcpy(void *to, const void *from, size_t n) +{ + int d0, d1, d2; + __asm__ __volatile__("rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) + :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) + :"memory"); + return (to); +} +#else +#define __memcpy(a,b,c) memcpy(a,b,c) +#endif + + + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 +#if DO_DEBUG +extern int INTEL_DEBUG; +#else +#define INTEL_DEBUG 0 +#endif + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BLIT 0x8 +#define DEBUG_MIPTREE 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_BATCH 0x80 +#define DEBUG_PIXEL 0x100 +#define DEBUG_BUFMGR 0x200 +#define DEBUG_REGION 0x400 +#define DEBUG_FBO 0x800 +#define DEBUG_LOCK 0x1000 + +#define DBG(...) do { if (INTEL_DEBUG & FILE_DEBUG_FLAG) _mesa_printf(__VA_ARGS__); } while(0) + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_Q33_G 0x29D2 + + +/* ================================================================ + * intel_context.c: + */ + +extern GLboolean intelInitContext(struct intel_context *intel, + const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate, + struct dd_function_table *functions); + +extern void intelGetLock(struct intel_context *intel, GLuint flags); + +extern void intelFinish(GLcontext * ctx); +extern void intelFlush(GLcontext * ctx); + +extern void intelInitDriverFunctions(struct dd_function_table *functions); + + +/* ================================================================ + * intel_state.c: + */ +extern void intelInitStateFuncs(struct dd_function_table *functions); + +#define COMPAREFUNC_ALWAYS 0 +#define COMPAREFUNC_NEVER 0x1 +#define COMPAREFUNC_LESS 0x2 +#define COMPAREFUNC_EQUAL 0x3 +#define COMPAREFUNC_LEQUAL 0x4 +#define COMPAREFUNC_GREATER 0x5 +#define COMPAREFUNC_NOTEQUAL 0x6 +#define COMPAREFUNC_GEQUAL 0x7 + +#define STENCILOP_KEEP 0 +#define STENCILOP_ZERO 0x1 +#define STENCILOP_REPLACE 0x2 +#define STENCILOP_INCRSAT 0x3 +#define STENCILOP_DECRSAT 0x4 +#define STENCILOP_INCR 0x5 +#define STENCILOP_DECR 0x6 +#define STENCILOP_INVERT 0x7 + +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf + +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_DST_COLR 0x09 +#define BLENDFACT_INV_DST_COLR 0x0a +#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b +#define BLENDFACT_CONST_COLOR 0x0c +#define BLENDFACT_INV_CONST_COLOR 0x0d +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f +#define BLENDFACT_MASK 0x0f + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +extern int intel_translate_compare_func(GLenum func); +extern int intel_translate_stencil_op(GLenum op); +extern int intel_translate_blend_factor(GLenum factor); +extern int intel_translate_logic_op(GLenum opcode); + + +/*====================================================================== + * Inline conversion functions. + * These are better-typed than the macros used previously: + */ +static INLINE struct intel_context * +intel_context(GLcontext * ctx) +{ + return (struct intel_context *) ctx; +} + +static INLINE struct intel_texture_object * +intel_texture_object(struct gl_texture_object *obj) +{ + return (struct intel_texture_object *) obj; +} + +static INLINE struct intel_texture_image * +intel_texture_image(struct gl_texture_image *img) +{ + return (struct intel_texture_image *) img; +} + +extern struct intel_renderbuffer *intel_renderbuffer(struct gl_renderbuffer + *rb); + + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_decode.c b/src/mesa/drivers/dri/i915/intel_decode.c new file mode 100644 index 0000000000..bf3387b28e --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_decode.c @@ -0,0 +1,832 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +/** @file intel_decode.c + * This file contains code to print out batchbuffer contents in a + * human-readable format. + * + * The current version only supports i915 packets, and only pretty-prints a + * subset of them. The intention is for it to make just a best attempt to + * decode, but never crash in the process. + */ + +#include +#include +#include + +#include "intel_decode.h" +#include "i915_reg.h" + +#define BUFFER_FAIL(_count, _len, _name) do { \ + fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ + (_name), (_count), (_len)); \ + (*failures)++; \ + return count; \ +} while (0) + +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; + +static float +int_as_float(uint32_t intval) +{ + union intfloat { + uint32_t i; + float f; + } uval; + + uval.i = intval; + return uval.f; +} + +static void +instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, + char *fmt, ...) +{ + va_list va; + + fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); + va_start(va, fmt); + vfprintf(out, fmt, va); + va_end(va); +} + + +static int +decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_mi[] = { + { 0x08, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 1, 1, "MI_FLUSH" }, + { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 1, 1, "MI_NOOP" }, + { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, + }; + + + for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); + opcode++) { + if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); + if (opcodes_mi[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_mi[opcode].min_len || + len > opcodes_mi[opcode].max_len) + { + fprintf(out, "Bad length in %s\n", + opcodes_mi[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_mi[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode, len; + char *format; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_2d[] = { + { 0x40, 5, 5, "COLOR_BLT" }, + { 0x43, 6, 6, "SRC_COPY_BLT" }, + { 0x01, 8, 8, "XY_SETUP_BLT" }, + { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, + { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, + { 0x24, 2, 2, "XY_PIXEL_BLT" }, + { 0x25, 3, 3, "XY_SCANLINES_BLT" }, + { 0x26, 4, 4, "Y_TEXT_BLT" }, + { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, + { 0x50, 6, 6, "XY_COLOR_BLT" }, + { 0x51, 6, 6, "XY_PAT_BLT" }, + { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, + { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, + { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, + { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, + { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, + { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, + { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, + { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, + { 0x55, 9, 9, "XY_FULL_BLT" }, + { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, + { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, + { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, + { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, + { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, + }; + + switch ((data[0] & 0x1fc00000) >> 22) { + case 0x50: + instr_out(data, hw_offset, 0, + "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 6) + fprintf(out, "Bad count in XY_COLOR_BLT\n"); + if (count < 6) + BUFFER_FAIL(count, len, "XY_COLOR_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "color\n"); + return len; + case 0x53: + instr_out(data, hw_offset, 0, + "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 8) + fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); + if (count < 8) + BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "src (%d,%d)\n", + data[5] & 0xffff, data[5] >> 16); + instr_out(data, hw_offset, 6, "src pitch %d\n", + data[6] & 0xffff); + instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); + opcode++) { + if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { + unsigned int i; + + len = 1; + instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); + if (opcodes_2d[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_2d[opcode].min_len || + len > opcodes_2d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_2d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + switch ((data[0] & 0x00f80000) >> 19) { + case 0x11: + instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); + return 1; + case 0x10: + instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); + return 1; + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int len, i, c, opcode, word, map, sampler, instr; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d_1d[] = { + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, + { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, + { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, + { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, + { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, + { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, + { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, + { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, + { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, + { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, + { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, + { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, + { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, + { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, + }; + + switch ((data[0] & 0x00ff0000) >> 16) { + case 0x07: + /* This instruction is unusual. A 0 length means just 1 DWORD instead of + * 2. The 0 length is specified in one place to be unsupported, but + * stated to be required in another, and 0 length LOAD_INDIRECTs appear + * to cause no harm at least. + */ + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); + len = (data[0] & 0x000000ff) + 1; + i = 1; + if (data[0] & (0x01 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SIS.0\n"); + instr_out(data, hw_offset, i++, "SIS.1\n"); + } + if (data[0] & (0x02 << 8)) { + if (i + 1 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "DIS.0\n"); + } + if (data[0] & (0x04 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SSB.0\n"); + instr_out(data, hw_offset, i++, "SSB.1\n"); + } + if (data[0] & (0x08 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "MSB.0\n"); + instr_out(data, hw_offset, i++, "MSB.1\n"); + } + if (data[0] & (0x10 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSP.0\n"); + instr_out(data, hw_offset, i++, "PSP.1\n"); + } + if (data[0] & (0x20 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSC.0\n"); + instr_out(data, hw_offset, i++, "PSC.1\n"); + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + return len; + } + return len; + case 0x04: + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); + len = (data[0] & 0x0000000f) + 2; + i = 1; + for (word = 0; word <= 7; word++) { + if (data[0] & (1 << (4 + word))) { + if (i >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + + /* save vertex state for decode */ + if (word == 2) { + saved_s2_set = 1; + saved_s2 = data[i]; + } + if (word == 4) { + saved_s4_set = 1; + saved_s4 = data[i]; + } + + instr_out(data, hw_offset, i++, "S%d\n", word); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + } + return len; + case 0x00: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + + i = 1; + for (map = 0; map <= 15; map++) { + if (data[1] & (1 << map)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "map %d MS2\n", map); + instr_out(data, hw_offset, i++, "map %d MS3\n", map); + instr_out(data, hw_offset, i++, "map %d MS4\n", map); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + return len; + } + return len; + case 0x06: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + len = (data[0] & 0x000000ff) + 2; + + i = 1; + for (c = 0; c <= 31; c++) { + if (data[1] & (1 << c)) { + if (i + 4 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); + instr_out(data, hw_offset, i, "C%d.X = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Y = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Z = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.W = %f\n", + c, int_as_float(data[i])); + i++; + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + } + return len; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); + len = (data[0] & 0x000000ff) + 2; + if ((len - 1) % 3 != 0 || len > 370) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); + (*failures)++; + } + i = 1; + for (instr = 0; instr < (len - 1) / 3; instr++) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + } + return len; + case 0x01: + instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + i = 1; + for (sampler = 0; sampler <= 15; sampler++) { + if (data[1] & (1 << sampler)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); + instr_out(data, hw_offset, i++, "sampler %d SS2\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS3\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS4\n", + sampler); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); + (*failures)++; + } + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); + opcode++) + { + if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); + if (opcodes_3d_1d[opcode].max_len > 1) { + len = (data[0] & 0x0000ffff) + 2; + if (len < opcodes_3d_1d[opcode].min_len || + len > opcodes_3d_1d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", + opcodes_3d_1d[opcode].name); + (*failures)++; + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, + int *failures) +{ + char immediate = (data[0] & (1 << 23)) == 0; + unsigned int len, i; + char *primtype; + + switch ((data[0] >> 18) & 0xf) { + case 0x0: primtype = "TRILIST"; break; + case 0x1: primtype = "TRISTRIP"; break; + case 0x2: primtype = "TRISTRIP_REVERSE"; break; + case 0x3: primtype = "TRIFAN"; break; + case 0x4: primtype = "POLYGON"; break; + case 0x5: primtype = "LINELIST"; break; + case 0x6: primtype = "LINESTRIP"; break; + case 0x7: primtype = "RECTLIST"; break; + case 0x8: primtype = "POINTLIST"; break; + case 0x9: primtype = "DIB"; break; + case 0xa: primtype = "CLEAR_RECT"; break; + default: primtype = "unknown"; break; + } + + /* XXX: 3DPRIM_DIB not supported */ + if (immediate) { + len = (data[0] & 0x0003ffff) + 2; + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); + if (!saved_s2_set || !saved_s4_set) { + fprintf(out, "unknown vertex format\n"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + unsigned int vertex = 0; + for (i = 1; i < len;) { + unsigned int tc; + +#define VERTEX_OUT(fmt, ...) do { \ + if (i < len) \ + instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ + else \ + fprintf(out, " missing data in V%d\n", vertex); \ + i++; \ +} while (0) + + VERTEX_OUT("X = %f", int_as_float(data[i])); + VERTEX_OUT("Y = %f", int_as_float(data[i])); + switch (saved_s4 >> 6 & 0x7) { + case 0x1: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + case 0x3: + break; + case 0x4: + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + default: + fprintf(out, "bad S4 position mask\n"); + } + + if (saved_s4 & (1 << 10)) { + VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 11)) { + VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 12)) + VERTEX_OUT("width = 0x%08x)", data[i]); + + for (tc = 0; tc <= 7; tc++) { + switch ((saved_s2 >> (tc * 4)) & 0xf) { + case 0x0: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + break; + case 0x1: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); + break; + case 0x3: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + break; + case 0x4: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + break; + case 0x5: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); + break; + case 0xf: + break; + default: + fprintf(out, "bad S2.T%d format\n", tc); + } + } + vertex++; + } + } + } else { + /* indirect vertices */ + len = data[0] & 0x0000ffff; /* index count */ + if (data[0] & (1 << 17)) { + /* random vertex access */ + if (count < (len + 1) / 2 + 1) { + BUFFER_FAIL(count, (len + 1) / 2 + 1, + "3DPRIMITIVE random indirect"); + } + instr_out(data, hw_offset, 0, + "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); + if (len == 0) { + /* vertex indices continue until 0xffff is found */ + for (i = 1; i < count; i++) { + if ((data[i] & 0xffff) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: (terminator)\n"); + return i; + } else if ((data[i] >> 16) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: 0x%04x, " + "(terminator)\n", + data[i] & 0xffff); + return i; + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + fprintf(out, + "3DPRIMITIVE: no terminator found in index buffer\n"); + (*failures)++; + return count; + } else { + /* fixed size vertex index buffer */ + for (i = 0; i < len; i += 2) { + if (i * 2 == len - 1) { + instr_out(data, hw_offset, i, + " indices: 0x%04x\n", + data[i] & 0xffff); + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + } + return (len + 1) / 2 + 1; + } else { + /* sequential vertex access */ + if (count < 2) + BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); + instr_out(data, hw_offset, 0, + "3DPRIMITIVE sequential indirect %s, %d starting from " + "%d\n", primtype, len, data[1] & 0xffff); + instr_out(data, hw_offset, 1, " start\n"); + return 2; + } + } + + return len; +} + +static int +decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, + { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, + { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, + { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, + { 0x0d, 1, 1, "3DSTATE_MODES_4" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** + * Decodes an i830-i915 batch buffer, writing the output to stdout. + * + * \param data batch buffer contents + * \param count number of DWORDs to decode in the batch buffer + * \param hw_offset hardware address for the buffer + */ +int +intel_decode(uint32_t *data, int count, uint32_t hw_offset) +{ + int index = 0; + int failures = 0; + + out = stdout; + + while (index < count) { + switch ((data[index] & 0xe0000000) >> 29) { + case 0x0: + index += decode_mi(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x2: + index += decode_2d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x3: + index += decode_3d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + default: + instr_out(data, hw_offset, index, "UNKNOWN\n"); + failures++; + index++; + break; + } + fflush(out); + } + + return failures; +} + +void intel_decode_context_reset() +{ + saved_s2_set = 0; + saved_s4_set = 1; +} + diff --git a/src/mesa/drivers/dri/i915/intel_decode.h b/src/mesa/drivers/dri/i915/intel_decode.h new file mode 100644 index 0000000000..ef0cba153c --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_decode.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +int intel_decode(uint32_t *data, int count, uint32_t hw_offset); +void intel_decode_context_reset(); diff --git a/src/mesa/drivers/dri/i915/intel_depthstencil.c b/src/mesa/drivers/dri/i915/intel_depthstencil.c new file mode 100644 index 0000000000..d269a85a3c --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_depthstencil.c @@ -0,0 +1,282 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "depthstencil.h" +#include "fbobject.h" +#include "framebuffer.h" +#include "hash.h" +#include "mtypes.h" +#include "renderbuffer.h" + +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_depthstencil.h" +#include "intel_regions.h" + + +/** + * The GL_EXT_framebuffer_object allows the user to create their own + * framebuffer objects consisting of color renderbuffers (0 or more), + * depth renderbuffers (0 or 1) and stencil renderbuffers (0 or 1). + * + * The spec considers depth and stencil renderbuffers to be totally independent + * buffers. In reality, most graphics hardware today uses a combined + * depth+stencil buffer (one 32-bit pixel = 24 bits of Z + 8 bits of stencil). + * + * This causes difficulty because the user may create some number of depth + * renderbuffers and some number of stencil renderbuffers and bind them + * together in framebuffers in any combination. + * + * This code manages all that. + * + * 1. Depth renderbuffers are always allocated in hardware as 32bpp + * GL_DEPTH24_STENCIL8 buffers. + * + * 2. Stencil renderbuffers are initially allocated in software as 8bpp + * GL_STENCIL_INDEX8 buffers. + * + * 3. Depth and Stencil renderbuffers use the PairedStencil and PairedDepth + * fields (respectively) to indicate if the buffer's currently paired + * with another stencil or depth buffer (respectively). + * + * 4. When a depth and stencil buffer are initially both attached to the + * current framebuffer, we merge the stencil buffer values into the + * depth buffer (really a depth+stencil buffer). The then hardware uses + * the combined buffer. + * + * 5. Whenever a depth or stencil buffer is reallocated (with + * glRenderbufferStorage) we undo the pairing and copy the stencil values + * from the combined depth/stencil buffer back to the stencil-only buffer. + * + * 6. We also undo the pairing when we find a change in buffer bindings. + * + * 7. If a framebuffer is only using a depth renderbuffer (no stencil), we + * just use the combined depth/stencil buffer and ignore the stencil values. + * + * 8. If a framebuffer is only using a stencil renderbuffer (no depth) we have + * to promote the 8bpp software stencil buffer to a 32bpp hardware + * depth+stencil buffer. + * + */ + + + +static void +map_regions(GLcontext * ctx, + struct intel_renderbuffer *depthRb, + struct intel_renderbuffer *stencilRb) +{ + struct intel_context *intel = intel_context(ctx); + if (depthRb && depthRb->region) { + intel_region_map(intel->intelScreen, depthRb->region); + depthRb->pfMap = depthRb->region->map; + depthRb->pfPitch = depthRb->region->pitch; + } + if (stencilRb && stencilRb->region) { + intel_region_map(intel->intelScreen, stencilRb->region); + stencilRb->pfMap = stencilRb->region->map; + stencilRb->pfPitch = stencilRb->region->pitch; + } +} + +static void +unmap_regions(GLcontext * ctx, + struct intel_renderbuffer *depthRb, + struct intel_renderbuffer *stencilRb) +{ + struct intel_context *intel = intel_context(ctx); + if (depthRb && depthRb->region) { + intel_region_unmap(intel->intelScreen, depthRb->region); + depthRb->pfMap = NULL; + depthRb->pfPitch = 0; + } + if (stencilRb && stencilRb->region) { + intel_region_unmap(intel->intelScreen, stencilRb->region); + stencilRb->pfMap = NULL; + stencilRb->pfPitch = 0; + } +} + + + +/** + * Undo the pairing/interleaving between depth and stencil buffers. + * irb should be a depth/stencil or stencil renderbuffer. + */ +void +intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb) +{ + if (irb->PairedStencil) { + /* irb is a depth/stencil buffer */ + struct gl_renderbuffer *stencilRb; + struct intel_renderbuffer *stencilIrb; + + ASSERT(irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + stencilRb = _mesa_lookup_renderbuffer(ctx, irb->PairedStencil); + stencilIrb = intel_renderbuffer(stencilRb); + if (stencilIrb) { + /* need to extract stencil values from the depth buffer */ + ASSERT(stencilIrb->PairedDepth == irb->Base.Name); + map_regions(ctx, irb, stencilIrb); + _mesa_extract_stencil(ctx, &irb->Base, &stencilIrb->Base); + unmap_regions(ctx, irb, stencilIrb); + stencilIrb->PairedDepth = 0; + } + irb->PairedStencil = 0; + } + else if (irb->PairedDepth) { + /* irb is a stencil buffer */ + struct gl_renderbuffer *depthRb; + struct intel_renderbuffer *depthIrb; + + ASSERT(irb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || + irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + depthRb = _mesa_lookup_renderbuffer(ctx, irb->PairedDepth); + depthIrb = intel_renderbuffer(depthRb); + if (depthIrb) { + /* need to extract stencil values from the depth buffer */ + ASSERT(depthIrb->PairedStencil == irb->Base.Name); + map_regions(ctx, depthIrb, irb); + _mesa_extract_stencil(ctx, &depthIrb->Base, &irb->Base); + unmap_regions(ctx, depthIrb, irb); + depthIrb->PairedStencil = 0; + } + irb->PairedDepth = 0; + } + else { + _mesa_problem(ctx, "Problem in undo_depth_stencil_pairing"); + } + + ASSERT(irb->PairedStencil == 0); + ASSERT(irb->PairedDepth == 0); +} + + +/** + * Examine the depth and stencil renderbuffers which are attached to the + * framebuffer. If both depth and stencil are attached, make sure that the + * renderbuffers are 'paired' (combined). If only depth or only stencil is + * attached, undo any previous pairing. + * + * Must be called if NewState & _NEW_BUFFER (when renderbuffer attachments + * change, for example). + */ +void +intel_validate_paired_depth_stencil(GLcontext * ctx, + struct gl_framebuffer *fb) +{ + struct intel_renderbuffer *depthRb, *stencilRb; + + depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH); + stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); + + if (depthRb && stencilRb) { + if (depthRb == stencilRb) { + /* Using a user-created combined depth/stencil buffer. + * Nothing to do. + */ + ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_STENCIL_EXT); + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + } + else { + /* Separate depth/stencil buffers, need to interleave now */ + ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_COMPONENT); + ASSERT(stencilRb->Base._BaseFormat == GL_STENCIL_INDEX); + /* may need to interleave depth/stencil now */ + if (depthRb->PairedStencil == stencilRb->Base.Name) { + /* OK, the depth and stencil buffers are already interleaved */ + ASSERT(stencilRb->PairedDepth == depthRb->Base.Name); + } + else { + /* need to setup new pairing/interleaving */ + if (depthRb->PairedStencil) { + intel_unpair_depth_stencil(ctx, depthRb); + } + if (stencilRb->PairedDepth) { + intel_unpair_depth_stencil(ctx, stencilRb); + } + + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + ASSERT(stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || + stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + /* establish new pairing: interleave stencil into depth buffer */ + map_regions(ctx, depthRb, stencilRb); + _mesa_insert_stencil(ctx, &depthRb->Base, &stencilRb->Base); + unmap_regions(ctx, depthRb, stencilRb); + depthRb->PairedStencil = stencilRb->Base.Name; + stencilRb->PairedDepth = depthRb->Base.Name; + } + + } + } + else if (depthRb) { + /* Depth buffer but no stencil buffer. + * We'll use a GL_DEPTH24_STENCIL8 buffer and ignore the stencil bits. + */ + /* can't assert this until storage is allocated: + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + */ + /* intel_undo any previous pairing */ + if (depthRb->PairedStencil) { + intel_unpair_depth_stencil(ctx, depthRb); + } + } + else if (stencilRb) { + /* Stencil buffer but no depth buffer. + * Since h/w doesn't typically support just 8bpp stencil w/out Z, + * we'll use a GL_DEPTH24_STENCIL8 buffer and ignore the depth bits. + */ + /* undo any previous pairing */ + if (stencilRb->PairedDepth) { + intel_unpair_depth_stencil(ctx, stencilRb); + } + if (stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT) { + /* promote buffer to GL_DEPTH24_STENCIL8 for hw rendering */ + _mesa_promote_stencil(ctx, &stencilRb->Base); + ASSERT(stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + } + } + + /* Finally, update the fb->_DepthBuffer and fb->_StencilBuffer fields */ + _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); + if (depthRb && depthRb->PairedStencil) + _mesa_update_stencil_buffer(ctx, fb, BUFFER_DEPTH); + else + _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); + + + /* The hardware should use fb->Attachment[BUFFER_DEPTH].Renderbuffer + * first, if present, then fb->Attachment[BUFFER_STENCIL].Renderbuffer + * if present. + */ +} diff --git a/src/mesa/drivers/dri/i915/intel_depthstencil.h b/src/mesa/drivers/dri/i915/intel_depthstencil.h new file mode 100644 index 0000000000..2d3fc48b3a --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_depthstencil.h @@ -0,0 +1,14 @@ + +#ifndef INTEL_DEPTH_STENCIL_H +#define INTEL_DEPTH_STENCIL_H + + +extern void +intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb); + +extern void +intel_validate_paired_depth_stencil(GLcontext * ctx, + struct gl_framebuffer *fb); + + +#endif /* INTEL_DEPTH_STENCIL_H */ diff --git a/src/mesa/drivers/dri/i915/intel_fbo.c b/src/mesa/drivers/dri/i915/intel_fbo.c new file mode 100644 index 0000000000..6f99f401c7 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_fbo.c @@ -0,0 +1,687 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "imports.h" +#include "mtypes.h" +#include "fbobject.h" +#include "framebuffer.h" +#include "renderbuffer.h" +#include "context.h" +#include "texformat.h" +#include "texrender.h" + +#include "intel_context.h" +#include "intel_buffers.h" +#include "intel_depthstencil.h" +#include "intel_fbo.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "intel_span.h" + + +#define FILE_DEBUG_FLAG DEBUG_FBO + +#define INTEL_RB_CLASS 0x12345678 + + +/* XXX FBO: move this to intel_context.h (inlined) */ +/** + * Return a gl_renderbuffer ptr casted to intel_renderbuffer. + * NULL will be returned if the rb isn't really an intel_renderbuffer. + * This is determiend by checking the ClassID. + */ +struct intel_renderbuffer * +intel_renderbuffer(struct gl_renderbuffer *rb) +{ + struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + if (irb && irb->Base.ClassID == INTEL_RB_CLASS) { + /*_mesa_warning(NULL, "Returning non-intel Rb\n");*/ + return irb; + } + else + return NULL; +} + + +struct intel_renderbuffer * +intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex) +{ + return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); +} + + +void +intel_flip_renderbuffers(struct intel_framebuffer *intel_fb) +{ + int current_page = intel_fb->pf_current_page; + int next_page = (current_page + 1) % intel_fb->pf_num_pages; + struct gl_renderbuffer *tmp_rb; + + /* Exchange renderbuffers if necessary but make sure their reference counts + * are preserved. + */ + if (intel_fb->color_rb[current_page] && + intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer != + &intel_fb->color_rb[current_page]->Base) { + tmp_rb = NULL; + _mesa_reference_renderbuffer(&tmp_rb, + intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + tmp_rb = &intel_fb->color_rb[current_page]->Base; + _mesa_reference_renderbuffer( + &intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb); + _mesa_reference_renderbuffer(&tmp_rb, NULL); + } + + if (intel_fb->color_rb[next_page] && + intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer != + &intel_fb->color_rb[next_page]->Base) { + tmp_rb = NULL; + _mesa_reference_renderbuffer(&tmp_rb, + intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + tmp_rb = &intel_fb->color_rb[next_page]->Base; + _mesa_reference_renderbuffer( + &intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb); + _mesa_reference_renderbuffer(&tmp_rb, NULL); + } +} + + +struct intel_region * +intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) +{ + struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex); + + if (irb) + return irb->region; + else + return NULL; +} + + + +/** + * Create a new framebuffer object. + */ +static struct gl_framebuffer * +intel_new_framebuffer(GLcontext * ctx, GLuint name) +{ + /* Only drawable state in intel_framebuffer at this time, just use Mesa's + * class + */ + return _mesa_new_framebuffer(ctx, name); +} + + +static void +intel_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + + ASSERT(irb); + + if (irb->PairedStencil || irb->PairedDepth) { + intel_unpair_depth_stencil(ctx, irb); + } + + if (intel && irb->region) { + intel_region_release(&irb->region); + } + + _mesa_free(irb); +} + + + +/** + * Return a pointer to a specific pixel in a renderbuffer. + */ +static void * +intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + /* By returning NULL we force all software rendering to go through + * the span routines. + */ + return NULL; +} + + + +/** + * Called via glRenderbufferStorageEXT() to set the format and allocate + * storage for a user-created renderbuffer. + */ +static GLboolean +intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + GLboolean softwareBuffer = GL_FALSE; + int cpp; + + ASSERT(rb->Name != 0); + + switch (internalFormat) { + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + rb->_ActualFormat = GL_RGB5; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 5; + rb->GreenBits = 6; + rb->BlueBits = 5; + cpp = 2; + break; + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + rb->_ActualFormat = GL_RGBA8; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 8; + rb->GreenBits = 8; + rb->BlueBits = 8; + rb->AlphaBits = 8; + cpp = 4; + break; + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX1_EXT: + case GL_STENCIL_INDEX4_EXT: + case GL_STENCIL_INDEX8_EXT: + case GL_STENCIL_INDEX16_EXT: + /* alloc a depth+stencil buffer */ + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->StencilBits = 8; + cpp = 4; + break; + case GL_DEPTH_COMPONENT16: + rb->_ActualFormat = GL_DEPTH_COMPONENT16; + rb->DataType = GL_UNSIGNED_SHORT; + rb->DepthBits = 16; + cpp = 2; + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + cpp = 4; + break; + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + rb->StencilBits = 8; + cpp = 4; + break; + default: + _mesa_problem(ctx, + "Unexpected format in intel_alloc_renderbuffer_storage"); + return GL_FALSE; + } + + intelFlush(ctx); + + /* free old region */ + if (irb->region) { + intel_region_release(&irb->region); + } + + /* allocate new memory region/renderbuffer */ + if (softwareBuffer) { + return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, + width, height); + } + else { + /* Choose a pitch to match hardware requirements: + */ + GLuint pitch = ((cpp * width + 63) & ~63) / cpp; + + /* alloc hardware renderbuffer */ + DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, + height, pitch); + + irb->region = intel_region_alloc(intel->intelScreen, cpp, pitch, height); + if (!irb->region) + return GL_FALSE; /* out of memory? */ + + ASSERT(irb->region->buffer); + + rb->Width = width; + rb->Height = height; + + /* This sets the Get/PutRow/Value functions */ + intel_set_span_functions(&irb->Base); + + return GL_TRUE; + } +} + + + +/** + * Called for each hardware renderbuffer when a _window_ is resized. + * Just update fields. + * Not used for user-created renderbuffers! + */ +static GLboolean +intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + ASSERT(rb->Name == 0); + rb->Width = width; + rb->Height = height; + rb->_ActualFormat = internalFormat; + + return GL_TRUE; +} + +static void +intel_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb, + GLuint width, GLuint height) +{ + struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)fb; + int i; + + _mesa_resize_framebuffer(ctx, fb, width, height); + + fb->Initialized = GL_TRUE; /* XXX remove someday */ + + if (fb->Name != 0) { + return; + } + + /* Make sure all window system renderbuffers are up to date */ + for (i = 0; i < 3; i++) { + struct gl_renderbuffer *rb = &intel_fb->color_rb[i]->Base; + + /* only resize if size is changing */ + if (rb && (rb->Width != width || rb->Height != height)) { + rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height); + } + } +} + +static GLboolean +intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); + return GL_FALSE; +} + + + +/** + * Create a new intel_renderbuffer which corresponds to an on-screen window, + * not a user-created renderbuffer. + * \param width the screen width + * \param height the screen height + */ +struct intel_renderbuffer * +intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, + int offset, int pitch, int cpp, void *map) +{ + GET_CURRENT_CONTEXT(ctx); + + struct intel_renderbuffer *irb; + const GLuint name = 0; + + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + switch (intFormat) { + case GL_RGB5: + irb->Base._ActualFormat = GL_RGB5; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.RedBits = 5; + irb->Base.GreenBits = 6; + irb->Base.BlueBits = 5; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 2; + break; + case GL_RGBA8: + irb->Base._ActualFormat = GL_RGBA8; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.RedBits = 8; + irb->Base.GreenBits = 8; + irb->Base.BlueBits = 8; + irb->Base.AlphaBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 4; + break; + case GL_STENCIL_INDEX8_EXT: + irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT; + irb->Base._BaseFormat = GL_STENCIL_INDEX; + irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 1; + break; + case GL_DEPTH_COMPONENT16: + irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + irb->Base.DepthBits = 16; + irb->Base.DataType = GL_UNSIGNED_SHORT; + cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + irb->Base.DepthBits = 24; + irb->Base.DataType = GL_UNSIGNED_INT; + cpp = 4; + break; + case GL_DEPTH24_STENCIL8_EXT: + irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; + irb->Base.DepthBits = 24; + irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; + cpp = 4; + break; + default: + _mesa_problem(NULL, + "Unexpected intFormat in intel_create_renderbuffer"); + return NULL; + } + + irb->Base.InternalFormat = intFormat; + + /* intel-specific methods */ + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_alloc_window_storage; + irb->Base.GetPointer = intel_get_pointer; + /* This sets the Get/PutRow/Value functions */ + intel_set_span_functions(&irb->Base); + + irb->pfMap = map; + irb->pfPitch = pitch / cpp; /* in pixels */ + +#if 00 + irb->region = intel_region_create_static(intel, + DRM_MM_TT, + offset, map, cpp, width, height); +#endif + + return irb; +} + + +/** + * Create a new renderbuffer object. + * Typically called via glBindRenderbufferEXT(). + */ +static struct gl_renderbuffer * +intel_new_renderbuffer(GLcontext * ctx, GLuint name) +{ + /*struct intel_context *intel = intel_context(ctx); */ + struct intel_renderbuffer *irb; + + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + /* intel-specific methods */ + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_alloc_renderbuffer_storage; + irb->Base.GetPointer = intel_get_pointer; + /* span routines set in alloc_storage function */ + + return &irb->Base; +} + + +/** + * Called via glBindFramebufferEXT(). + */ +static void +intel_bind_framebuffer(GLcontext * ctx, GLenum target, + struct gl_framebuffer *fb, struct gl_framebuffer *fbread) +{ + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + intel_draw_buffer(ctx, fb); + /* Integer depth range depends on depth buffer bits */ + ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far); + } + else { + /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ + } +} + + +/** + * Called via glFramebufferRenderbufferEXT(). + */ +static void +intel_framebuffer_renderbuffer(GLcontext * ctx, + struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); + + intelFlush(ctx); + + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + intel_draw_buffer(ctx, fb); +} + + +/** + * When glFramebufferTexture[123]D is called this function sets up the + * gl_renderbuffer wrapper around the texture image. + * This will have the region info needed for hardware rendering. + */ +static struct intel_renderbuffer * +intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +{ + const GLuint name = ~0; /* not significant, but distinct for debugging */ + struct intel_renderbuffer *irb; + + /* make an intel_renderbuffer to wrap the texture image */ + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + if (texImage->TexFormat == &_mesa_texformat_argb8888) { + irb->Base._ActualFormat = GL_RGBA8; + irb->Base._BaseFormat = GL_RGBA; + DBG("Render to RGBA8 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_rgb565) { + irb->Base._ActualFormat = GL_RGB5; + irb->Base._BaseFormat = GL_RGB; + DBG("Render to RGB5 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_z16) { + irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + DBG("Render to DEPTH16 texture OK\n"); + } + else { + DBG("Render to texture BAD FORMAT %d\n", + texImage->TexFormat->MesaFormat); + _mesa_free(irb); + return NULL; + } + + irb->Base.InternalFormat = irb->Base._ActualFormat; + irb->Base.Width = texImage->Width; + irb->Base.Height = texImage->Height; + irb->Base.DataType = GL_UNSIGNED_BYTE; /* FBO XXX fix */ + irb->Base.RedBits = texImage->TexFormat->RedBits; + irb->Base.GreenBits = texImage->TexFormat->GreenBits; + irb->Base.BlueBits = texImage->TexFormat->BlueBits; + irb->Base.AlphaBits = texImage->TexFormat->AlphaBits; + irb->Base.DepthBits = texImage->TexFormat->DepthBits; + + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_nop_alloc_storage; + intel_set_span_functions(&irb->Base); + + irb->RenderToTexture = GL_TRUE; + + return irb; +} + + +/** + * Called by glFramebufferTexture[123]DEXT() (and other places) to + * prepare for rendering into texture memory. This might be called + * many times to choose different texture levels, cube faces, etc + * before intel_finish_render_texture() is ever called. + */ +static void +intel_render_texture(GLcontext * ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct gl_texture_image *newImage + = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); + struct intel_texture_image *intel_image; + GLuint imageOffset; + + (void) fb; + + ASSERT(newImage); + + if (!irb) { + irb = intel_wrap_texture(ctx, newImage); + if (irb) { + /* bind the wrapper to the attachment point */ + _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base); + } + else { + /* fallback to software rendering */ + _mesa_render_texture(ctx, fb, att); + return; + } + } + + DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", + _glthread_GetID(), + att->Texture->Name, newImage->Width, newImage->Height, + irb->Base.RefCount); + + /* point the renderbufer's region to the texture image region */ + intel_image = intel_texture_image(newImage); + if (irb->region != intel_image->mt->region) { + if (irb->region) + intel_region_release(&irb->region); + intel_region_reference(&irb->region, intel_image->mt->region); + } + + /* compute offset of the particular 2D image within the texture region */ + imageOffset = intel_miptree_image_offset(intel_image->mt, + att->CubeMapFace, + att->TextureLevel); + + if (att->Texture->Target == GL_TEXTURE_3D) { + const GLuint *offsets = intel_miptree_depth_offsets(intel_image->mt, + att->TextureLevel); + imageOffset += offsets[att->Zoffset]; + } + + /* store that offset in the region */ + intel_image->mt->region->draw_offset = imageOffset; + + /* update drawing region, etc */ + intel_draw_buffer(ctx, fb); +} + + +/** + * Called by Mesa when rendering to a texture is done. + */ +static void +intel_finish_render_texture(GLcontext * ctx, + struct gl_renderbuffer_attachment *att) +{ + struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); + + DBG("End render texture (tid %x) tex %u\n", _glthread_GetID(), att->Texture->Name); + + if (irb) { + /* just release the region */ + intel_region_release(&irb->region); + } + else if (att->Renderbuffer) { + /* software fallback */ + _mesa_finish_render_texture(ctx, att); + /* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */ + } +} + + +/** + * Do one-time context initializations related to GL_EXT_framebuffer_object. + * Hook in device driver functions. + */ +void +intel_fbo_init(struct intel_context *intel) +{ + intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; + intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; + intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; + intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; + intel->ctx.Driver.RenderTexture = intel_render_texture; + intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; + intel->ctx.Driver.ResizeBuffers = intel_resize_buffers; +} diff --git a/src/mesa/drivers/dri/i915/intel_fbo.h b/src/mesa/drivers/dri/i915/intel_fbo.h new file mode 100644 index 0000000000..411d634231 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_fbo.h @@ -0,0 +1,115 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_FBO_H +#define INTEL_FBO_H + + +struct intel_context; +struct intel_region; + +/** + * Intel framebuffer, derived from gl_framebuffer. + */ +struct intel_framebuffer +{ + struct gl_framebuffer Base; + + struct intel_renderbuffer *color_rb[3]; + + /* Drawable page flipping state */ + GLboolean pf_active; + GLuint pf_seq; + GLint pf_planes; + GLint pf_current_page; + GLint pf_num_pages; + + /* VBI + */ + GLuint vbl_seq; + GLuint vblank_flags; + GLuint vbl_waited; + + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; +}; + + +/** + * Intel renderbuffer, derived from gl_renderbuffer. + * Note: The PairedDepth and PairedStencil fields use renderbuffer IDs, + * not pointers because in some circumstances a deleted renderbuffer could + * result in a dangling pointer here. + */ +struct intel_renderbuffer +{ + struct gl_renderbuffer Base; + struct intel_region *region; + void *pfMap; /* possibly paged flipped map pointer */ + GLuint pfPitch; /* possibly paged flipped pitch */ + GLboolean RenderToTexture; /* RTT? */ + + GLuint PairedDepth; /**< only used if this is a depth renderbuffer */ + GLuint PairedStencil; /**< only used if this is a stencil renderbuffer */ + + GLuint pf_pending; /**< sequence number of pending flip */ + + GLuint vbl_pending; /**< vblank sequence number of pending flip */ +}; + + +extern struct intel_renderbuffer *intel_create_renderbuffer(GLenum intFormat, + GLsizei width, + GLsizei height, + int offset, + int pitch, + int cpp, + void *map); + + +extern void intel_fbo_init(struct intel_context *intel); + + +/* XXX make inline or macro */ +extern struct intel_renderbuffer *intel_get_renderbuffer(struct gl_framebuffer + *fb, + GLuint attIndex); + +extern void intel_flip_renderbuffers(struct intel_framebuffer *intel_fb); + + +/* XXX make inline or macro */ +extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb, + GLuint attIndex); + + + + +#endif /* INTEL_FBO_H */ diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c new file mode 100644 index 0000000000..6e76737c78 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_ioctl.c @@ -0,0 +1,135 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include +#include +#include +#include + +#include "mtypes.h" +#include "context.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "drm.h" + +#define FILE_DEBUG_FLAG DEBUG_IOCTL + +int +intelEmitIrqLocked(intelScreenPrivate *intelScreen) +{ + drmI830IrqEmit ie; + int ret, seq; + + ie.irq_seq = &seq; + + ret = drmCommandWriteRead(intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_EMIT, &ie, sizeof(ie)); + if (ret) { + fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); + exit(1); + } + + DBG("%s --> %d\n", __FUNCTION__, seq); + + return seq; +} + +void +intelWaitIrq(intelScreenPrivate *intelScreen, int seq) +{ + drm_i915_irq_wait_t iw; + int ret; + + DBG("%s %d\n", __FUNCTION__, seq); + + iw.irq_seq = seq; + + do { + ret = drmCommandWrite(intelScreen->driScrnPriv->fd, + DRM_I830_IRQ_WAIT, &iw, sizeof(iw)); + } while (ret == -EAGAIN || ret == -EINTR); + + if (ret) { + fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); + exit(1); + } +} + + +void +intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + drmI830BatchBuffer batch; + + assert(intel->locked); + assert(used); + + DBG("%s used %d offset %x..%x ignore_cliprects %d\n", + __FUNCTION__, + used, start_offset, start_offset + used, ignore_cliprects); + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + + + batch.start = start_offset; + batch.used = used; + batch.cliprects = intel->pClipRects; + batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + batch.DR1 = 0; + batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); + + DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); + + if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } + + /* FIXME: use hardware contexts to avoid 'losing' hardware after + * each buffer flush. + */ + intel->vtbl.lost_hardware(intel); +} diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h new file mode 100644 index 0000000000..7a5b175ed1 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_ioctl.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_IOCTL_H +#define INTEL_IOCTL_H + +#include "intel_context.h" + +void intelWaitIrq(intelScreenPrivate *intelScreen, int seq); +int intelEmitIrqLocked(intelScreenPrivate *intelScreen); + +void intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock); +#endif diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c new file mode 100644 index 0000000000..74f6b2d851 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c @@ -0,0 +1,371 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "enums.h" + +#define FILE_DEBUG_FLAG DEBUG_MIPTREE + +static GLenum +target_to_target(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return GL_TEXTURE_CUBE_MAP_ARB; + default: + return target; + } +} + +struct intel_mipmap_tree * +intel_miptree_create(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, GLuint cpp, GLuint compress_byte) +{ + GLboolean ok; + struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); + + DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); + + mt->target = target_to_target(target); + mt->internal_format = internal_format; + mt->first_level = first_level; + mt->last_level = last_level; + mt->width0 = width0; + mt->height0 = height0; + mt->depth0 = depth0; + mt->cpp = compress_byte ? compress_byte : cpp; + mt->compressed = compress_byte ? 1 : 0; + mt->refcount = 1; + + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q33_G: + case PCI_CHIP_Q35_G: + ok = i945_miptree_layout(mt); + break; + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + case PCI_CHIP_I830_M: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + default: + /* All the i830 chips and the i915 use this layout: + */ + ok = i915_miptree_layout(mt); + break; + } + + if (ok) { + if (!mt->compressed) { + /* XXX: Align pitch to multiple of 64 bytes for now to allow + * render-to-texture to work in all cases. This should probably be + * replaced at some point by some scheme to only do this when really + * necessary. + */ + mt->pitch = ((mt->pitch * cpp + 63) & ~63) / cpp; + } + + mt->region = intel_region_alloc(intel->intelScreen, + mt->cpp, mt->pitch, mt->total_height); + } + + if (!mt->region) { + free(mt); + return NULL; + } + + return mt; +} + + +void +intel_miptree_reference(struct intel_mipmap_tree **dst, + struct intel_mipmap_tree *src) +{ + src->refcount++; + *dst = src; + DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount); +} + +void +intel_miptree_release(struct intel_context *intel, + struct intel_mipmap_tree **mt) +{ + if (!*mt) + return; + + DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1); + if (--(*mt)->refcount <= 0) { + GLuint i; + + DBG("%s deleting %p\n", __FUNCTION__, *mt); + + intel_region_release(&((*mt)->region)); + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + if ((*mt)->level[i].image_offset) + free((*mt)->level[i].image_offset); + + free(*mt); + } + *mt = NULL; +} + + + + +/* Can the image be pulled into a unified mipmap tree. This mirrors + * the completeness test in a lot of ways. + * + * Not sure whether I want to pass gl_texture_image here. + */ +GLboolean +intel_miptree_match_image(struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, GLuint level) +{ + /* Images with borders are never pulled into mipmap trees. + */ + if (image->Border) + return GL_FALSE; + + if (image->InternalFormat != mt->internal_format || + image->IsCompressed != mt->compressed) + return GL_FALSE; + + /* Test image dimensions against the base level image adjusted for + * minification. This will also catch images not present in the + * tree, changed targets, etc. + */ + if (image->Width != mt->level[level].width || + image->Height != mt->level[level].height || + image->Depth != mt->level[level].depth) + return GL_FALSE; + + return GL_TRUE; +} + + +void +intel_miptree_set_level_info(struct intel_mipmap_tree *mt, + GLuint level, + GLuint nr_images, + GLuint x, GLuint y, GLuint w, GLuint h, GLuint d) +{ + + mt->level[level].width = w; + mt->level[level].height = h; + mt->level[level].depth = d; + mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; + mt->level[level].nr_images = nr_images; + + DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + level, w, h, d, x, y, mt->level[level].level_offset); + + /* Not sure when this would happen, but anyway: + */ + if (mt->level[level].image_offset) { + free(mt->level[level].image_offset); + mt->level[level].image_offset = NULL; + } + + assert(nr_images); + + mt->level[level].image_offset = malloc(nr_images * sizeof(GLuint)); + mt->level[level].image_offset[0] = 0; +} + + + +void +intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, + GLuint level, GLuint img, GLuint x, GLuint y) +{ + if (img == 0 && level == 0) + assert(x == 0 && y == 0); + + assert(img < mt->level[level].nr_images); + + mt->level[level].image_offset[img] = (x + y * mt->pitch); + + DBG("%s level %d img %d pos %d,%d image_offset %x\n", + __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); +} + + +/* Although we use the image_offset[] array to store relative offsets + * to cube faces, Mesa doesn't know anything about this and expects + * each cube face to be treated as a separate image. + * + * These functions present that view to mesa: + */ +const GLuint * +intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level) +{ + static const GLuint zero = 0; + + if (mt->target != GL_TEXTURE_3D || mt->level[level].nr_images == 1) + return &zero; + else + return mt->level[level].image_offset; +} + + +GLuint +intel_miptree_image_offset(struct intel_mipmap_tree * mt, + GLuint face, GLuint level) +{ + if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) + return (mt->level[level].level_offset + + mt->level[level].image_offset[face] * mt->cpp); + else + return mt->level[level].level_offset; +} + + + +/** + * Map a teximage in a mipmap tree. + * \param row_stride returns row stride in bytes + * \param image_stride returns image stride in bytes (for 3D textures). + * \return address of mapping + */ +GLubyte * +intel_miptree_image_map(struct intel_context * intel, + struct intel_mipmap_tree * mt, + GLuint face, + GLuint level, + GLuint * row_stride, GLuint * image_offsets) +{ + DBG("%s \n", __FUNCTION__); + + if (row_stride) + *row_stride = mt->pitch * mt->cpp; + + if (image_offsets) + memcpy(image_offsets, mt->level[level].image_offset, + mt->level[level].depth * sizeof(GLuint)); + + return (intel_region_map(intel->intelScreen, mt->region) + + intel_miptree_image_offset(mt, face, level)); +} + +void +intel_miptree_image_unmap(struct intel_context *intel, + struct intel_mipmap_tree *mt) +{ + DBG("%s\n", __FUNCTION__); + intel_region_unmap(intel->intelScreen, mt->region); +} + + + +/* Upload data for a particular image. + */ +void +intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, + GLuint src_row_pitch, GLuint src_image_pitch) +{ + GLuint depth = dst->level[level].depth; + GLuint dst_offset = intel_miptree_image_offset(dst, face, level); + const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); + GLuint i; + GLuint height = 0; + + DBG("%s\n", __FUNCTION__); + for (i = 0; i < depth; i++) { + height = dst->level[level].height; + if(dst->compressed) + height /= 4; + intel_region_data(intel->intelScreen, dst->region, + dst_offset + dst_depth_offset[i], /* dst_offset */ + 0, 0, /* dstx, dsty */ + src, + src_row_pitch, + 0, 0, /* source x, y */ + dst->level[level].width, height); /* width, height */ + + src += src_image_pitch * dst->cpp; + } +} + +extern GLuint intel_compressed_alignment(GLenum); +/* Copy mipmap image between trees + */ +void +intel_miptree_image_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src) +{ + GLuint width = src->level[level].width; + GLuint height = src->level[level].height; + GLuint depth = src->level[level].depth; + GLuint dst_offset = intel_miptree_image_offset(dst, face, level); + GLuint src_offset = intel_miptree_image_offset(src, face, level); + const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); + const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); + GLuint i; + + if (dst->compressed) { + GLuint alignment = intel_compressed_alignment(dst->internal_format); + height = (height + 3) / 4; + width = ((width + alignment - 1) & ~(alignment - 1)); + } + + for (i = 0; i < depth; i++) { + intel_region_copy(intel->intelScreen, + dst->region, dst_offset + dst_depth_offset[i], + 0, + 0, + src->region, src_offset + src_depth_offset[i], + 0, 0, width, height); + } + +} diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h new file mode 100644 index 0000000000..ecdb7be244 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h @@ -0,0 +1,198 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_MIPMAP_TREE_H +#define INTEL_MIPMAP_TREE_H + +#include "intel_regions.h" + +/* A layer on top of the intel_regions code which adds: + * + * - Code to size and layout a region to hold a set of mipmaps. + * - Query to determine if a new image fits in an existing tree. + * - More refcounting + * - maybe able to remove refcounting from intel_region? + * - ? + * + * The fixed mipmap layout of intel hardware where one offset + * specifies the position of all images in a mipmap hierachy + * complicates the implementation of GL texture image commands, + * compared to hardware where each image is specified with an + * independent offset. + * + * In an ideal world, each texture object would be associated with a + * single bufmgr buffer or 2d intel_region, and all the images within + * the texture object would slot into the tree as they arrive. The + * reality can be a little messier, as images can arrive from the user + * with sizes that don't fit in the existing tree, or in an order + * where the tree layout cannot be guessed immediately. + * + * This structure encodes an idealized mipmap tree. The GL image + * commands build these where possible, otherwise store the images in + * temporary system buffers. + */ + + +/** + * Describes the location of each texture image within a texture region. + */ +struct intel_mipmap_level +{ + GLuint level_offset; + GLuint width; + GLuint height; + GLuint depth; + GLuint nr_images; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + GLuint *image_offset; +}; + +struct intel_mipmap_tree +{ + /* Effectively the key: + */ + GLenum target; + GLenum internal_format; + + GLuint first_level; + GLuint last_level; + + GLuint width0, height0, depth0; /**< Level zero image dimensions */ + GLuint cpp; + GLboolean compressed; + + /* Derived from the above: + */ + GLuint pitch; + GLuint depth_pitch; /* per-image on i945? */ + GLuint total_height; + + /* Includes image offset tables: + */ + struct intel_mipmap_level level[MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct intel_region *region; + + /* These are also refcounted: + */ + GLuint refcount; +}; + + + +struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, + GLuint cpp, + GLuint compress_byte); + +void intel_miptree_reference(struct intel_mipmap_tree **dst, + struct intel_mipmap_tree *src); + +void intel_miptree_release(struct intel_context *intel, + struct intel_mipmap_tree **mt); + +/* Check if an image fits an existing mipmap tree layout + */ +GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, GLuint level); + +/* Return a pointer to an image within a tree. Return image stride as + * well. + */ +GLubyte *intel_miptree_image_map(struct intel_context *intel, + struct intel_mipmap_tree *mt, + GLuint face, + GLuint level, + GLuint * row_stride, GLuint * image_stride); + +void intel_miptree_image_unmap(struct intel_context *intel, + struct intel_mipmap_tree *mt); + + +/* Return the linear offset of an image relative to the start of the + * tree: + */ +GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, + GLuint face, GLuint level); + +/* Return pointers to each 2d slice within an image. Indexed by depth + * value. + */ +const GLuint *intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, + GLuint level); + + +void intel_miptree_set_level_info(struct intel_mipmap_tree *mt, + GLuint level, + GLuint nr_images, + GLuint x, GLuint y, + GLuint w, GLuint h, GLuint d); + +void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, + GLuint level, + GLuint img, GLuint x, GLuint y); + + +/* Upload an image into a tree + */ +void intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, + GLuint src_row_pitch, GLuint src_image_pitch); + +/* Copy an image between two trees + */ +void intel_miptree_image_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src); + +/* i915_mipmap_tree.c: + */ +GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt); +GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt); + + + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c new file mode 100644 index 0000000000..9018e3daef --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel.c @@ -0,0 +1,120 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portionsalloc + * 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 "enums.h" +#include "state.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_pixel.h" +#include "intel_regions.h" + + +/** + * Check if any fragment operations are in effect which might effect + * glDraw/CopyPixels. + */ +GLboolean +intel_check_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* XXX Note: Scissor could be done with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Scissor.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Texture._EnabledUnits || + ctx->FragmentProgram._Enabled || + ctx->Color.BlendEnabled); +} + + +GLboolean +intel_check_meta_tex_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Some of _ImageTransferState (scale, bias) could be done with + * fragment programs on i915. + */ + return !(ctx->_ImageTransferState || ctx->Fog.Enabled || /* not done yet */ + ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled); +} + +/* The intel_region struct doesn't really do enough to capture the + * format of the pixels in the region. For now this code assumes that + * the region is a display surface and hence is either ARGB8888 or + * RGB565. + * XXX FBO: If we'd pass in the intel_renderbuffer instead of region, we'd + * know the buffer's pixel format. + * + * \param format as given to glDraw/ReadPixels + * \param type as given to glDraw/ReadPixels + */ +GLboolean +intel_check_blit_format(struct intel_region * region, + GLenum format, GLenum type) +{ + if (region->cpp == 4 && + (type == GL_UNSIGNED_INT_8_8_8_8_REV || + type == GL_UNSIGNED_BYTE) && format == GL_BGRA) { + return GL_TRUE; + } + + if (region->cpp == 2 && + type == GL_UNSIGNED_SHORT_5_6_5_REV && format == GL_BGR) { + return GL_TRUE; + } + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: bad format for blit (cpp %d, type %s format %s)\n", + __FUNCTION__, region->cpp, + _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); + + return GL_FALSE; +} + + +void +intelInitPixelFuncs(struct dd_function_table *functions) +{ + functions->Accum = _swrast_Accum; + functions->Bitmap = _swrast_Bitmap; + functions->CopyPixels = intelCopyPixels; + functions->ReadPixels = intelReadPixels; + functions->DrawPixels = intelDrawPixels; +} diff --git a/src/mesa/drivers/dri/i915/intel_pixel.h b/src/mesa/drivers/dri/i915/intel_pixel.h new file mode 100644 index 0000000000..a6fcf90ce0 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_PIXEL_H +#define INTEL_PIXEL_H + +#include "mtypes.h" + +void intelInitPixelFuncs(struct dd_function_table *functions); + +GLboolean intel_check_blit_fragment_ops(GLcontext * ctx); + +GLboolean intel_check_meta_tex_fragment_ops(GLcontext * ctx); + +GLboolean intel_check_blit_format(struct intel_region *region, + GLenum format, GLenum type); + + +void intelReadPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid * pixels); + +void intelDrawPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels); + +void intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type); + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i915/intel_pixel_bitmap.c new file mode 100644 index 0000000000..65bf338589 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel_bitmap.c @@ -0,0 +1,350 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portionsalloc + * 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 "glheader.h" +#include "enums.h" +#include "image.h" +#include "colormac.h" +#include "mtypes.h" +#include "macros.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_buffer_objects.h" + + + +#define FILE_DEBUG_FLAG DEBUG_PIXEL + + +/* Unlike the other intel_pixel_* functions, the expectation here is + * that the incoming data is not in a PBO. With the XY_TEXT blit + * method, there's no benefit haveing it in a PBO, but we could + * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit + * PBO bitmaps. I think they are probably pretty rare though - I + * wonder if Xgl uses them? + */ +static const GLubyte *map_pbo( GLcontext *ctx, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + GLubyte *buf; + + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + GL_COLOR_INDEX, GL_BITMAP, + (GLvoid *) bitmap)) { + _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)"); + return NULL; + } + + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, + unpack->BufferObj); + if (!buf) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); + return NULL; + } + + return ADD_POINTERS(buf, bitmap); +} + +static GLboolean test_bit( const GLubyte *src, + GLuint bit ) +{ + return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0; +} + +static void set_bit( GLubyte *dest, + GLuint bit ) +{ + dest[bit/8] |= 1 << (bit % 8); +} + +static int align(int x, int align) +{ + return (x + align - 1) & ~(align - 1); +} + +/* Extract a rectangle's worth of data from the bitmap. Called + * per-cliprect. + */ +static GLuint get_bitmap_rect(GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap, + GLuint x, GLuint y, + GLuint w, GLuint h, + GLubyte *dest, + GLuint row_align, + GLboolean invert) +{ + GLuint src_offset = (x + unpack->SkipPixels) & 0x7; + GLuint mask = unpack->LsbFirst ? 0 : 7; + GLuint bit = 0; + GLint row, col; + GLint first, last; + GLint incr; + GLuint count = 0; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n", + __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask); + + if (invert) { + first = h-1; + last = 0; + incr = -1; + } + else { + first = 0; + last = h-1; + incr = 1; + } + + /* Require that dest be pre-zero'd. + */ + for (row = first; row != (last+incr); row += incr) { + const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, + width, height, + GL_COLOR_INDEX, GL_BITMAP, + y + row, x); + + for (col = 0; col < w; col++, bit++) { + if (test_bit(rowsrc, (col + src_offset) ^ mask)) { + set_bit(dest, bit ^ 7); + count++; + } + } + + if (row_align) + bit = (bit + row_align - 1) & ~(row_align - 1); + } + + return count; +} + + + + +/* + * Render a bitmap. + */ +static GLboolean +do_blit_bitmap( GLcontext *ctx, + GLint dstx, GLint dsty, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + + union { + GLuint ui; + GLubyte ub[4]; + } color; + + + if (unpack->BufferObj->Name) { + bitmap = map_pbo(ctx, width, height, unpack, bitmap); + if (bitmap == NULL) + return GL_TRUE; /* even though this is an error, we're done */ + } + + UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], ctx->Current.RasterColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], ctx->Current.RasterColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], ctx->Current.RasterColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], ctx->Current.RasterColor[3]); + + /* Does zoom apply to bitmaps? + */ + if (!intel_check_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint srcx = 0, srcy = 0; + GLint orig_screen_x1, orig_screen_y2; + GLuint i; + + + orig_screen_x1 = dPriv->x + dstx; + orig_screen_y2 = dPriv->y + (dPriv->h - dsty); + + /* Do scissoring in GL coordinates: + */ +x if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->y + (dPriv->h - dsty - height); + dstx = dPriv->x + dstx; + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + int box_w, box_h; + GLint px, py; + GLuint stipple[32]; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + /* Now go back to GL coordinates to figure out what subset of + * the bitmap we are uploading for this cliprect: + */ + box_w = rect.x2 - rect.x1; + box_h = rect.y2 - rect.y1; + srcx = rect.x1 - orig_screen_x1; + srcy = orig_screen_y2 - rect.y2; + + +#define DY 32 +#define DX 32 + + /* Then, finally, chop it all into chunks that can be + * digested by hardware: + */ + for (py = 0; py < box_h; py += DY) { + for (px = 0; px < box_w; px += DX) { + int h = MIN2(DY, box_h - py); + int w = MIN2(DX, box_w - px); + GLuint sz = align(align(w,8) * h, 64)/8; + + assert(sz <= sizeof(stipple)); + memset(stipple, 0, sz); + + /* May need to adjust this when padding has been introduced in + * sz above: + */ + if (get_bitmap_rect(width, height, unpack, + bitmap, + srcx + px, srcy + py, w, h, + (GLubyte *)stipple, + 8, + GL_TRUE) == 0) + continue; + + /* + */ + intelEmitImmediateColorExpandBlit( intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color.ui, + dst->pitch, + dst->buffer, + 0, + dst->tiled, + rect.x1 + px, + rect.y2 - (py + h), + w, h); + } + } + } + intel->need_flush = GL_TRUE; + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + + if (unpack->BufferObj->Name) { + /* done with PBO so unmap it now */ + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } + + return GL_TRUE; +} + + + + + +/* There are a large number of possible ways to implement bitmap on + * this hardware, most of them have some sort of drawback. Here are a + * few that spring to mind: + * + * Blit: + * - XY_MONO_SRC_BLT_CMD + * - use XY_SETUP_CLIP_BLT for cliprect clipping. + * - XY_TEXT_BLT + * - XY_TEXT_IMMEDIATE_BLT + * - blit per cliprect, subject to maximum immediate data size. + * - XY_COLOR_BLT + * - per pixel or run of pixels + * - XY_PIXEL_BLT + * - good for sparse bitmaps + * + * 3D engine: + * - Point per pixel + * - Translate bitmap to an alpha texture and render as a quad + * - Chop bitmap up into 32x32 squares and render w/polygon stipple. + */ +void +intelBitmap(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte * pixels) +{ + if (do_blit_bitmap(ctx, x, y, width, height, + unpack, pixels)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_Bitmap(ctx, x, y, width, height, unpack, pixels); +} diff --git a/src/mesa/drivers/dri/i915/intel_pixel_copy.c b/src/mesa/drivers/dri/i915/intel_pixel_copy.c new file mode 100644 index 0000000000..9d478283e4 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel_copy.c @@ -0,0 +1,383 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "image.h" +#include "state.h" +#include "mtypes.h" +#include "macros.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_buffers.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_tris.h" +#include "intel_pixel.h" + +#define FILE_DEBUG_FLAG DEBUG_PIXEL + +static struct intel_region * +copypix_src_region(struct intel_context *intel, GLenum type) +{ + switch (type) { + case GL_COLOR: + return intel_readbuf_region(intel); + case GL_DEPTH: + /* Don't think this is really possible execpt at 16bpp, when we have no stencil. + */ + if (intel->intelScreen->depth_region && + intel->intelScreen->depth_region->cpp == 2) + return intel->intelScreen->depth_region; + case GL_STENCIL: + /* Don't think this is really possible. + */ + break; + case GL_DEPTH_STENCIL_EXT: + /* Does it matter whether it is stencil/depth or depth/stencil? + */ + return intel->intelScreen->depth_region; + default: + break; + } + + return NULL; +} + + +/** + * Check if any fragment operations are in effect which might effect + * glCopyPixels. Differs from intel_check_blit_fragment_ops in that + * we allow Scissor. + */ +static GLboolean +intel_check_copypixel_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Could do logicop with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Texture._EnabledUnits || + ctx->FragmentProgram._Enabled || + ctx->Color.BlendEnabled); +} + +/* Doesn't work for overlapping regions. Could do a double copy or + * just fallback. + */ +static GLboolean +do_texture_copypixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + GLenum src_format; + GLenum src_type; + + DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__, + srcx, srcy, width, height, dstx, dsty); + + if (!src || !dst || type != GL_COLOR) + return GL_FALSE; + + /* Can't handle overlapping regions. Don't have sufficient control + * over rasterization to pull it off in-place. Punt on these for + * now. + * + * XXX: do a copy to a temporary. + */ + if (src->buffer == dst->buffer) { + drm_clip_rect_t srcbox; + drm_clip_rect_t dstbox; + drm_clip_rect_t tmp; + + srcbox.x1 = srcx; + srcbox.y1 = srcy; + srcbox.x2 = srcx + width; + srcbox.y2 = srcy + height; + + dstbox.x1 = dstx; + dstbox.y1 = dsty; + dstbox.x2 = dstx + width * ctx->Pixel.ZoomX; + dstbox.y2 = dsty + height * ctx->Pixel.ZoomY; + + DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2); + DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2, + width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + + if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) { + DBG("%s: regions overlap\n", __FUNCTION__); + return GL_FALSE; + } + } + + intelFlush(&intel->ctx); + + intel->vtbl.install_meta_state(intel); + + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_no_depth_write(intel); + + /* Set the 3d engine to draw into the destination region: + */ + intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + + intel->vtbl.meta_import_pixel_state(intel); + + if (src->cpp == 2) { + src_format = GL_RGB; + src_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + src_format = GL_BGRA; + src_type = GL_UNSIGNED_BYTE; + } + + /* Set the frontbuffer up as a large rectangular texture. + */ + if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0, + src->pitch, + src->height, src_format, src_type)) { + intel->vtbl.leave_meta_state(intel); + return GL_FALSE; + } + + + intel->vtbl.meta_texture_blend_replace(intel); + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + + srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */ + + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. XXX: Just set the texcord wrap mode to clamp + * or similar. + * + */ + if (0) { + GLint orig_x = srcx; + GLint orig_y = srcy; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx += srcx - orig_x; + dsty += (srcy - orig_y) * ctx->Pixel.ZoomY; + } + + /* Just use the regular cliprect mechanism... Does this need to + * even hold the lock??? + */ + intel_meta_draw_quad(intel, + dstx, + dstx + width * ctx->Pixel.ZoomX, + dPriv->h - (dsty + height * ctx->Pixel.ZoomY), + dPriv->h - (dsty), 0, /* XXX: what z value? */ + 0x00ff00ff, + srcx, srcx + width, srcy, srcy + height); + + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + DBG("%s: success\n", __FUNCTION__); + return GL_TRUE; +} + + + + + +/** + * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. + */ +static GLboolean +do_blit_copypixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + + /* Copypixels can be more than a straight copy. Ensure all the + * extra operations are disabled: + */ + if (!intel_check_copypixel_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + if (!src || !dst) + return GL_FALSE; + + + + intelFlush(&intel->ctx); + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint delta_x = 0; + GLint delta_y = 0; + GLuint i; + + /* Do scissoring in GL coordinates: + */ + if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + GLint dx = dstx - srcx; + GLint dy = dsty - srcy; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + + srcx = dstx - dx; + srcy = dsty - dy; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->h - dsty - height; + srcy = dPriv->h - srcy - height; + dstx += dPriv->x; + dsty += dPriv->y; + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. Dst is clipped with cliprects below. + */ + { + delta_x = srcx - dstx; + delta_y = srcy - dsty; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx = srcx - delta_x; + dsty = srcy - delta_y; + } + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + + /* Could do slightly more clipping: Eg, take the intersection of + * the existing set of cliprects and those cliprects translated + * by delta_x, delta_y: + * + * This code will not overwrite other windows, but will + * introduce garbage when copying from obscured window regions. + */ + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + + intelEmitCopyBlit(intel, dst->cpp, + src->pitch, src->buffer, 0, + dst->pitch, dst->buffer, 0, + rect.x1 + delta_x, + rect.y1 + delta_y, /* srcx, srcy */ + rect.x1, rect.y1, /* dstx, dsty */ + rect.x2 - rect.x1, rect.y2 - rect.y1, + ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY); + } + + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + DBG("%s: success\n", __FUNCTION__); + return GL_TRUE; +} + + +void +intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + DBG("fallback to _swrast_CopyPixels\n"); + + _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); +} diff --git a/src/mesa/drivers/dri/i915/intel_pixel_draw.c b/src/mesa/drivers/dri/i915/intel_pixel_draw.c new file mode 100644 index 0000000000..afb586b4a3 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel_draw.c @@ -0,0 +1,388 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portionsalloc + * 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 "glheader.h" +#include "enums.h" +#include "image.h" +#include "mtypes.h" +#include "macros.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" +#include "intel_tris.h" + + + +static GLboolean +do_texture_drawpixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); + GLuint rowLength = unpack->RowLength ? unpack->RowLength : width; + GLuint src_offset; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(&intel->ctx); + intel->vtbl.render_start(intel); + intel->vtbl.emit_state(intel); + + if (!dst) + return GL_FALSE; + + if (src) { + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ +/* _mesa_printf("%s - not PBO\n", __FUNCTION__); */ + return GL_FALSE; + } + + /* There are a couple of things we can't do yet, one of which is + * set the correct state for pixel operations when GL texturing is + * enabled. That's a pretty rare state and probably not worth the + * effort. A completely device-independent version of this may do + * more. + * + * Similarly, we make no attempt to merge metaops processing with + * an enabled fragment program, though it would certainly be + * possible. + */ + if (!intel_check_meta_tex_fragment_ops(ctx)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad GL fragment state for metaops texture\n", + __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.install_meta_state(intel); + + + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_no_depth_write(intel); + + /* Set the 3d engine to draw into the destination region: + */ + intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + + intel->vtbl.meta_import_pixel_state(intel); + + src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Setup the pbo up as a rectangular texture, if possible. + * + * TODO: This is almost always possible if the i915 fragment + * program is adjusted to correctly swizzle the sampled colors. + * The major exception is any 24bit texture, like RGB888, for which + * there is no hardware support. + */ + if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, src_offset, + rowLength, height, format, type)) { + intel->vtbl.leave_meta_state(intel); + return GL_FALSE; + } + + intel->vtbl.meta_texture_blend_replace(intel); + + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + GLint srcx, srcy; + GLint dstx, dsty; + + dstx = x; + dsty = dPriv->h - (y + height); + + srcx = 0; /* skiprows/pixels already done */ + srcy = 0; + + if (0) { + const GLint orig_x = dstx; + const GLint orig_y = dsty; + + if (!_mesa_clip_to_region(0, 0, dst->pitch, dst->height, + &dstx, &dsty, &width, &height)) + goto out; + + srcx += dstx - orig_x; + srcy += dsty - orig_y; + } + + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("draw %d,%d %dx%d\n", dstx, dsty, width, height); + + /* Must use the regular cliprect mechanism in order to get the + * drawing origin set correctly. Otherwise scissor state is in + * incorrect coordinate space. Does this even need to hold the + * lock??? + */ + intel_meta_draw_quad(intel, + dstx, dstx + width * ctx->Pixel.ZoomX, + dPriv->h - (y + height * ctx->Pixel.ZoomY), + dPriv->h - (y), + -ctx->Current.RasterPos[2] * .5, + 0x00ff00ff, + srcx, srcx + width, srcy + height, srcy); + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + return GL_TRUE; +} + + + + + +/* Pros: + * - no waiting for idle before updating framebuffer. + * + * Cons: + * - if upload is by memcpy, this may actually be slower than fallback path. + * - uploads the whole image even if destination is clipped + * + * Need to benchmark. + * + * Given the questions about performance, implement for pbo's only. + * This path is definitely a win if the pbo is already in agp. If it + * turns out otherwise, we can add the code necessary to upload client + * data to agp space before performing the blit. (Though it may turn + * out to be better/simpler just to use the texture engine). + */ +static GLboolean +do_blit_drawpixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dest = intel_drawbuf_region(intel); + struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); + GLuint src_offset; + GLuint rowLength; + dri_fence *fence = NULL; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + + if (!dest) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - no dest\n", __FUNCTION__); + return GL_FALSE; + } + + if (src) { + /* This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + if (!intel_check_blit_format(dest, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (!intel_check_blit_fragment_ops(ctx)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad GL fragment state for blitter\n", + __FUNCTION__); + return GL_FALSE; + } + + if (ctx->Pixel.ZoomX != 1.0F) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomX for blit\n", __FUNCTION__); + return GL_FALSE; + } + + + if (unpack->RowLength > 0) + rowLength = unpack->RowLength; + else + rowLength = width; + + if (ctx->Pixel.ZoomY == -1.0F) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); + return GL_FALSE; /* later */ + y -= height; + } + else if (ctx->Pixel.ZoomY == 1.0F) { + rowLength = -rowLength; + } + else { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, + format, type, 0, 0, 0); + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t dest_rect; + dri_bo *src_buffer = intel_bufferobj_buffer(intel, src, INTEL_READ); + int i; + + dest_rect.x1 = dPriv->x + x; + dest_rect.y1 = dPriv->y + dPriv->h - (y + height); + dest_rect.x2 = dest_rect.x1 + width; + dest_rect.y2 = dest_rect.y1 + height; + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + intelEmitCopyBlit(intel, + dest->cpp, + rowLength, + src_buffer, src_offset, + dest->pitch, + dest->buffer, 0, + rect.x1 - dest_rect.x1, + rect.y2 - dest_rect.y2, + rect.x1, + rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1, + ctx->Color.ColorLogicOpEnabled ? + ctx->Color.LogicOp : GL_COPY); + } + intel_batchbuffer_flush(intel->batch); + fence = intel->batch->last_fence; + dri_fence_reference(fence); + } + UNLOCK_HARDWARE(intel); + + if (fence) { + dri_fence_wait(fence); + dri_fence_unreference(fence); + } + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + + + +void +intelDrawPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + if (do_blit_drawpixels(ctx, x, y, width, height, format, type, + unpack, pixels)) + return; + + if (do_texture_drawpixels(ctx, x, y, width, height, format, type, + unpack, pixels)) + return; + + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) { + /* + * We don't want the i915 texenv program to be applied to DrawPixels. + * This is really just a performance optimization (mesa will other- + * wise happily run the fragment program on each pixel in the image). + */ + struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current; + /* can't just set current frag prog to 0 here as on buffer resize + we'll get new state checks which will segfault. Remains a hack. */ + ctx->FragmentProgram._Current = NULL; + ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE; + ctx->FragmentProgram._Active = GL_FALSE; + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + ctx->FragmentProgram._Current = fpSave; + ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; + ctx->FragmentProgram._Active = GL_TRUE; + } + else { + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); + } +} diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c new file mode 100644 index 0000000000..a22844926c --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c @@ -0,0 +1,319 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "image.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" + +/* For many applications, the new ability to pull the source buffers + * back out of the GTT and then do the packing/conversion operations + * in software will be as much of an improvement as trying to get the + * blitter and/or texture engine to do the work. + * + * This step is gated on private backbuffers. + * + * Obviously the frontbuffer can't be pulled back, so that is either + * an argument for blit/texture readpixels, or for blitting to a + * temporary and then pulling that back. + * + * When the destination is a pbo, however, it's not clear if it is + * ever going to be pulled to main memory (though the access param + * will be a good hint). So it sounds like we do want to be able to + * choose between blit/texture implementation on the gpu and pullback + * and cpu-based copying. + * + * Unless you can magically turn client memory into a PBO for the + * duration of this call, there will be a cpu-based copying step in + * any case. + */ + + +static GLboolean +do_texture_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + struct intel_region *dest_region) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + intelScreenPrivate *screen = intel->intelScreen; + GLint pitch = pack->RowLength ? pack->RowLength : width; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int textureFormat; + GLenum glTextureFormat; + int destFormat, depthFormat, destPitch; + drm_clip_rect_t tmp; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (ctx->_ImageTransferState || + pack->SwapBytes || pack->LsbFirst || !pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); + + if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: couldn't set dest %s/%s\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(type), + _mesa_lookup_enum_by_nr(format)); + return GL_FALSE; + } + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + intel->vtbl.install_meta_state(intel); + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + + if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { + UNLOCK_HARDWARE(intel); + SET_STATE(i830, state); + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); + return GL_TRUE; + } + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); + + + intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); + + + /* Set the 3d engine to draw into the destination region: + */ + + intel->vtbl.meta_draw_region(intel, dest_region); + intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ + + + /* Draw a single quad, no cliprects: + */ + intel->vtbl.meta_disable_cliprects(intel); + + intel->vtbl.draw_quad(intel, + 0, width, 0, height, + 0x00ff00ff, x, x + width, y, y + height); + + intel->vtbl.leave_meta_state(intel); + } + UNLOCK_HARDWARE(intel); + + intel_region_wait_fence(ctx, dest_region); /* required by GL */ + return GL_TRUE; +#endif + + return GL_FALSE; +} + + + + +static GLboolean +do_blit_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *src = intel_readbuf_region(intel); + struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); + GLuint dst_offset; + GLuint rowLength; + dri_fence *fence = NULL; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + if (!src) + return GL_FALSE; + + if (dst) { + /* XXX This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, pack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + + if (ctx->_ImageTransferState || + !intel_check_blit_format(src, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: bad packing params\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->RowLength > 0) + rowLength = pack->RowLength; + else + rowLength = width; + + if (pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); + return GL_FALSE; + } + else { + rowLength = -rowLength; + } + + /* XXX 64-bit cast? */ + dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Although the blits go on the command buffer, need to do this and + * fire with lock held to guarentee cliprects are correct. + */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + GLboolean all = (width * height * src->cpp == dst->Base.Size && + x == 0 && dst_offset == 0); + + dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t src_rect; + int i; + + src_rect.x1 = dPriv->x + x; + src_rect.y1 = dPriv->y + dPriv->h - (y + height); + src_rect.x2 = src_rect.x1 + width; + src_rect.y2 = src_rect.y1 + height; + + + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) + continue; + + intelEmitCopyBlit(intel, + src->cpp, + src->pitch, src->buffer, 0, + rowLength, + dst_buffer, dst_offset, + rect.x1, + rect.y1, + rect.x1 - src_rect.x1, + rect.y2 - src_rect.y2, + rect.x2 - rect.x1, rect.y2 - rect.y1, + GL_COPY); + } + + intel_batchbuffer_flush(intel->batch); + fence = intel->batch->last_fence; + dri_fence_reference(fence); + + } + UNLOCK_HARDWARE(intel); + + if (fence) { + dri_fence_wait(fence); + dri_fence_unreference(fence); + } + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + +void +intelReadPixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(ctx); + + if (do_blit_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (do_texture_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); +} diff --git a/src/mesa/drivers/dri/i915/intel_reg.h b/src/mesa/drivers/dri/i915/intel_reg.h new file mode 100644 index 0000000000..7828ba6ad3 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_reg.h @@ -0,0 +1,88 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + + +#define CMD_3D (0x3<<29) + + +#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24)) +#define PRIM_INDIRECT (1<<23) +#define PRIM_INLINE (0<<23) +#define PRIM_INDIRECT_SEQUENTIAL (0<<17) +#define PRIM_INDIRECT_ELTS (1<<17) + +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_MASK (0x1f<<18) + +#define I915PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define I915PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define I915PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define I915PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define MI_WAIT_FOR_EVENT ((0x3<<23)) +#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) +#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c new file mode 100644 index 0000000000..4eac859a13 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_regions.c @@ -0,0 +1,482 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Provide additional functionality on top of bufmgr buffers: + * - 2d semantics and blit operations + * - refcounting of buffers for multiple images in a buffer. + * - refcounting of buffer mappings. + * - some logic for moving the buffers to the best memory pools for + * given operations. + * + * Most of this is to make it easier to implement the fixed-layout + * mipmap tree required by intel hardware in the face of GL's + * programming interface where each image can be specifed in random + * order and it isn't clear what layout the tree should have until the + * last moment. + */ + +#include "intel_context.h" +#include "intel_regions.h" +#include "intel_blit.h" +#include "intel_buffer_objects.h" +#include "dri_bufmgr.h" +#include "intel_batchbuffer.h" + +#define FILE_DEBUG_FLAG DEBUG_REGION + +void +intel_region_idle(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + /* XXX: Using this function is likely bogus -- it ought to only have been + * used before a map, anyway, but leave this cheap implementation of it + * for now. + */ + if (region && region->buffer) { + /* Mapping it for read will ensure that any acceleration to the region + * would have landed already. + */ + dri_bo_map(region->buffer, GL_TRUE); + dri_bo_unmap(region->buffer); + } +} + +/* XXX: Thread safety? + */ +GLubyte * +intel_region_map(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (!region->map_refcount++) { + if (region->pbo) + intel_region_cow(intelScreen, region); + + dri_bo_map(region->buffer, GL_TRUE); + region->map = region->buffer->virtual; + } + + return region->map; +} + +void +intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (!--region->map_refcount) { + dri_bo_unmap(region->buffer); + region->map = NULL; + } +} + +struct intel_region * +intel_region_alloc(intelScreenPrivate *intelScreen, + GLuint cpp, GLuint pitch, GLuint height) +{ + struct intel_region *region = calloc(sizeof(*region), 1); + + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + region->refcount = 1; + + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); + return region; +} + +void +intel_region_reference(struct intel_region **dst, struct intel_region *src) +{ + assert(*dst == NULL); + if (src) { + src->refcount++; + *dst = src; + } +} + +void +intel_region_release(struct intel_region **region) +{ + if (!*region) + return; + + DBG("%s %d\n", __FUNCTION__, (*region)->refcount - 1); + + ASSERT((*region)->refcount > 0); + (*region)->refcount--; + + if ((*region)->refcount == 0) { + assert((*region)->map_refcount == 0); + + if ((*region)->pbo) + (*region)->pbo->region = NULL; + (*region)->pbo = NULL; + dri_bo_unreference((*region)->buffer); + free(*region); + } + *region = NULL; +} + + +struct intel_region * +intel_region_create_static(intelScreenPrivate *intelScreen, + GLuint mem_type, + unsigned int bo_handle, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + struct intel_region *region = calloc(sizeof(*region), 1); + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + region->refcount = 1; + + if (intelScreen->ttm) { + assert(bo_handle != -1); + region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, + "static region", + bo_handle); + } else { + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, + "static region", + offset, pitch * cpp * height, + virtual, + DRM_BO_FLAG_MEM_TT); + } + + return region; +} + + + +void +intel_region_update_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + unsigned int bo_handle, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + + /* + * We use a "shared" buffer type to indicate buffers created and + * shared by others. + */ + + dri_bo_unreference(region->buffer); + if (intelScreen->ttm) { + assert(bo_handle != -1); + region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, + "static region", + bo_handle); + } else { + region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, + "static region", + offset, pitch * cpp * height, + virtual, + DRM_BO_FLAG_MEM_TT); + } +} + + + +/* + * XXX Move this into core Mesa? + */ +static void +_mesa_copy_rect(GLubyte * dst, + GLuint cpp, + GLuint dst_pitch, + GLuint dst_x, + GLuint dst_y, + GLuint width, + GLuint height, + const GLubyte * src, + GLuint src_pitch, GLuint src_x, GLuint src_y) +{ + GLuint i; + + dst_pitch *= cpp; + src_pitch *= cpp; + dst += dst_x * cpp; + src += src_x * cpp; + dst += dst_y * dst_pitch; + src += src_y * dst_pitch; + width *= cpp; + + if (width == dst_pitch && width == src_pitch) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_pitch; + src += src_pitch; + } + } +} + + +/* Upload data to a rectangular sub-region. Lots of choices how to do this: + * + * - memcpy by span to current destination + * - upload data as new buffer and blit + * + * Currently always memcpy. + */ +void +intel_region_data(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + const void *src, GLuint src_pitch, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + + LOCK_HARDWARE(intel); + + _mesa_copy_rect(intel_region_map(intelScreen, dst) + dst_offset, + dst->cpp, + dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); + + intel_region_unmap(intelScreen, dst); + + UNLOCK_HARDWARE(intel); + +} + +/* Copy rectangular sub-regions. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +void +intel_region_copy(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + assert(src->cpp == dst->cpp); + + intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, src_offset, + dst->pitch, dst->buffer, dst_offset, + srcx, srcy, dstx, dsty, width, height, + GL_COPY); +} + +/* Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +void +intel_region_fill(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + GLuint width, GLuint height, GLuint color) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + intelEmitFillBlit(intel, + dst->cpp, + dst->pitch, dst->buffer, dst_offset, + dstx, dsty, width, height, color); +} + +/* Attach to a pbo, discarding our data. Effectively zero-copy upload + * the pbo's data. + */ +void +intel_region_attach_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region, + struct intel_buffer_object *pbo) +{ + if (region->pbo == pbo) + return; + + /* If there is already a pbo attached, break the cow tie now. + * Don't call intel_region_release_pbo() as that would + * unnecessarily allocate a new buffer we would have to immediately + * discard. + */ + if (region->pbo) { + region->pbo->region = NULL; + region->pbo = NULL; + } + + if (region->buffer) { + dri_bo_unreference(region->buffer); + region->buffer = NULL; + } + + region->pbo = pbo; + region->pbo->region = region; + dri_bo_reference(pbo->buffer); + region->buffer = pbo->buffer; +} + + +/* Break the COW tie to the pbo and allocate a new buffer. + * The pbo gets to keep the data. + */ +void +intel_region_release_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region) +{ + assert(region->buffer == region->pbo->buffer); + region->pbo->region = NULL; + region->pbo = NULL; + dri_bo_unreference(region->buffer); + region->buffer = NULL; + + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + region->pitch * region->cpp * region->height, + 64, DRM_BO_FLAG_MEM_TT); +} + +/* Break the COW tie to the pbo. Both the pbo and the region end up + * with a copy of the data. + */ +void +intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + struct intel_buffer_object *pbo = region->pbo; + + if (intel == NULL) + return; + + intel_region_release_pbo(intelScreen, region); + + assert(region->cpp * region->pitch * region->height == pbo->Base.Size); + + DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size); + + /* Now blit from the texture buffer to the new buffer: + */ + + intel_batchbuffer_flush(intel->batch); + + if (!intel->locked) { + LOCK_HARDWARE(intel); + intelEmitCopyBlit(intel, + region->cpp, + region->pitch, + region->buffer, 0, + region->pitch, + pbo->buffer, 0, + 0, 0, 0, 0, + region->pitch, region->height, + GL_COPY); + + intel_batchbuffer_flush(intel->batch); + UNLOCK_HARDWARE(intel); + } + else { + intelEmitCopyBlit(intel, + region->cpp, + region->pitch, + region->buffer, 0, + region->pitch, + pbo->buffer, 0, + 0, 0, 0, 0, + region->pitch, region->height, + GL_COPY); + + intel_batchbuffer_flush(intel->batch); + } +} + +dri_bo * +intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, GLuint flag) +{ + if (region->pbo) { + if (flag == INTEL_WRITE_PART) + intel_region_cow(intelScreen, region); + else if (flag == INTEL_WRITE_FULL) + intel_region_release_pbo(intelScreen, region); + } + + return region->buffer; +} diff --git a/src/mesa/drivers/dri/i915/intel_regions.h b/src/mesa/drivers/dri/i915/intel_regions.h new file mode 100644 index 0000000000..42d7b17711 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_regions.h @@ -0,0 +1,143 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTEL_REGIONS_H +#define INTEL_REGIONS_H + +#include "mtypes.h" +#include "intel_screen.h" + +struct intel_context; +struct intel_buffer_object; + +/** + * A layer on top of the bufmgr buffers that adds a few useful things: + * + * - Refcounting for local buffer references. + * - Refcounting for buffer maps + * - Buffer dimensions - pitch and height. + * - Blitter commands for copying 2D regions between buffers. (really???) + */ +struct intel_region +{ + dri_bo *buffer; /**< buffer manager's buffer */ + GLuint refcount; /**< Reference count for region */ + GLuint cpp; /**< bytes per pixel */ + GLuint pitch; /**< in pixels */ + GLuint height; /**< in pixels */ + GLubyte *map; /**< only non-NULL when region is actually mapped */ + GLuint map_refcount; /**< Reference count for mapping */ + + GLuint draw_offset; /**< Offset of drawing address within the region */ + + struct intel_buffer_object *pbo; /* zero-copy uploads */ +}; + + +/* Allocate a refcounted region. Pointers to regions should only be + * copied by calling intel_reference_region(). + */ +struct intel_region *intel_region_alloc(intelScreenPrivate *intelScreen, + GLuint cpp, + GLuint pitch, GLuint height); + +void intel_region_reference(struct intel_region **dst, + struct intel_region *src); + +void intel_region_release(struct intel_region **ib); + +extern struct intel_region +*intel_region_create_static(intelScreenPrivate *intelScreen, + GLuint mem_type, + unsigned int bo_handle, + GLuint offset, + void *virtual, + GLuint cpp, + GLuint pitch, GLuint height); +extern void +intel_region_update_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + unsigned int bo_handle, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height); + + +void intel_region_idle(intelScreenPrivate *intelScreen, + struct intel_region *ib); + +/* Map/unmap regions. This is refcounted also: + */ +GLubyte *intel_region_map(intelScreenPrivate *intelScreen, + struct intel_region *ib); + +void intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *ib); + + +/* Upload data to a rectangular sub-region + */ +void intel_region_data(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + const void *src, GLuint src_stride, + GLuint srcx, GLuint srcy, GLuint width, GLuint height); + +/* Copy rectangular sub-regions + */ +void intel_region_copy(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height); + +/* Fill a rectangular sub-region + */ +void intel_region_fill(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + GLuint width, GLuint height, GLuint color); + +/* Helpers for zerocopy uploads, particularly texture image uploads: + */ +void intel_region_attach_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region, + struct intel_buffer_object *pbo); +void intel_region_release_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region); +void intel_region_cow(intelScreenPrivate *intelScreen, + struct intel_region *region); + +dri_bo *intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint flag); + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c new file mode 100644 index 0000000000..c8b6d308d9 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -0,0 +1,244 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware acceleration where possible. + * + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "enums.h" + +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_tris.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 0 /* Has it, but can't use because subpixel has to + * be adjusted for points on the INTEL/I845G + */ +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ +#define HAVE_TRI_FANS 1 +#define HAVE_POLYGONS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS 0 + +static GLuint hw_prim[GL_POLYGON + 1] = { + 0, + PRIM3D_LINELIST, + PRIM3D_LINESTRIP, + PRIM3D_LINESTRIP, + PRIM3D_TRILIST, + PRIM3D_TRISTRIP, + PRIM3D_TRIFAN, + 0, + 0, + PRIM3D_POLY +}; + +static const GLenum reduced_prim[GL_POLYGON + 1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +static const int scale_prim[GL_POLYGON + 1] = { + 0, /* fallback case */ + 1, + 2, + 2, + 1, + 3, + 3, + 0, /* fallback case */ + 0, /* fallback case */ + 3 +}; + + +static void +intelDmaPrimitive(struct intel_context *intel, GLenum prim) +{ + if (0) + fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); + INTEL_FIREVERTICES(intel); + intel->vtbl.reduced_primitive_state(intel, reduced_prim[prim]); + intelStartInlinePrimitive(intel, hw_prim[prim], INTEL_BATCH_CLIPRECTS); +} + + +#define LOCAL_VARS struct intel_context *intel = intel_context(ctx) +#define INIT( prim ) \ +do { \ + intelDmaPrimitive( intel, prim ); \ +} while (0) + +#define FLUSH() INTEL_FIREVERTICES(intel) + +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + ((intel->batch->size - 1500) / (intel->vertex_size*4)) +#define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS() + +#define ALLOC_VERTS( nr ) \ + intelExtendInlinePrimitive( intel, (nr) * intel->vertex_size ) + +#define EMIT_VERTS( ctx, j, nr, buf ) \ + _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf ) + +#define TAG(x) intel_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + +/* Heuristic to choose between the two render paths: + */ +static GLboolean +choose_render(struct intel_context *intel, struct vertex_buffer *VB) +{ + int vertsz = intel->vertex_size; + int cost_render = 0; + int cost_fallback = 0; + int nr_prims = 0; + int nr_rprims = 0; + int nr_rverts = 0; + int rprim = intel->reduced_primitive; + int i = 0; + + for (i = 0; i < VB->PrimitiveCount; i++) { + GLuint prim = VB->Primitive[i].mode; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + nr_prims++; + nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK]; + + if (reduced_prim[prim & PRIM_MODE_MASK] != rprim) { + nr_rprims++; + rprim = reduced_prim[prim & PRIM_MODE_MASK]; + } + } + + /* One point for each generated primitive: + */ + cost_render = nr_prims; + cost_fallback = nr_rprims; + + /* One point for every 1024 dwords (4k) of dma: + */ + cost_render += (vertsz * i) / 1024; + cost_fallback += (vertsz * nr_rverts) / 1024; + + if (0) + fprintf(stderr, "cost render: %d fallback: %d\n", + cost_render, cost_fallback); + + if (cost_render > cost_fallback) + return GL_FALSE; + + return GL_TRUE; +} + + +static GLboolean +intel_run_render(GLcontext * ctx, struct tnl_pipeline_stage *stage) +{ + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + intel->vtbl.render_prevalidate( intel ); + + /* Don't handle clipping or indexed vertices. + */ + if (intel->RenderIndex != 0 || + !intel_validate_render(ctx, VB) || !choose_render(intel, VB)) { + return GL_TRUE; + } + + tnl->clipspace.new_inputs |= VERT_BIT_POS; + + tnl->Driver.Render.Start(ctx); + + for (i = 0; i < VB->PrimitiveCount; i++) { + GLuint prim = VB->Primitive[i].mode; + GLuint start = VB->Primitive[i].start; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + intel_render_tab_verts[prim & PRIM_MODE_MASK] (ctx, start, + start + length, prim); + } + + tnl->Driver.Render.Finish(ctx); + + INTEL_FIREVERTICES(intel); + + return GL_FALSE; /* finished the pipe */ +} + +const struct tnl_pipeline_stage _intel_render_stage = { + "intel render", + NULL, + NULL, + NULL, + NULL, + intel_run_render /* run */ +}; diff --git a/src/mesa/drivers/dri/i915/intel_rotate.c b/src/mesa/drivers/dri/i915/intel_rotate.c new file mode 100644 index 0000000000..12d98c4ad2 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_rotate.c @@ -0,0 +1,237 @@ + +/** + * Routines for simple 2D->2D transformations for rotated, flipped screens. + * + * XXX This code is not intel-specific. Move it into a common/utility + * someday. + */ + +#include "intel_rotate.h" + +#define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) ) + +#define ABS(A) ( ((A) < 0) ? -(A) : (A) ) + + +void +matrix23Set(struct matrix23 *m, + int m00, int m01, int m02, int m10, int m11, int m12) +{ + m->m00 = m00; + m->m01 = m01; + m->m02 = m02; + m->m10 = m10; + m->m11 = m11; + m->m12 = m12; +} + + +/* + * Transform (x,y) coordinate by the given matrix. + */ +void +matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y) +{ + const float x0 = *x; + const float y0 = *y; + + *x = m->m00 * x0 + m->m01 * y0 + m->m02; + *y = m->m10 * x0 + m->m11 * y0 + m->m12; +} + + +void +matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y) +{ + const int x0 = *x; + const int y0 = *y; + + *x = m->m00 * x0 + m->m01 * y0 + m->m02; + *y = m->m10 * x0 + m->m11 * y0 + m->m12; +} + + +/* + * Transform a width and height by the given matrix. + * XXX this could be optimized quite a bit. + */ +void +matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist) +{ + int x0 = 0, y0 = 0; + int x1 = *xDist, y1 = 0; + int x2 = 0, y2 = *yDist; + matrix23TransformCoordi(m, &x0, &y0); + matrix23TransformCoordi(m, &x1, &y1); + matrix23TransformCoordi(m, &x2, &y2); + + *xDist = (x1 - x0) + (x2 - x0); + *yDist = (y1 - y0) + (y2 - y0); + + if (*xDist < 0) + *xDist = -*xDist; + if (*yDist < 0) + *yDist = -*yDist; +} + + +/** + * Transform the rect defined by (x, y, w, h) by m. + */ +void +matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w, + int *h) +{ + int x0 = *x, y0 = *y; + int x1 = *x + *w, y1 = *y; + int x2 = *x + *w, y2 = *y + *h; + int x3 = *x, y3 = *y + *h; + matrix23TransformCoordi(m, &x0, &y0); + matrix23TransformCoordi(m, &x1, &y1); + matrix23TransformCoordi(m, &x2, &y2); + matrix23TransformCoordi(m, &x3, &y3); + *w = ABS(x1 - x0) + ABS(x2 - x1); + /**w = ABS(*w);*/ + *h = ABS(y1 - y0) + ABS(y2 - y1); + /**h = ABS(*h);*/ + *x = MIN2(x0, x1); + *x = MIN2(*x, x2); + *y = MIN2(y0, y1); + *y = MIN2(*y, y2); +} + + +/* + * Make rotation matrix for width X height screen. + */ +void +matrix23Rotate(struct matrix23 *m, int width, int height, int angle) +{ + switch (angle) { + case 0: + matrix23Set(m, 1, 0, 0, 0, 1, 0); + break; + case 90: + matrix23Set(m, 0, 1, 0, -1, 0, width); + break; + case 180: + matrix23Set(m, -1, 0, width, 0, -1, height); + break; + case 270: + matrix23Set(m, 0, -1, height, 1, 0, 0); + break; + default: + /*abort() */ ; + } +} + + +/* + * Make flip/reflection matrix for width X height screen. + */ +void +matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip) +{ + if (xflip) { + m->m00 = -1; + m->m01 = 0; + m->m02 = width - 1; + } + else { + m->m00 = 1; + m->m01 = 0; + m->m02 = 0; + } + if (yflip) { + m->m10 = 0; + m->m11 = -1; + m->m12 = height - 1; + } + else { + m->m10 = 0; + m->m11 = 1; + m->m12 = 0; + } +} + + +/* + * result = a * b + */ +void +matrix23Multiply(struct matrix23 *result, + const struct matrix23 *a, const struct matrix23 *b) +{ + result->m00 = a->m00 * b->m00 + a->m01 * b->m10; + result->m01 = a->m00 * b->m01 + a->m01 * b->m11; + result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02; + + result->m10 = a->m10 * b->m00 + a->m11 * b->m10; + result->m11 = a->m10 * b->m01 + a->m11 * b->m11; + result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12; +} + + +#if 000 + +#include + +int +main(int argc, char *argv[]) +{ + int width = 500, height = 400; + int rot; + int fx = 0, fy = 0; /* flip x and/or y ? */ + int coords[4][2]; + + /* four corner coords to test with */ + coords[0][0] = 0; + coords[0][1] = 0; + coords[1][0] = width - 1; + coords[1][1] = 0; + coords[2][0] = width - 1; + coords[2][1] = height - 1; + coords[3][0] = 0; + coords[3][1] = height - 1; + + + for (rot = 0; rot < 360; rot += 90) { + struct matrix23 rotate, flip, m; + int i; + + printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy); + + /* make transformation matrix 'm' */ + matrix23Rotate(&rotate, width, height, rot); + matrix23Flip(&flip, width, height, fx, fy); + matrix23Multiply(&m, &rotate, &flip); + + /* xform four coords */ + for (i = 0; i < 4; i++) { + int x = coords[i][0]; + int y = coords[i][1]; + matrix23TransformCoordi(&m, &x, &y); + printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y); + } + + /* xform width, height */ + { + int x = width; + int y = height; + matrix23TransformDistance(&m, &x, &y); + printf(" %d x %d -> %d x %d\n", width, height, x, y); + } + + /* xform rect */ + { + int x = 50, y = 10, w = 200, h = 100; + matrix23TransformRect(&m, &x, &y, &w, &h); + printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100, + x, y, w, h); + } + + } + + return 0; +} +#endif diff --git a/src/mesa/drivers/dri/i915/intel_rotate.h b/src/mesa/drivers/dri/i915/intel_rotate.h new file mode 100644 index 0000000000..9c8802ca47 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_rotate.h @@ -0,0 +1,39 @@ +#ifndef INTEL_ROTATE_H +#define INTEL_ROTATE_H 1 + +struct matrix23 +{ + int m00, m01, m02; + int m10, m11, m12; +}; + + + +extern void +matrix23Set(struct matrix23 *m, + int m00, int m01, int m02, int m10, int m11, int m12); + +extern void matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y); + +extern void +matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y); + +extern void +matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist); + +extern void +matrix23TransformRect(const struct matrix23 *m, + int *x, int *y, int *w, int *h); + +extern void +matrix23Rotate(struct matrix23 *m, int width, int height, int angle); + +extern void +matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip); + +extern void +matrix23Multiply(struct matrix23 *result, + const struct matrix23 *a, const struct matrix23 *b); + + +#endif /* INTEL_ROTATE_H */ diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c new file mode 100644 index 0000000000..2721a90094 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -0,0 +1,955 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "context.h" +#include "framebuffer.h" +#include "matrix.h" +#include "renderbuffer.h" +#include "simple_list.h" +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + + +#include "intel_screen.h" + +#include "intel_buffers.h" +#include "intel_tex.h" +#include "intel_span.h" +#include "intel_tris.h" +#include "intel_ioctl.h" +#include "intel_fbo.h" + +#include "i830_dri.h" +#include "dri_bufmgr.h" +#include "intel_regions.h" +#include "intel_batchbuffer.h" + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + const GLuint __driNConfigOptions = 4; + +#ifdef USE_NEW_INTERFACE + static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + + extern const struct dri_extension card_extensions[]; + +/** + * Map all the memory regions described by the screen. + * \return GL_TRUE if success, GL_FALSE if error. + */ +GLboolean +intelMapScreenRegions(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + if (intelScreen->front.handle) { + if (drmMap(sPriv->fd, + intelScreen->front.handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + _mesa_problem(NULL, "drmMap(frontbuffer) failed!"); + return GL_FALSE; + } + } + else { + _mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!"); + } + + if (0) + _mesa_printf("Back 0x%08x ", intelScreen->back.handle); + if (drmMap(sPriv->fd, + intelScreen->back.handle, + intelScreen->back.size, + (drmAddress *) & intelScreen->back.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + + if (intelScreen->third.handle) { + if (0) + _mesa_printf("Third 0x%08x ", intelScreen->third.handle); + if (drmMap(sPriv->fd, + intelScreen->third.handle, + intelScreen->third.size, + (drmAddress *) & intelScreen->third.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + } + + if (0) + _mesa_printf("Depth 0x%08x ", intelScreen->depth.handle); + if (drmMap(sPriv->fd, + intelScreen->depth.handle, + intelScreen->depth.size, + (drmAddress *) & intelScreen->depth.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + + if (0) + _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); + if (intelScreen->tex.size != 0) { + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *) & intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + } + + if (0) + printf("Mappings: front: %p back: %p third: %p depth: %p tex: %p\n", + intelScreen->front.map, + intelScreen->back.map, intelScreen->third.map, + intelScreen->depth.map, intelScreen->tex.map); + return GL_TRUE; +} + +/** Driver-specific fence emit implementation for the fake memory manager. */ +static unsigned int +intel_fence_emit(void *private) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + unsigned int fence; + + /* XXX: Need to emit a flush, if we haven't already (at least with the + * current batchbuffer implementation, we have). + */ + + fence = intelEmitIrqLocked(intelScreen); + + return fence; +} + +/** Driver-specific fence wait implementation for the fake memory manager. */ +static int +intel_fence_wait(void *private, unsigned int cookie) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + + intelWaitIrq(intelScreen, cookie); + + return 0; +} + +static struct intel_region * +intel_recreate_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + intelRegion *region_desc, + GLuint mem_type) +{ + if (region) { + intel_region_update_static(intelScreen, region, mem_type, + region_desc->bo_handle, region_desc->offset, + region_desc->map, intelScreen->cpp, + region_desc->pitch / intelScreen->cpp, + intelScreen->height); + } else { + region = intel_region_create_static(intelScreen, mem_type, + region_desc->bo_handle, + region_desc->offset, + region_desc->map, intelScreen->cpp, + region_desc->pitch / intelScreen->cpp, + intelScreen->height); + } + + assert(region->buffer != NULL); + + return region; +} + + +/* Create intel_region structs to describe the static front,back,depth + * buffers created by the xserver. + * + * Although FBO's mean we now no longer use these as render targets in + * all circumstances, they won't go away until the back and depth + * buffers become private, and the front and rotated buffers will + * remain even then. + * + * Note that these don't allocate video memory, just describe + * allocations alread made by the X server. + */ +static void +intel_recreate_static_regions(intelScreenPrivate *intelScreen) +{ + intelScreen->front_region = + intel_recreate_static(intelScreen, + intelScreen->front_region, + &intelScreen->front, + DRM_BO_FLAG_MEM_TT); + + /* The rotated region is only used for old DDXes that didn't handle rotation +\ * on their own. + */ + if (intelScreen->driScrnPriv->ddxMinor < 8) { + intelScreen->rotated_region = + intel_recreate_static(intelScreen, + intelScreen->rotated_region, + &intelScreen->rotated, + DRM_BO_FLAG_MEM_TT); + } + + intelScreen->back_region = + intel_recreate_static(intelScreen, + intelScreen->back_region, + &intelScreen->back, + DRM_BO_FLAG_MEM_TT); + + if (intelScreen->third.handle) { + intelScreen->third_region = + intel_recreate_static(intelScreen, + intelScreen->third_region, + &intelScreen->third, + DRM_BO_FLAG_MEM_TT); + } + + /* Still assumes front.cpp == depth.cpp. We can kill this when we move to + * private buffers. + */ + intelScreen->depth_region = + intel_recreate_static(intelScreen, + intelScreen->depth_region, + &intelScreen->depth, + DRM_BO_FLAG_MEM_TT); +} + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + intelUnmapScreenRegions(intelScreen); + intelUpdateScreenFromSAREA(intelScreen, sarea); + if (!intelMapScreenRegions(sPriv)) { + fprintf(stderr, "ERROR Remapping screen regions!!!\n"); + } + intel_recreate_static_regions(intelScreen); +} + + +void +intelUnmapScreenRegions(intelScreenPrivate * intelScreen) +{ +#define REALLY_UNMAP 1 + if (intelScreen->front.map) { +#if REALLY_UNMAP + if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0) + printf("drmUnmap front failed!\n"); +#endif + intelScreen->front.map = NULL; + } + if (intelScreen->back.map) { +#if REALLY_UNMAP + if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0) + printf("drmUnmap back failed!\n"); +#endif + intelScreen->back.map = NULL; + } + if (intelScreen->third.map) { +#if REALLY_UNMAP + if (drmUnmap(intelScreen->third.map, intelScreen->third.size) != 0) + printf("drmUnmap third failed!\n"); +#endif + intelScreen->third.map = NULL; + } + if (intelScreen->depth.map) { +#if REALLY_UNMAP + drmUnmap(intelScreen->depth.map, intelScreen->depth.size); + intelScreen->depth.map = NULL; +#endif + } + if (intelScreen->tex.map) { +#if REALLY_UNMAP + drmUnmap(intelScreen->tex.map, intelScreen->tex.size); + intelScreen->tex.map = NULL; +#endif + } +} + + +static void +intelPrintDRIInfo(intelScreenPrivate * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->back.size, intelScreen->back.offset, + intelScreen->back.pitch); + fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->depth.size, intelScreen->depth.offset, + intelScreen->depth.pitch); + fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->rotated.size, intelScreen->rotated.offset, + intelScreen->rotated.pitch); + fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", + intelScreen->tex.size, intelScreen->tex.offset); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + + +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} + + +/** + * A number of the screen parameters are obtained/computed from + * information in the SAREA. This function updates those parameters. + */ +void +intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, + drmI830Sarea * sarea) +{ + intelScreen->width = sarea->width; + intelScreen->height = sarea->height; + + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->front.handle = sarea->front_handle; + intelScreen->front.size = sarea->front_size; + + intelScreen->back.offset = sarea->back_offset; + intelScreen->back.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->back.handle = sarea->back_handle; + intelScreen->back.size = sarea->back_size; + + if (intelScreen->driScrnPriv->ddxMinor >= 8) { + intelScreen->third.offset = sarea->third_offset; + intelScreen->third.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->third.handle = sarea->third_handle; + intelScreen->third.size = sarea->third_size; + } + + intelScreen->depth.offset = sarea->depth_offset; + intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->depth.handle = sarea->depth_handle; + intelScreen->depth.size = sarea->depth_size; + + if (intelScreen->driScrnPriv->ddxMinor >= 9) { + intelScreen->front.bo_handle = sarea->front_bo_handle; + intelScreen->back.bo_handle = sarea->back_bo_handle; + intelScreen->third.bo_handle = sarea->third_bo_handle; + intelScreen->depth.bo_handle = sarea->depth_bo_handle; + } else { + intelScreen->front.bo_handle = -1; + intelScreen->back.bo_handle = -1; + intelScreen->third.bo_handle = -1; + intelScreen->depth.bo_handle = -1; + } + + intelScreen->tex.offset = sarea->tex_offset; + intelScreen->logTextureGranularity = sarea->log_tex_granularity; + intelScreen->tex.handle = sarea->tex_handle; + intelScreen->tex.size = sarea->tex_size; + + intelScreen->rotated.offset = sarea->rotated_offset; + intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; + intelScreen->rotated.size = sarea->rotated_size; + intelScreen->current_rotation = sarea->rotation; + matrix23Rotate(&intelScreen->rotMatrix, + sarea->width, sarea->height, sarea->rotation); + intelScreen->rotatedWidth = sarea->virtualX; + intelScreen->rotatedHeight = sarea->virtualY; + + if (0) + intelPrintSAREA(sarea); +} + + +static GLboolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + drmI830Sarea *sarea; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); + if (!intelScreen) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return GL_FALSE; + } + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + intelScreen->driScrnPriv = sPriv; + sPriv->private = (void *) intelScreen; + intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + sarea = (drmI830Sarea *) + (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); + + intelScreen->deviceID = gDRIPriv->deviceID; + if (intelScreen->deviceID == PCI_CHIP_I865_G) + intelScreen->maxBatchSize = 4096; + else + intelScreen->maxBatchSize = BATCH_SZ; + + intelScreen->mem = gDRIPriv->mem; + intelScreen->cpp = gDRIPriv->cpp; + + switch (gDRIPriv->bitsPerPixel) { + case 16: + intelScreen->fbFormat = DV_PF_565; + break; + case 32: + intelScreen->fbFormat = DV_PF_8888; + break; + default: + exit(1); + break; + } + + intelUpdateScreenFromSAREA(intelScreen, sarea); + + if (!intelMapScreenRegions(sPriv)) { + fprintf(stderr, "\nERROR! mapping regions\n"); + _mesa_free(intelScreen); + sPriv->private = NULL; + return GL_FALSE; + } + + intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + intelScreen->drmMinor = sPriv->drmMinor; + + /* Determine if IRQs are active? */ + { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_IRQ_ACTIVE; + gp.value = &intelScreen->irq_active; + + ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: %d\n", ret); + return GL_FALSE; + } + } + + /* Determine if batchbuffers are allowed */ + { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_ALLOW_BATCHBUFFER; + gp.value = &intelScreen->allow_batchbuffer; + + ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret); + return GL_FALSE; + } + } + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + /* If we've got a new enough DDX that's initializing TTM and giving us + * object handles for the shared buffers, use that. + */ + intelScreen->ttm = GL_FALSE; + if (getenv("INTEL_NO_TTM") == NULL && + intelScreen->driScrnPriv->ddxMinor >= 9 && + intelScreen->front.bo_handle != -1) { + intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, + DRM_FENCE_TYPE_EXE, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW); + if (intelScreen->bufmgr != NULL) + intelScreen->ttm = GL_TRUE; + } + /* Otherwise, use the classic buffer manager. */ + if (intelScreen->bufmgr == NULL) { + if (intelScreen->tex.size == 0) { + fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", + __func__, __LINE__); + return GL_FALSE; + } + fprintf(stderr, "[%s:%u] Failed to init TTM buffer manager, falling back" + " to classic.\n", __func__, __LINE__); + intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, + intelScreen->tex.map, + intelScreen->tex.size, + intel_fence_emit, + intel_fence_wait, + intelScreen); + } + + intel_recreate_static_regions(intelScreen); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + intelUnmapScreenRegions(intelScreen); + + dri_bufmgr_destroy(intelScreen->bufmgr); + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static GLboolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * mesaVis, GLboolean isPixmap) +{ + intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private; + + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + GLboolean swStencil = (mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24); + GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); + + struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer); + + if (!intel_fb) + return GL_FALSE; + + _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis); + + /* setup the hardware-based renderbuffers */ + { + intel_fb->color_rb[0] + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->front.offset, + screen->front.pitch, + screen->cpp, + screen->front.map); + intel_set_span_functions(&intel_fb->color_rb[0]->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, + &intel_fb->color_rb[0]->Base); + } + + if (mesaVis->doubleBufferMode) { + intel_fb->color_rb[1] + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->back.offset, + screen->back.pitch, + screen->cpp, + screen->back.map); + intel_set_span_functions(&intel_fb->color_rb[1]->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, + &intel_fb->color_rb[1]->Base); + + if (screen->third.handle) { + struct gl_renderbuffer *tmp_rb = NULL; + + intel_fb->color_rb[2] + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->third.offset, + screen->third.pitch, + screen->cpp, + screen->third.map); + intel_set_span_functions(&intel_fb->color_rb[2]->Base); + _mesa_reference_renderbuffer(&tmp_rb, &intel_fb->color_rb[2]->Base); + } + } + + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + /* combined depth/stencil buffer */ + struct intel_renderbuffer *depthStencilRb + = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 4! */ + screen->depth.map); + intel_set_span_functions(&depthStencilRb->Base); + /* note: bind RB to two attachment points */ + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, + &depthStencilRb->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL, + &depthStencilRb->Base); + } + else if (mesaVis->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct intel_renderbuffer *depthRb + = intel_create_renderbuffer(GL_DEPTH_COMPONENT16, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 2! */ + screen->depth.map); + intel_set_span_functions(&depthRb->Base); + _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base); + } + + /* now add any/all software-based renderbuffers we may need */ + _mesa_add_soft_renderbuffers(&intel_fb->Base, + GL_FALSE, /* never sw color */ + GL_FALSE, /* never sw depth */ + swStencil, mesaVis->accumRedBits > 0, + GL_FALSE, /* never sw alpha */ + GL_FALSE /* never sw aux */ ); + driDrawPriv->driverPrivate = (void *) intel_fb; + + return GL_TRUE; + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + struct intel_framebuffer *intel_fb; + + if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + intel_fb = dPriv->driverPrivate; + sInfo->swap_count = intel_fb->swap_count; + sInfo->swap_ust = intel_fb->swap_ust; + sInfo->swap_missed_count = intel_fb->swap_missed_count; + + sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) + ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust) + : 0.0; + + return 0; +} + + +/* There are probably better ways to do this, such as an + * init-designated function to register chipids and createcontext + * functions. + */ +extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + + + +static GLboolean +intelCreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + switch (intelScreen->deviceID) { + /* Don't deal with i830 until texture work complete: + */ + case PCI_CHIP_845_G: + case PCI_CHIP_I830_M: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); + + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + case PCI_CHIP_I945_GME: + case PCI_CHIP_G33_G: + case PCI_CHIP_Q35_G: + case PCI_CHIP_Q33_G: + return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate); + + default: + fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID); + return GL_FALSE; + } +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + if (depth_bits == 24) + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 5, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 5, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} + +struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) +{ + /* + * This should probably change to have the screen allocate a dummy + * context at screen creation. For now just use the current context. + */ + + GET_CURRENT_CONTEXT(ctx); + if (ctx == NULL) { + _mesa_problem(NULL, "No current context in intelScreenContext\n"); + return NULL; + } + return intel_context(ctx); +} + diff --git a/src/mesa/drivers/dri/i915/intel_screen.h b/src/mesa/drivers/dri/i915/intel_screen.h new file mode 100644 index 0000000000..aa0ef2c509 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_screen.h @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _INTEL_INIT_H_ +#define _INTEL_INIT_H_ + +#include +#include "dri_util.h" +#include "intel_rotate.h" +#include "i830_common.h" +#include "xmlconfig.h" +#include "dri_bufmgr.h" + +/* XXX: change name or eliminate to avoid conflict with "struct + * intel_region"!!! + */ +typedef struct +{ + drm_handle_t handle; + drmSize size; /* region size in bytes */ + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ + unsigned int bo_handle; /* buffer object id if available, or -1 */ +} intelRegion; + +typedef struct +{ + intelRegion front; + intelRegion back; + intelRegion third; + intelRegion rotated; + intelRegion depth; + intelRegion tex; + + struct intel_region *front_region; + struct intel_region *back_region; + struct intel_region *third_region; + struct intel_region *depth_region; + struct intel_region *rotated_region; + + int deviceID; + int width; + int height; + int mem; /* unused */ + + int cpp; /* for front and back buffers */ +/* int bitsPerPixel; */ + int fbFormat; /* XXX FBO: this is obsolete - remove after i830 updates */ + + int logTextureGranularity; + + __DRIscreenPrivate *driScrnPriv; + unsigned int sarea_priv_offset; + + int drmMinor; + + int irq_active; + int allow_batchbuffer; + + struct matrix23 rotMatrix; + + int current_rotation; /* 0, 90, 180 or 270 */ + int rotatedWidth, rotatedHeight; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + + dri_bufmgr *bufmgr; + unsigned int maxBatchSize; + + /** + * This value indicates that the kernel memory manager is being used + * instead of the fake client-side memory manager. + */ + GLboolean ttm; +} intelScreenPrivate; + + + +extern GLboolean intelMapScreenRegions(__DRIscreenPrivate * sPriv); + +extern void intelUnmapScreenRegions(intelScreenPrivate * intelScreen); + +extern void +intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, + drmI830Sarea * sarea); + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); + +extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_span.c b/src/mesa/drivers/dri/i915/intel_span.c new file mode 100644 index 0000000000..d1f8ef06be --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_span.c @@ -0,0 +1,409 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "colormac.h" + +#include "intel_fbo.h" +#include "intel_screen.h" +#include "intel_span.h" +#include "intel_regions.h" +#include "intel_ioctl.h" +#include "intel_tex.h" + +#include "swrast/swrast.h" + +/* + break intelWriteRGBASpan_ARGB8888 +*/ + +#undef DBG +#define DBG 0 + +#define LOCAL_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLint yScale = irb->RenderToTexture ? 1 : -1; \ + const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + GLubyte *buf = (GLubyte *) irb->pfMap \ + + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\ + GLuint p; \ + assert(irb->pfMap);\ + (void) p; + +/* XXX FBO: this is identical to the macro in spantmp2.h except we get + * the cliprect info from the context, not the driDrawable. + * Move this into spantmp2.h someday. + */ +#define HW_CLIPLOOP() \ + do { \ + int _nc = intel->numClipRects; \ + while ( _nc-- ) { \ + int minx = intel->pClipRects[_nc].x1 - intel->drawX; \ + int miny = intel->pClipRects[_nc].y1 - intel->drawY; \ + int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \ + int maxy = intel->pClipRects[_nc].y2 - intel->drawY; + + + + +#define Y_FLIP(_y) ((_y) * yScale + yBias) + +#define HW_LOCK() + +#define HW_UNLOCK() + +/* 16 bit, RGB565 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 + +#define TAG(x) intel##x##_RGB565 +#define TAG2(x,y) intel##x##_RGB565##y +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2) +#include "spantmp2.h" + +/* 32 bit, ARGB8888 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV + +#define TAG(x) intel##x##_ARGB8888 +#define TAG2(x,y) intel##x##_ARGB8888##y +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4) +#include "spantmp2.h" + + +#define LOCAL_DEPTH_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \ + const GLint yScale = irb->RenderToTexture ? 1 : -1; \ + const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \ + (intel->drawY * pitch + intel->drawX) * irb->region->cpp; + + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +/** + ** 16-bit depthbuffer functions. + **/ +#define WRITE_DEPTH( _x, _y, d ) \ + ((GLushort *)buf)[(_x) + (_y) * pitch] = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = ((GLushort *)buf)[(_x) + (_y) * pitch]; + + +#define TAG(x) intel##x##_z16 +#include "depthtmp.h" + + +/** + ** 24/8-bit interleaved depth/stencil functions + ** Note: we're actually reading back combined depth+stencil values. + ** The wrappers in main/depthstencil.c are used to extract the depth + ** and stencil values. + **/ +/* Change ZZZS -> SZZZ */ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = ((d) >> 8) | ((d) << 24); \ + ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \ +} + +/* Change SZZZ -> ZZZS */ +#define READ_DEPTH( d, _x, _y ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + d = (tmp << 8) | (tmp >> 24); \ +} + +#define TAG(x) intel##x##_z24_s8 +#include "depthtmp.h" + + +/** + ** 8-bit stencil function (XXX FBO: This is obsolete) + **/ +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + tmp &= 0xffffff; \ + tmp |= ((d) << 24); \ + ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24; + +#define TAG(x) intel##x##_z24_s8 +#include "stenciltmp.h" + + + +/** + * Map or unmap all the renderbuffers which we may need during + * software rendering. + * XXX in the future, we could probably convey extra information to + * reduce the number of mappings needed. I.e. if doing a glReadPixels + * from the depth buffer, we really only need one mapping. + * + * XXX Rewrite this function someday. + * We can probably just loop over all the renderbuffer attachments, + * map/unmap all of them, and not worry about the _ColorDrawBuffers + * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields. + */ +static void +intel_map_unmap_buffers(struct intel_context *intel, GLboolean map) +{ + GLcontext *ctx = &intel->ctx; + GLuint i, j; + struct intel_renderbuffer *irb; + + /* color draw buffers */ + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) { + struct gl_renderbuffer *rb = + ctx->DrawBuffer->_ColorDrawBuffers[i][j]; + irb = intel_renderbuffer(rb); + if (irb) { + /* this is a user-created intel_renderbuffer */ + if (irb->region) { + if (map) + intel_region_map(intel->intelScreen, irb->region); + else + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + } + } + } + + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = + ctx->DrawBuffer->Attachment + i; + struct gl_texture_object *tex = att->Texture; + if (tex) { + /* render to texture */ + ASSERT(att->Renderbuffer); + if (map) { + struct gl_texture_image *texImg; + texImg = tex->Image[att->CubeMapFace][att->TextureLevel]; + intel_tex_map_images(intel, intel_texture_object(tex)); + } + else { + intel_tex_unmap_images(intel, intel_texture_object(tex)); + } + } + } + + /* color read buffers */ + irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + if (irb && irb->region) { + if (map) + intel_region_map(intel->intelScreen, irb->region); + else + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + + /* Account for front/back color page flipping. + * The span routines use the pfMap and pfPitch fields which will + * swap the front/back region map/pitch if we're page flipped. + * Do this after mapping, above, so the map field is valid. + */ +#if 0 + if (map && ctx->DrawBuffer->Name == 0) { + struct intel_renderbuffer *irbFront + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT); + struct intel_renderbuffer *irbBack + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT); + if (irbBack) { + /* double buffered */ + if (intel->sarea->pf_current_page == 0) { + irbFront->pfMap = irbFront->region->map; + irbFront->pfPitch = irbFront->region->pitch; + irbBack->pfMap = irbBack->region->map; + irbBack->pfPitch = irbBack->region->pitch; + } + else { + irbFront->pfMap = irbBack->region->map; + irbFront->pfPitch = irbBack->region->pitch; + irbBack->pfMap = irbFront->region->map; + irbBack->pfPitch = irbFront->region->pitch; + } + } + } +#endif + + /* depth buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_DepthBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) { + intel_region_map(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + else { + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = NULL; + irb->pfPitch = 0; + } + } + } + + /* stencil buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_StencilBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) { + intel_region_map(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + else { + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = NULL; + irb->pfPitch = 0; + } + } + } +} + + + +/** + * Prepare for softare rendering. Map current read/draw framebuffers' + * renderbuffes and all currently bound texture objects. + * + * Old note: Moved locking out to get reasonable span performance. + */ +void +intelSpanRenderStart(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + GLuint i; + + intelFinish(&intel->ctx); + LOCK_HARDWARE(intel); + +#if 0 + /* Just map the framebuffer and all textures. Bufmgr code will + * take care of waiting on the necessary fences: + */ + intel_region_map(intel->intelScreen, intel->front_region); + intel_region_map(intel->intelScreen, intel->back_region); + intel_region_map(intel->intelScreen, intel->intelScreen->depth_region); +#endif + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; + intel_tex_map_images(intel, intel_texture_object(texObj)); + } + } + + intel_map_unmap_buffers(intel, GL_TRUE); +} + +/** + * Called when done softare rendering. Unmap the buffers we mapped in + * the above function. + */ +void +intelSpanRenderFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + GLuint i; + + _swrast_flush(ctx); + + /* Now unmap the framebuffer: + */ +#if 0 + intel_region_unmap(intel, intel->front_region); + intel_region_unmap(intel, intel->back_region); + intel_region_unmap(intel, intel->intelScreen->depth_region); +#endif + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; + intel_tex_unmap_images(intel, intel_texture_object(texObj)); + } + } + + intel_map_unmap_buffers(intel, GL_FALSE); + + UNLOCK_HARDWARE(intel); +} + + +void +intelInitSpanFuncs(GLcontext * ctx) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + swdd->SpanRenderStart = intelSpanRenderStart; + swdd->SpanRenderFinish = intelSpanRenderFinish; +} + + +/** + * Plug in appropriate span read/write functions for the given renderbuffer. + * These are used for the software fallbacks. + */ +void +intel_set_span_functions(struct gl_renderbuffer *rb) +{ + if (rb->_ActualFormat == GL_RGB5) { + /* 565 RGB */ + intelInitPointers_RGB565(rb); + } + else if (rb->_ActualFormat == GL_RGBA8) { + /* 8888 RGBA */ + intelInitPointers_ARGB8888(rb); + } + else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) { + intelInitDepthPointers_z16(rb); + } + else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */ + rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { + intelInitDepthPointers_z24_s8(rb); + } + else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { /* XXX FBO remove */ + intelInitStencilPointers_z24_s8(rb); + } + else { + _mesa_problem(NULL, + "Unexpected _ActualFormat in intelSetSpanFunctions"); + } +} diff --git a/src/mesa/drivers/dri/i915/intel_span.h b/src/mesa/drivers/dri/i915/intel_span.h new file mode 100644 index 0000000000..5201f6d6c6 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_span.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _INTEL_SPAN_H +#define _INTEL_SPAN_H + +extern void intelInitSpanFuncs(GLcontext * ctx); + +extern void intelSpanRenderFinish(GLcontext * ctx); +extern void intelSpanRenderStart(GLcontext * ctx); + +extern void intel_set_span_functions(struct gl_renderbuffer *rb); + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_state.c b/src/mesa/drivers/dri/i915/intel_state.c new file mode 100644 index 0000000000..271511037e --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_state.c @@ -0,0 +1,269 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "colormac.h" +#include "dd.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_regions.h" +#include "swrast/swrast.h" + +int +intel_translate_compare_func(GLenum func) +{ + switch (func) { + case GL_NEVER: + return COMPAREFUNC_NEVER; + case GL_LESS: + return COMPAREFUNC_LESS; + case GL_LEQUAL: + return COMPAREFUNC_LEQUAL; + case GL_GREATER: + return COMPAREFUNC_GREATER; + case GL_GEQUAL: + return COMPAREFUNC_GEQUAL; + case GL_NOTEQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_EQUAL: + return COMPAREFUNC_EQUAL; + case GL_ALWAYS: + return COMPAREFUNC_ALWAYS; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_ALWAYS; +} + +int +intel_translate_stencil_op(GLenum op) +{ + switch (op) { + case GL_KEEP: + return STENCILOP_KEEP; + case GL_ZERO: + return STENCILOP_ZERO; + case GL_REPLACE: + return STENCILOP_REPLACE; + case GL_INCR: + return STENCILOP_INCRSAT; + case GL_DECR: + return STENCILOP_DECRSAT; + case GL_INCR_WRAP: + return STENCILOP_INCR; + case GL_DECR_WRAP: + return STENCILOP_DECR; + case GL_INVERT: + return STENCILOP_INVERT; + default: + return STENCILOP_ZERO; + } +} + +int +intel_translate_blend_factor(GLenum factor) +{ + switch (factor) { + case GL_ZERO: + return BLENDFACT_ZERO; + case GL_SRC_ALPHA: + return BLENDFACT_SRC_ALPHA; + case GL_ONE: + return BLENDFACT_ONE; + case GL_SRC_COLOR: + return BLENDFACT_SRC_COLR; + case GL_ONE_MINUS_SRC_COLOR: + return BLENDFACT_INV_SRC_COLR; + case GL_DST_COLOR: + return BLENDFACT_DST_COLR; + case GL_ONE_MINUS_DST_COLOR: + return BLENDFACT_INV_DST_COLR; + case GL_ONE_MINUS_SRC_ALPHA: + return BLENDFACT_INV_SRC_ALPHA; + case GL_DST_ALPHA: + return BLENDFACT_DST_ALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return BLENDFACT_INV_DST_ALPHA; + case GL_SRC_ALPHA_SATURATE: + return BLENDFACT_SRC_ALPHA_SATURATE; + case GL_CONSTANT_COLOR: + return BLENDFACT_CONST_COLOR; + case GL_ONE_MINUS_CONSTANT_COLOR: + return BLENDFACT_INV_CONST_COLOR; + case GL_CONSTANT_ALPHA: + return BLENDFACT_CONST_ALPHA; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return BLENDFACT_INV_CONST_ALPHA; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor); + return BLENDFACT_ZERO; +} + +int +intel_translate_logic_op(GLenum opcode) +{ + switch (opcode) { + case GL_CLEAR: + return LOGICOP_CLEAR; + case GL_AND: + return LOGICOP_AND; + case GL_AND_REVERSE: + return LOGICOP_AND_RVRSE; + case GL_COPY: + return LOGICOP_COPY; + case GL_COPY_INVERTED: + return LOGICOP_COPY_INV; + case GL_AND_INVERTED: + return LOGICOP_AND_INV; + case GL_NOOP: + return LOGICOP_NOOP; + case GL_XOR: + return LOGICOP_XOR; + case GL_OR: + return LOGICOP_OR; + case GL_OR_INVERTED: + return LOGICOP_OR_INV; + case GL_NOR: + return LOGICOP_NOR; + case GL_EQUIV: + return LOGICOP_EQUIV; + case GL_INVERT: + return LOGICOP_INV; + case GL_OR_REVERSE: + return LOGICOP_OR_RVRSE; + case GL_NAND: + return LOGICOP_NAND; + case GL_SET: + return LOGICOP_SET; + default: + return LOGICOP_SET; + } +} + + +static void +intelClearColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct intel_context *intel = intel_context(ctx); + GLubyte clear[4]; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + /* compute both 32 and 16-bit clear values */ + intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], + clear[2], clear[3]); + intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); +} + + +/** + * Update the viewport transformation matrix. Depends on: + * - viewport pos/size + * - depthrange + * - window pos/size or FBO size + */ +static void +intelCalcViewport(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; + GLfloat *m = intel->ViewportMatrix.m; + GLfloat yScale, yBias; + + if (ctx->DrawBuffer->Name) { + /* User created FBO */ + struct intel_renderbuffer *irb + = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]); + if (irb && !irb->RenderToTexture) { + /* y=0=top */ + yScale = -1.0; + yBias = irb->Base.Height; + } + else { + /* y=0=bottom */ + yScale = 1.0; + yBias = 0.0; + } + } + else { + /* window buffer, y=0=top */ + yScale = -1.0; + yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; + } + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + + m[MAT_SY] = v[MAT_SY] * yScale; + m[MAT_TY] = v[MAT_TY] * yScale + yBias + SUBPIXEL_Y; + + m[MAT_SZ] = v[MAT_SZ] * depthScale; + m[MAT_TZ] = v[MAT_TZ] * depthScale; +} + +static void +intelViewport(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + intelCalcViewport(ctx); +} + +static void +intelDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) +{ + intelCalcViewport(ctx); +} + +/* Fallback to swrast for select and feedback. + */ +static void +intelRenderMode(GLcontext * ctx, GLenum mode) +{ + struct intel_context *intel = intel_context(ctx); + FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); +} + + +void +intelInitStateFuncs(struct dd_function_table *functions) +{ + functions->RenderMode = intelRenderMode; + functions->Viewport = intelViewport; + functions->DepthRange = intelDepthRange; + functions->ClearColor = intelClearColor; +} diff --git a/src/mesa/drivers/dri/i915/intel_structs.h b/src/mesa/drivers/dri/i915/intel_structs.h new file mode 100644 index 0000000000..522e3bd92c --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_structs.h @@ -0,0 +1,132 @@ +#ifndef INTEL_STRUCTS_H +#define INTEL_STRUCTS_H + +struct br0 { + GLuint length:8; + GLuint pad0:3; + GLuint dst_tiled:1; + GLuint pad1:8; + GLuint write_rgb:1; + GLuint write_alpha:1; + GLuint opcode:7; + GLuint client:3; +}; + + +struct br13 { + GLint dest_pitch:16; + GLuint rop:8; + GLuint color_depth:2; + GLuint pad1:3; + GLuint mono_source_transparency:1; + GLuint clipping_enable:1; + GLuint pad0:1; +}; + + + +/* This is an attempt to move some of the 2D interaction in this + * driver to using structs for packets rather than a bunch of #defines + * and dwords. + */ +struct xy_color_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint color; +}; + +struct xy_src_copy_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + + struct { + GLuint src_x1:16; + GLuint src_y1:16; + } dw5; + + struct { + GLint src_pitch:16; + GLuint pad:16; + } dw6; + + GLuint src_base_addr; +}; + +struct xy_setup_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint clip_x1:16; + GLuint clip_y1:16; + } dw2; + + struct { + GLuint clip_x2:16; + GLuint clip_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint background_color; + GLuint foreground_color; + GLuint pattern_base_addr; +}; + + +struct xy_text_immediate_blit { + struct { + GLuint length:8; + GLuint pad2:3; + GLuint dst_tiled:1; + GLuint pad1:4; + GLuint byte_packed:1; + GLuint pad0:5; + GLuint opcode:7; + GLuint client:3; + } dw0; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw1; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw2; + + /* Src bitmap data follows as inline dwords. + */ +}; + + +#define CLIENT_2D 0x2 +#define OPCODE_XY_SETUP_BLT 0x1 +#define OPCODE_XY_COLOR_BLT 0x50 +#define OPCODE_XY_TEXT_IMMEDIATE_BLT 0x31 + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c new file mode 100644 index 0000000000..b08dee43bc --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex.c @@ -0,0 +1,192 @@ +#include "texobj.h" +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static GLboolean +intelIsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + + return + intelObj->mt && + intelObj->mt->region && + intel_is_region_resident(intel, intelObj->mt->region); +#endif + return 1; +} + + + +static struct gl_texture_image * +intelNewTextureImage(GLcontext * ctx) +{ + DBG("%s\n", __FUNCTION__); + (void) ctx; + return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); +} + + +static struct gl_texture_object * +intelNewTextureObject(GLcontext * ctx, GLuint name, GLenum target) +{ + struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); + + DBG("%s\n", __FUNCTION__); + _mesa_initialize_texture_object(&obj->base, name, target); + + return &obj->base; +} + +static void +intelDeleteTextureObject(GLcontext *ctx, + struct gl_texture_object *texObj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + _mesa_delete_texture_object(ctx, texObj); +} + + +static void +intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + + DBG("%s\n", __FUNCTION__); + + if (intelImage->mt) { + intel_miptree_release(intel, &intelImage->mt); + } + + if (texImage->Data) { + free(texImage->Data); + texImage->Data = NULL; + } +} + + +/* The system memcpy (at least on ubuntu 5.10) has problems copying + * to agp (writecombined) memory from a source which isn't 64-byte + * aligned - there is a 4x performance falloff. + * + * The x86 __memcpy is immune to this but is slightly slower + * (10%-ish) than the system memcpy. + * + * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but + * isn't much faster than x86_memcpy for agp copies. + * + * TODO: switch dynamically. + */ +static void * +do_memcpy(void *dest, const void *src, size_t n) +{ + if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { + return __memcpy(dest, src, n); + } + else + return memcpy(dest, src, n); +} + + +#if DO_DEBUG + +#ifndef __x86_64__ +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" + "pushl %%ebx\n\t" + "cpuid\n\t" ".byte 0x0f, 0x31\n\t" + "popl %%ebx\n":"=a" (eax) + :"0"(0) + :"ecx", "edx", "cc"); + + return eax; +} +#else +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax) + :"0"(0) + :"ecx", "edx", "ebx", "cc"); + + return eax; +} +#endif + +static unsigned +time_diff(unsigned t, unsigned t2) +{ + return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1)); +} + + +static void * +timed_memcpy(void *dest, const void *src, size_t n) +{ + void *ret; + unsigned t1, t2; + double rate; + + if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) + _mesa_printf("Warning - non-aligned texture copy!\n"); + + t1 = fastrdtsc(); + ret = do_memcpy(dest, src, n); + t2 = fastrdtsc(); + + rate = time_diff(t1, t2); + rate /= (double) n; + _mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate); + return ret; +} +#endif /* DO_DEBUG */ + + +void +intelInitTextureFuncs(struct dd_function_table *functions) +{ + functions->ChooseTextureFormat = intelChooseTextureFormat; + functions->TexImage1D = intelTexImage1D; + functions->TexImage2D = intelTexImage2D; + functions->TexImage3D = intelTexImage3D; + functions->TexSubImage1D = intelTexSubImage1D; + functions->TexSubImage2D = intelTexSubImage2D; + functions->TexSubImage3D = intelTexSubImage3D; + functions->CopyTexImage1D = intelCopyTexImage1D; + functions->CopyTexImage2D = intelCopyTexImage2D; + functions->CopyTexSubImage1D = intelCopyTexSubImage1D; + functions->CopyTexSubImage2D = intelCopyTexSubImage2D; + functions->GetTexImage = intelGetTexImage; + + /* compressed texture functions */ + functions->CompressedTexImage2D = intelCompressedTexImage2D; + functions->GetCompressedTexImage = intelGetCompressedTexImage; + + functions->NewTextureObject = intelNewTextureObject; + functions->NewTextureImage = intelNewTextureImage; + functions->DeleteTexture = intelDeleteTextureObject; + functions->FreeTexImageData = intelFreeTextureImageData; + functions->UpdateTexturePalette = 0; + functions->IsTextureResident = intelIsTextureResident; + +#if DO_DEBUG + if (INTEL_DEBUG & DEBUG_BUFMGR) + functions->TextureMemCpy = timed_memcpy; + else +#endif + functions->TextureMemCpy = do_memcpy; +} diff --git a/src/mesa/drivers/dri/i915/intel_tex.h b/src/mesa/drivers/dri/i915/intel_tex.h new file mode 100644 index 0000000000..b77d7a1d8a --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex.h @@ -0,0 +1,151 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTELTEX_INC +#define INTELTEX_INC + +#include "mtypes.h" +#include "intel_context.h" +#include "texmem.h" + + +void intelInitTextureFuncs(struct dd_function_table *functions); + +const struct gl_texture_format *intelChooseTextureFormat(GLcontext * ctx, + GLint internalFormat, + GLenum format, + GLenum type); + + +void intelTexImage3D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage3D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexImage2D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage2D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexImage1D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage1D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border); + +void intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + +void intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); + +void intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + +void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + +void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage); + +void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch); + +GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); + +void intel_tex_map_images(struct intel_context *intel, + struct intel_texture_object *intelObj); + +void intel_tex_unmap_images(struct intel_context *intel, + struct intel_texture_object *intelObj); + +int intel_compressed_num_bytes(GLuint mesaFormat); + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_tex_copy.c b/src/mesa/drivers/dri/i915/intel_tex_copy.c new file mode 100644 index 0000000000..b85a25642a --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex_copy.c @@ -0,0 +1,302 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "mtypes.h" +#include "enums.h" +#include "image.h" +#include "teximage.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_buffers.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "intel_fbo.h" +#include "intel_tex.h" +#include "intel_blit.h" +#include "intel_pixel.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/** + * Get the intel_region which is the source for any glCopyTex[Sub]Image call. + * + * Do the best we can using the blitter. A future project is to use + * the texture engine and fragment programs for these copies. + */ +static const struct intel_region * +get_teximage_source(struct intel_context *intel, GLenum internalFormat) +{ + struct intel_renderbuffer *irb; + + DBG("%s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(internalFormat)); + + switch (internalFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_ARB: + irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); + if (irb && irb->region && irb->region->cpp == 2) + return irb->region; + return NULL; + case GL_DEPTH24_STENCIL8_EXT: + case GL_DEPTH_STENCIL_EXT: + irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); + if (irb && irb->region && irb->region->cpp == 4) + return irb->region; + return NULL; + case GL_RGBA: + case GL_RGBA8: + return intel_readbuf_region(intel); + case GL_RGB: + if (intel->intelScreen->cpp == 2) + return intel_readbuf_region(intel); + return NULL; + default: + return NULL; + } +} + + +static GLboolean +do_copy_texsubimage(struct intel_context *intel, + struct intel_texture_image *intelImage, + GLenum internalFormat, + GLint dstx, GLint dsty, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + GLcontext *ctx = &intel->ctx; + const struct intel_region *src = + get_teximage_source(intel, internalFormat); + + if (!intelImage->mt || !src) { + DBG("%s fail %p %p\n", __FUNCTION__, intelImage->mt, src); + return GL_FALSE; + } + + intelFlush(ctx); + LOCK_HARDWARE(intel); + { + GLuint image_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + const GLint orig_x = x; + const GLint orig_y = y; + const struct gl_framebuffer *fb = ctx->DrawBuffer; + + if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, + &x, &y, &width, &height)) { + /* Update dst for clipped src. Need to also clip the source rect. + */ + dstx += x - orig_x; + dsty += y - orig_y; + + if (ctx->ReadBuffer->Name == 0) { + /* reading from a window, adjust x, y */ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + GLuint window_y; + /* window_y = position of window on screen if y=0=bottom */ + window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); + y = window_y + y; + x += dPriv->x; + } + else { + /* reading from a FBO */ + /* invert Y */ + y = ctx->ReadBuffer->Height - y - 1; + } + + + /* A bit of fiddling to get the blitter to work with -ve + * pitches. But we get a nice inverted blit this way, so it's + * worth it: + */ + intelEmitCopyBlit(intel, + intelImage->mt->cpp, + -src->pitch, + src->buffer, + src->height * src->pitch * src->cpp, + intelImage->mt->pitch, + intelImage->mt->region->buffer, + image_offset, + x, y + height, dstx, dsty, width, height, + GL_COPY); /* ? */ + + intel_batchbuffer_flush(intel->batch); + } + } + + + UNLOCK_HARDWARE(intel); + +#if 0 + /* GL_SGIS_generate_mipmap -- this can be accelerated now. + * XXX Add a ctx->Driver.GenerateMipmaps() function? + */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif + + return GL_TRUE; +} + + + + + +void +intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + + if (border) + goto fail; + + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage1D(ctx, target, level, internalFormat, + width, border, + GL_RGBA, CHAN_TYPE, NULL, + &ctx->DefaultPacking, texObj, texImage); + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, 0, 0, x, y, width, 1)) + goto fail; + + return; + + fail: + _swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y, + width, border); +} + +void +intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + + if (border) + goto fail; + + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, + GL_RGBA, CHAN_TYPE, NULL, + &ctx->DefaultPacking, texObj, texImage); + + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, 0, 0, x, y, width, height)) + goto fail; + + return; + + fail: + _swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y, + width, height, border); +} + + +void +intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + GLenum internalFormat = texImage->InternalFormat; + + /* XXX need to check as in above function? */ + + /* Need to check texture is compatible with source format. + */ + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, xoffset, 0, x, y, width, 1)) { + _swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width); + } +} + + + +void +intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + GLenum internalFormat = texImage->InternalFormat; + + + /* Need to check texture is compatible with source format. + */ + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, + xoffset, yoffset, x, y, width, height)) { + + DBG("%s - fallback to swrast\n", __FUNCTION__); + + _swrast_copy_texsubimage2d(ctx, target, level, + xoffset, yoffset, x, y, width, height); + } +} diff --git a/src/mesa/drivers/dri/i915/intel_tex_format.c b/src/mesa/drivers/dri/i915/intel_tex_format.c new file mode 100644 index 0000000000..6e058dff69 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex_format.c @@ -0,0 +1,172 @@ +#include "intel_context.h" +#include "intel_tex.h" +#include "texformat.h" +#include "enums.h" + +/* It works out that this function is fine for all the supported + * hardware. However, there is still a need to map the formats onto + * hardware descriptors. + */ +/* Note that the i915 can actually support many more formats than + * these if we take the step of simply swizzling the colors + * immediately after sampling... + */ +const struct gl_texture_format * +intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, + GLenum format, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + const GLboolean do32bpt = (intel->intelScreen->cpp == 4); + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + if (format == GL_BGRA) { + if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) { + return &_mesa_texformat_argb8888; + } + else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { + return &_mesa_texformat_argb4444; + } + else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { + return &_mesa_texformat_argb1555; + } + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { + return &_mesa_texformat_rgb565; + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_argb8888; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return &_mesa_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return &_mesa_texformat_a8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return &_mesa_texformat_l8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return &_mesa_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return &_mesa_texformat_i8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + case GL_COMPRESSED_RGB_FXT1_3DFX: + return &_mesa_texformat_rgb_fxt1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return &_mesa_texformat_rgba_fxt1; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + return &_mesa_texformat_z16; + + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + return &_mesa_texformat_z24_s8; + + default: + fprintf(stderr, "unexpected texture format %s in %s\n", + _mesa_lookup_enum_by_nr(internalFormat), __FUNCTION__); + return NULL; + } + + return NULL; /* never get here */ +} + +int intel_compressed_num_bytes(GLuint mesaFormat) +{ + int bytes = 0; + switch(mesaFormat) { + + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + bytes = 2; + break; + + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + bytes = 4; + default: + break; + } + + return bytes; +} diff --git a/src/mesa/drivers/dri/i915/intel_tex_image.c b/src/mesa/drivers/dri/i915/intel_tex_image.c new file mode 100644 index 0000000000..197cf35ebe --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex_image.c @@ -0,0 +1,690 @@ + +#include +#include + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "enums.h" +#include "colortab.h" +#include "convolve.h" +#include "context.h" +#include "simple_list.h" +#include "texcompress.h" +#include "texformat.h" +#include "texobj.h" +#include "texstore.h" + +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_buffer_objects.h" +#include "intel_batchbuffer.h" +#include "intel_tex.h" +#include "intel_ioctl.h" +#include "intel_blit.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/* Functions to store texture images. Where possible, mipmap_tree's + * will be created or further instantiated with image data, otherwise + * images will be stored in malloc'd memory. A validation step is + * required to pull those images into a mipmap tree, or otherwise + * decide a fallback is required. + */ + + +static int +logbase2(int n) +{ + GLint i = 1; + GLint log2 = 0; + + while (n > i) { + i *= 2; + log2++; + } + + return log2; +} + + +/* Otherwise, store it in memory if (Border != 0) or (any dimension == + * 1). + * + * Otherwise, if max_level >= level >= min_level, create tree with + * space for textures from min_level down to max_level. + * + * Otherwise, create tree with space for textures from (level + * 0)..(1x1). Consider pruning this tree at a validation if the + * saving is worth it. + */ +static void +guess_and_alloc_mipmap_tree(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage) +{ + GLuint firstLevel; + GLuint lastLevel; + GLuint width = intelImage->base.Width; + GLuint height = intelImage->base.Height; + GLuint depth = intelImage->base.Depth; + GLuint l2width, l2height, l2depth; + GLuint i, comp_byte = 0; + + DBG("%s\n", __FUNCTION__); + + if (intelImage->base.Border) + return; + + if (intelImage->level > intelObj->base.BaseLevel && + (intelImage->base.Width == 1 || + (intelObj->base.Target != GL_TEXTURE_1D && + intelImage->base.Height == 1) || + (intelObj->base.Target == GL_TEXTURE_3D && + intelImage->base.Depth == 1))) + return; + + /* If this image disrespects BaseLevel, allocate from level zero. + * Usually BaseLevel == 0, so it's unlikely to happen. + */ + if (intelImage->level < intelObj->base.BaseLevel) + firstLevel = 0; + else + firstLevel = intelObj->base.BaseLevel; + + + /* Figure out image dimensions at start level. + */ + for (i = intelImage->level; i > firstLevel; i--) { + width <<= 1; + if (height != 1) + height <<= 1; + if (depth != 1) + depth <<= 1; + } + + /* Guess a reasonable value for lastLevel. This is probably going + * to be wrong fairly often and might mean that we have to look at + * resizable buffers, or require that buffers implement lazy + * pagetable arrangements. + */ + if ((intelObj->base.MinFilter == GL_NEAREST || + intelObj->base.MinFilter == GL_LINEAR) && + intelImage->level == firstLevel) { + lastLevel = firstLevel; + } + else { + l2width = logbase2(width); + l2height = logbase2(height); + l2depth = logbase2(depth); + lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); + } + + assert(!intelObj->mt); + if (intelImage->base.IsCompressed) + comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat); + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + intelImage->base.InternalFormat, + firstLevel, + lastLevel, + width, + height, + depth, + intelImage->base.TexFormat->TexelBytes, + comp_byte); + + DBG("%s - success\n", __FUNCTION__); +} + + + + +static GLuint +target_to_face(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); + default: + return 0; + } +} + +/* There are actually quite a few combinations this will work for, + * more than what I've listed here. + */ +static GLboolean +check_pbo_format(GLint internalFormat, + GLenum format, GLenum type, + const struct gl_texture_format *mesa_format) +{ + switch (internalFormat) { + case 4: + case GL_RGBA: + return (format == GL_BGRA && + (type == GL_UNSIGNED_BYTE || + type == GL_UNSIGNED_INT_8_8_8_8_REV) && + mesa_format == &_mesa_texformat_argb8888); + case 3: + case GL_RGB: + return (format == GL_RGB && + type == GL_UNSIGNED_SHORT_5_6_5 && + mesa_format == &_mesa_texformat_rgb565); + case GL_YCBCR_MESA: + return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); + default: + return GL_FALSE; + } +} + + +/* XXX: Do this for TexSubImage also: + */ +static GLboolean +try_pbo_upload(struct intel_context *intel, + struct intel_texture_image *intelImage, + const struct gl_pixelstore_attrib *unpack, + GLint internalFormat, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels) +{ + struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); + GLuint src_offset, src_stride; + GLuint dst_offset, dst_stride; + + if (!pbo || + intel->ctx._ImageTransferState || + unpack->SkipPixels || unpack->SkipRows) { + _mesa_printf("%s: failure 1\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) pixels; + + if (unpack->RowLength > 0) + src_stride = unpack->RowLength; + else + src_stride = width; + + dst_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + + dst_stride = intelImage->mt->pitch; + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + { + dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); + dri_bo *dst_buffer = intel_region_buffer(intel->intelScreen, + intelImage->mt->region, + INTEL_WRITE_FULL); + + + intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_stride, src_buffer, src_offset, + dst_stride, dst_buffer, dst_offset, + 0, 0, 0, 0, width, height, + GL_COPY); + + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + return GL_TRUE; +} + + + +static GLboolean +try_pbo_zcopy(struct intel_context *intel, + struct intel_texture_image *intelImage, + const struct gl_pixelstore_attrib *unpack, + GLint internalFormat, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels) +{ + struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); + GLuint src_offset, src_stride; + GLuint dst_offset, dst_stride; + + if (!pbo || + intel->ctx._ImageTransferState || + unpack->SkipPixels || unpack->SkipRows) { + _mesa_printf("%s: failure 1\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) pixels; + + if (unpack->RowLength > 0) + src_stride = unpack->RowLength; + else + src_stride = width; + + dst_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + + dst_stride = intelImage->mt->pitch; + + if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) { + _mesa_printf("%s: failure 2\n", __FUNCTION__); + return GL_FALSE; + } + + intel_region_attach_pbo(intel->intelScreen, intelImage->mt->region, pbo); + + return GL_TRUE; +} + + + + + + +static void +intelTexImage(GLcontext * ctx, + GLint dims, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, GLsizei imageSize, int compressed) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + GLint postConvWidth = width; + GLint postConvHeight = height; + GLint texelBytes, sizeInBytes; + GLuint dstRowStride; + + + DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); + + intelFlush(ctx); + + intelImage->face = target_to_face(target); + intelImage->level = level; + + if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, + &postConvHeight); + } + + /* choose the texture format */ + texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat, + format, type); + + _mesa_set_fetch_functions(texImage, dims); + + if (texImage->TexFormat->TexelBytes == 0) { + /* must be a compressed format */ + texelBytes = 0; + texImage->IsCompressed = GL_TRUE; + texImage->CompressedSize = + ctx->Driver.CompressedTextureSize(ctx, texImage->Width, + texImage->Height, texImage->Depth, + texImage->TexFormat->MesaFormat); + } else { + texelBytes = texImage->TexFormat->TexelBytes; + + /* Minimum pitch of 32 bytes */ + if (postConvWidth * texelBytes < 32) { + postConvWidth = 32 / texelBytes; + texImage->RowStride = postConvWidth; + } + + assert(texImage->RowStride == postConvWidth); + } + + /* Release the reference to a potentially orphaned buffer. + * Release any old malloced memory. + */ + if (intelImage->mt) { + intel_miptree_release(intel, &intelImage->mt); + assert(!texImage->Data); + } + else if (texImage->Data) { + _mesa_align_free(texImage->Data); + } + + /* If this is the only texture image in the tree, could call + * bmBufferData with NULL data to free the old block and avoid + * waiting on any outstanding fences. + */ + if (intelObj->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level && + intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && + !intel_miptree_match_image(intelObj->mt, &intelImage->base, + intelImage->face, intelImage->level)) { + + DBG("release it\n"); + intel_miptree_release(intel, &intelObj->mt); + assert(!intelObj->mt); + } + + if (!intelObj->mt) { + guess_and_alloc_mipmap_tree(intel, intelObj, intelImage); + if (!intelObj->mt) { + DBG("guess_and_alloc_mipmap_tree: failed\n"); + } + } + + assert(!intelImage->mt); + + if (intelObj->mt && + intel_miptree_match_image(intelObj->mt, &intelImage->base, + intelImage->face, intelImage->level)) { + + intel_miptree_reference(&intelImage->mt, intelObj->mt); + assert(intelImage->mt); + } + + if (!intelImage->mt) + DBG("XXX: Image did not fit into tree - storing in local memory!\n"); + + /* PBO fastpaths: + */ + if (dims <= 2 && + intelImage->mt && + intel_buffer_object(unpack->BufferObj) && + check_pbo_format(internalFormat, format, + type, intelImage->base.TexFormat)) { + + DBG("trying pbo upload\n"); + + /* Attempt to texture directly from PBO data (zero copy upload). + * + * Currently disable as it can lead to worse as well as better + * performance (in particular when intel_region_cow() is + * required). + */ + if (intelObj->mt == intelImage->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level) { + + if (try_pbo_zcopy(intel, intelImage, unpack, + internalFormat, + width, height, format, type, pixels)) { + + DBG("pbo zcopy upload succeeded\n"); + return; + } + } + + + /* Otherwise, attempt to use the blitter for PBO image uploads. + */ + if (try_pbo_upload(intel, intelImage, unpack, + internalFormat, + width, height, format, type, pixels)) { + DBG("pbo upload succeeded\n"); + return; + } + + DBG("pbo upload failed\n"); + } + + + + /* intelCopyTexImage calls this function with pixels == NULL, with + * the expectation that the mipmap tree will be set up but nothing + * more will be done. This is where those calls return: + */ + if (compressed) { + pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, + unpack, + "glCompressedTexImage"); + } else { + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, + format, type, + pixels, unpack, "glTexImage"); + } + if (!pixels) + return; + + + if (intelImage->mt) + intel_region_idle(intel->intelScreen, intelImage->mt->region); + + LOCK_HARDWARE(intel); + + if (intelImage->mt) { + texImage->Data = intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &dstRowStride, + intelImage->base.ImageOffsets); + } + else { + /* Allocate regular memory and store the image there temporarily. */ + if (texImage->IsCompressed) { + sizeInBytes = texImage->CompressedSize; + dstRowStride = + _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); + assert(dims != 3); + } + else { + dstRowStride = postConvWidth * texelBytes; + sizeInBytes = depth * dstRowStride * postConvHeight; + } + + texImage->Data = malloc(sizeInBytes); + } + + DBG("Upload image %dx%dx%d row_len %x " + "pitch %x\n", + width, height, depth, width * texelBytes, dstRowStride); + + /* Copy data. Would like to know when it's ok for us to eg. use + * the blitter to copy. Or, use the hardware to do the format + * conversion and copy: + */ + if (compressed) { + memcpy(texImage->Data, pixels, imageSize); + } else if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, unpack)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + } + + _mesa_unmap_teximage_pbo(ctx, unpack); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + texImage->Data = NULL; + } + + UNLOCK_HARDWARE(intel); + +#if 0 + /* GL_SGIS_generate_mipmap -- this can be accelerated now. + */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif +} + +void +intelTexImage3D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 3, target, level, + internalFormat, width, height, depth, border, + format, type, pixels, unpack, texObj, texImage, 0, 0); +} + + +void +intelTexImage2D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 2, target, level, + internalFormat, width, height, 1, border, + format, type, pixels, unpack, texObj, texImage, 0, 0); +} + +void +intelTexImage1D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 1, target, level, + internalFormat, width, 1, 1, border, + format, type, pixels, unpack, texObj, texImage, 0, 0); +} + +void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + intelTexImage(ctx, 2, target, level, + internalFormat, width, height, 1, border, + 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); +} + +/** + * Need to map texture image into memory before copying image data, + * then unmap it. + */ +static void +intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, int compressed) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + + /* Map */ + if (intelImage->mt) { + /* Image is stored in hardware format in a buffer managed by the + * kernel. Need to explicitly map and unmap it. + */ + intelImage->base.Data = + intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &intelImage->base.RowStride, + intelImage->base.ImageOffsets); + intelImage->base.RowStride /= intelImage->mt->cpp; + } + else { + /* Otherwise, the image should actually be stored in + * intelImage->base.Data. This is pretty confusing for + * everybody, I'd much prefer to separate the two functions of + * texImage->Data - storage for texture images in main memory + * and access (ie mappings) of images. In other words, we'd + * create a new texImage->Map field and leave Data simply for + * storage. + */ + assert(intelImage->base.Data); + } + + + if (compressed) { + _mesa_get_compressed_teximage(ctx, target, level, pixels, + texObj, texImage); + } else { + _mesa_get_teximage(ctx, target, level, format, type, pixels, + texObj, texImage); + } + + + /* Unmap */ + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; + } +} + +void +intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intel_get_tex_image(ctx, target, level, format, type, pixels, + texObj, texImage, 0); + + +} + +void +intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage) +{ + intel_get_tex_image(ctx, target, level, 0, 0, pixels, + texObj, texImage, 1); + +} + +void +intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch) +{ + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct intel_texture_object *intelObj = intel_texture_object(tObj); + + if (!intelObj) + return; + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + intelObj->imageOverride = GL_TRUE; + intelObj->depthOverride = depth; + intelObj->pitchOverride = pitch; + + if (offset) + intelObj->textureOffset = offset; +} diff --git a/src/mesa/drivers/dri/i915/intel_tex_layout.c b/src/mesa/drivers/dri/i915/intel_tex_layout.c new file mode 120000 index 0000000000..fe61b44194 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex_layout.c @@ -0,0 +1 @@ +../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i915/intel_tex_subimage.c b/src/mesa/drivers/dri/i915/intel_tex_subimage.c new file mode 100644 index 0000000000..3935787806 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex_subimage.c @@ -0,0 +1,182 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "mtypes.h" +#include "texobj.h" +#include "texstore.h" +#include "enums.h" + +#include "intel_context.h" +#include "intel_tex.h" +#include "intel_mipmap_tree.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static void +intelTexSubimage(GLcontext * ctx, + GLint dims, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + GLuint dstRowStride; + + DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + level, xoffset, yoffset, width, height); + + intelFlush(ctx); + + pixels = + _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, + type, pixels, packing, "glTexSubImage2D"); + if (!pixels) + return; + + if (intelImage->mt) + intel_region_idle(intel->intelScreen, intelImage->mt->region); + + LOCK_HARDWARE(intel); + + /* Map buffer if necessary. Need to lock to prevent other contexts + * from uploading the buffer under us. + */ + if (intelImage->mt) + texImage->Data = intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &dstRowStride, + texImage->ImageOffsets); + + assert(dstRowStride); + + if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, + xoffset, yoffset, zoffset, + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, packing)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + } + +#if 0 + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif + + _mesa_unmap_teximage_pbo(ctx, packing); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + texImage->Data = NULL; + } + + UNLOCK_HARDWARE(intel); +} + + + + + +void +intelTexSubImage3D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + + intelTexSubimage(ctx, 3, + target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, packing, texObj, texImage); + +} + + + +void +intelTexSubImage2D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + + intelTexSubimage(ctx, 2, + target, level, + xoffset, yoffset, 0, + width, height, 1, + format, type, pixels, packing, texObj, texImage); + +} + + +void +intelTexSubImage1D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexSubimage(ctx, 1, + target, level, + xoffset, 0, 0, + width, 1, 1, + format, type, pixels, packing, texObj, texImage); + +} diff --git a/src/mesa/drivers/dri/i915/intel_tex_validate.c b/src/mesa/drivers/dri/i915/intel_tex_validate.c new file mode 100644 index 0000000000..af18c26d55 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tex_validate.c @@ -0,0 +1,272 @@ +#include "mtypes.h" +#include "macros.h" + +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/** + * Compute which mipmap levels that really need to be sent to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + */ +static void +intel_calculate_first_last_level(struct intel_texture_object *intelObj) +{ + struct gl_texture_object *tObj = &intelObj->base; + const struct gl_texture_image *const baseImage = + tObj->Image[0][tObj->BaseLevel]; + + /* These must be signed values. MinLod and MaxLod can be negative numbers, + * and having firstLevel and lastLevel as signed prevents the need for + * extra sign checks. + */ + int firstLevel; + int lastLevel; + + /* Yes, this looks overly complicated, but it's all needed. + */ + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { + /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. + */ + firstLevel = lastLevel = tObj->BaseLevel; + } + else { + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_4D_SGIS: + firstLevel = lastLevel = 0; + break; + default: + return; + } + + /* save these values */ + intelObj->firstLevel = firstLevel; + intelObj->lastLevel = lastLevel; +} + +static void +copy_image_data_to_tree(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage) +{ + if (intelImage->mt) { + /* Copy potentially with the blitter: + */ + intel_miptree_image_copy(intel, + intelObj->mt, + intelImage->face, + intelImage->level, intelImage->mt); + + intel_miptree_release(intel, &intelImage->mt); + } + else { + assert(intelImage->base.Data != NULL); + + /* More straightforward upload. + */ + intel_miptree_image_data(intel, + intelObj->mt, + intelImage->face, + intelImage->level, + intelImage->base.Data, + intelImage->base.RowStride, + intelImage->base.RowStride * + intelImage->base.Height); + _mesa_align_free(intelImage->base.Data); + intelImage->base.Data = NULL; + } + + intel_miptree_reference(&intelImage->mt, intelObj->mt); +} + + +/* + */ +GLuint +intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) +{ + struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + int comp_byte = 0; + int cpp; + + GLuint face, i; + GLuint nr_faces = 0; + struct intel_texture_image *firstImage; + + GLboolean need_flush = GL_FALSE; + + /* We know/require this is true by now: + */ + assert(intelObj->base._Complete); + + /* What levels must the tree include at a minimum? + */ + intel_calculate_first_last_level(intelObj); + firstImage = + intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]); + + /* Fallback case: + */ + if (firstImage->base.Border) { + if (intelObj->mt) { + intel_miptree_release(intel, &intelObj->mt); + } + return GL_FALSE; + } + + + /* If both firstImage and intelObj have a tree which can contain + * all active images, favour firstImage. Note that because of the + * completeness requirement, we know that the image dimensions + * will match. + */ + if (firstImage->mt && + firstImage->mt != intelObj->mt && + firstImage->mt->first_level <= intelObj->firstLevel && + firstImage->mt->last_level >= intelObj->lastLevel) { + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + intel_miptree_reference(&intelObj->mt, firstImage->mt); + } + + if (firstImage->base.IsCompressed) { + comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); + cpp = comp_byte; + } + else cpp = firstImage->base.TexFormat->TexelBytes; + + /* Check tree can hold all active levels. Check tree matches + * target, imageFormat, etc. + * + * XXX: For some layouts (eg i945?), the test might have to be + * first_level == firstLevel, as the tree isn't valid except at the + * original start level. Hope to get around this by + * programming minLod, maxLod, baseLevel into the hardware and + * leaving the tree alone. + */ + if (intelObj->mt && + (intelObj->mt->target != intelObj->base.Target || + intelObj->mt->internal_format != firstImage->base.InternalFormat || + intelObj->mt->first_level != intelObj->firstLevel || + intelObj->mt->last_level != intelObj->lastLevel || + intelObj->mt->width0 != firstImage->base.Width || + intelObj->mt->height0 != firstImage->base.Height || + intelObj->mt->depth0 != firstImage->base.Depth || + intelObj->mt->cpp != cpp || + intelObj->mt->compressed != firstImage->base.IsCompressed)) { + intel_miptree_release(intel, &intelObj->mt); + } + + + /* May need to create a new tree: + */ + if (!intelObj->mt) { + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + firstImage->base.InternalFormat, + intelObj->firstLevel, + intelObj->lastLevel, + firstImage->base.Width, + firstImage->base.Height, + firstImage->base.Depth, + cpp, + comp_byte); + } + + /* Pull in any images not in the object's tree: + */ + nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + /* Need to import images in main memory or held in other trees. + */ + if (intelObj->mt != intelImage->mt) { + copy_image_data_to_tree(intel, intelObj, intelImage); + need_flush = GL_TRUE; + } + } + } + + if (need_flush) + intel_batchbuffer_flush(intel->batch); + + return GL_TRUE; +} + + + +void +intel_tex_map_images(struct intel_context *intel, + struct intel_texture_object *intelObj) +{ + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + GLuint face, i; + + DBG("%s\n", __FUNCTION__); + + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + if (intelImage->mt) { + intelImage->base.Data = + intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &intelImage->base.RowStride, + intelImage->base.ImageOffsets); + /* convert stride to texels, not bytes */ + intelImage->base.RowStride /= intelImage->mt->cpp; +/* intelImage->base.ImageStride /= intelImage->mt->cpp; */ + } + } + } +} + + + +void +intel_tex_unmap_images(struct intel_context *intel, + struct intel_texture_object *intelObj) +{ + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + GLuint face, i; + + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; + } + } + } +} diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c new file mode 100644 index 0000000000..5fe3d4561f --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -0,0 +1,1152 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "texobj.h" +#include "state.h" +#include "dd.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_tris.h" +#include "intel_batchbuffer.h" +#include "intel_buffers.h" +#include "intel_reg.h" +#include "intel_span.h" +#include "intel_tex.h" + +static void intelRenderPrimitive(GLcontext * ctx, GLenum prim); +static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, + GLuint hwprim); + +/* + */ +static void +intel_flush_inline_primitive(struct intel_context *intel) +{ + GLuint used = intel->batch->ptr - intel->prim.start_ptr; + + assert(intel->prim.primitive != ~0); + +/* _mesa_printf("/\n"); */ + + if (used < 8) + goto do_discard; + + *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | + intel->prim.primitive | (used / 4 - 2)); + + goto finished; + + do_discard: + intel->batch->ptr -= used; + + finished: + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; +} + + +/* Emit a primitive referencing vertices in a vertex buffer. + */ +void +intelStartInlinePrimitive(struct intel_context *intel, + GLuint prim, GLuint batch_flags) +{ + BATCH_LOCALS; + + intel->vtbl.emit_state(intel); + + /* Need to make sure at the very least that we don't wrap + * batchbuffers in BEGIN_BATCH below, otherwise the primitive will + * be emitted to a batchbuffer missing the required full-state + * preamble. + */ + if (intel_batchbuffer_space(intel->batch) < 100) { + intel_batchbuffer_flush(intel->batch); + intel->vtbl.emit_state(intel); + } + +/* _mesa_printf("%s *", __progname); */ + + intel_wait_flips(intel, batch_flags); + + /* Emit a slot which will be filled with the inline primitive + * command later. + */ + BEGIN_BATCH(2, batch_flags); + OUT_BATCH(0); + + intel->prim.start_ptr = intel->batch->ptr; + intel->prim.primitive = prim; + intel->prim.flush = intel_flush_inline_primitive; + + OUT_BATCH(0); + ADVANCE_BATCH(); + +/* _mesa_printf(">"); */ +} + + +void +intelWrapInlinePrimitive(struct intel_context *intel) +{ + GLuint prim = intel->prim.primitive; + GLuint batchflags = intel->batch->flags; + + intel_flush_inline_primitive(intel); + intel_batchbuffer_flush(intel->batch); + intelStartInlinePrimitive(intel, prim, batchflags); /* ??? */ +} + +GLuint * +intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords) +{ + GLuint sz = dwords * sizeof(GLuint); + GLuint *ptr; + + assert(intel->prim.flush == intel_flush_inline_primitive); + + if (intel_batchbuffer_space(intel->batch) < sz) + intelWrapInlinePrimitive(intel); + +/* _mesa_printf("."); */ + + intel->vtbl.assert_not_dirty(intel); + + ptr = (GLuint *) intel->batch->ptr; + intel->batch->ptr += sz; + + return ptr; +} + + + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#ifdef __i386__ +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v) ); \ +} while (0) +#else +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + for ( j = 0 ; j < vertsize ; j++ ) { \ + vb[j] = ((GLuint *)v)[j]; \ + } \ + vb += vertsize; \ +} while (0) +#endif + +static void +intel_draw_quad(struct intel_context *intel, + intelVertexPtr v0, + intelVertexPtr v1, intelVertexPtr v2, intelVertexPtr v3) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 6 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + + /* If smooth shading, draw like a trifan which gives better + * rasterization. Otherwise draw as two triangles with provoking + * vertex in third position as required for flat shading. + */ + if (intel->ctx.Light.ShadeModel == GL_FLAT) { + COPY_DWORDS(j, vb, vertsize, v3); + COPY_DWORDS(j, vb, vertsize, v1); + } + else { + COPY_DWORDS(j, vb, vertsize, v2); + COPY_DWORDS(j, vb, vertsize, v0); + } + + COPY_DWORDS(j, vb, vertsize, v2); + COPY_DWORDS(j, vb, vertsize, v3); +} + +static void +intel_draw_triangle(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 3 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + COPY_DWORDS(j, vb, vertsize, v2); +} + + +static void +intel_draw_line(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 2 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); +} + + +static void +intel_draw_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, vertsize); + int j; + + /* Adjust for sub pixel position -- still required for conform. */ + *(float *) &vb[0] = v0->v.x - 0.125; + *(float *) &vb[1] = v0->v.y - 0.125; + for (j = 2; j < vertsize; j++) + vb[j] = v0->ui[j]; +} + + + +/*********************************************************************** + * Fixup for ARB_point_parameters * + ***********************************************************************/ + +/* Currently not working - VERT_ATTRIB_POINTSIZE isn't correctly + * represented in the fragment program InputsRead field. + */ +static void +intel_atten_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLcontext *ctx = &intel->ctx; + GLfloat psz[4], col[4], restore_psz, restore_alpha; + + _tnl_get_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_get_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + + restore_psz = psz[0]; + restore_alpha = col[3]; + + if (psz[0] >= ctx->Point.Threshold) { + psz[0] = MIN2(psz[0], ctx->Point.MaxSize); + } + else { + GLfloat dsize = psz[0] / ctx->Point.Threshold; + psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); + col[3] *= dsize * dsize; + } + + if (psz[0] < 1.0) + psz[0] = 1.0; + + if (restore_psz != psz[0] || restore_alpha != col[3]) { + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + + intel_draw_point(intel, v0); + + psz[0] = restore_psz; + col[3] = restore_alpha; + + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + } + else + intel_draw_point(intel, v0); +} + + + + + +/*********************************************************************** + * Fixup for I915 WPOS texture coordinate * + ***********************************************************************/ + + + +static void +intel_wpos_triangle(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + __memcpy(((char *) v1) + offset, v1, size); + __memcpy(((char *) v2) + offset, v2, size); + + intel_draw_triangle(intel, v0, v1, v2); +} + + +static void +intel_wpos_line(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + __memcpy(((char *) v1) + offset, v1, size); + + intel_draw_line(intel, v0, v1); +} + + +static void +intel_wpos_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + + intel_draw_point(intel, v0); +} + + + + + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_tri( intel, a, b, c ); \ + else \ + intel_draw_triangle( intel, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + intel->draw_tri( intel, a, b, d ); \ + intel->draw_tri( intel, b, c, d ); \ + } else \ + intel_draw_quad( intel, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_line( intel, v0, v1 ); \ + else \ + intel_draw_line( intel, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_point( intel, v0 ); \ + else \ + intel_draw_point( intel, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define INTEL_OFFSET_BIT 0x01 +#define INTEL_TWOSIDE_BIT 0x02 +#define INTEL_UNFILLED_BIT 0x04 +#define INTEL_FALLBACK_BIT 0x08 +#define INTEL_MAX_TRIFUNC 0x10 + + +static struct +{ + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[INTEL_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & INTEL_FALLBACK_BIT) +#define DO_OFFSET (IND & INTEL_OFFSET_BIT) +#define DO_UNFILLED (IND & INTEL_UNFILLED_BIT) +#define DO_TWOSIDE (IND & INTEL_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define VERTEX intelVertex +#define TAB rast_tab + +/* Only used to pull back colors into vertices (ie, we know color is + * floating point). + */ +#define INTEL_COLOR( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \ +} while (0) + +#define INTEL_SPEC( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ +} while (0) + + +#define DEPTH_SCALE intel->polygon_offset_scale +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a > 0) +#define GET_VERTEX(e) (intel->verts + (e * intel->vertex_size * sizeof(GLuint))) + +#define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c ) +#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx] + +#define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c ) +#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset]) +#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx] + +#define LOCAL_VARS(n) \ + struct intel_context *intel = intel_context(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = intel->coloroffset; \ + GLboolean specoffset = intel->specoffset; \ + (void) color; (void) spec; (void) coloroffset; (void) specoffset; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON + 1] = { + PRIM3D_POINTLIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST +}; + +#define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] ) +#define RENDER_PRIMITIVE intel->render_primitive +#define TAG(x) x +#define IND INTEL_FALLBACK_BIT +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \ + INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +static void +init_rast_tab(void) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); +} + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +intel_fallback_tri(struct intel_context *intel, + intelVertex * v0, intelVertex * v1, intelVertex * v2) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[3]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + _swsetup_Translate(ctx, v2, &v[2]); + intelSpanRenderStart(ctx); + _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); + intelSpanRenderFinish(ctx); +} + + +static void +intel_fallback_line(struct intel_context *intel, + intelVertex * v0, intelVertex * v1) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[2]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + intelSpanRenderStart(ctx); + _swrast_Line(ctx, &v[0], &v[1]); + intelSpanRenderFinish(ctx); +} + +static void +intel_fallback_point(struct intel_context *intel, + intelVertex * v0) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[1]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + intelSpanRenderStart(ctx); + _swrast_Point(ctx, &v[0]); + intelSpanRenderFinish(ctx); +} + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (intelVertex *)(vertptr + ((x)*vertsize*sizeof(GLuint))) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) POINT( V(ELT(start)) ); +#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) +#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) +#define INIT(x) intelRenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + struct intel_context *intel = intel_context(ctx); \ + GLubyte *vertptr = (GLubyte *)intel->verts; \ + const GLuint vertsize = intel->vertex_size; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) intel_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) intel_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void +intelRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) +{ + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint prim = intel->render_primitive; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *) elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON] (ctx, 0, n, + PRIM_BEGIN | PRIM_END); + VB->Elts = tmp; + } + + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify(ctx, prim); +} + +static void +intelRenderClippedLine(GLcontext * ctx, GLuint ii, GLuint jj) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.Render.Line(ctx, ii, jj); +} + +static void +intelFastRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) +{ + struct intel_context *intel = intel_context(ctx); + const GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, (n - 2) * 3 * vertsize); + GLubyte *vertptr = (GLubyte *) intel->verts; + const GLuint *start = (const GLuint *) V(elts[0]); + int i, j; + + for (i = 2; i < n; i++) { + COPY_DWORDS(j, vb, vertsize, V(elts[i - 1])); + COPY_DWORDS(j, vb, vertsize, V(elts[i])); + COPY_DWORDS(j, vb, vertsize, start); + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + + + +#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN | DD_POINT_SMOOTH | DD_TRI_SMOOTH) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED) + +void +intelChooseRenderState(GLcontext * ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + GLuint flags = ctx->_TriangleCaps; + const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; + GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS)); + GLuint index = 0; + + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + if ((flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) || have_wpos) { + + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) + index |= INTEL_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) + index |= INTEL_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) + index |= INTEL_UNFILLED_BIT; + } + + if (have_wpos) { + intel->draw_point = intel_wpos_point; + intel->draw_line = intel_wpos_line; + intel->draw_tri = intel_wpos_triangle; + + /* Make sure these get called: + */ + index |= INTEL_FALLBACK_BIT; + } + else { + intel->draw_point = intel_draw_point; + intel->draw_line = intel_draw_line; + intel->draw_tri = intel_draw_triangle; + } + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) { + if (flags & DD_LINE_STIPPLE) + intel->draw_line = intel_fallback_line; + + if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) + intel->draw_tri = intel_fallback_tri; + + if (flags & DD_TRI_SMOOTH) { + if (intel->strict_conformance) + intel->draw_tri = intel_fallback_tri; + } + + if (flags & DD_POINT_ATTEN) { + if (0) + intel->draw_point = intel_atten_point; + else + intel->draw_point = intel_fallback_point; + } + + if (flags & DD_POINT_SMOOTH) { + if (intel->strict_conformance) + intel->draw_point = intel_fallback_point; + } + + index |= INTEL_FALLBACK_BIT; + } + } + + if (intel->RenderIndex != index) { + intel->RenderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = intel_render_tab_verts; + tnl->Driver.Render.PrimTabElts = intel_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = intelFastRenderClippedPoly; + } + else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = intelRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = intelRenderClippedPoly; + } + } +} + +static const GLenum reduced_prim[GL_POLYGON + 1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + + + +static void +intelRunPipeline(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + _mesa_lock_context_textures(ctx); + + if (ctx->NewState) + _mesa_update_state_locked(ctx); + + if (intel->NewGLState) { + if (intel->NewGLState & _NEW_TEXTURE) { + intel->vtbl.update_texture_state(intel); + } + + if (!intel->Fallback) { + if (intel->NewGLState & _INTEL_NEW_RENDERSTATE) + intelChooseRenderState(ctx); + } + + intel->NewGLState = 0; + } + + _tnl_run_pipeline(ctx); + + _mesa_unlock_context_textures(ctx); +} + +static void +intelRenderStart(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + intel->vtbl.render_start(intel_context(ctx)); + intel->vtbl.emit_state(intel); +} + +static void +intelRenderFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + if (intel->RenderIndex & INTEL_FALLBACK_BIT) + _swrast_flush(ctx); + + INTEL_FIREVERTICES(intel); +} + + + + + /* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +static void +intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim) +{ + struct intel_context *intel = intel_context(ctx); + + if (0) + fprintf(stderr, "%s %s %x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(rprim), hwprim); + + intel->vtbl.reduced_primitive_state(intel, rprim); + + /* Start a new primitive. Arrange to have it flushed later on. + */ + if (hwprim != intel->prim.primitive) { + INTEL_FIREVERTICES(intel); + + intelStartInlinePrimitive(intel, hwprim, INTEL_BATCH_CLIPRECTS); + } +} + + + /* + */ +static void +intelRenderPrimitive(GLcontext * ctx, GLenum prim) +{ + struct intel_context *intel = intel_context(ctx); + + if (0) + fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); + + /* Let some clipping routines know which primitive they're dealing + * with. + */ + intel->render_primitive = prim; + + /* Shortcircuit this when called from t_dd_rendertmp.h for unfilled + * triangles. The rasterized primitive will always be reset by + * lower level functions in that case, potentially pingponging the + * state: + */ + if (reduced_prim[prim] == GL_TRIANGLES && + (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + /* Set some primitive-dependent state and Start? a new primitive. + */ + intelRasterPrimitive(ctx, reduced_prim[prim], hw_prim[prim]); +} + + + /**********************************************************************/ + /* Transition to/from hardware rasterization. */ + /**********************************************************************/ + +static char *fallbackStrings[] = { + [0] = "Draw buffer", + [1] = "Read buffer", + [2] = "Depth buffer", + [3] = "Stencil buffer", + [4] = "User disable", + [5] = "Render mode", + + [12] = "Texture", + [13] = "Color mask", + [14] = "Stencil", + [15] = "Stipple", + [16] = "Program", + [17] = "Logic op", + [18] = "Smooth polygon", + [19] = "Smooth point", +}; + + +static char * +getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + + +void +intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode) +{ + GLcontext *ctx = &intel->ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = intel->Fallback; + + if (mode) { + intel->Fallback |= bit; + if (oldfallback == 0) { + intelFlush(ctx); + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "ENTER FALLBACK %x: %s\n", + bit, getFallbackString(bit)); + _swsetup_Wakeup(ctx); + intel->RenderIndex = ~0; + } + } + else { + intel->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush(ctx); + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString(bit)); + tnl->Driver.Render.Start = intelRenderStart; + tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; + tnl->Driver.Render.Finish = intelRenderFinish; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state(ctx, ~0); + _tnl_invalidate_vertices(ctx, ~0); + _tnl_install_attrs(ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->NewGLState |= _INTEL_NEW_RENDERSTATE; + } + } +} + +union fi +{ + GLfloat f; + GLint i; +}; + + +/**********************************************************************/ +/* Used only with the metaops callbacks. */ +/**********************************************************************/ +void +intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]) +{ + union fi *vb; + GLint i; + + /* All 3d primitives should be emitted with INTEL_BATCH_CLIPRECTS, + * otherwise the drawing origin (DR4) might not be set correctly. + */ + intelStartInlinePrimitive(intel, PRIM3D_TRIFAN, INTEL_BATCH_CLIPRECTS); + vb = (union fi *) intelExtendInlinePrimitive(intel, n * 6); + + for (i = 0; i < n; i++) { + vb[0].f = xy[i][0]; + vb[1].f = xy[i][1]; + vb[2].f = z; + vb[3].i = color; + vb[4].f = tex[i][0]; + vb[5].f = tex[i][1]; + vb += 6; + } + + INTEL_FIREVERTICES(intel); +} + +void +intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1) +{ + GLfloat xy[4][2]; + GLfloat tex[4][2]; + + xy[0][0] = x0; + xy[0][1] = y0; + xy[1][0] = x1; + xy[1][1] = y0; + xy[2][0] = x1; + xy[2][1] = y1; + xy[3][0] = x0; + xy[3][1] = y1; + + tex[0][0] = s0; + tex[0][1] = t0; + tex[1][0] = s1; + tex[1][1] = t0; + tex[2][0] = s1; + tex[2][1] = t1; + tex[3][0] = s0; + tex[3][1] = t1; + + intel_meta_draw_poly(intel, 4, xy, z, color, tex); +} + + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + + +void +intelInitTriFuncs(GLcontext * ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = intelRunPipeline; + tnl->Driver.Render.Start = intelRenderStart; + tnl->Driver.Render.Finish = intelRenderFinish; + tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; +} diff --git a/src/mesa/drivers/dri/i915/intel_tris.h b/src/mesa/drivers/dri/i915/intel_tris.h new file mode 100644 index 0000000000..b7bae8cd3b --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_tris.h @@ -0,0 +1,69 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef INTELTRIS_INC +#define INTELTRIS_INC + +#include "mtypes.h" + + + +#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_PROGRAM | \ + _NEW_POLYGONSTIPPLE) + +extern void intelInitTriFuncs(GLcontext * ctx); + +extern void intelChooseRenderState(GLcontext * ctx); + +extern void intelStartInlinePrimitive(struct intel_context *intel, + GLuint prim, GLuint flags); +extern void intelWrapInlinePrimitive(struct intel_context *intel); + +GLuint *intelExtendInlinePrimitive(struct intel_context *intel, + GLuint dwords); + + +void intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1); + +void intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]); + + + +#endif diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/i915/server/i830_common.h new file mode 100644 index 0000000000..a877f3c2f4 --- /dev/null +++ b/src/mesa/drivers/dri/i915/server/i830_common.h @@ -0,0 +1,236 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 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 +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 +ATI, VA LINUX SYSTEMS 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. + +**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + + +#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ +#define I830_LOG_MIN_TEX_REGION_SIZE 14 + + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_FLUSH 0x01 +#define DRM_I830_FLIP 0x02 +#define DRM_I830_BATCHBUFFER 0x03 +#define DRM_I830_IRQ_EMIT 0x04 +#define DRM_I830_IRQ_WAIT 0x05 +#define DRM_I830_GETPARAM 0x06 +#define DRM_I830_SETPARAM 0x07 +#define DRM_I830_ALLOC 0x08 +#define DRM_I830_FREE 0x09 +#define DRM_I830_INIT_HEAP 0x0a +#define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_SET_VBLANK_PIPE 0x0d +#define DRM_I830_GET_VBLANK_PIPE 0x0e + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02, + I830_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drmI830Init; + +typedef struct { + drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + /** Last context that used the buffer manager. */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int planeA_x; + int planeA_y; + int planeA_w; + int planeA_h; + int planeB_x; + int planeB_y; + int planeB_w; + int planeB_h; + + /* Triple buffering */ + drm_handle_t third_handle; + int third_offset; + int third_size; + unsigned int third_tiled; + + /* buffer object handles for the static buffers. May change + * over the lifetime of the client, though it doesn't in our current + * implementation. + */ + unsigned int front_bo_handle; + unsigned int back_bo_handle; + unsigned int third_bo_handle; + unsigned int depth_bo_handle; +} drmI830Sarea; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +typedef struct { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830BatchBuffer; + +typedef struct { + char *buf; /* agp offset */ + int sz; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830CmdBuffer; + +typedef struct { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct { + int irq_seq; +} drmI830IrqWait; + +typedef struct { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 + +typedef struct { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 + + +/* A memory manager for regions of shared memory: + */ +#define I830_MEM_REGION_AGP 1 + +typedef struct { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drmI830MemAlloc; + +typedef struct { + int region; + int region_offset; +} drmI830MemFree; + +typedef struct { + int region; + int size; + int start; +} drmI830MemInitHeap; + +typedef struct { + int region; +} drmI830MemDestroyHeap; + +#define DRM_I830_VBLANK_PIPE_A 1 +#define DRM_I830_VBLANK_PIPE_B 2 + +typedef struct { + int pipe; +} drmI830VBlankPipe; + +#endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i915/server/i830_dri.h b/src/mesa/drivers/dri/i915/server/i830_dri.h new file mode 100644 index 0000000000..c2a3af8cbf --- /dev/null +++ b/src/mesa/drivers/dri/i915/server/i830_dri.h @@ -0,0 +1,63 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "xf86drm.h" +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 7 +#define I830_PATCHLEVEL 2 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize unused1; /* backbufferSize */ + drm_handle_t unused2; /* backbuffer */ + + drmSize unused3; /* depthbufferSize */ + drm_handle_t unused4; /* depthbuffer */ + + drmSize unused5; /* rotatedSize */ + drm_handle_t unused6; /* rotatedbuffer */ + + drm_handle_t unused7; /* textures */ + int unused8; /* textureSize */ + + drm_handle_t unused9; /* agp_buffers */ + drmSize unused10; /* agp_buf_size */ + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + + int unused11[8]; /* was front/back/depth/rotated offset/pitch */ + + int unused12; /* logTextureGranularity */ + int unused13; /* textureOffset */ + + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + + +#endif diff --git a/src/mesa/drivers/dri/i915/server/intel.h b/src/mesa/drivers/dri/i915/server/intel.h new file mode 100644 index 0000000000..6ea72499c1 --- /dev/null +++ b/src/mesa/drivers/dri/i915/server/intel.h @@ -0,0 +1,331 @@ +#ifndef _INTEL_H_ +#define _INTEL_H_ + +#include "xf86drm.h" /* drm_handle_t, etc */ + +/* Intel */ +#ifndef PCI_CHIP_I810 +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 +#define PCI_CHIP_I810_BRIDGE 0x7120 +#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 +#define PCI_CHIP_I810_E_BRIDGE 0x7124 +#define PCI_CHIP_I815_BRIDGE 0x1130 +#endif + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 + +#ifndef PCI_CHIP_I855_GM +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I855_GM_BRIDGE 0x3580 +#endif + +#ifndef PCI_CHIP_I865_G +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I865_G_BRIDGE 0x2570 +#endif + +#ifndef PCI_CHIP_I915_G +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I915_GM +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I915_GM_BRIDGE 0x2590 +#endif + +#ifndef PCI_CHIP_E7221_G +#define PCI_CHIP_E7221_G 0x258A +/* Same as I915_G_BRIDGE */ +#define PCI_CHIP_E7221_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I945_G +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_G_BRIDGE 0x2770 +#endif + +#ifndef PCI_CHIP_I945_GM +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 +#endif + +#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ + pI810->Chipset == PCI_CHIP_I810_DC100 || \ + pI810->Chipset == PCI_CHIP_I810_E) +#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) +#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) +#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) +#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) +#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) +#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) +#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) + +#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) +#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) +#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) +#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) +#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) + +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) + +#define I830_GMCH_CTRL 0x52 + +#define I830_GMCH_MEM_MASK 0x1 +#define I830_GMCH_MEM_64M 0x1 +#define I830_GMCH_MEM_128M 0 + +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_DISABLED 0x00 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 + +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_DISABLED 0x00 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) + +typedef unsigned char Bool; +#define TRUE 1 +#define FALSE 0 + +#define PIPE_NONE 0<<0 +#define PIPE_CRT 1<<0 +#define PIPE_TV 1<<1 +#define PIPE_DFP 1<<2 +#define PIPE_LFP 1<<3 +#define PIPE_CRT2 1<<4 +#define PIPE_TV2 1<<5 +#define PIPE_DFP2 1<<6 +#define PIPE_LFP2 1<<7 + +typedef struct _I830MemPool *I830MemPoolPtr; +typedef struct _I830MemRange *I830MemRangePtr; +typedef struct _I830MemRange { + long Start; + long End; + long Size; + unsigned long Physical; + unsigned long Offset; /* Offset of AGP-allocated portion */ + unsigned long Alignment; + drm_handle_t Key; + unsigned long Pitch; // add pitch + I830MemPoolPtr Pool; +} I830MemRange; + +typedef struct _I830MemPool { + I830MemRange Total; + I830MemRange Free; + I830MemRange Fixed; + I830MemRange Allocated; +} I830MemPool; + +typedef struct { + int tail_mask; + I830MemRange mem; + unsigned char *virtual_start; + int head; + int tail; + int space; +} I830RingBuffer; + +typedef struct _I830Rec { + unsigned char *MMIOBase; + unsigned char *FbBase; + int cpp; + uint32_t aper_size; + unsigned int bios_version; + + /* These are set in PreInit and never changed. */ + long FbMapSize; + long TotalVideoRam; + I830MemRange StolenMemory; /* pre-allocated memory */ + long BIOSMemorySize; /* min stolen pool size */ + int BIOSMemSizeLoc; + + /* These change according to what has been allocated. */ + long FreeMemory; + I830MemRange MemoryAperture; + I830MemPool StolenPool; + long allocatedMemory; + + /* Regions allocated either from the above pools, or from agpgart. */ + /* for single and dual head configurations */ + I830MemRange FrontBuffer; + I830MemRange FrontBuffer2; + I830MemRange Scratch; + I830MemRange Scratch2; + + I830RingBuffer *LpRing; + + I830MemRange BackBuffer; + I830MemRange DepthBuffer; + I830MemRange TexMem; + int TexGranularity; + I830MemRange ContextMem; + int drmMinor; + Bool have3DWindows; + + Bool NeedRingBufferLow; + Bool allowPageFlip; + Bool disableTiling; + + int Chipset; + unsigned long LinearAddr; + unsigned long MMIOAddr; + + drmSize registerSize; /**< \brief MMIO register map size */ + drm_handle_t registerHandle; /**< \brief MMIO register map handle */ + // IOADDRESS ioBase; + int irq; /**< \brief IRQ number */ + int GttBound; + + drm_handle_t ring_map; + unsigned int Fence[8]; + +} I830Rec; + +/* + * 12288 is set as the maximum, chosen because it is enough for + * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. + */ +#define I830_MAXIMUM_VBIOS_MEM 12288 +#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) +#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) + +/* Flags for memory allocation function */ +#define FROM_ANYWHERE 0x00000000 +#define FROM_POOL_ONLY 0x00000001 +#define FROM_NEW_ONLY 0x00000002 +#define FROM_MASK 0x0000000f + +#define ALLOCATE_AT_TOP 0x00000010 +#define ALLOCATE_AT_BOTTOM 0x00000020 +#define FORCE_GAPS 0x00000040 + +#define NEED_PHYSICAL_ADDR 0x00000100 +#define ALIGN_BOTH_ENDS 0x00000200 +#define FORCE_LOW 0x00000400 + +#define ALLOC_NO_TILING 0x00001000 +#define ALLOC_INITIAL 0x00002000 + +#define ALLOCATE_DRY_RUN 0x80000000 + +/* Chipset registers for VIDEO BIOS memory RW access */ +#define _855_DRAM_RW_CONTROL 0x58 +#define _845_DRAM_RW_CONTROL 0x90 +#define DRAM_WRITE 0x33330000 + +#define KB(x) ((x) * 1024) +#define MB(x) ((x) * KB(1024)) + +#define GTT_PAGE_SIZE KB(4) +#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) +#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) +#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) +#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) +#define PRIMARY_RINGBUFFER_SIZE KB(128) + + +/* Ring buffer registers, p277, overview p19 + */ +#define LP_RING 0x2030 +#define HP_RING 0x2040 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define I830_TAIL_MASK 0x001FFFF8 + +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define I830_HEAD_MASK 0x001FFFFC + +#define RING_START 0x08 +#define START_ADDR 0x03FFFFF8 +#define I830_RING_START_MASK 0xFFFFF000 + +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x001FF000 +#define I830_RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + + +/* Fence/Tiling ranges [0..7] + */ +#define FENCE 0x2000 +#define FENCE_NR 8 + +#define I915G_FENCE_START_MASK 0x0ff00000 + +#define I830_FENCE_START_MASK 0x07f80000 + +#define FENCE_START_MASK 0x03F80000 +#define FENCE_X_MAJOR 0x00000000 +#define FENCE_Y_MAJOR 0x00001000 +#define FENCE_SIZE_MASK 0x00000700 +#define FENCE_SIZE_512K 0x00000000 +#define FENCE_SIZE_1M 0x00000100 +#define FENCE_SIZE_2M 0x00000200 +#define FENCE_SIZE_4M 0x00000300 +#define FENCE_SIZE_8M 0x00000400 +#define FENCE_SIZE_16M 0x00000500 +#define FENCE_SIZE_32M 0x00000600 +#define FENCE_SIZE_64M 0x00000700 +#define I915G_FENCE_SIZE_1M 0x00000000 +#define I915G_FENCE_SIZE_2M 0x00000100 +#define I915G_FENCE_SIZE_4M 0x00000200 +#define I915G_FENCE_SIZE_8M 0x00000300 +#define I915G_FENCE_SIZE_16M 0x00000400 +#define I915G_FENCE_SIZE_32M 0x00000500 +#define I915G_FENCE_SIZE_64M 0x00000600 +#define I915G_FENCE_SIZE_128M 0x00000700 +#define FENCE_PITCH_1 0x00000000 +#define FENCE_PITCH_2 0x00000010 +#define FENCE_PITCH_4 0x00000020 +#define FENCE_PITCH_8 0x00000030 +#define FENCE_PITCH_16 0x00000040 +#define FENCE_PITCH_32 0x00000050 +#define FENCE_PITCH_64 0x00000060 +#define FENCE_VALID 0x00000001 + +#include + +# define MMIO_IN8(base, offset) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) +# define MMIO_IN32(base, offset) \ + read_MMIO_LE32(base, offset) +# define MMIO_OUT8(base, offset, val) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) +# define MMIO_OUT32(base, offset, val) \ + *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) + + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(MMIO, addr) +#define INREG(addr) MMIO_IN32(MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) + +#define DSPABASE 0x70184 + +#endif diff --git a/src/mesa/drivers/dri/i915/server/intel_dri.c b/src/mesa/drivers/dri/i915/server/intel_dri.c new file mode 100644 index 0000000000..e49c4214ad --- /dev/null +++ b/src/mesa/drivers/dri/i915/server/intel_dri.c @@ -0,0 +1,1306 @@ +/** + * \file server/intel_dri.c + * \brief File to perform the device-specific initialization tasks typically + * done in the X server. + * + * Here they are converted to run in the client (or perhaps a standalone + * process), and to work with the frame buffer device rather than the X + * server infrastructure. + * + * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) + + 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 THE COPYRIGHT HOLDERS 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. +*/ + +#include +#include +#include +#include +#include + +#include "driver.h" +#include "drm.h" + +#include "intel.h" +#include "i830_dri.h" + +#include "memops.h" +#include "pciaccess.h" + +static size_t drm_page_size; +static int nextTile = 0; +#define xf86DrvMsg(...) do {} while(0) + +static const int pitches[] = { + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 +}; + +static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); + +static unsigned long +GetBestTileAlignment(unsigned long size) +{ + unsigned long i; + + for (i = KB(512); i < size; i <<= 1) + ; + + if (i > MB(64)) + i = MB(64); + + return i; +} + +static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + unsigned char *MMIO = ctx->MMIOAddress; + + for (i = 0; i < 8; i++) { + OUTREG(FENCE + i * 4, pI830->Fence[i]); + // if (I810_DEBUG & DEBUG_VERBOSE_VGA) + fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); + } +} + +/* Tiled memory is good... really, really good... + * + * Need to make it less likely that we miss out on this - probably + * need to move the frontbuffer away from the 'guarenteed' alignment + * of the first memory segment, or perhaps allocate a discontigous + * framebuffer to get more alignment 'sweet spots'. + */ +static void +SetFence(const DRIDriverContext *ctx, I830Rec *pI830, + int nr, unsigned int start, unsigned int pitch, + unsigned int size) +{ + unsigned int val; + unsigned int fence_mask = 0; + unsigned int fence_pitch; + + if (nr < 0 || nr > 7) { + fprintf(stderr, + "SetFence: fence %d out of range\n",nr); + return; + } + + pI830->Fence[nr] = 0; + + if (IS_I9XX(pI830)) + fence_mask = ~I915G_FENCE_START_MASK; + else + fence_mask = ~I830_FENCE_START_MASK; + + if (start & fence_mask) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not %s aligned\n", + nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); + return; + } + + if (start % size) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", + nr, start, size / 1024); + return; + } + + if (pitch & 127) { + fprintf(stderr, + "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", + nr, pitch); + return; + } + + val = (start | FENCE_X_MAJOR | FENCE_VALID); + + if (IS_I9XX(pI830)) { + switch (size) { + case MB(1): + val |= I915G_FENCE_SIZE_1M; + break; + case MB(2): + val |= I915G_FENCE_SIZE_2M; + break; + case MB(4): + val |= I915G_FENCE_SIZE_4M; + break; + case MB(8): + val |= I915G_FENCE_SIZE_8M; + break; + case MB(16): + val |= I915G_FENCE_SIZE_16M; + break; + case MB(32): + val |= I915G_FENCE_SIZE_32M; + break; + case MB(64): + val |= I915G_FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } else { + switch (size) { + case KB(512): + val |= FENCE_SIZE_512K; + break; + case MB(1): + val |= FENCE_SIZE_1M; + break; + case MB(2): + val |= FENCE_SIZE_2M; + break; + case MB(4): + val |= FENCE_SIZE_4M; + break; + case MB(8): + val |= FENCE_SIZE_8M; + break; + case MB(16): + val |= FENCE_SIZE_16M; + break; + case MB(32): + val |= FENCE_SIZE_32M; + break; + case MB(64): + val |= FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } + + if (IS_I9XX(pI830)) + fence_pitch = pitch / 512; + else + fence_pitch = pitch / 128; + + switch (fence_pitch) { + case 1: + val |= FENCE_PITCH_1; + break; + case 2: + val |= FENCE_PITCH_2; + break; + case 4: + val |= FENCE_PITCH_4; + break; + case 8: + val |= FENCE_PITCH_8; + break; + case 16: + val |= FENCE_PITCH_16; + break; + case 32: + val |= FENCE_PITCH_32; + break; + case 64: + val |= FENCE_PITCH_64; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal pitch (%d)\n", nr, pitch); + return; + } + + pI830->Fence[nr] = val; +} + +static Bool +MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) +{ + int pitch, ntiles, i; + + pitch = pMem->Pitch * ctx->cpp; + /* + * Simply try to break the region up into at most four pieces of size + * equal to the alignment. + */ + ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; + if (ntiles >= 4) { + return FALSE; + } + + for (i = 0; i < ntiles; i++, nextTile++) { + SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, + pitch, pMem->Alignment); + } + return TRUE; +} + +static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + + /* Clear out */ + for (i = 0; i < 8; i++) + pI830->Fence[i] = 0; + + nextTile = 0; + + if (pI830->BackBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { + fprintf(stderr, + "Activating tiled memory for the back buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the back buffer.\n"); + pI830->allowPageFlip = FALSE; + } + } + + if (pI830->DepthBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { + fprintf(stderr, + "Activating tiled memory for the depth buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the depth buffer.\n"); + } + } + + return; +} + +static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + struct pci_device host_bridge, ig_dev; + uint32_t gmch_ctrl; + int memsize = 0; + int range; + uint32_t aper_size; + uint32_t membase2 = 0; + + memset(&host_bridge, 0, sizeof(host_bridge)); + memset(&ig_dev, 0, sizeof(ig_dev)); + + ig_dev.dev = 2; + + pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); + + if (IS_I830(pI830) || IS_845G(pI830)) { + if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { + aper_size = 0x80000000; + } else { + aper_size = 0x40000000; + } + } else { + if (IS_I9XX(pI830)) { + int ret; + ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18); + if (membase2 & 0x08000000) + aper_size = 0x8000000; + else + aper_size = 0x10000000; + + fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret); + } else + aper_size = 0x8000000; + } + + pI830->aper_size = aper_size; + + + /* We need to reduce the stolen size, by the GTT and the popup. + * The GTT varying according the the FbMapSize and the popup is 4KB */ + range = (ctx->shared.fbSize / (1024*1024)) + 4; + + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + memsize = MB(1) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_4M: + memsize = MB(4) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_8M: + memsize = MB(8) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_16M: + memsize = MB(16) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_32M: + memsize = MB(32) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_48M: + if (IS_I9XX(pI830)) + memsize = MB(48) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_64M: + if (IS_I9XX(pI830)) + memsize = MB(64) - KB(range); + break; + } + } else { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: + memsize = KB(512) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_1024: + memsize = MB(1) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_8192: + memsize = MB(8) - KB(range); + break; + case I830_GMCH_GMS_LOCAL: + memsize = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Local memory found, but won't be used.\n"); + break; + } + } + if (memsize > 0) { + fprintf(stderr, + "detected %d kB stolen memory.\n", memsize / 1024); + } else { + fprintf(stderr, + "no video memory detected.\n"); + } + return memsize; +} + +static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) +{ + unsigned long mode = 0x4; + + if (drmAgpAcquire(ctx->drmFD) < 0) { + fprintf(stderr, "[gart] AGP not available\n"); + return 0; + } + + if (drmAgpEnable(ctx->drmFD, mode) < 0) { + fprintf(stderr, "[gart] AGP not enabled\n"); + drmAgpRelease(ctx->drmFD); + return 0; + } + else + fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); + + return 1; +} + +/* + * Allocate memory from the given pool. Grow the pool if needed and if + * possible. + */ +static unsigned long +AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, + long size, unsigned long alignment, int flags) +{ + long needed, start, end; + + if (!result || !pool || !size) + return 0; + + /* Calculate how much space is needed. */ + if (alignment <= GTT_PAGE_SIZE) + needed = size; + else { + start = ROUND_TO(pool->Free.Start, alignment); + end = ROUND_TO(start + size, alignment); + needed = end - pool->Free.Start; + } + if (needed > pool->Free.Size) { + return 0; + } + + result->Start = ROUND_TO(pool->Free.Start, alignment); + pool->Free.Start += needed; + result->End = pool->Free.Start; + + pool->Free.Size = pool->Free.End - pool->Free.Start; + result->Size = result->End - result->Start; + result->Pool = pool; + result->Alignment = alignment; + return needed; +} + +static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) +{ + unsigned long start, end; + unsigned long newApStart, newApEnd; + int ret; + if (!result || !size) + return 0; + + if (!alignment) + alignment = 4; + + start = ROUND_TO(pI830->MemoryAperture.Start, alignment); + end = ROUND_TO(start + size, alignment); + newApStart = end; + newApEnd = pI830->MemoryAperture.End; + + ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); + + if (ret) + { + fprintf(stderr,"drmAgpAlloc failed %d\n", ret); + return 0; + } + pI830->allocatedMemory += size; + pI830->MemoryAperture.Start = newApStart; + pI830->MemoryAperture.End = newApEnd; + pI830->MemoryAperture.Size = newApEnd - newApStart; + // pI830->FreeMemory -= size; + result->Start = start; + result->End = start + size; + result->Size = size; + result->Offset = start; + result->Alignment = alignment; + result->Pool = NULL; + + return size; +} + +unsigned long +I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, long size, + unsigned long alignment, int flags) +{ + unsigned long ret; + + if (!result) + return 0; + + /* Make sure these are initialised. */ + result->Size = 0; + result->Key = -1; + + if (!size) { + return 0; + } + + if (pool->Free.Size < size) { + ret = AllocFromAGP(ctx, pI830, size, alignment, result); + } + else { + ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); + if (ret == 0) + ret = AllocFromAGP(ctx, pI830, size, alignment, result); + } + return ret; +} + +static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) +{ + if (!mem) + return FALSE; + + if (mem->Key == -1) + return TRUE; + + return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); +} + +/* simple memory allocation routines needed */ +/* put ring buffer in low memory */ +/* need to allocate front, back, depth buffers aligned correctly, + allocate ring buffer, +*/ + +/* */ +static Bool +I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long size, ret; + unsigned long lines, lineSize, align; + + /* allocate ring buffer */ + memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); + pI830->LpRing->mem.Key = -1; + + size = PRIMARY_RINGBUFFER_SIZE; + + ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); + + if (ret != size) + { + fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); + return FALSE; + } + + pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; + + + /* allocate front buffer */ + memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); + pI830->FrontBuffer.Key = -1; + pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; + + align = KB(512); + + lineSize = ctx->shared.virtualWidth * ctx->cpp; + lines = (ctx->shared.virtualHeight + 15) / 16 * 16; + size = lineSize * lines; + size = ROUND_TO_PAGE(size); + + align = GetBestTileAlignment(size); + + ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate front buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); + pI830->BackBuffer.Key = -1; + pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate back buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); + pI830->DepthBuffer.Key = -1; + pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); + pI830->ContextMem.Key = -1; + size = KB(32); + + ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate context buffer %ld\n", ret); + return FALSE; + } + +#if 0 + memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); + pI830->TexMem.Key = -1; + + size = 32768 * 1024; + ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); + if (ret < size) + { + fprintf(stderr,"unable to allocate texture memory %ld\n", ret); + return FALSE; + } +#endif + + return TRUE; +} + +static Bool +I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + if (!BindAgpRange(ctx, &pI830->LpRing->mem)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->FrontBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->BackBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->DepthBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->ContextMem)) + return FALSE; +#if 0 + if (!BindAgpRange(ctx, &pI830->TexMem)) + return FALSE; +#endif + return TRUE; +} + +static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE; + + fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize); + if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { + fprintf(stderr, + "DRM MM Initialization Failed\n"); + } else { + fprintf(stderr, + "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart); + } + +} + +static Bool +I830CleanupDma(const DRIDriverContext *ctx) +{ + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_CLEANUP_DMA; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, "I830 Dma Cleanup Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) +{ + I830RingBuffer *ring = pI830->LpRing; + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_INIT_DMA; + + info.ring_start = ring->mem.Start + pI830->LinearAddr; + info.ring_end = ring->mem.End + pI830->LinearAddr; + info.ring_size = ring->mem.Size; + + info.mmio_offset = (unsigned int)ctx->MMIOStart; + + info.sarea_priv_offset = sizeof(drm_sarea_t); + + info.front_offset = pI830->FrontBuffer.Start; + info.back_offset = pI830->BackBuffer.Start; + info.depth_offset = pI830->DepthBuffer.Start; + info.w = ctx->shared.virtualWidth; + info.h = ctx->shared.virtualHeight; + info.pitch = ctx->shared.virtualWidth; + info.back_pitch = pI830->BackBuffer.Pitch; + info.depth_pitch = pI830->DepthBuffer.Pitch; + info.cpp = ctx->cpp; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, + "I830 Dma Initialization Failed\n"); + return FALSE; + } + + return TRUE; +} + +static int I830CheckDRMVersion( const DRIDriverContext *ctx, + I830Rec *pI830 ) +{ + drmVersionPtr version; + + version = drmGetVersion(ctx->drmFD); + + if (version) { + int req_minor, req_patch; + + req_minor = 4; + req_patch = 0; + + if (version->version_major != 1 || + version->version_minor < req_minor || + (version->version_minor == req_minor && + version->version_patchlevel < req_patch)) { + /* Incompatible drm version */ + fprintf(stderr, + "[dri] I830DRIScreenInit failed because of a version " + "mismatch.\n" + "[dri] i915.o kernel module version is %d.%d.%d " + "but version 1.%d.%d or newer is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel, + req_minor, + req_patch); + drmFreeVersion(version); + return 0; + } + + pI830->drmMinor = version->version_minor; + drmFreeVersion(version); + } + return 1; +} + +static void +I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned int itemp; + unsigned char *MMIO = ctx->MMIOAddress; + + OUTREG(LP_RING + RING_LEN, 0); + OUTREG(LP_RING + RING_TAIL, 0); + OUTREG(LP_RING + RING_HEAD, 0); + + if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != + pI830->LpRing->mem.Start) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer start (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + OUTREG(LP_RING + RING_START, itemp); + + if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem.Size - 4096) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + I830_RING_NR_PAGES); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp |= (RING_NO_REPORT | RING_VALID); + OUTREG(LP_RING + RING_LEN, itemp); + + pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; + pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); + pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); + if (pI830->LpRing->space < 0) + pI830->LpRing->space += pI830->LpRing->mem.Size; + + SetFenceRegs(ctx, pI830); + + /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky + hacky hacky */ + OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); + +} + +static Bool +I830SetParam(const DRIDriverContext *ctx, int param, int value) +{ + drmI830SetParam sp; + + memset(&sp, 0, sizeof(sp)); + sp.param = param; + sp.value = value; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { + fprintf(stderr, "I830 SetParam Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + fprintf(stderr, + "[drm] Mapping front buffer\n"); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), + sarea->front_size, + DRM_FRAME_BUFFER, /*DRM_AGP,*/ + 0, + &sarea->front_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); + return FALSE; + } + ctx->shared.hFrameBuffer = sarea->front_handle; + ctx->shared.fbSize = sarea->front_size; + fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", + sarea->front_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->back_offset), + sarea->back_size, DRM_AGP, 0, + &sarea->back_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", + sarea->back_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->depth_offset, + sarea->depth_size, DRM_AGP, 0, + &sarea->depth_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", + sarea->depth_handle); + +#if 0 + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->tex_offset, + sarea->tex_size, DRM_AGP, 0, + &sarea->tex_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] textures = 0x%08x\n", + sarea->tex_handle); +#endif + return TRUE; +} + + +static void +I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ +#if 1 + if (sarea->front_handle) { + drmRmMap(ctx->drmFD, sarea->front_handle); + sarea->front_handle = 0; + } +#endif + if (sarea->back_handle) { + drmRmMap(ctx->drmFD, sarea->back_handle); + sarea->back_handle = 0; + } + if (sarea->depth_handle) { + drmRmMap(ctx->drmFD, sarea->depth_handle); + sarea->depth_handle = 0; + } + if (sarea->tex_handle) { + drmRmMap(ctx->drmFD, sarea->tex_handle); + sarea->tex_handle = 0; + } +} + +static Bool +I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + if (drmAddMap(ctx->drmFD, + (drm_handle_t)pI830->LpRing->mem.Start, + pI830->LpRing->mem.Size, DRM_AGP, 0, + &pI830->ring_map) < 0) { + fprintf(stderr, + "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] ring buffer = 0x%08x\n", + pI830->ring_map); + + if (I830InitDma(ctx, pI830) == FALSE) { + return FALSE; + } + + /* init to zero to be safe */ + + I830DRIMapScreenRegions(ctx, pI830, sarea); + SetupDRIMM(ctx, pI830); + + if (ctx->pciDevice != PCI_CHIP_845_G && + ctx->pciDevice != PCI_CHIP_I830_M) { + I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); + } + + /* Okay now initialize the dma engine */ + { + pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, + ctx->pciBus, + ctx->pciDevice, + ctx->pciFunc); + + if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { + fprintf(stderr, + "[drm] failure adding irq handler\n"); + pI830->irq = 0; + return FALSE; + } + else + fprintf(stderr, + "[drm] dma control initialized, using IRQ %d\n", + pI830->irq); + } + + fprintf(stderr, "[dri] visual configs initialized\n"); + + return TRUE; +} + +static Bool +I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + /* need to drmMap front and back buffers and zero them */ + drmAddress map_addr; + int ret; + + ret = drmMap(ctx->drmFD, + sarea->front_handle, + sarea->front_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map front buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->front_size); + drmUnmap(map_addr, sarea->front_size); + + + ret = drmMap(ctx->drmFD, + sarea->back_handle, + sarea->back_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map back buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->back_size); + drmUnmap(map_addr, sarea->back_size); + + return TRUE; +} + +static Bool +I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) + +{ + I830DRIPtr pI830DRI; + drmI830Sarea *pSAREAPriv; + int err; + + drm_page_size = getpagesize(); + + pI830->registerSize = ctx->MMIOSize; + /* This is a hack for now. We have to have more than a 4k page here + * because of the size of the state. However, the state should be + * in a per-context mapping. This will be added in the Mesa 3.5 port + * of the I830 driver. + */ + ctx->shared.SAREASize = SAREA_MAX; + + /* Note that drmOpen will try to load the kernel module, if needed. */ + ctx->drmFD = drmOpen("i915", NULL ); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + ctx->drmFD, ctx->pciBusID, strerror(-err)); + return 0; + } + + if (drmAddMap( ctx->drmFD, + 0, + ctx->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &ctx->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap( ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + + } + + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + + if (drmAddMap(ctx->drmFD, + ctx->MMIOStart, + ctx->MMIOSize, + DRM_REGISTERS, + DRM_READ_ONLY, + &pI830->registerHandle) < 0) { + fprintf(stderr, "[drm] drmAddMap mmio failed\n"); + return 0; + } + fprintf(stderr, + "[drm] register handle = 0x%08x\n", pI830->registerHandle); + + + if (!I830CheckDRMVersion(ctx, pI830)) { + return FALSE; + } + + /* Create a 'server' context so we can grab the lock for + * initialization ioctls. + */ + if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); + + /* Initialize the SAREA private data structure */ + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); + pI830->StolenMemory.Start = 0; + pI830->StolenMemory.End = pI830->StolenMemory.Size; + + pI830->MemoryAperture.Start = pI830->StolenMemory.End; + pI830->MemoryAperture.End = KB(40000); + pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; + + pI830->StolenPool.Fixed = pI830->StolenMemory; + pI830->StolenPool.Total = pI830->StolenMemory; + pI830->StolenPool.Free = pI830->StolenPool.Total; + pI830->FreeMemory = pI830->StolenPool.Total.Size; + + if (!AgpInit(ctx, pI830)) + return FALSE; + + if (I830AllocateMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + if (I830BindMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + pSAREAPriv->rotated_offset = -1; + pSAREAPriv->rotated_size = 0; + pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth; + + pSAREAPriv->front_offset = pI830->FrontBuffer.Start; + pSAREAPriv->front_size = pI830->FrontBuffer.Size; + pSAREAPriv->width = ctx->shared.virtualWidth; + pSAREAPriv->height = ctx->shared.virtualHeight; + pSAREAPriv->pitch = ctx->shared.virtualWidth; + pSAREAPriv->virtualX = ctx->shared.virtualWidth; + pSAREAPriv->virtualY = ctx->shared.virtualHeight; + pSAREAPriv->back_offset = pI830->BackBuffer.Start; + pSAREAPriv->back_size = pI830->BackBuffer.Size; + pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; + pSAREAPriv->depth_size = pI830->DepthBuffer.Size; +#if 0 + pSAREAPriv->tex_offset = pI830->TexMem.Start; + pSAREAPriv->tex_size = pI830->TexMem.Size; +#endif + pSAREAPriv->log_tex_granularity = pI830->TexGranularity; + + ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); + ctx->driverClientMsgSize = sizeof(I830DRIRec); + pI830DRI = (I830DRIPtr)ctx->driverClientMsg; + pI830DRI->deviceID = pI830->Chipset; + pI830DRI->regsSize = I830_REG_SIZE; + pI830DRI->width = ctx->shared.virtualWidth; + pI830DRI->height = ctx->shared.virtualHeight; + pI830DRI->mem = ctx->shared.fbSize; + pI830DRI->cpp = ctx->cpp; + + pI830DRI->bitsPerPixel = ctx->bpp; + pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); + + err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); + if (err == FALSE) + return FALSE; + + I830SetupMemoryTiling(ctx, pI830); + + /* Quick hack to clear the front & back buffers. Could also use + * the clear ioctl to do this, but would need to setup hw state + * first. + */ + I830ClearScreen(ctx, pI830, pSAREAPriv); + + I830SetRingRegs(ctx, pI830); + + return TRUE; +} + + +/** + * \brief Validate the fbdev mode. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa radeonValidateMode(). + */ +static int i830ValidateMode( const DRIDriverContext *ctx ) +{ + return 1; +} + +/** + * \brief Examine mode returned by fbdev. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa i810ValidateMode(). + */ +static int i830PostValidateMode( const DRIDriverContext *ctx ) +{ + I830Rec *pI830 = ctx->driverPrivate; + + I830SetRingRegs(ctx, pI830); + return 1; +} + + +/** + * \brief Initialize the framebuffer device mode + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p ctx + * and then calls I810ScreenInit() for the screen initialization. + * + * Before exiting clears the framebuffer memory accessing it directly. + */ +static int i830InitFBDev( DRIDriverContext *ctx ) +{ + I830Rec *pI830 = calloc(1, sizeof(I830Rec)); + int i; + + { + int dummy = ctx->shared.virtualWidth; + + switch (ctx->bpp / 8) { + case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; + case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; + case 3: + case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; + } + + ctx->shared.virtualWidth = dummy; + ctx->shared.Width = ctx->shared.virtualWidth; + } + + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= ctx->shared.virtualWidth) { + ctx->shared.virtualWidth = pitches[i]; + break; + } + } + + ctx->driverPrivate = (void *)pI830; + + pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); + pI830->Chipset = ctx->chipset; + pI830->LinearAddr = ctx->FBStart; + + if (!I830ScreenInit( ctx, pI830 )) + return 0; + + + return 1; +} + + +/** + * \brief The screen is being closed, so clean up any state and free any + * resources used by the DRI. + * + * \param ctx display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void i830HaltFBDev( DRIDriverContext *ctx ) +{ + drmI830Sarea *pSAREAPriv; + I830Rec *pI830 = ctx->driverPrivate; + + if (pI830->irq) { + drmCtlUninstHandler(ctx->drmFD); + pI830->irq = 0; } + + I830CleanupDma(ctx); + + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + + I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); + drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); + drmClose(ctx->drmFD); + + if (ctx->driverPrivate) { + free(ctx->driverPrivate); + ctx->driverPrivate = 0; + } +} + + +extern void i810NotifyFocus( int ); + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa DRIDriverRec. + */ +const struct DRIDriverRec __driDriver = { + i830ValidateMode, + i830PostValidateMode, + i830InitFBDev, + i830HaltFBDev, + NULL,//I830EngineShutdown, + NULL, //I830EngineRestore, +#ifndef _EMBEDDED + 0, +#else + i810NotifyFocus, +#endif +}; diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile deleted file mode 100644 index d3d0bd570c..0000000000 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ /dev/null @@ -1,71 +0,0 @@ - -TOP = ../../../../.. -include $(TOP)/configs/current - -LIBNAME = i915_dri.so - -MINIGLX_SOURCES = server/intel_dri.c - -DRIVER_SOURCES = \ - i830_context.c \ - i830_metaops.c \ - i830_state.c \ - i830_texblend.c \ - i830_tex.c \ - i830_texstate.c \ - i830_vtbl.c \ - intel_render.c \ - intel_regions.c \ - intel_buffer_objects.c \ - intel_batchbuffer.c \ - intel_mipmap_tree.c \ - i915_tex_layout.c \ - intel_tex_layout.c \ - intel_tex_image.c \ - intel_tex_subimage.c \ - intel_tex_copy.c \ - intel_tex_validate.c \ - intel_tex_format.c \ - intel_tex.c \ - intel_pixel.c \ - intel_pixel_copy.c \ - intel_pixel_read.c \ - intel_pixel_draw.c \ - intel_buffers.c \ - intel_blit.c \ - i915_tex.c \ - i915_texstate.c \ - i915_context.c \ - i915_debug.c \ - i915_debug_fp.c \ - i915_fragprog.c \ - i915_metaops.c \ - i915_program.c \ - i915_state.c \ - i915_vtbl.c \ - intel_context.c \ - intel_decode.c \ - intel_ioctl.c \ - intel_rotate.c \ - intel_screen.c \ - intel_span.c \ - intel_state.c \ - intel_tris.c \ - intel_fbo.c \ - intel_depthstencil.c - -C_SOURCES = \ - $(COMMON_SOURCES) \ - $(COMMON_BM_SOURCES) \ - $(DRIVER_SOURCES) - -ASM_SOURCES = - -DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ - && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") - -include ../Makefile.template - -intel_tex_layout.o: ../intel/intel_tex_layout.c - -symlinks: diff --git a/src/mesa/drivers/dri/i915tex/i830_context.c b/src/mesa/drivers/dri/i915tex/i830_context.c deleted file mode 100644 index 2ff8621c42..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_context.c +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "i830_context.h" -#include "imports.h" -#include "texmem.h" -#include "intel_tex.h" -#include "tnl/tnl.h" -#include "tnl/t_vertex.h" -#include "tnl/t_context.h" -#include "utils.h" - -/*************************************** - * Mesa's Driver Functions - ***************************************/ - -static const struct dri_extension i830_extensions[] = { - {"GL_ARB_texture_env_crossbar", NULL}, - {NULL, NULL} -}; - - -static void -i830InitDriverFunctions(struct dd_function_table *functions) -{ - intelInitDriverFunctions(functions); - i830InitStateFuncs(functions); - i830InitTextureFuncs(functions); -} - - -GLboolean -i830CreateContext(const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - struct dd_function_table functions; - struct i830_context *i830 = CALLOC_STRUCT(i830_context); - struct intel_context *intel = &i830->intel; - GLcontext *ctx = &intel->ctx; - if (!i830) - return GL_FALSE; - - i830InitVtbl(i830); - i830InitDriverFunctions(&functions); - - if (!intelInitContext(intel, mesaVis, driContextPriv, - sharedContextPrivate, &functions)) { - FREE(i830); - return GL_FALSE; - } - - intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; - intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; - intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; - - /* Advertise the full hardware capabilities. The new memory - * manager should cope much better with overload situations: - */ - ctx->Const.MaxTextureLevels = 12; - ctx->Const.Max3DTextureLevels = 9; - ctx->Const.MaxCubeTextureLevels = 11; - ctx->Const.MaxTextureRectSize = (1 << 11); - ctx->Const.MaxTextureUnits = I830_TEX_UNITS; - - _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, - 18 * sizeof(GLfloat)); - - intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; - - driInitExtensions(ctx, i830_extensions, GL_FALSE); - - i830InitState(i830); - i830InitMetaFuncs(i830); - - _tnl_allow_vertex_fog(ctx, 1); - _tnl_allow_pixel_fog(ctx, 0); - - return GL_TRUE; -} diff --git a/src/mesa/drivers/dri/i915tex/i830_context.h b/src/mesa/drivers/dri/i915tex/i830_context.h deleted file mode 100644 index 9397fa45b5..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_context.h +++ /dev/null @@ -1,213 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef I830CONTEXT_INC -#define I830CONTEXT_INC - -#include "intel_context.h" - -#define I830_FALLBACK_TEXTURE 0x1000 -#define I830_FALLBACK_COLORMASK 0x2000 -#define I830_FALLBACK_STENCIL 0x4000 -#define I830_FALLBACK_STIPPLE 0x8000 -#define I830_FALLBACK_LOGICOP 0x10000 - -#define I830_UPLOAD_CTX 0x1 -#define I830_UPLOAD_BUFFERS 0x2 -#define I830_UPLOAD_STIPPLE 0x4 -#define I830_UPLOAD_INVARIENT 0x8 -#define I830_UPLOAD_TEX(i) (0x10<<(i)) -#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i)) -#define I830_UPLOAD_TEX_ALL (0x0f0) -#define I830_UPLOAD_TEXBLEND_ALL (0xf00) - -/* State structure offsets - these will probably disappear. - */ -#define I830_DESTREG_CBUFADDR0 0 -#define I830_DESTREG_CBUFADDR1 1 -#define I830_DESTREG_DBUFADDR0 2 -#define I830_DESTREG_DBUFADDR1 3 -#define I830_DESTREG_DV0 4 -#define I830_DESTREG_DV1 5 -#define I830_DESTREG_SENABLE 6 -#define I830_DESTREG_SR0 7 -#define I830_DESTREG_SR1 8 -#define I830_DESTREG_SR2 9 -#define I830_DEST_SETUP_SIZE 10 - -#define I830_CTXREG_STATE1 0 -#define I830_CTXREG_STATE2 1 -#define I830_CTXREG_STATE3 2 -#define I830_CTXREG_STATE4 3 -#define I830_CTXREG_STATE5 4 -#define I830_CTXREG_IALPHAB 5 -#define I830_CTXREG_STENCILTST 6 -#define I830_CTXREG_ENABLES_1 7 -#define I830_CTXREG_ENABLES_2 8 -#define I830_CTXREG_AA 9 -#define I830_CTXREG_FOGCOLOR 10 -#define I830_CTXREG_BLENDCOLOR0 11 -#define I830_CTXREG_BLENDCOLOR1 12 -#define I830_CTXREG_VF 13 -#define I830_CTXREG_VF2 14 -#define I830_CTXREG_MCSB0 15 -#define I830_CTXREG_MCSB1 16 -#define I830_CTX_SETUP_SIZE 17 - -#define I830_STPREG_ST0 0 -#define I830_STPREG_ST1 1 -#define I830_STP_SETUP_SIZE 2 - -#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ -#define I830_TEXREG_TM0S1 1 -#define I830_TEXREG_TM0S2 2 -#define I830_TEXREG_TM0S3 3 -#define I830_TEXREG_TM0S4 4 -#define I830_TEXREG_MCS 5 /* _3DSTATE_MAP_COORD_SETS */ -#define I830_TEXREG_CUBE 6 /* _3DSTATE_MAP_SUBE */ -#define I830_TEX_SETUP_SIZE 7 - -#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ - -struct i830_texture_object -{ - struct intel_texture_object intel; - GLuint Setup[I830_TEX_SETUP_SIZE]; -}; - -#define I830_TEX_UNITS 4 - -struct i830_hw_state -{ - GLuint Ctx[I830_CTX_SETUP_SIZE]; - GLuint Buffer[I830_DEST_SETUP_SIZE]; - GLuint Stipple[I830_STP_SETUP_SIZE]; - GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE]; - GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE]; - GLuint TexBlendWordsUsed[I830_TEX_UNITS]; - - struct intel_region *draw_region; - struct intel_region *depth_region; - - /* Regions aren't actually that appropriate here as the memory may - * be from a PBO or FBO. Will have to do this for draw and depth for - * FBO's... - */ - dri_bo *tex_buffer[I830_TEX_UNITS]; - GLuint tex_offset[I830_TEX_UNITS]; - - GLuint emitted; /* I810_UPLOAD_* */ - GLuint active; -}; - -struct i830_context -{ - struct intel_context intel; - - GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; - DECLARE_RENDERINPUTS(last_index_bitset); - - struct i830_hw_state meta, initial, state, *current; -}; - - - - -#define I830_STATECHANGE(i830, flag) \ -do { \ - INTEL_FIREVERTICES( &i830->intel ); \ - i830->state.emitted &= ~flag; \ -} while (0) - -#define I830_ACTIVESTATE(i830, flag, mode) \ -do { \ - INTEL_FIREVERTICES( &i830->intel ); \ - if (mode) \ - i830->state.active |= flag; \ - else \ - i830->state.active &= ~flag; \ -} while (0) - -/* i830_vtbl.c - */ -extern void i830InitVtbl(struct i830_context *i830); - -extern void -i830_state_draw_region(struct intel_context *intel, - struct i830_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region); -/* i830_context.c - */ -extern GLboolean -i830CreateContext(const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -/* i830_tex.c, i830_texstate.c - */ -extern void i830UpdateTextureState(struct intel_context *intel); - -extern void i830InitTextureFuncs(struct dd_function_table *functions); - -/* i830_texblend.c - */ -extern GLuint i830SetTexEnvCombine(struct i830_context *i830, - const struct gl_tex_env_combine_state - *combine, GLint blendUnit, GLuint texel_op, - GLuint * state, const GLfloat * factor); - -extern void i830EmitTextureBlend(struct i830_context *i830); - - -/* i830_state.c - */ -extern void i830InitStateFuncs(struct dd_function_table *functions); - -extern void i830EmitState(struct i830_context *i830); - -extern void i830InitState(struct i830_context *i830); - -/* i830_metaops.c - */ -extern void i830InitMetaFuncs(struct i830_context *i830); - -extern void -i830RotateWindow(struct intel_context *intel, __DRIdrawablePrivate * dPriv, - GLuint srcBuf); - -/*====================================================================== - * Inline conversion functions. These are better-typed than the - * macros used previously: - */ -static INLINE struct i830_context * -i830_context(GLcontext * ctx) -{ - return (struct i830_context *) ctx; -} - -#endif diff --git a/src/mesa/drivers/dri/i915tex/i830_metaops.c b/src/mesa/drivers/dri/i915tex/i830_metaops.c deleted file mode 100644 index 13e4ab3aac..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_metaops.c +++ /dev/null @@ -1,457 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_regions.h" - -#include "i830_context.h" -#include "i830_reg.h" - -/* A large amount of state doesn't need to be uploaded. - */ -#define ACTIVE (I830_UPLOAD_INVARIENT | \ - I830_UPLOAD_CTX | \ - I830_UPLOAD_BUFFERS | \ - I830_UPLOAD_STIPPLE | \ - I830_UPLOAD_TEXBLEND(0) | \ - I830_UPLOAD_TEX(0)) - - -#define SET_STATE( i830, STATE ) \ -do { \ - i830->current->emitted &= ~ACTIVE; \ - i830->current = &i830->STATE; \ - i830->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -set_no_stencil_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -static void -set_no_depth_write(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Set depth unit to replace. - */ -static void -set_depth_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; - - /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) - */ - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; - i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC - (COMPAREFUNC_ALWAYS)); - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -set_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK((s_mask & - 0xff))); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | - STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) - */ - i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); - i830->meta.Ctx[I830_CTXREG_STENCILTST] |= - (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE((s_clear & 0xff)) | - STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); - - - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -set_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | - (1 << WRITEMASK_GREEN_SHIFT) | - (1 << WRITEMASK_BLUE_SHIFT) | - (1 << WRITEMASK_ALPHA_SHIFT)); - - i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; - - if (state) { - i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= - (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); - } - - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - -/* Installs a one-stage passthrough texture blend pipeline. Is there - * more that can be done to turn off texturing? - */ -static void -set_no_texture(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_NONE, GL_NONE, - {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,}, - {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0}, - 0, 0, 0, 0 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); -} - -/* Set up a single element blend stage for 'replace' texturing with no - * funny ops. - */ -static void -set_texture_blend_replace(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - static const struct gl_tex_env_combine_state comb = { - GL_REPLACE, GL_REPLACE, - {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE, - GL_TEXTURE,}, - {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA, - GL_SRC_ALPHA}, - 0, 0, 1, 1 - }; - - i830->meta.TexBlendWordsUsed[0] = - i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, - i830->meta.TexBlend[0], NULL); - - i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; - i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); - -/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ -/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ -} - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -set_tex_rect_source(struct intel_context *intel, - dri_bo *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - GLuint *setup = i830->meta.Tex[0]; - GLint numLevels = 1; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - i830->meta.tex_buffer[0] = buffer; - i830->meta.tex_offset[0] = offset; - - setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << 0) | 4); - setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | - ((pitch - 1) << TM0S1_WIDTH_SHIFT) | - textureFormat); - setup[I830_TEXREG_TM0S2] = - (((((pitch * cpp) / 4) - - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); - - setup[I830_TEXREG_TM0S3] = - ((((numLevels - - 1) * - 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST << - TM0S3_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST << - TM0S3_MAG_FILTER_SHIFT)); - - setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0)); - - setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(0) | - ENABLE_TEXCOORD_PARAMS | - TEXCOORDS_ARE_IN_TEXELUNITS | - TEXCOORDTYPE_CARTESIAN | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | - ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); - - i830->meta.emitted &= ~I830_UPLOAD_TEX(0); - return GL_TRUE; -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | - VFT0_TEX_COUNT(1) | - VFT0_DIFFUSE | VFT0_XYZ); - i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | - VFT1_TEX0_FMT(TEXCOORDFMT_2D) | - VFT1_TEX1_FMT(TEXCOORDFMT_2D) | - VFT1_TEX2_FMT(TEXCOORDFMT_2D) | - VFT1_TEX3_FMT(TEXCOORDFMT_2D)); - i830->meta.emitted &= ~I830_UPLOAD_CTX; -} - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1]; - i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2]; - i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3]; - i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; - i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5]; - i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB]; - i830->meta.Ctx[I830_CTXREG_STENCILTST] = - i830->state.Ctx[I830_CTXREG_STENCILTST]; - i830->meta.Ctx[I830_CTXREG_ENABLES_1] = - i830->state.Ctx[I830_CTXREG_ENABLES_1]; - i830->meta.Ctx[I830_CTXREG_ENABLES_2] = - i830->state.Ctx[I830_CTXREG_ENABLES_2]; - i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA]; - i830->meta.Ctx[I830_CTXREG_FOGCOLOR] = - i830->state.Ctx[I830_CTXREG_FOGCOLOR]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR0]; - i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; - i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0]; - i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1]; - - - i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - i830->meta.emitted &= ~I830_UPLOAD_CTX; - - - i830->meta.Buffer[I830_DESTREG_SENABLE] = - i830->state.Buffer[I830_DESTREG_SENABLE]; - i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; - i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; - i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; -} - - - -/* Select between front and back draw buffers. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - - i830_state_draw_region(intel, &i830->meta, color_region, depth_region); -} - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - memcpy(&i830->meta, &i830->initial, sizeof(i830->meta)); - - i830->meta.active = ACTIVE; - i830->meta.emitted = 0; - - SET_STATE(i830, meta); - set_vertex_format(intel); - set_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - intel_region_release(&i830->meta.draw_region); - intel_region_release(&i830->meta.depth_region); -/* intel_region_release(intel, &i830->meta.tex_region[0]); */ - SET_STATE(i830, state); -} - - - -void -i830InitMetaFuncs(struct i830_context *i830) -{ - i830->intel.vtbl.install_meta_state = install_meta_state; - i830->intel.vtbl.leave_meta_state = leave_meta_state; - i830->intel.vtbl.meta_no_depth_write = set_no_depth_write; - i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write; - i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; - i830->intel.vtbl.meta_depth_replace = set_depth_replace; - i830->intel.vtbl.meta_color_mask = set_color_mask; - i830->intel.vtbl.meta_no_texture = set_no_texture; - i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; - i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; - i830->intel.vtbl.meta_draw_region = meta_draw_region; - i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915tex/i830_reg.h b/src/mesa/drivers/dri/i915tex/i830_reg.h deleted file mode 100644 index 41280bca7c..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_reg.h +++ /dev/null @@ -1,642 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef _I830_REG_H_ -#define _I830_REG_H_ - - -#include "intel_reg.h" - -#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) - -#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) -#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) -#define AA_LINE_ECAAR_WIDTH_0_5 0 -#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) -#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) -#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) -#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) -#define AA_LINE_REGION_WIDTH_0_5 0 -#define AA_LINE_REGION_WIDTH_1_0 (1<<6) -#define AA_LINE_REGION_WIDTH_2_0 (2<<6) -#define AA_LINE_REGION_WIDTH_4_0 (3<<6) -#define AA_LINE_ENABLE ((1<<1) | 1) -#define AA_LINE_DISABLE (1<<1) - -#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) -/* Dword 1 */ -#define BUF_3D_ID_COLOR_BACK (0x3<<24) -#define BUF_3D_ID_DEPTH (0x7<<24) -#define BUF_3D_USE_FENCE (1<<23) -#define BUF_3D_TILED_SURFACE (1<<22) -#define BUF_3D_TILE_WALK_X 0 -#define BUF_3D_TILE_WALK_Y (1<<21) -#define BUF_3D_PITCH(x) (((x)/4)<<2) -/* Dword 2 */ -#define BUF_3D_ADDR(x) ((x) & ~0x3) - - -#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) - -#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ - ((0x90+(stage))<<16)) - -#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) - -#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) - -#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) - -#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) - - -#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) -/* Dword 1 */ -#define DSTORG_HORT_BIAS(x) ((x)<<20) -#define DSTORG_VERT_BIAS(x) ((x)<<16) -#define COLOR_4_2_2_CHNL_WRT_ALL 0 -#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) -#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) -#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) -#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) -#define COLR_BUF_8BIT 0 -#define COLR_BUF_RGB555 (1<<8) -#define COLR_BUF_RGB565 (2<<8) -#define COLR_BUF_ARGB8888 (3<<8) -#define DEPTH_IS_Z 0 -#define DEPTH_IS_W (1<<6) -#define DEPTH_FRMT_16_FIXED 0 -#define DEPTH_FRMT_16_FLOAT (1<<2) -#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) -#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) -#define VERT_LINE_STRIDE_1 (1<<1) -#define VERT_LINE_STRIDE_0 0 -#define VERT_LINE_STRIDE_OFS_1 1 -#define VERT_LINE_STRIDE_OFS_0 0 - - -#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) -/* Dword 1 */ -#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) -#define DRAW_DITHER_OFS_X(x) ((x)<<26) -#define DRAW_DITHER_OFS_Y(x) ((x)<<24) -/* Dword 2 */ -#define DRAW_YMIN(x) ((x)<<16) -#define DRAW_XMIN(x) (x) -/* Dword 3 */ -#define DRAW_YMAX(x) ((x)<<16) -#define DRAW_XMAX(x) (x) -/* Dword 4 */ -#define DRAW_YORG(x) ((x)<<16) -#define DRAW_XORG(x) (x) - - -#define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) -#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) -#define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) -#define DISABLE_LOGIC_OP (1<<23) -#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) -#define DISABLE_STENCIL_TEST (1<<21) -#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) -#define DISABLE_DEPTH_BIAS (1<<11) -#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) -#define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) -#define DISABLE_SPEC_ADD (1<<9) -#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) -#define ENABLE_FOG ((1<<7)|(1<<6)) -#define DISABLE_FOG (1<<7) -#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) -#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) -#define DISABLE_ALPHA_TEST (1<<5) -#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) -#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) -#define DISABLE_COLOR_BLEND (1<<3) -#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) -#define ENABLE_DEPTH_TEST ((1<<1)|1) -#define DISABLE_DEPTH_TEST (1<<1) - -/* _3DSTATE_ENABLES_2, p138 */ -#define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) -#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) -#define DISABLE_STENCIL_WRITE (1<<21) -#define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) -#define DISABLE_TEX_CACHE (1<<17) -#define ENABLE_DITHER ((1<<9)|(1<<8)) -#define DISABLE_DITHER (1<<9) -#define ENABLE_COLOR_MASK (1<<10) -#define WRITEMASK_ALPHA (1<<7) -#define WRITEMASK_ALPHA_SHIFT 7 -#define WRITEMASK_RED (1<<6) -#define WRITEMASK_RED_SHIFT 6 -#define WRITEMASK_GREEN (1<<5) -#define WRITEMASK_GREEN_SHIFT 5 -#define WRITEMASK_BLUE (1<<4) -#define WRITEMASK_BLUE_SHIFT 4 -#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) -#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) -#define DISABLE_COLOR_WRITE (1<<3) -#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 -#define ENABLE_DEPTH_WRITE ((1<<1)|1) -#define DISABLE_DEPTH_WRITE (1<<1) - -/* _3DSTATE_FOG_COLOR, p139 */ -#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) -#define FOG_COLOR_RED(x) ((x)<<16) -#define FOG_COLOR_GREEN(x) ((x)<<8) -#define FOG_COLOR_BLUE(x) (x) - -/* _3DSTATE_FOG_MODE, p140 */ -#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) -/* Dword 1 */ -#define FOGFUNC_ENABLE (1<<31) -#define FOGFUNC_VERTEX 0 -#define FOGFUNC_PIXEL_EXP (1<<28) -#define FOGFUNC_PIXEL_EXP2 (2<<28) -#define FOGFUNC_PIXEL_LINEAR (3<<28) -#define FOGSRC_INDEX_Z (1<<27) -#define FOGSRC_INDEX_W ((1<<27)|(1<<25)) -#define FOG_LINEAR_CONST (1<<24) -#define FOG_CONST_1(x) ((x)<<4) -#define ENABLE_FOG_DENSITY (1<<23) -/* Dword 2 */ -#define FOG_CONST_2(x) (x) -/* Dword 3 */ -#define FOG_DENSITY(x) (x) - -/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ -#define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) -#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) -#define DISABLE_INDPT_ALPHA_BLEND (1<<23) -#define ALPHA_BLENDFUNC_MASK 0x3f0000 -#define ENABLE_ALPHA_BLENDFUNC (1<<21) -#define ABLENDFUNC_ADD 0 -#define ABLENDFUNC_SUB (1<<16) -#define ABLENDFUNC_RVSE_SUB (2<<16) -#define ABLENDFUNC_MIN (3<<16) -#define ABLENDFUNC_MAX (4<<16) -#define SRC_DST_ABLEND_MASK 0xfff -#define ENABLE_SRC_ABLEND_FACTOR (1<<11) -#define SRC_ABLEND_FACT(x) ((x)<<6) -#define ENABLE_DST_ABLEND_FACTOR (1<<5) -#define DST_ABLEND_FACT(x) (x) - - -/* _3DSTATE_MAP_BLEND_ARG, p152 */ -#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) - -#define TEXPIPE_COLOR 0 -#define TEXPIPE_ALPHA (1<<18) -#define TEXPIPE_KILL (2<<18) -#define TEXBLEND_ARG0 0 -#define TEXBLEND_ARG1 (1<<15) -#define TEXBLEND_ARG2 (2<<15) -#define TEXBLEND_ARG3 (3<<15) -#define TEXBLENDARG_MODIFY_PARMS (1<<6) -#define TEXBLENDARG_REPLICATE_ALPHA (1<<5) -#define TEXBLENDARG_INV_ARG (1<<4) -#define TEXBLENDARG_ONE 0 -#define TEXBLENDARG_FACTOR 0x01 -#define TEXBLENDARG_ACCUM 0x02 -#define TEXBLENDARG_DIFFUSE 0x03 -#define TEXBLENDARG_SPEC 0x04 -#define TEXBLENDARG_CURRENT 0x05 -#define TEXBLENDARG_TEXEL0 0x06 -#define TEXBLENDARG_TEXEL1 0x07 -#define TEXBLENDARG_TEXEL2 0x08 -#define TEXBLENDARG_TEXEL3 0x09 -#define TEXBLENDARG_FACTOR_N 0x0e - -/* _3DSTATE_MAP_BLEND_OP, p155 */ -#define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) -#if 0 -# define TEXPIPE_COLOR 0 -# define TEXPIPE_ALPHA (1<<18) -# define TEXPIPE_KILL (2<<18) -#endif -#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) -#define TEXOP_OUTPUT_CURRENT 0 -#define TEXOP_OUTPUT_ACCUM (1<<15) -#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) -#define DISABLE_TEX_CNTRL_STAGE (1<<12) -#define TEXOP_SCALE_SHIFT 9 -#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) -#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) -#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) -#define TEXOP_MODIFY_PARMS (1<<8) -#define TEXOP_LAST_STAGE (1<<7) -#define TEXBLENDOP_KILLPIXEL 0x02 -#define TEXBLENDOP_ARG1 0x01 -#define TEXBLENDOP_ARG2 0x02 -#define TEXBLENDOP_MODULATE 0x03 -#define TEXBLENDOP_ADD 0x06 -#define TEXBLENDOP_ADDSIGNED 0x07 -#define TEXBLENDOP_BLEND 0x08 -#define TEXBLENDOP_BLEND_AND_ADD 0x09 -#define TEXBLENDOP_SUBTRACT 0x0a -#define TEXBLENDOP_DOT3 0x0b -#define TEXBLENDOP_DOT4 0x0c -#define TEXBLENDOP_MODULATE_AND_ADD 0x0d -#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e -#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f - -/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ -/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ - -#define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) -#define DISABLE_TEX_TRANSFORM (1<<28) -#define TEXTURE_SET(x) (x<<29) - -#define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) -#define DISABLE_VIEWPORT_TRANSFORM (1<<31) -#define DISABLE_PERSPECTIVE_DIVIDE (1<<29) - - -/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ -#define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) -#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) -#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) -#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) -#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) - -#define TEXBIND_SET3(x) ((x)<<12) -#define TEXBIND_SET2(x) ((x)<<8) -#define TEXBIND_SET1(x) ((x)<<4) -#define TEXBIND_SET0(x) (x) - -#define TEXCOORDSRC_KEEP 0 -#define TEXCOORDSRC_DEFAULT 0x01 -#define TEXCOORDSRC_VTXSET_0 0x08 -#define TEXCOORDSRC_VTXSET_1 0x09 -#define TEXCOORDSRC_VTXSET_2 0x0a -#define TEXCOORDSRC_VTXSET_3 0x0b -#define TEXCOORDSRC_VTXSET_4 0x0c -#define TEXCOORDSRC_VTXSET_5 0x0d -#define TEXCOORDSRC_VTXSET_6 0x0e -#define TEXCOORDSRC_VTXSET_7 0x0f - -#define MAP_UNIT(unit) ((unit)<<16) -#define MAP_UNIT_MASK (0x7<<16) - -/* _3DSTATE_MAP_COORD_SETS, p164 */ -#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) -#define ENABLE_TEXCOORD_PARAMS (1<<15) -#define TEXCOORDS_ARE_NORMAL (1<<14) -#define TEXCOORDS_ARE_IN_TEXELUNITS 0 -#define TEXCOORDTYPE_CARTESIAN 0 -#define TEXCOORDTYPE_HOMOGENEOUS (1<<11) -#define TEXCOORDTYPE_VECTOR (2<<11) -#define TEXCOORDTYPE_MASK (0x7<<11) -#define ENABLE_ADDR_V_CNTL (1<<7) -#define ENABLE_ADDR_U_CNTL (1<<3) -#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) -#define TEXCOORD_ADDR_U_MODE(x) (x) -#define TEXCOORDMODE_WRAP 0 -#define TEXCOORDMODE_MIRROR 1 -#define TEXCOORDMODE_CLAMP 2 -#define TEXCOORDMODE_WRAP_SHORTEST 3 -#define TEXCOORDMODE_CLAMP_BORDER 4 -#define TEXCOORD_ADDR_V_MASK 0x70 -#define TEXCOORD_ADDR_U_MASK 0x7 - -/* _3DSTATE_MAP_CUBE, p168 TODO */ -#define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) -#define CUBE_NEGX_ENABLE (1<<5) -#define CUBE_POSX_ENABLE (1<<4) -#define CUBE_NEGY_ENABLE (1<<3) -#define CUBE_POSY_ENABLE (1<<2) -#define CUBE_NEGZ_ENABLE (1<<1) -#define CUBE_POSZ_ENABLE (1<<0) - - -/* _3DSTATE_MODES_1, p190 */ -#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) -#define BLENDFUNC_MASK 0x3f0000 -#define ENABLE_COLR_BLND_FUNC (1<<21) -#define BLENDFUNC_ADD 0 -#define BLENDFUNC_SUB (1<<16) -#define BLENDFUNC_RVRSE_SUB (2<<16) -#define BLENDFUNC_MIN (3<<16) -#define BLENDFUNC_MAX (4<<16) -#define SRC_DST_BLND_MASK 0xfff -#define ENABLE_SRC_BLND_FACTOR (1<<11) -#define ENABLE_DST_BLND_FACTOR (1<<5) -#define SRC_BLND_FACT(x) ((x)<<6) -#define DST_BLND_FACT(x) (x) - - -/* _3DSTATE_MODES_2, p192 */ -#define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) -#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) -#define GLOBAL_DEPTH_BIAS(x) ((x)<<14) -#define ENABLE_ALPHA_TEST_FUNC (1<<13) -#define ENABLE_ALPHA_REF_VALUE (1<<8) -#define ALPHA_TEST_FUNC(x) ((x)<<9) -#define ALPHA_REF_VALUE(x) (x) - -#define ALPHA_TEST_REF_MASK 0x3fff - -/* _3DSTATE_MODES_3, p193 */ -#define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) -#define DEPTH_TEST_FUNC_MASK 0x1f0000 -#define ENABLE_DEPTH_TEST_FUNC (1<<20) -/* Uses COMPAREFUNC */ -#define DEPTH_TEST_FUNC(x) ((x)<<16) -#define ENABLE_ALPHA_SHADE_MODE (1<<11) -#define ENABLE_FOG_SHADE_MODE (1<<9) -#define ENABLE_SPEC_SHADE_MODE (1<<7) -#define ENABLE_COLOR_SHADE_MODE (1<<5) -#define ALPHA_SHADE_MODE(x) ((x)<<10) -#define FOG_SHADE_MODE(x) ((x)<<8) -#define SPEC_SHADE_MODE(x) ((x)<<6) -#define COLOR_SHADE_MODE(x) ((x)<<4) -#define CULLMODE_MASK 0xf -#define ENABLE_CULL_MODE (1<<3) -#define CULLMODE_BOTH 0 -#define CULLMODE_NONE 1 -#define CULLMODE_CW 2 -#define CULLMODE_CCW 3 - -#define SHADE_MODE_LINEAR 0 -#define SHADE_MODE_FLAT 0x1 - -/* _3DSTATE_MODES_4, p195 */ -#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) -#define ENABLE_LOGIC_OP_FUNC (1<<23) -#define LOGIC_OP_FUNC(x) ((x)<<18) -#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) -#define LOGICOP_CLEAR 0 -#define LOGICOP_NOR 0x1 -#define LOGICOP_AND_INV 0x2 -#define LOGICOP_COPY_INV 0x3 -#define LOGICOP_AND_RVRSE 0x4 -#define LOGICOP_INV 0x5 -#define LOGICOP_XOR 0x6 -#define LOGICOP_NAND 0x7 -#define LOGICOP_AND 0x8 -#define LOGICOP_EQUIV 0x9 -#define LOGICOP_NOOP 0xa -#define LOGICOP_OR_INV 0xb -#define LOGICOP_COPY 0xc -#define LOGICOP_OR_RVRSE 0xd -#define LOGICOP_OR 0xe -#define LOGICOP_SET 0xf -#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) -#define ENABLE_STENCIL_TEST_MASK (1<<17) -#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) -#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) -#define ENABLE_STENCIL_WRITE_MASK (1<<16) -#define STENCIL_WRITE_MASK(x) ((x)&0xff) - -/* _3DSTATE_MODES_5, p196 */ -#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) -#define ENABLE_SPRITE_POINT_TEX (1<<23) -#define SPRITE_POINT_TEX_ON (1<<22) -#define SPRITE_POINT_TEX_OFF 0 -#define FLUSH_RENDER_CACHE (1<<18) -#define FLUSH_TEXTURE_CACHE (1<<16) -#define FIXED_LINE_WIDTH_MASK 0xfc00 -#define ENABLE_FIXED_LINE_WIDTH (1<<15) -#define FIXED_LINE_WIDTH(x) ((x)<<10) -#define FIXED_POINT_WIDTH_MASK 0x3ff -#define ENABLE_FIXED_POINT_WIDTH (1<<9) -#define FIXED_POINT_WIDTH(x) (x) - -/* _3DSTATE_RASTERIZATION_RULES, p198 */ -#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) -#define ENABLE_POINT_RASTER_RULE (1<<15) -#define OGL_POINT_RASTER_RULE (1<<13) -#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) -#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) -#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) -#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) -#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) -#define TRI_STRIP_PROVOKE_VRTX(x) (x) - -/* _3DSTATE_SCISSOR_ENABLE, p200 */ -#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) -#define ENABLE_SCISSOR_RECT ((1<<1) | 1) -#define DISABLE_SCISSOR_RECT (1<<1) - -/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ -#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) -/* Dword 1 */ -#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) -#define SCISSOR_RECT_0_XMIN(x) (x) -/* Dword 2 */ -#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) -#define SCISSOR_RECT_0_XMAX(x) (x) - -/* _3DSTATE_STENCIL_TEST, p202 */ -#define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) -#define ENABLE_STENCIL_PARMS (1<<23) -#define STENCIL_OPS_MASK (0xffc000) -#define STENCIL_FAIL_OP(x) ((x)<<20) -#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) -#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) - -#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) -#define ENABLE_STENCIL_TEST_FUNC (1<<13) -/* Uses COMPAREFUNC */ -#define STENCIL_TEST_FUNC(x) ((x)<<9) -#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) -#define ENABLE_STENCIL_REF_VALUE (1<<8) -#define STENCIL_REF_VALUE(x) (x) - -/* _3DSTATE_VERTEX_FORMAT, p204 */ -#define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) -#define VFT0_POINT_WIDTH (1<<12) -#define VFT0_TEX_COUNT_MASK (7<<8) -#define VFT0_TEX_COUNT_SHIFT 8 -#define VFT0_TEX_COUNT(x) ((x)<<8) -#define VFT0_SPEC (1<<7) -#define VFT0_DIFFUSE (1<<6) -#define VFT0_DEPTH_OFFSET (1<<5) -#define VFT0_XYZ (1<<1) -#define VFT0_XYZW (2<<1) -#define VFT0_XY (3<<1) -#define VFT0_XYW (4<<1) -#define VFT0_XYZW_MASK (7<<1) - -/* _3DSTATE_VERTEX_FORMAT_2, p206 */ -#define _3DSTATE_VFT1_CMD (CMD_3D|(0x0a<<24)) -#define VFT1_TEX7_FMT(x) ((x)<<14) -#define VFT1_TEX6_FMT(x) ((x)<<12) -#define VFT1_TEX5_FMT(x) ((x)<<10) -#define VFT1_TEX4_FMT(x) ((x)<<8) -#define VFT1_TEX3_FMT(x) ((x)<<6) -#define VFT1_TEX2_FMT(x) ((x)<<4) -#define VFT1_TEX1_FMT(x) ((x)<<2) -#define VFT1_TEX0_FMT(x) (x) -#define VFT1_TEX0_MASK 3 -#define VFT1_TEX1_SHIFT 2 -#define TEXCOORDFMT_2D 0 -#define TEXCOORDFMT_3D 1 -#define TEXCOORDFMT_4D 2 -#define TEXCOORDFMT_1D 3 - -/*New stuff picked up along the way */ - -#define MLC_LOD_BIAS_MASK ((1<<7)-1) - - -/* _3DSTATE_VERTEX_TRANSFORM, p207 */ -#define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) -#define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) -/* Dword 1 */ -#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) -#define DISABLE_VIEWPORT_TRANSFORM (1<<31) -#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) -#define DISABLE_PERSP_DIVIDE (1<<29) -#define VRTX_TRANS_LOAD_MATRICES 0x7421 -#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 -/* Dword 2 -> 7 are matrix elements */ - -/* _3DSTATE_W_STATE, p209 */ -#define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) -/* Dword 1 */ -#define MAGIC_W_STATE_DWORD1 0x00000008 -/* Dword 2 */ -#define WFAR_VALUE(x) (x) - - -/* Stipple command, carried over from the i810, apparently: - */ -#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define ST1_ENABLE (1<<16) -#define ST1_MASK (0xffff) - - - -#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) -#define LOAD_TEXTURE_MAP0 (1<<11) -#define LOAD_GLOBAL_COLOR_FACTOR (1<<6) - -#define TM0S0_ADDRESS_MASK 0xfffffffc -#define TM0S0_USE_FENCE (1<<1) - -#define TM0S1_HEIGHT_SHIFT 21 -#define TM0S1_WIDTH_SHIFT 10 -#define TM0S1_PALETTE_SELECT (1<<9) -#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) -#define TM0S1_MAPSURF_FORMAT_SHIFT 6 -#define MAPSURF_8BIT_INDEXED (0<<6) -#define MAPSURF_8BIT (1<<6) -#define MAPSURF_16BIT (2<<6) -#define MAPSURF_32BIT (3<<6) -#define MAPSURF_411 (4<<6) -#define MAPSURF_422 (5<<6) -#define MAPSURF_COMPRESSED (6<<6) -#define MAPSURF_4BIT_INDEXED (7<<6) -#define TM0S1_MT_FORMAT_MASK (0x7 << 3) -#define TM0S1_MT_FORMAT_SHIFT 3 -#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ -#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ -#define MT_8BIT_IDX_ARGB1555 (1<<3) -#define MT_8BIT_IDX_ARGB4444 (2<<3) -#define MT_8BIT_IDX_AY88 (3<<3) -#define MT_8BIT_IDX_ABGR8888 (4<<3) -#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) -#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) -#define MT_8BIT_IDX_ARGB8888 (7<<3) -#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ -#define MT_8BIT_L8 (1<<3) -#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ -#define MT_16BIT_ARGB1555 (1<<3) -#define MT_16BIT_ARGB4444 (2<<3) -#define MT_16BIT_AY88 (3<<3) -#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) -#define MT_16BIT_BUMP_88DVDU (5<<3) -#define MT_16BIT_BUMP_655LDVDU (6<<3) -#define MT_16BIT_DIB_RGB565_8888 (7<<3) -#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ -#define MT_32BIT_ABGR8888 (1<<3) -#define MT_32BIT_XRGB8888 (2<<3) /* XXX: Guess from i915_reg.h */ -#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) -#define MT_32BIT_DIB_8888 (7<<3) -#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ -#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ -#define MT_422_YCRCB_NORMAL (1<<3) -#define MT_422_YCRCB_SWAPUV (2<<3) -#define MT_422_YCRCB_SWAPUVY (3<<3) -#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ -#define MT_COMPRESS_DXT2_3 (1<<3) -#define MT_COMPRESS_DXT4_5 (2<<3) -#define MT_COMPRESS_FXT1 (3<<3) -#define TM0S1_COLORSPACE_CONVERSION (1 << 2) -#define TM0S1_TILED_SURFACE (1 << 1) -#define TM0S1_TILE_WALK (1 << 0) - -#define TM0S2_PITCH_SHIFT 21 -#define TM0S2_CUBE_FACE_ENA_SHIFT 15 -#define TM0S2_CUBE_FACE_ENA_MASK (1<<15) -#define TM0S2_MAP_FORMAT (1<<14) -#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) -#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) -#define TM0S2_OUTPUT_CHAN_SHIFT 10 -#define TM0S2_OUTPUT_CHAN_MASK (3<<10) - -#define TM0S3_MIP_FILTER_MASK (0x3<<30) -#define TM0S3_MIP_FILTER_SHIFT 30 -#define MIPFILTER_NONE 0 -#define MIPFILTER_NEAREST 1 -#define MIPFILTER_LINEAR 3 -#define TM0S3_MAG_FILTER_MASK (0x3<<28) -#define TM0S3_MAG_FILTER_SHIFT 28 -#define TM0S3_MIN_FILTER_MASK (0x3<<26) -#define TM0S3_MIN_FILTER_SHIFT 26 -#define FILTER_NEAREST 0 -#define FILTER_LINEAR 1 -#define FILTER_ANISOTROPIC 2 - -#define TM0S3_LOD_BIAS_SHIFT 17 -#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) -#define TM0S3_MAX_MIP_SHIFT 9 -#define TM0S3_MAX_MIP_MASK (0xff<<9) -#define TM0S3_MIN_MIP_SHIFT 3 -#define TM0S3_MIN_MIP_MASK (0x3f<<3) -#define TM0S3_KILL_PIXEL (1<<2) -#define TM0S3_KEYED_FILTER (1<<1) -#define TM0S3_CHROMA_KEY (1<<0) - - -/* _3DSTATE_MAP_TEXEL_STREAM, p188 */ -#define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) -#define DISABLE_TEX_STREAM_BUMP (1<<12) -#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) -#define TEX_MODIFY_UNIT_0 0 -#define TEX_MODIFY_UNIT_1 (1<<8) -#define ENABLE_TEX_STREAM_COORD_SET (1<<7) -#define TEX_STREAM_COORD_SET(x) ((x)<<4) -#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) -#define TEX_STREAM_MAP_IDX(x) (x) - - -#define MI_FLUSH ((0<<29)|(4<<23)) -#define FLUSH_MAP_CACHE (1<<0) - -#endif diff --git a/src/mesa/drivers/dri/i915tex/i830_state.c b/src/mesa/drivers/dri/i915tex/i830_state.c deleted file mode 100644 index 3c149e6905..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_state.c +++ /dev/null @@ -1,1116 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" - -#include "texmem.h" - -#include "drivers/common/driverfuncs.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_fbo.h" - -#include "i830_context.h" -#include "i830_reg.h" - -#define FILE_DEBUG_FLAG DEBUG_STATE - -static void -i830StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, - GLuint mask) -{ - struct i830_context *i830 = i830_context(ctx); - int test = intel_translate_compare_func(func); - - mask = mask & 0xff; - - DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(func), ref, mask); - - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(mask)); - i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | - ENABLE_STENCIL_TEST_FUNC_MASK); - i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_REF_VALUE(ref) | - STENCIL_TEST_FUNC(test)); -} - -static void -i830StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) -{ - struct i830_context *i830 = i830_context(ctx); - - DBG("%s : mask 0x%x\n", __FUNCTION__, mask); - - mask = mask & 0xff; - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(mask)); -} - -static void -i830StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, - GLenum zpass) -{ - struct i830_context *i830 = i830_context(ctx); - int fop, dfop, dpop; - - DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(fail), - _mesa_lookup_enum_by_nr(zfail), - _mesa_lookup_enum_by_nr(zpass)); - - fop = 0; - dfop = 0; - dpop = 0; - - switch (fail) { - case GL_KEEP: - fop = STENCILOP_KEEP; - break; - case GL_ZERO: - fop = STENCILOP_ZERO; - break; - case GL_REPLACE: - fop = STENCILOP_REPLACE; - break; - case GL_INCR: - fop = STENCILOP_INCRSAT; - break; - case GL_DECR: - fop = STENCILOP_DECRSAT; - break; - case GL_INCR_WRAP: - fop = STENCILOP_INCR; - break; - case GL_DECR_WRAP: - fop = STENCILOP_DECR; - break; - case GL_INVERT: - fop = STENCILOP_INVERT; - break; - default: - break; - } - switch (zfail) { - case GL_KEEP: - dfop = STENCILOP_KEEP; - break; - case GL_ZERO: - dfop = STENCILOP_ZERO; - break; - case GL_REPLACE: - dfop = STENCILOP_REPLACE; - break; - case GL_INCR: - dfop = STENCILOP_INCRSAT; - break; - case GL_DECR: - dfop = STENCILOP_DECRSAT; - break; - case GL_INCR_WRAP: - dfop = STENCILOP_INCR; - break; - case GL_DECR_WRAP: - dfop = STENCILOP_DECR; - break; - case GL_INVERT: - dfop = STENCILOP_INVERT; - break; - default: - break; - } - switch (zpass) { - case GL_KEEP: - dpop = STENCILOP_KEEP; - break; - case GL_ZERO: - dpop = STENCILOP_ZERO; - break; - case GL_REPLACE: - dpop = STENCILOP_REPLACE; - break; - case GL_INCR: - dpop = STENCILOP_INCRSAT; - break; - case GL_DECR: - dpop = STENCILOP_DECRSAT; - break; - case GL_INCR_WRAP: - dpop = STENCILOP_INCR; - break; - case GL_DECR_WRAP: - dpop = STENCILOP_DECR; - break; - case GL_INVERT: - dpop = STENCILOP_INVERT; - break; - default: - break; - } - - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); - i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(fop) | - STENCIL_PASS_DEPTH_FAIL_OP - (dfop) | - STENCIL_PASS_DEPTH_PASS_OP - (dpop)); -} - -static void -i830AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) -{ - struct i830_context *i830 = i830_context(ctx); - int test = intel_translate_compare_func(func); - GLubyte refByte; - GLuint refInt; - - UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); - refInt = (GLuint) refByte; - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; - i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | - ENABLE_ALPHA_REF_VALUE | - ALPHA_TEST_FUNC(test) | - ALPHA_REF_VALUE(refInt)); -} - -/** - * Makes sure that the proper enables are set for LogicOp, Independant Alpha - * Blend, and Blending. It needs to be called from numerous places where we - * could change the LogicOp or Independant Alpha Blend without subsequent - * calls to glEnable. - * - * \todo - * This function is substantially different from the old i830-specific driver. - * I'm not sure which is correct. - */ -static void -i830EvalLogicOpBlendState(GLcontext * ctx) -{ - struct i830_context *i830 = i830_context(ctx); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - if (RGBA_LOGICOP_ENABLED(ctx)) { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | - ENABLE_LOGIC_OP_MASK); - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | - ENABLE_LOGIC_OP); - } - else if (ctx->Color.BlendEnabled) { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | - ENABLE_LOGIC_OP_MASK); - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND | - DISABLE_LOGIC_OP); - } - else { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | - ENABLE_LOGIC_OP_MASK); - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | - DISABLE_LOGIC_OP); - } -} - -static void -i830BlendColor(GLcontext * ctx, const GLfloat color[4]) -{ - struct i830_context *i830 = i830_context(ctx); - GLubyte r, g, b, a; - - DBG("%s\n", __FUNCTION__); - - UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = - (a << 24) | (r << 16) | (g << 8) | b; -} - -/** - * Sets both the blend equation (called "function" in i830 docs) and the - * blend function (called "factor" in i830 docs). This is done in a single - * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) - * change the interpretation of the blend function. - */ -static void -i830_set_blend_state(GLcontext * ctx) -{ - struct i830_context *i830 = i830_context(ctx); - int funcA; - int funcRGB; - int eqnA; - int eqnRGB; - int iab; - int s1; - - - funcRGB = - SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcRGB)) - | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstRGB)); - - switch (ctx->Color.BlendEquationRGB) { - case GL_FUNC_ADD: - eqnRGB = BLENDFUNC_ADD; - break; - case GL_MIN: - eqnRGB = BLENDFUNC_MIN; - funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_MAX: - eqnRGB = BLENDFUNC_MAX; - funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_FUNC_SUBTRACT: - eqnRGB = BLENDFUNC_SUB; - break; - case GL_FUNC_REVERSE_SUBTRACT: - eqnRGB = BLENDFUNC_RVRSE_SUB; - break; - default: - fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB); - return; - } - - - funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcA)) - | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstA)); - - switch (ctx->Color.BlendEquationA) { - case GL_FUNC_ADD: - eqnA = BLENDFUNC_ADD; - break; - case GL_MIN: - eqnA = BLENDFUNC_MIN; - funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_MAX: - eqnA = BLENDFUNC_MAX; - funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); - break; - case GL_FUNC_SUBTRACT: - eqnA = BLENDFUNC_SUB; - break; - case GL_FUNC_REVERSE_SUBTRACT: - eqnA = BLENDFUNC_RVRSE_SUB; - break; - default: - fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationA); - return; - } - - iab = eqnA | funcA - | _3DSTATE_INDPT_ALPHA_BLEND_CMD - | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR - | ENABLE_ALPHA_BLENDFUNC; - s1 = eqnRGB | funcRGB - | _3DSTATE_MODES_1_CMD - | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR - | ENABLE_COLR_BLND_FUNC; - - if ((eqnA | funcA) != (eqnRGB | funcRGB)) - iab |= ENABLE_INDPT_ALPHA_BLEND; - else - iab |= DISABLE_INDPT_ALPHA_BLEND; - - if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] || - s1 != i830->state.Ctx[I830_CTXREG_STATE1]) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_IALPHAB] = iab; - i830->state.Ctx[I830_CTXREG_STATE1] = s1; - } - - /* This will catch a logicop blend equation. It will also ensure - * independant alpha blend is really in the correct state (either enabled - * or disabled) if blending is already enabled. - */ - - i830EvalLogicOpBlendState(ctx); - - if (0) { - fprintf(stderr, - "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n", - __FUNCTION__, __LINE__, i830->state.Ctx[I830_CTXREG_STATE1], - i830->state.Ctx[I830_CTXREG_IALPHAB], - (ctx->Color.BlendEnabled) ? "en" : "dis"); - } -} - - -static void -i830BlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA) -{ - DBG("%s -> %s, %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(modeRGB), - _mesa_lookup_enum_by_nr(modeA)); - - (void) modeRGB; - (void) modeA; - i830_set_blend_state(ctx); -} - - -static void -i830BlendFuncSeparate(GLcontext * ctx, GLenum sfactorRGB, - GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) -{ - DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(sfactorRGB), - _mesa_lookup_enum_by_nr(dfactorRGB), - _mesa_lookup_enum_by_nr(sfactorA), - _mesa_lookup_enum_by_nr(dfactorA)); - - (void) sfactorRGB; - (void) dfactorRGB; - (void) sfactorA; - (void) dfactorA; - i830_set_blend_state(ctx); -} - - - -static void -i830DepthFunc(GLcontext * ctx, GLenum func) -{ - struct i830_context *i830 = i830_context(ctx); - int test = intel_translate_compare_func(func); - - DBG("%s\n", __FUNCTION__); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; - i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC(test)); -} - -static void -i830DepthMask(GLcontext * ctx, GLboolean flag) -{ - struct i830_context *i830 = i830_context(ctx); - - DBG("%s flag (%d)\n", __FUNCTION__, flag); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; - - if (flag && ctx->Depth.Test) - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; - else - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; -} - -/* ============================================================= - * Polygon stipple - * - * The i830 supports a 4x4 stipple natively, GL wants 32x32. - * Fortunately stipple is usually a repeating pattern. - */ -static void -i830PolygonStipple(GLcontext * ctx, const GLubyte * mask) -{ - struct i830_context *i830 = i830_context(ctx); - const GLubyte *m = mask; - GLubyte p[4]; - int i, j, k; - int active = (ctx->Polygon.StippleFlag && - i830->intel.reduced_primitive == GL_TRIANGLES); - GLuint newMask; - - if (active) { - I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); - i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - } - - p[0] = mask[12] & 0xf; - p[0] |= p[0] << 4; - p[1] = mask[8] & 0xf; - p[1] |= p[1] << 4; - p[2] = mask[4] & 0xf; - p[2] |= p[2] << 4; - p[3] = mask[0] & 0xf; - p[3] |= p[3] << 4; - - for (k = 0; k < 8; k++) - for (j = 3; j >= 0; j--) - for (i = 0; i < 4; i++, m++) - if (*m != p[j]) { - i830->intel.hw_stipple = 0; - return; - } - - newMask = (((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); - - - if (newMask == 0xffff || newMask == 0x0) { - /* this is needed to make conform pass */ - i830->intel.hw_stipple = 0; - return; - } - - i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff; - i830->state.Stipple[I830_STPREG_ST1] |= newMask; - i830->intel.hw_stipple = 1; - - if (active) - i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; -} - - -/* ============================================================= - * Hardware clipping - */ -static void -i830Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - struct i830_context *i830 = i830_context(ctx); - int x1, y1, x2, y2; - - if (!ctx->DrawBuffer) - return; - - DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); - - if (ctx->DrawBuffer->Name == 0) { - x1 = x; - y1 = ctx->DrawBuffer->Height - (y + h); - x2 = x + w - 1; - y2 = y1 + h - 1; - DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); - } - else { - /* FBO - not inverted - */ - x1 = x; - y1 = y; - x2 = x + w - 1; - y2 = y + h - 1; - DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); - } - - x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); - y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); - x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); - y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); - - DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); - - I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); - i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); - i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); -} - -static void -i830LogicOp(GLcontext * ctx, GLenum opcode) -{ - struct i830_context *i830 = i830_context(ctx); - int tmp = intel_translate_logic_op(opcode); - - DBG("%s\n", __FUNCTION__); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; - i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); -} - - - -static void -i830CullFaceFrontFace(GLcontext * ctx, GLenum unused) -{ - struct i830_context *i830 = i830_context(ctx); - GLuint mode; - - DBG("%s\n", __FUNCTION__); - - if (!ctx->Polygon.CullFlag) { - mode = CULLMODE_NONE; - } - else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { - mode = CULLMODE_CW; - - if (ctx->Polygon.CullFaceMode == GL_FRONT) - mode ^= (CULLMODE_CW ^ CULLMODE_CCW); - if (ctx->Polygon.FrontFace != GL_CCW) - mode ^= (CULLMODE_CW ^ CULLMODE_CCW); - } - else { - mode = CULLMODE_BOTH; - } - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; - i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; -} - -static void -i830LineWidth(GLcontext * ctx, GLfloat widthf) -{ - struct i830_context *i830 = i830_context(ctx); - int width; - int state5; - - DBG("%s\n", __FUNCTION__); - - width = (int) (widthf * 2); - CLAMP_SELF(width, 1, 15); - - state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK; - state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width)); - - if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE5] = state5; - } -} - -static void -i830PointSize(GLcontext * ctx, GLfloat size) -{ - struct i830_context *i830 = i830_context(ctx); - GLint point_size = (int) size; - - DBG("%s\n", __FUNCTION__); - - CLAMP_SELF(point_size, 1, 256); - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; - i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | - FIXED_POINT_WIDTH(point_size)); -} - - -/* ============================================================= - * Color masks - */ - -static void -i830ColorMask(GLcontext * ctx, - GLboolean r, GLboolean g, GLboolean b, GLboolean a) -{ - struct i830_context *i830 = i830_context(ctx); - GLuint tmp = 0; - - DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); - - tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) | - ENABLE_COLOR_MASK | - ENABLE_COLOR_WRITE | - ((!r) << WRITEMASK_RED_SHIFT) | - ((!g) << WRITEMASK_GREEN_SHIFT) | - ((!b) << WRITEMASK_BLUE_SHIFT) | ((!a) << WRITEMASK_ALPHA_SHIFT)); - - if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp; - } -} - -static void -update_specular(GLcontext * ctx) -{ - struct i830_context *i830 = i830_context(ctx); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; - - if (NEED_SECONDARY_COLOR(ctx)) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; -} - -static void -i830LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) -{ - DBG("%s\n", __FUNCTION__); - - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - update_specular(ctx); - } -} - -/* In Mesa 3.5 we can reliably do native flatshading. - */ -static void -i830ShadeModel(GLcontext * ctx, GLenum mode) -{ - struct i830_context *i830 = i830_context(ctx); - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - -#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) - - i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; - - if (mode == GL_FLAT) { - i830->state.Ctx[I830_CTXREG_STATE3] |= - (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | FOG_SHADE_MODE(SHADE_MODE_FLAT) - | SPEC_SHADE_MODE(SHADE_MODE_FLAT) | - COLOR_SHADE_MODE(SHADE_MODE_FLAT)); - } - else { - i830->state.Ctx[I830_CTXREG_STATE3] |= - (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | - FOG_SHADE_MODE(SHADE_MODE_LINEAR) | - SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | - COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); - } -} - -/* ============================================================= - * Fog - */ -static void -i830Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) -{ - struct i830_context *i830 = i830_context(ctx); - - DBG("%s\n", __FUNCTION__); - - if (pname == GL_FOG_COLOR) { - GLuint color = (((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | - ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | - ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_FOGCOLOR] = - (_3DSTATE_FOG_COLOR_CMD | color); - } -} - -/* ============================================================= - */ - -static void -i830Enable(GLcontext * ctx, GLenum cap, GLboolean state) -{ - struct i830_context *i830 = i830_context(ctx); - - switch (cap) { - case GL_LIGHTING: - case GL_COLOR_SUM: - update_specular(ctx); - break; - - case GL_ALPHA_TEST: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; - - break; - - case GL_BLEND: - i830EvalLogicOpBlendState(ctx); - break; - - case GL_COLOR_LOGIC_OP: - i830EvalLogicOpBlendState(ctx); - - /* Logicop doesn't seem to work at 16bpp: - */ - if (i830->intel.intelScreen->cpp == 2) - FALLBACK(&i830->intel, I830_FALLBACK_LOGICOP, state); - break; - - case GL_DITHER: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; - - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; - else - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; - break; - - case GL_DEPTH_TEST: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; - - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; - - /* Also turn off depth writes when GL_DEPTH_TEST is disabled: - */ - i830DepthMask(ctx, ctx->Depth.Mask); - break; - - case GL_SCISSOR_TEST: - I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); - - if (state) - i830->state.Buffer[I830_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); - else - i830->state.Buffer[I830_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - - break; - - case GL_LINE_SMOOTH: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; - if (state) - i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE; - else - i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE; - break; - - case GL_FOG: - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; - if (state) - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG; - else - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG; - break; - - case GL_CULL_FACE: - i830CullFaceFrontFace(ctx, 0); - break; - - case GL_TEXTURE_2D: - break; - - case GL_STENCIL_TEST: - { - GLboolean hw_stencil = GL_FALSE; - if (ctx->DrawBuffer) { - struct intel_renderbuffer *irbStencil - = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); - hw_stencil = (irbStencil && irbStencil->region); - } - if (hw_stencil) { - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - if (state) { - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; - } - else { - i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; - i830->state.Ctx[I830_CTXREG_ENABLES_2] &= - ~ENABLE_STENCIL_WRITE; - i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; - i830->state.Ctx[I830_CTXREG_ENABLES_2] |= - DISABLE_STENCIL_WRITE; - } - } - else { - FALLBACK(&i830->intel, I830_FALLBACK_STENCIL, state); - } - } - break; - - case GL_POLYGON_STIPPLE: - /* The stipple command worked on my 855GM box, but not my 845G. - * I'll do more testing later to find out exactly which hardware - * supports it. Disabled for now. - */ - if (i830->intel.hw_stipple && - i830->intel.reduced_primitive == GL_TRIANGLES) { - I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); - i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; - if (state) - i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; - } - break; - - default: - ; - } -} - - -static void -i830_init_packets(struct i830_context *i830) -{ - intelScreenPrivate *screen = i830->intel.intelScreen; - - /* Zero all state */ - memset(&i830->state, 0, sizeof(i830->state)); - - /* Set default blend state */ - i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXOP_LAST_STAGE | TEXBLENDOP_ARG1); - i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); - i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_DIFFUSE); - i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_DIFFUSE); - - i830->state.TexBlendWordsUsed[0] = 4; - - - i830->state.Ctx[I830_CTXREG_VF] = 0; - i830->state.Ctx[I830_CTXREG_VF2] = 0; - - i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | - AA_LINE_REGION_WIDTH_1_0 | - AA_LINE_DISABLE); - - i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD | - DISABLE_LOGIC_OP | - DISABLE_STENCIL_TEST | - DISABLE_DEPTH_BIAS | - DISABLE_SPEC_ADD | - DISABLE_FOG | - DISABLE_ALPHA_TEST | - DISABLE_COLOR_BLEND | - DISABLE_DEPTH_TEST); - -#if 000 /* XXX all the stencil enable state is set in i830Enable(), right? */ - if (i830->intel.hw_stencil) { - i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | - ENABLE_STENCIL_WRITE | - ENABLE_TEX_CACHE | - ENABLE_DITHER | - ENABLE_COLOR_MASK | - /* set no color comps disabled */ - ENABLE_COLOR_WRITE | - ENABLE_DEPTH_WRITE); - } - else -#endif - { - i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | - DISABLE_STENCIL_WRITE | - ENABLE_TEX_CACHE | - ENABLE_DITHER | - ENABLE_COLOR_MASK | - /* set no color comps disabled */ - ENABLE_COLOR_WRITE | - ENABLE_DEPTH_WRITE); - } - - i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD | - ENABLE_COLR_BLND_FUNC | - BLENDFUNC_ADD | - ENABLE_SRC_BLND_FACTOR | - SRC_BLND_FACT(BLENDFACT_ONE) | - ENABLE_DST_BLND_FACTOR | - DST_BLND_FACT(BLENDFACT_ZERO)); - - i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD | - ENABLE_GLOBAL_DEPTH_BIAS | - GLOBAL_DEPTH_BIAS(0) | - ENABLE_ALPHA_TEST_FUNC | - ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) - | ALPHA_REF_VALUE(0)); - - i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD | - ENABLE_DEPTH_TEST_FUNC | - DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | - ENABLE_ALPHA_SHADE_MODE | - ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) - | ENABLE_FOG_SHADE_MODE | - FOG_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_SPEC_SHADE_MODE | - SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | - ENABLE_COLOR_SHADE_MODE | - COLOR_SHADE_MODE(SHADE_MODE_LINEAR) - | ENABLE_CULL_MODE | CULLMODE_NONE); - - i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff) | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(0xff)); - - i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD | - ENABLE_STENCIL_PARMS | - STENCIL_FAIL_OP(STENCILOP_KEEP) - | - STENCIL_PASS_DEPTH_FAIL_OP - (STENCILOP_KEEP) | - STENCIL_PASS_DEPTH_PASS_OP - (STENCILOP_KEEP) | - ENABLE_STENCIL_TEST_FUNC | - STENCIL_TEST_FUNC - (COMPAREFUNC_ALWAYS) | - ENABLE_STENCIL_REF_VALUE | - STENCIL_REF_VALUE(0)); - - i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD | FLUSH_TEXTURE_CACHE | ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF | ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */ - ENABLE_FIXED_POINT_WIDTH | - FIXED_POINT_WIDTH(1)); - - i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD | - DISABLE_INDPT_ALPHA_BLEND | - ENABLE_ALPHA_BLENDFUNC | - ABLENDFUNC_ADD); - - i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | - FOG_COLOR_RED(0) | - FOG_COLOR_GREEN(0) | - FOG_COLOR_BLUE(0)); - - i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; - i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0; - - i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD; - i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | - TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | - TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | - TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); - - - i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE; - - i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i830->state.Buffer[I830_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - - - i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - i830->state.Buffer[I830_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - - i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; - -#if 0 - switch (screen->fbFormat) { - case DV_PF_565: - i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - screen->fbFormat | - DEPTH_IS_Z | - DEPTH_FRMT_16_FIXED); - break; - case DV_PF_8888: - i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - screen->fbFormat | - DEPTH_IS_Z | - DEPTH_FRMT_24_FIXED_8_OTHER); - break; - } -#endif - i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | - DISABLE_SCISSOR_RECT); - i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; - i830->state.Buffer[I830_DESTREG_SR1] = 0; - i830->state.Buffer[I830_DESTREG_SR2] = 0; -} - - -void -i830InitStateFuncs(struct dd_function_table *functions) -{ - functions->AlphaFunc = i830AlphaFunc; - functions->BlendColor = i830BlendColor; - functions->BlendEquationSeparate = i830BlendEquationSeparate; - functions->BlendFuncSeparate = i830BlendFuncSeparate; - functions->ColorMask = i830ColorMask; - functions->CullFace = i830CullFaceFrontFace; - functions->DepthFunc = i830DepthFunc; - functions->DepthMask = i830DepthMask; - functions->Enable = i830Enable; - functions->Fogfv = i830Fogfv; - functions->FrontFace = i830CullFaceFrontFace; - functions->LightModelfv = i830LightModelfv; - functions->LineWidth = i830LineWidth; - functions->LogicOpcode = i830LogicOp; - functions->PointSize = i830PointSize; - functions->PolygonStipple = i830PolygonStipple; - functions->Scissor = i830Scissor; - functions->ShadeModel = i830ShadeModel; - functions->StencilFuncSeparate = i830StencilFuncSeparate; - functions->StencilMaskSeparate = i830StencilMaskSeparate; - functions->StencilOpSeparate = i830StencilOpSeparate; -} - -void -i830InitState(struct i830_context *i830) -{ - GLcontext *ctx = &i830->intel.ctx; - - i830_init_packets(i830); - - _mesa_init_driver_state(ctx); - - memcpy(&i830->initial, &i830->state, sizeof(i830->state)); - - i830->current = &i830->state; - i830->state.emitted = 0; - i830->state.active = (I830_UPLOAD_INVARIENT | - I830_UPLOAD_TEXBLEND(0) | - I830_UPLOAD_STIPPLE | - I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS); -} diff --git a/src/mesa/drivers/dri/i915tex/i830_tex.c b/src/mesa/drivers/dri/i915tex/i830_tex.c deleted file mode 100644 index fed464d1aa..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_tex.c +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "simple_list.h" -#include "enums.h" -#include "image.h" -#include "texstore.h" -#include "texformat.h" -#include "texmem.h" -#include "swrast/swrast.h" - -#include "mm.h" - -#include "intel_ioctl.h" - -#include "i830_context.h" -#include "i830_reg.h" - - - -static void -i830TexEnv(GLcontext * ctx, GLenum target, - GLenum pname, const GLfloat * param) -{ - - switch (pname) { - case GL_TEXTURE_ENV_COLOR: - case GL_TEXTURE_ENV_MODE: - case GL_COMBINE_RGB: - case GL_COMBINE_ALPHA: - case GL_SOURCE0_RGB: - case GL_SOURCE1_RGB: - case GL_SOURCE2_RGB: - case GL_SOURCE0_ALPHA: - case GL_SOURCE1_ALPHA: - case GL_SOURCE2_ALPHA: - case GL_OPERAND0_RGB: - case GL_OPERAND1_RGB: - case GL_OPERAND2_RGB: - case GL_OPERAND0_ALPHA: - case GL_OPERAND1_ALPHA: - case GL_OPERAND2_ALPHA: - case GL_RGB_SCALE: - case GL_ALPHA_SCALE: - break; - - case GL_TEXTURE_LOD_BIAS:{ - struct i830_context *i830 = i830_context(ctx); - GLuint unit = ctx->Texture.CurrentUnit; - int b = (int) ((*param) * 16.0); - if (b > 63) - b = 63; - if (b < -64) - b = -64; - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - i830->lodbias_tm0s3[unit] = - ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); - break; - } - - default: - break; - } -} - - - - -void -i830InitTextureFuncs(struct dd_function_table *functions) -{ - functions->TexEnv = i830TexEnv; -} diff --git a/src/mesa/drivers/dri/i915tex/i830_texblend.c b/src/mesa/drivers/dri/i915tex/i830_texblend.c deleted file mode 100644 index 58f220eb7c..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_texblend.c +++ /dev/null @@ -1,463 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "simple_list.h" -#include "enums.h" -#include "texformat.h" -#include "texstore.h" - -#include "mm.h" - -#include "intel_screen.h" -#include "intel_ioctl.h" -#include "intel_tex.h" - -#include "i830_context.h" -#include "i830_reg.h" - - -/* ================================================================ - * Texture combine functions - */ -static GLuint -pass_through(GLuint * state, GLuint blendUnit) -{ - state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); - state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); - state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); - state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); - - return 4; -} - -static GLuint -emit_factor(GLuint blendUnit, GLuint * state, GLuint count, - const GLfloat * factor) -{ - GLubyte r, g, b, a; - GLuint col; - - if (0) - fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n", - blendUnit, factor[0], factor[1], factor[2], factor[3]); - - UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]); - UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]); - UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]); - UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]); - - col = ((a << 24) | (r << 16) | (g << 8) | b); - - state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit); - state[count++] = col; - - return count; -} - - -static INLINE GLuint -GetTexelOp(GLint unit) -{ - switch (unit) { - case 0: - return TEXBLENDARG_TEXEL0; - case 1: - return TEXBLENDARG_TEXEL1; - case 2: - return TEXBLENDARG_TEXEL2; - case 3: - return TEXBLENDARG_TEXEL3; - default: - return TEXBLENDARG_TEXEL0; - } -} - - -/** - * Calculate the hardware instuctions to setup the current texture enviromnemt - * settings. Since \c gl_texture_unit::_CurrentCombine is used, both - * "classic" texture enviroments and GL_ARB_texture_env_combine type texture - * environments are treated identically. - * - * \todo - * This function should return \c GLboolean. When \c GL_FALSE is returned, - * it means that an environment is selected that the hardware cannot do. This - * is the way the Radeon and R200 drivers work. - * - * \todo - * Looking at i830_3d_regs.h, it seems the i830 can do part of - * GL_ATI_texture_env_combine3. It can handle using \c GL_ONE and - * \c GL_ZERO as combine inputs (which the code already supports). It can - * also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating - * partial support for the extension? - */ -GLuint -i830SetTexEnvCombine(struct i830_context * i830, - const struct gl_tex_env_combine_state * combine, - GLint blendUnit, - GLuint texel_op, GLuint * state, const GLfloat * factor) -{ - const GLuint numColorArgs = combine->_NumArgsRGB; - const GLuint numAlphaArgs = combine->_NumArgsA; - - GLuint blendop; - GLuint ablendop; - GLuint args_RGB[3]; - GLuint args_A[3]; - GLuint rgb_shift; - GLuint alpha_shift; - GLboolean need_factor = 0; - int i; - unsigned used; - static const GLuint tex_blend_rgb[3] = { - TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, - }; - static const GLuint tex_blend_a[3] = { - TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, - TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, - }; - - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "%s\n", __FUNCTION__); - - - /* The EXT version of the DOT3 extension does not support the - * scale factor, but the ARB version (and the version in OpenGL - * 1.3) does. - */ - switch (combine->ModeRGB) { - case GL_DOT3_RGB_EXT: - alpha_shift = combine->ScaleShiftA; - rgb_shift = 0; - break; - - case GL_DOT3_RGBA_EXT: - alpha_shift = 0; - rgb_shift = 0; - break; - - default: - rgb_shift = combine->ScaleShiftRGB; - alpha_shift = combine->ScaleShiftA; - break; - } - - - switch (combine->ModeRGB) { - case GL_REPLACE: - blendop = TEXBLENDOP_ARG1; - break; - case GL_MODULATE: - blendop = TEXBLENDOP_MODULATE; - break; - case GL_ADD: - blendop = TEXBLENDOP_ADD; - break; - case GL_ADD_SIGNED: - blendop = TEXBLENDOP_ADDSIGNED; - break; - case GL_INTERPOLATE: - blendop = TEXBLENDOP_BLEND; - break; - case GL_SUBTRACT: - blendop = TEXBLENDOP_SUBTRACT; - break; - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGB: - blendop = TEXBLENDOP_DOT3; - break; - case GL_DOT3_RGBA_EXT: - case GL_DOT3_RGBA: - blendop = TEXBLENDOP_DOT3; - break; - default: - return pass_through(state, blendUnit); - } - - blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); - - - /* Handle RGB args */ - for (i = 0; i < 3; i++) { - switch (combine->SourceRGB[i]) { - case GL_TEXTURE: - args_RGB[i] = texel_op; - break; - case GL_TEXTURE0: - case GL_TEXTURE1: - case GL_TEXTURE2: - case GL_TEXTURE3: - args_RGB[i] = GetTexelOp(combine->SourceRGB[i] - GL_TEXTURE0); - break; - case GL_CONSTANT: - args_RGB[i] = TEXBLENDARG_FACTOR_N; - need_factor = 1; - break; - case GL_PRIMARY_COLOR: - args_RGB[i] = TEXBLENDARG_DIFFUSE; - break; - case GL_PREVIOUS: - args_RGB[i] = TEXBLENDARG_CURRENT; - break; - default: - return pass_through(state, blendUnit); - } - - switch (combine->OperandRGB[i]) { - case GL_SRC_COLOR: - args_RGB[i] |= 0; - break; - case GL_ONE_MINUS_SRC_COLOR: - args_RGB[i] |= TEXBLENDARG_INV_ARG; - break; - case GL_SRC_ALPHA: - args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; - break; - case GL_ONE_MINUS_SRC_ALPHA: - args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | TEXBLENDARG_INV_ARG); - break; - default: - return pass_through(state, blendUnit); - } - } - - - /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to - * match the spec. Can't use DOT3 as it won't propogate values - * into alpha as required: - * - * Note - the global factor is set up with alpha == .5, so - * the alpha part of the DOT4 calculation should be zero. - */ - if (combine->ModeRGB == GL_DOT3_RGBA_EXT || - combine->ModeRGB == GL_DOT3_RGBA) { - ablendop = TEXBLENDOP_DOT4; - args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */ - args_A[1] = TEXBLENDARG_FACTOR; - args_A[2] = TEXBLENDARG_FACTOR; - } - else { - switch (combine->ModeA) { - case GL_REPLACE: - ablendop = TEXBLENDOP_ARG1; - break; - case GL_MODULATE: - ablendop = TEXBLENDOP_MODULATE; - break; - case GL_ADD: - ablendop = TEXBLENDOP_ADD; - break; - case GL_ADD_SIGNED: - ablendop = TEXBLENDOP_ADDSIGNED; - break; - case GL_INTERPOLATE: - ablendop = TEXBLENDOP_BLEND; - break; - case GL_SUBTRACT: - ablendop = TEXBLENDOP_SUBTRACT; - break; - default: - return pass_through(state, blendUnit); - } - - - ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); - - /* Handle A args */ - for (i = 0; i < 3; i++) { - switch (combine->SourceA[i]) { - case GL_TEXTURE: - args_A[i] = texel_op; - break; - case GL_TEXTURE0: - case GL_TEXTURE1: - case GL_TEXTURE2: - case GL_TEXTURE3: - args_A[i] = GetTexelOp(combine->SourceA[i] - GL_TEXTURE0); - break; - case GL_CONSTANT: - args_A[i] = TEXBLENDARG_FACTOR_N; - need_factor = 1; - break; - case GL_PRIMARY_COLOR: - args_A[i] = TEXBLENDARG_DIFFUSE; - break; - case GL_PREVIOUS: - args_A[i] = TEXBLENDARG_CURRENT; - break; - default: - return pass_through(state, blendUnit); - } - - switch (combine->OperandA[i]) { - case GL_SRC_ALPHA: - args_A[i] |= 0; - break; - case GL_ONE_MINUS_SRC_ALPHA: - args_A[i] |= TEXBLENDARG_INV_ARG; - break; - default: - return pass_through(state, blendUnit); - } - } - } - - - - /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ - /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ - /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ - - /* When we render we need to figure out which is the last really enabled - * tex unit, and put last stage on it - */ - - - /* Build color & alpha pipelines */ - - used = 0; - state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | TEXOP_MODIFY_PARMS | blendop); - state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | TEXOP_MODIFY_PARMS | ablendop); - - for (i = 0; i < numColorArgs; i++) { - state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - tex_blend_rgb[i] | args_RGB[i]); - } - - for (i = 0; i < numAlphaArgs; i++) { - state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | - tex_blend_a[i] | args_A[i]); - } - - - if (need_factor) - return emit_factor(blendUnit, state, used, factor); - else - return used; -} - - -static void -emit_texblend(struct i830_context *i830, GLuint unit, GLuint blendUnit, - GLboolean last_stage) -{ - struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; - GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; - - - if (0) - fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); - - /* Update i830->state.TexBlend - */ - tmp_sz = i830SetTexEnvCombine(i830, texUnit->_CurrentCombine, blendUnit, - GetTexelOp(unit), tmp, texUnit->EnvColor); - - if (last_stage) - tmp[0] |= TEXOP_LAST_STAGE; - - if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] || - memcmp(tmp, i830->state.TexBlend[blendUnit], - tmp_sz * sizeof(GLuint))) { - - I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(blendUnit)); - memcpy(i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint)); - i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz; - } - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); -} - -static void -emit_passthrough(struct i830_context *i830) -{ - GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; - GLuint unit = 0; - - tmp_sz = pass_through(tmp, unit); - tmp[0] |= TEXOP_LAST_STAGE; - - if (tmp_sz != i830->state.TexBlendWordsUsed[unit] || - memcmp(tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) { - - I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(unit)); - memcpy(i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint)); - i830->state.TexBlendWordsUsed[unit] = tmp_sz; - } - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); -} - -void -i830EmitTextureBlend(struct i830_context *i830) -{ - GLcontext *ctx = &i830->intel.ctx; - GLuint unit, last_stage = 0, blendunit = 0; - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE); - - if (ctx->Texture._EnabledUnits) { - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) - if (ctx->Texture.Unit[unit]._ReallyEnabled) - last_stage = unit; - - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) - if (ctx->Texture.Unit[unit]._ReallyEnabled) - emit_texblend(i830, unit, blendunit++, last_stage == unit); - } - else { - emit_passthrough(i830); - } -} diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c deleted file mode 100644 index 7613b9d2a6..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_texstate.c +++ /dev/null @@ -1,343 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "mtypes.h" -#include "enums.h" -#include "texformat.h" -#include "dri_bufmgr.h" - -#include "intel_mipmap_tree.h" -#include "intel_tex.h" - -#include "i830_context.h" -#include "i830_reg.h" - - - -static GLuint -translate_texture_format(GLuint mesa_format) -{ - switch (mesa_format) { - case MESA_FORMAT_L8: - return MAPSURF_8BIT | MT_8BIT_L8; - case MESA_FORMAT_I8: - return MAPSURF_8BIT | MT_8BIT_I8; - case MESA_FORMAT_A8: - return MAPSURF_8BIT | MT_8BIT_I8; /* Kludge! */ - case MESA_FORMAT_AL88: - return MAPSURF_16BIT | MT_16BIT_AY88; - case MESA_FORMAT_RGB565: - return MAPSURF_16BIT | MT_16BIT_RGB565; - case MESA_FORMAT_ARGB1555: - return MAPSURF_16BIT | MT_16BIT_ARGB1555; - case MESA_FORMAT_ARGB4444: - return MAPSURF_16BIT | MT_16BIT_ARGB4444; - case MESA_FORMAT_ARGB8888: - return MAPSURF_32BIT | MT_32BIT_ARGB8888; - case MESA_FORMAT_YCBCR_REV: - return (MAPSURF_422 | MT_422_YCRCB_NORMAL); - case MESA_FORMAT_YCBCR: - return (MAPSURF_422 | MT_422_YCRCB_SWAPY); - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); - case MESA_FORMAT_RGBA_DXT1: - case MESA_FORMAT_RGB_DXT1: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - case MESA_FORMAT_RGBA_DXT3: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - case MESA_FORMAT_RGBA_DXT5: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); - default: - fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); - abort(); - return 0; - } -} - - - - -/* The i915 (and related graphics cores) do not support GL_CLAMP. The - * Intel drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - */ -static GLuint -translate_wrap_mode(GLenum wrap) -{ - switch (wrap) { - case GL_REPEAT: - return TEXCOORDMODE_WRAP; - case GL_CLAMP: - case GL_CLAMP_TO_EDGE: - return TEXCOORDMODE_CLAMP; /* not really correct */ - case GL_CLAMP_TO_BORDER: - return TEXCOORDMODE_CLAMP_BORDER; - case GL_MIRRORED_REPEAT: - return TEXCOORDMODE_MIRROR; - default: - return TEXCOORDMODE_WRAP; - } -} - - -/* Recalculate all state from scratch. Perhaps not the most - * efficient, but this has gotten complex enough that we need - * something which is understandable and reliable. - */ -static GLboolean -i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) -{ - GLcontext *ctx = &intel->ctx; - struct i830_context *i830 = i830_context(ctx); - struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; - struct intel_texture_object *intelObj = intel_texture_object(tObj); - struct gl_texture_image *firstImage; - GLuint *state = i830->state.Tex[unit], format, pitch; - - memset(state, 0, sizeof(state)); - - /*We need to refcount these. */ - - if (i830->state.tex_buffer[unit] != NULL) { - dri_bo_unreference(i830->state.tex_buffer[unit]); - i830->state.tex_buffer[unit] = NULL; - } - - if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit)) - return GL_FALSE; - - /* Get first image here, since intelObj->firstLevel will get set in - * the intel_finalize_mipmap_tree() call above. - */ - firstImage = tObj->Image[0][intelObj->firstLevel]; - - if (intelObj->imageOverride) { - i830->state.tex_buffer[unit] = NULL; - i830->state.tex_offset[unit] = intelObj->textureOffset; - - switch (intelObj->depthOverride) { - case 32: - format = MAPSURF_32BIT | MT_32BIT_ARGB8888; - break; - case 24: - default: - format = MAPSURF_32BIT | MT_32BIT_XRGB8888; - break; - case 16: - format = MAPSURF_16BIT | MT_16BIT_RGB565; - break; - } - - pitch = intelObj->pitchOverride; - } else { - dri_bo_reference(intelObj->mt->region->buffer); - i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; - i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, - 0, intelObj-> - firstLevel); - - format = translate_texture_format(firstImage->TexFormat->MesaFormat); - pitch = intelObj->mt->pitch * intelObj->mt->cpp; - } - - state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | - (LOAD_TEXTURE_MAP0 << unit) | 4); - -/* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */ -/* t->intel.TextureOffset); */ - - - state[I830_TEXREG_TM0S1] = - (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | - ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format); - - state[I830_TEXREG_TM0S2] = - ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); - - { - if (tObj->Target == GL_TEXTURE_CUBE_MAP) - state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit) | - CUBE_NEGX_ENABLE | - CUBE_POSX_ENABLE | - CUBE_NEGY_ENABLE | - CUBE_POSY_ENABLE | - CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE); - else - state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit)); - } - - - - - { - GLuint minFilt, mipFilt, magFilt; - - switch (tObj->MinFilter) { - case GL_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NONE; - break; - case GL_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_LINEAR; - break; - default: - return GL_FALSE; - } - - if (tObj->MaxAnisotropy > 1.0) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - switch (tObj->MagFilter) { - case GL_NEAREST: - magFilt = FILTER_NEAREST; - break; - case GL_LINEAR: - magFilt = FILTER_LINEAR; - break; - default: - return GL_FALSE; - } - } - - state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit]; - -#if 0 - /* YUV conversion: - */ - if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || - firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) - state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION; -#endif - - state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - - intelObj->firstLevel) * - 4) << TM0S3_MIN_MIP_SHIFT; - - state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | - (mipFilt << TM0S3_MIP_FILTER_SHIFT) | - (magFilt << TM0S3_MAG_FILTER_SHIFT)); - } - - { - GLenum ws = tObj->WrapS; - GLenum wt = tObj->WrapT; - - - /* 3D textures not available on i830 - */ - if (tObj->Target == GL_TEXTURE_3D) - return GL_FALSE; - - state[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | - MAP_UNIT(unit) | - ENABLE_TEXCOORD_PARAMS | - ss3 | - ENABLE_ADDR_V_CNTL | - TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt)) - | ENABLE_ADDR_U_CNTL | - TEXCOORD_ADDR_U_MODE(translate_wrap_mode - (ws))); - } - - - state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], - tObj->_BorderChan[1], - tObj->_BorderChan[2], - tObj->_BorderChan[3]); - - - I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); - /* memcmp was already disabled, but definitely won't work as the - * region might now change and that wouldn't be detected: - */ - I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); - return GL_TRUE; -} - - - - -void -i830UpdateTextureState(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - GLboolean ok = GL_TRUE; - GLuint i; - - for (i = 0; i < I830_TEX_UNITS && ok; i++) { - switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { - case TEXTURE_1D_BIT: - case TEXTURE_2D_BIT: - case TEXTURE_CUBE_BIT: - ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_NORMAL); - break; - case TEXTURE_RECT_BIT: - ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_IN_TEXELUNITS); - break; - case 0:{ - struct i830_context *i830 = i830_context(&intel->ctx); - if (i830->state.active & I830_UPLOAD_TEX(i)) - I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); - - if (i830->state.tex_buffer[i] != NULL) { - dri_bo_unreference(i830->state.tex_buffer[i]); - i830->state.tex_buffer[i] = NULL; - } - break; - } - case TEXTURE_3D_BIT: - default: - ok = GL_FALSE; - break; - } - } - - FALLBACK(intel, I830_FALLBACK_TEXTURE, !ok); - - if (ok) - i830EmitTextureBlend(i830); -} diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c deleted file mode 100644 index eecff2729f..0000000000 --- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c +++ /dev/null @@ -1,674 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "i830_context.h" -#include "i830_reg.h" -#include "intel_batchbuffer.h" -#include "intel_regions.h" -#include "tnl/t_context.h" -#include "tnl/t_vertex.h" - -#define FILE_DEBUG_FLAG DEBUG_STATE - -static GLboolean i830_check_vertex_size(struct intel_context *intel, - GLuint expected); - -#define SZ_TO_HW(sz) ((sz-2)&0x3) -#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) -#define EMIT_ATTR( ATTR, STYLE, V0 ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ - intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ - intel->vertex_attr_count++; \ - v0 |= V0; \ -} while (0) - -#define EMIT_PAD( N ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ - intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ - intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ - intel->vertex_attr_count++; \ -} while (0) - - -#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) -#define TEXBIND_SET(n, x) ((x)<<((n)*4)) - -static void -i830_render_prevalidate(struct intel_context *intel) -{ -} - -static void -i830_render_start(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - struct i830_context *i830 = i830_context(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - DECLARE_RENDERINPUTS(index_bitset); - GLuint v0 = _3DSTATE_VFT0_CMD; - GLuint v2 = _3DSTATE_VFT1_CMD; - GLuint mcsb1 = 0; - - RENDERINPUTS_COPY(index_bitset, tnl->render_inputs_bitset); - - /* Important: - */ - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - intel->vertex_attr_count = 0; - - /* EMIT_ATTR's must be in order as they tell t_vertex.c how to - * build up a hardware vertex. - */ - if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { - EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW); - intel->coloroffset = 4; - } - else { - EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ); - intel->coloroffset = 3; - } - - if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_POINTSIZE)) { - EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH); - } - - EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE); - - intel->specoffset = 0; - if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1) || - RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) { - if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1)) { - intel->specoffset = intel->coloroffset + 1; - EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC); - } - else - EMIT_PAD(3); - - if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) - EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC); - else - EMIT_PAD(1); - } - - if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { - int i, count = 0; - - for (i = 0; i < I830_TEX_UNITS; i++) { - if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_TEX(i))) { - GLuint sz = VB->TexCoordPtr[i]->size; - GLuint emit; - GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] & - ~TEXCOORDTYPE_MASK); - - switch (sz) { - case 1: - case 2: - emit = EMIT_2F; - sz = 2; - mcs |= TEXCOORDTYPE_CARTESIAN; - break; - case 3: - emit = EMIT_3F; - sz = 3; - mcs |= TEXCOORDTYPE_VECTOR; - break; - case 4: - emit = EMIT_3F_XYW; - sz = 3; - mcs |= TEXCOORDTYPE_HOMOGENEOUS; - break; - default: - continue; - }; - - - EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, emit, 0); - v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz)); - mcsb1 |= (count + 8) << (i * 4); - - if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) { - I830_STATECHANGE(i830, I830_UPLOAD_TEX(i)); - i830->state.Tex[i][I830_TEXREG_MCS] = mcs; - } - - count++; - } - } - - v0 |= VFT0_TEX_COUNT(count); - } - - /* Only need to change the vertex emit code if there has been a - * statechange to a new hardware vertex format: - */ - if (v0 != i830->state.Ctx[I830_CTXREG_VF] || - v2 != i830->state.Ctx[I830_CTXREG_VF2] || - mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] || - !RENDERINPUTS_EQUAL(index_bitset, i830->last_index_bitset)) { - int k; - - I830_STATECHANGE(i830, I830_UPLOAD_CTX); - - /* Must do this *after* statechange, so as not to affect - * buffered vertices reliant on the old state: - */ - intel->vertex_size = - _tnl_install_attrs(ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0); - - intel->vertex_size >>= 2; - - i830->state.Ctx[I830_CTXREG_VF] = v0; - i830->state.Ctx[I830_CTXREG_VF2] = v2; - i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1; - RENDERINPUTS_COPY(i830->last_index_bitset, index_bitset); - - k = i830_check_vertex_size(intel, intel->vertex_size); - assert(k); - } -} - -static void -i830_reduced_primitive_state(struct intel_context *intel, GLenum rprim) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - GLuint st1 = i830->state.Stipple[I830_STPREG_ST1]; - - st1 &= ~ST1_ENABLE; - - switch (rprim) { - case GL_TRIANGLES: - if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) - st1 |= ST1_ENABLE; - break; - case GL_LINES: - case GL_POINTS: - default: - break; - } - - i830->intel.reduced_primitive = rprim; - - if (st1 != i830->state.Stipple[I830_STPREG_ST1]) { - INTEL_FIREVERTICES(intel); - - I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); - i830->state.Stipple[I830_STPREG_ST1] = st1; - } -} - -/* Pull apart the vertex format registers and figure out how large a - * vertex is supposed to be. - */ -static GLboolean -i830_check_vertex_size(struct intel_context *intel, GLuint expected) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - int vft0 = i830->current->Ctx[I830_CTXREG_VF]; - int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; - int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; - int i, sz = 0; - - switch (vft0 & VFT0_XYZW_MASK) { - case VFT0_XY: - sz = 2; - break; - case VFT0_XYZ: - sz = 3; - break; - case VFT0_XYW: - sz = 3; - break; - case VFT0_XYZW: - sz = 4; - break; - default: - fprintf(stderr, "no xyzw specified\n"); - return 0; - } - - if (vft0 & VFT0_SPEC) - sz++; - if (vft0 & VFT0_DIFFUSE) - sz++; - if (vft0 & VFT0_DEPTH_OFFSET) - sz++; - if (vft0 & VFT0_POINT_WIDTH) - sz++; - - for (i = 0; i < nrtex; i++) { - switch (vft1 & VFT1_TEX0_MASK) { - case TEXCOORDFMT_2D: - sz += 2; - break; - case TEXCOORDFMT_3D: - sz += 3; - break; - case TEXCOORDFMT_4D: - sz += 4; - break; - case TEXCOORDFMT_1D: - sz += 1; - break; - } - vft1 >>= VFT1_TEX1_SHIFT; - } - - if (sz != expected) - fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); - - return sz == expected; -} - -static void -i830_emit_invarient_state(struct intel_context *intel) -{ - BATCH_LOCALS; - - BEGIN_BATCH(40, 0); - - OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_Z_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_FOG_MODE_CMD); - OUT_BATCH(FOGFUNC_ENABLE | - FOG_LINEAR_CONST | FOGSRC_INDEX_Z | ENABLE_FOG_DENSITY); - OUT_BATCH(0); - OUT_BATCH(0); - - - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(0) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(0) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0)); - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(1) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(1) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1)); - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(2) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(2) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2)); - OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | - MAP_UNIT(3) | - DISABLE_TEX_STREAM_BUMP | - ENABLE_TEX_STREAM_COORD_SET | - TEX_STREAM_COORD_SET(3) | - ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); - - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1)); - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2)); - OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); - OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3)); - - OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - ENABLE_TRI_STRIP_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2)); - - OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM); - OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); - - OUT_BATCH(_3DSTATE_W_STATE_CMD); - OUT_BATCH(MAGIC_W_STATE_DWORD1); - OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ ); - - - OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD); - OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */ - - ADVANCE_BATCH(); -} - - -#define emit( intel, state, size ) \ -do { \ - int k; \ - BEGIN_BATCH(size / sizeof(GLuint), 0); \ - for (k = 0 ; k < size / sizeof(GLuint) ; k++) { \ - if (0) _mesa_printf(" 0x%08x\n", state[k]); \ - OUT_BATCH(state[k]); \ - } \ - ADVANCE_BATCH(); \ -} while (0) - -static GLuint -get_state_size(struct i830_hw_state *state) -{ - GLuint dirty = state->active & ~state->emitted; - GLuint sz = 0; - GLuint i; - - if (dirty & I830_UPLOAD_INVARIENT) - sz += 40 * sizeof(int); - - if (dirty & I830_UPLOAD_CTX) - sz += sizeof(state->Ctx); - - if (dirty & I830_UPLOAD_BUFFERS) - sz += sizeof(state->Buffer); - - if (dirty & I830_UPLOAD_STIPPLE) - sz += sizeof(state->Stipple); - - for (i = 0; i < I830_TEX_UNITS; i++) { - if ((dirty & I830_UPLOAD_TEX(i))) - sz += sizeof(state->Tex[i]); - - if (dirty & I830_UPLOAD_TEXBLEND(i)) - sz += state->TexBlendWordsUsed[i] * 4; - } - - return sz; -} - - -/* Push the state into the sarea and/or texture memory. - */ -static void -i830_emit_state(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - struct i830_hw_state *state = i830->current; - int i; - GLuint dirty; - BATCH_LOCALS; - - /* We don't hold the lock at this point, so want to make sure that - * there won't be a buffer wrap. - * - * It might be better to talk about explicit places where - * scheduling is allowed, rather than assume that it is whenever a - * batchbuffer fills up. - */ - intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); - - /* Do this here as we may have flushed the batchbuffer above, - * causing more state to be dirty! - */ - dirty = state->active & ~state->emitted; - - if (dirty & I830_UPLOAD_INVARIENT) { - DBG("I830_UPLOAD_INVARIENT:\n"); - i830_emit_invarient_state(intel); - } - - if (dirty & I830_UPLOAD_CTX) { - DBG("I830_UPLOAD_CTX:\n"); - emit(i830, state->Ctx, sizeof(state->Ctx)); - - } - - if (dirty & I830_UPLOAD_BUFFERS) { - DBG("I830_UPLOAD_BUFFERS:\n"); - BEGIN_BATCH(I830_DEST_SETUP_SIZE + 2, 0); - OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]); - OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); - OUT_RELOC(state->draw_region->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - state->draw_region->draw_offset); - - if (state->depth_region) { - OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]); - OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); - OUT_RELOC(state->depth_region->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - state->depth_region->draw_offset); - } - - OUT_BATCH(state->Buffer[I830_DESTREG_DV0]); - OUT_BATCH(state->Buffer[I830_DESTREG_DV1]); - OUT_BATCH(state->Buffer[I830_DESTREG_SENABLE]); - OUT_BATCH(state->Buffer[I830_DESTREG_SR0]); - OUT_BATCH(state->Buffer[I830_DESTREG_SR1]); - OUT_BATCH(state->Buffer[I830_DESTREG_SR2]); - ADVANCE_BATCH(); - } - - if (dirty & I830_UPLOAD_STIPPLE) { - DBG("I830_UPLOAD_STIPPLE:\n"); - emit(i830, state->Stipple, sizeof(state->Stipple)); - } - - for (i = 0; i < I830_TEX_UNITS; i++) { - if ((dirty & I830_UPLOAD_TEX(i))) { - DBG("I830_UPLOAD_TEX(%d):\n", i); - - BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, 0); - OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]); - - if (state->tex_buffer[i]) { - OUT_RELOC(state->tex_buffer[i], - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - state->tex_offset[i] | TM0S0_USE_FENCE); - } - else if (state == &i830->meta) { - assert(i == 0); - OUT_BATCH(0); - } - else { - OUT_BATCH(state->tex_offset[i]); - } - - OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); - OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); - OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S3]); - OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]); - OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]); - OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]); - } - - if (dirty & I830_UPLOAD_TEXBLEND(i)) { - DBG("I830_UPLOAD_TEXBLEND(%d): %d words\n", i, - state->TexBlendWordsUsed[i]); - emit(i830, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4); - } - } - - state->emitted |= dirty; -} - -static void -i830_destroy_context(struct intel_context *intel) -{ - GLuint i; - struct i830_context *i830 = i830_context(&intel->ctx); - - for (i = 0; i < I830_TEX_UNITS; i++) { - if (i830->state.tex_buffer[i] != NULL) { - dri_bo_unreference(i830->state.tex_buffer[i]); - i830->state.tex_buffer[i] = NULL; - } - } - - _tnl_free_vertices(&intel->ctx); -} - - -void -i830_state_draw_region(struct intel_context *intel, - struct i830_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - GLuint value; - - ASSERT(state == &i830->state || state == &i830->meta); - - if (state->draw_region != color_region) { - intel_region_release(&state->draw_region); - intel_region_reference(&state->draw_region, color_region); - } - if (state->depth_region != depth_region) { - intel_region_release(&state->depth_region); - intel_region_reference(&state->depth_region, depth_region); - } - - /* - * Set stride/cpp values - */ - if (color_region) { - state->Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - state->Buffer[I830_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(color_region->pitch * color_region->cpp) | - BUF_3D_USE_FENCE); - } - - if (depth_region) { - state->Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - state->Buffer[I830_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | - BUF_3D_USE_FENCE); - } - - /* - * Compute/set I830_DESTREG_DV1 value - */ - value = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | DEPTH_IS_Z); /* .5 */ - - if (color_region && color_region->cpp == 4) { - value |= DV_PF_8888; - } - else { - value |= DV_PF_565; - } - if (depth_region && depth_region->cpp == 4) { - value |= DEPTH_FRMT_24_FIXED_8_OTHER; - } - else { - value |= DEPTH_FRMT_16_FIXED; - } - state->Buffer[I830_DESTREG_DV1] = value; - - I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); - - -} - - -static void -i830_set_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830_state_draw_region(intel, &i830->state, color_region, depth_region); -} - -#if 0 -static void -i830_update_color_z_regions(intelContextPtr intel, - const intelRegion * colorRegion, - const intelRegion * depthRegion) -{ - i830ContextPtr i830 = I830_CONTEXT(intel); - - i830->state.Buffer[I830_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | - BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset; - - i830->state.Buffer[I830_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset; -} -#endif - - -/* This isn't really handled at the moment. - */ -static void -i830_lost_hardware(struct intel_context *intel) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - i830->state.emitted = 0; -} - - - -static GLuint -i830_flush_cmd(void) -{ - return MI_FLUSH | FLUSH_MAP_CACHE; -} - - -static void -i830_assert_not_dirty( struct intel_context *intel ) -{ - struct i830_context *i830 = i830_context(&intel->ctx); - struct i830_hw_state *state = i830->current; - GLuint dirty = state->active & ~state->emitted; - assert(!dirty); -} - - -void -i830InitVtbl(struct i830_context *i830) -{ - i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; - i830->intel.vtbl.destroy = i830_destroy_context; - i830->intel.vtbl.emit_state = i830_emit_state; - i830->intel.vtbl.lost_hardware = i830_lost_hardware; - i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state; - i830->intel.vtbl.set_draw_region = i830_set_draw_region; - i830->intel.vtbl.update_texture_state = i830UpdateTextureState; - i830->intel.vtbl.flush_cmd = i830_flush_cmd; - i830->intel.vtbl.render_start = i830_render_start; - i830->intel.vtbl.render_prevalidate = i830_render_prevalidate; - i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c deleted file mode 100644 index 49e30141e4..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_context.c +++ /dev/null @@ -1,174 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "i915_context.h" -#include "imports.h" -#include "intel_tex.h" -#include "intel_tris.h" -#include "tnl/t_context.h" -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" - -#include "utils.h" -#include "i915_reg.h" - -#include "intel_regions.h" -#include "intel_batchbuffer.h" - -/*************************************** - * Mesa's Driver Functions - ***************************************/ - -static const struct dri_extension i915_extensions[] = { - {"GL_ARB_depth_texture", NULL}, - {"GL_ARB_fragment_program", NULL}, - {"GL_ARB_shadow", NULL}, - {"GL_ARB_texture_env_crossbar", NULL}, - {"GL_ARB_texture_non_power_of_two", NULL}, - {"GL_EXT_shadow_funcs", NULL}, - /* ARB extn won't work if not enabled */ - {"GL_SGIX_depth_texture", NULL}, - {NULL, NULL} -}; - -/* Override intel default. - */ -static void -i915InvalidateState(GLcontext * ctx, GLuint new_state) -{ - _swrast_InvalidateState(ctx, new_state); - _swsetup_InvalidateState(ctx, new_state); - _vbo_InvalidateState(ctx, new_state); - _tnl_InvalidateState(ctx, new_state); - _tnl_invalidate_vertex_state(ctx, new_state); - intel_context(ctx)->NewGLState |= new_state; - - /* Todo: gather state values under which tracked parameters become - * invalidated, add callbacks for things like - * ProgramLocalParameters, etc. - */ - { - struct i915_fragment_program *p = - (struct i915_fragment_program *) ctx->FragmentProgram._Current; - if (p && p->nr_params) - p->params_uptodate = 0; - } - - if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM)) - i915_update_fog(ctx); -} - - -static void -i915InitDriverFunctions(struct dd_function_table *functions) -{ - intelInitDriverFunctions(functions); - i915InitStateFunctions(functions); - i915InitTextureFuncs(functions); - i915InitFragProgFuncs(functions); - functions->UpdateState = i915InvalidateState; -} - - - -GLboolean -i915CreateContext(const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - struct dd_function_table functions; - struct i915_context *i915 = - (struct i915_context *) CALLOC_STRUCT(i915_context); - struct intel_context *intel = &i915->intel; - GLcontext *ctx = &intel->ctx; - - if (!i915) - return GL_FALSE; - - if (0) - _mesa_printf("\ntexmem-0-3 branch\n\n"); - - i915InitVtbl(i915); - i915InitMetaFuncs(i915); - - i915InitDriverFunctions(&functions); - - if (!intelInitContext(intel, mesaVis, driContextPriv, - sharedContextPrivate, &functions)) { - FREE(i915); - return GL_FALSE; - } - - ctx->Const.MaxTextureUnits = I915_TEX_UNITS; - ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS; - ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS; - - - /* Advertise the full hardware capabilities. The new memory - * manager should cope much better with overload situations: - */ - ctx->Const.MaxTextureLevels = 12; - ctx->Const.Max3DTextureLevels = 9; - ctx->Const.MaxCubeTextureLevels = 12; - ctx->Const.MaxTextureRectSize = (1 << 11); - ctx->Const.MaxTextureUnits = I915_TEX_UNITS; - - /* GL_ARB_fragment_program limits - don't think Mesa actually - * validates programs against these, and in any case one ARB - * instruction can translate to more than one HW instruction, so - * we'll still have to check and fallback each time. - */ - ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY; - ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */ - ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT; - ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN; - ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN; - ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN + - I915_MAX_TEX_INSN); - ctx->Const.FragmentProgram.MaxNativeTexIndirections = - I915_MAX_TEX_INDIRECT; - ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ - - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; - - driInitExtensions(ctx, i915_extensions, GL_FALSE); - - - _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, - 36 * sizeof(GLfloat)); - - intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; - - i915InitState(i915); - - return GL_TRUE; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h deleted file mode 100644 index 0be2b3cc8b..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ /dev/null @@ -1,360 +0,0 @@ - /************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef I915CONTEXT_INC -#define I915CONTEXT_INC - -#include "intel_context.h" - -#define I915_FALLBACK_TEXTURE 0x1000 -#define I915_FALLBACK_COLORMASK 0x2000 -#define I915_FALLBACK_STENCIL 0x4000 -#define I915_FALLBACK_STIPPLE 0x8000 -#define I915_FALLBACK_PROGRAM 0x10000 -#define I915_FALLBACK_LOGICOP 0x20000 -#define I915_FALLBACK_POLYGON_SMOOTH 0x40000 -#define I915_FALLBACK_POINT_SMOOTH 0x80000 - -#define I915_UPLOAD_CTX 0x1 -#define I915_UPLOAD_BUFFERS 0x2 -#define I915_UPLOAD_STIPPLE 0x4 -#define I915_UPLOAD_PROGRAM 0x8 -#define I915_UPLOAD_CONSTANTS 0x10 -#define I915_UPLOAD_FOG 0x20 -#define I915_UPLOAD_INVARIENT 0x40 -#define I915_UPLOAD_DEFAULTS 0x80 -#define I915_UPLOAD_TEX(i) (0x00010000<<(i)) -#define I915_UPLOAD_TEX_ALL (0x00ff0000) -#define I915_UPLOAD_TEX_0_SHIFT 16 - - -/* State structure offsets - these will probably disappear. - */ -#define I915_DESTREG_CBUFADDR0 0 -#define I915_DESTREG_CBUFADDR1 1 -#define I915_DESTREG_DBUFADDR0 3 -#define I915_DESTREG_DBUFADDR1 4 -#define I915_DESTREG_DV0 6 -#define I915_DESTREG_DV1 7 -#define I915_DESTREG_SENABLE 8 -#define I915_DESTREG_SR0 9 -#define I915_DESTREG_SR1 10 -#define I915_DESTREG_SR2 11 -#define I915_DEST_SETUP_SIZE 12 - -#define I915_CTXREG_STATE4 0 -#define I915_CTXREG_LI 1 -#define I915_CTXREG_LIS2 2 -#define I915_CTXREG_LIS4 3 -#define I915_CTXREG_LIS5 4 -#define I915_CTXREG_LIS6 5 -#define I915_CTXREG_IAB 6 -#define I915_CTXREG_BLENDCOLOR0 7 -#define I915_CTXREG_BLENDCOLOR1 8 -#define I915_CTX_SETUP_SIZE 9 - -#define I915_FOGREG_COLOR 0 -#define I915_FOGREG_MODE0 1 -#define I915_FOGREG_MODE1 2 -#define I915_FOGREG_MODE2 3 -#define I915_FOGREG_MODE3 4 -#define I915_FOG_SETUP_SIZE 5 - -#define I915_STPREG_ST0 0 -#define I915_STPREG_ST1 1 -#define I915_STP_SETUP_SIZE 2 - -#define I915_TEXREG_MS3 1 -#define I915_TEXREG_MS4 2 -#define I915_TEXREG_SS2 3 -#define I915_TEXREG_SS3 4 -#define I915_TEXREG_SS4 5 -#define I915_TEX_SETUP_SIZE 6 - -#define I915_DEFREG_C0 0 -#define I915_DEFREG_C1 1 -#define I915_DEFREG_S0 2 -#define I915_DEFREG_S1 3 -#define I915_DEFREG_Z0 4 -#define I915_DEFREG_Z1 5 -#define I915_DEF_SETUP_SIZE 6 - - -#define I915_MAX_CONSTANT 32 -#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) - - -#define I915_PROGRAM_SIZE 192 - - -/* Hardware version of a parsed fragment program. "Derived" from the - * mesa fragment_program struct. - */ -struct i915_fragment_program -{ - struct gl_fragment_program FragProg; - - GLboolean translated; - GLboolean params_uptodate; - GLboolean on_hardware; - GLboolean error; /* If program is malformed for any reason. */ - - GLuint nr_tex_indirect; - GLuint nr_tex_insn; - GLuint nr_alu_insn; - GLuint nr_decl_insn; - - - - - /* TODO: split between the stored representation of a program and - * the state used to build that representation. - */ - GLcontext *ctx; - - GLuint declarations[I915_PROGRAM_SIZE]; - GLuint program[I915_PROGRAM_SIZE]; - - GLfloat constant[I915_MAX_CONSTANT][4]; - GLuint constant_flags[I915_MAX_CONSTANT]; - GLuint nr_constants; - - GLuint *csr; /* Cursor, points into program. - */ - - GLuint *decl; /* Cursor, points into declarations. - */ - - GLuint decl_s; /* flags for which s regs need to be decl'd */ - GLuint decl_t; /* flags for which t regs need to be decl'd */ - - GLuint temp_flag; /* Tracks temporary regs which are in - * use. - */ - - GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in - * use. - */ - - - - /* Helpers for i915_fragprog.c: - */ - GLuint wpos_tex; - GLboolean depth_written; - - struct - { - GLuint reg; /* Hardware constant idx */ - const GLfloat *values; /* Pointer to tracked values */ - } param[I915_MAX_CONSTANT]; - GLuint nr_params; - - - /* Helpers for i915_texprog.c: - */ - GLuint src_texture; /* Reg containing sampled texture color, - * else UREG_BAD. - */ - - GLuint src_previous; /* Reg containing color from previous - * stage. May need to be decl'd. - */ - - GLuint last_tex_stage; /* Number of last enabled texture unit */ - - struct vertex_buffer *VB; -}; - - - - - - - -#define I915_TEX_UNITS 8 - - -struct i915_hw_state -{ - GLuint Ctx[I915_CTX_SETUP_SIZE]; - GLuint Buffer[I915_DEST_SETUP_SIZE]; - GLuint Stipple[I915_STP_SETUP_SIZE]; - GLuint Fog[I915_FOG_SETUP_SIZE]; - GLuint Defaults[I915_DEF_SETUP_SIZE]; - GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; - GLuint Constant[I915_CONSTANT_SIZE]; - GLuint ConstantSize; - GLuint Program[I915_PROGRAM_SIZE]; - GLuint ProgramSize; - - /* Region pointers for relocation: - */ - struct intel_region *draw_region; - struct intel_region *depth_region; -/* struct intel_region *tex_region[I915_TEX_UNITS]; */ - - /* Regions aren't actually that appropriate here as the memory may - * be from a PBO or FBO. Will have to do this for draw and depth for - * FBO's... - */ - dri_bo *tex_buffer[I915_TEX_UNITS]; - GLuint tex_offset[I915_TEX_UNITS]; - - - GLuint active; /* I915_UPLOAD_* */ - GLuint emitted; /* I915_UPLOAD_* */ -}; - -#define I915_FOG_PIXEL 2 -#define I915_FOG_VERTEX 1 -#define I915_FOG_NONE 0 - -struct i915_context -{ - struct intel_context intel; - - GLuint last_ReallyEnabled; - GLuint vertex_fog; - GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; - - - struct i915_fragment_program *current_program; - - struct i915_hw_state meta, initial, state, *current; -}; - - -#define I915_STATECHANGE(i915, flag) \ -do { \ - INTEL_FIREVERTICES( &(i915)->intel ); \ - (i915)->state.emitted &= ~(flag); \ -} while (0) - -#define I915_ACTIVESTATE(i915, flag, mode) \ -do { \ - INTEL_FIREVERTICES( &(i915)->intel ); \ - if (mode) \ - (i915)->state.active |= (flag); \ - else \ - (i915)->state.active &= ~(flag); \ -} while (0) - - -/*====================================================================== - * i915_vtbl.c - */ -extern void i915InitVtbl(struct i915_context *i915); - -extern void -i915_state_draw_region(struct intel_context *intel, - struct i915_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region); - - - -#define SZ_TO_HW(sz) ((sz-2)&0x3) -#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) -#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ - intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ - s4 |= S4; \ - intel->vertex_attr_count++; \ - offset += (SZ); \ -} while (0) - -#define EMIT_PAD( N ) \ -do { \ - intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ - intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ - intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ - intel->vertex_attr_count++; \ - offset += (N); \ -} while (0) - - - -/*====================================================================== - * i915_context.c - */ -extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - - -/*====================================================================== - * i915_debug.c - */ -extern void i915_disassemble_program(const GLuint * program, GLuint sz); -extern void i915_print_ureg(const char *msg, GLuint ureg); - - -/*====================================================================== - * i915_state.c - */ -extern void i915InitStateFunctions(struct dd_function_table *functions); -extern void i915InitState(struct i915_context *i915); -extern void i915_update_fog(GLcontext * ctx); - - -/*====================================================================== - * i915_tex.c - */ -extern void i915UpdateTextureState(struct intel_context *intel); -extern void i915InitTextureFuncs(struct dd_function_table *functions); - -/*====================================================================== - * i915_metaops.c - */ -void i915InitMetaFuncs(struct i915_context *i915); - - -/*====================================================================== - * i915_fragprog.c - */ -extern void i915ValidateFragmentProgram(struct i915_context *i915); -extern void i915InitFragProgFuncs(struct dd_function_table *functions); - -/*====================================================================== - * Inline conversion functions. These are better-typed than the - * macros used previously: - */ -static INLINE struct i915_context * -i915_context(GLcontext * ctx) -{ - return (struct i915_context *) ctx; -} - - - -#define I915_CONTEXT(ctx) i915_context(ctx) - - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_debug.c deleted file mode 100644 index c0e1242a0e..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_debug.c +++ /dev/null @@ -1,843 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "imports.h" - -#include "i915_reg.h" -#include "i915_context.h" -#include "i915_debug.h" - -#define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) - -static GLboolean debug( struct debug_stream *stream, const char *name, GLuint len ) -{ - GLuint i; - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - - if (len == 0) { - PRINTF("Error - zero length packet (0x%08x)\n", stream->ptr[0]); - assert(0); - return GL_FALSE; - } - - if (stream->print_addresses) - PRINTF("%08x: ", stream->offset); - - - PRINTF("%s (%d dwords):\n", name, len); - for (i = 0; i < len; i++) - PRINTF("\t0x%08x\n", ptr[i]); - PRINTF("\n"); - - stream->offset += len * sizeof(GLuint); - - return GL_TRUE; -} - - -static const char *get_prim_name( GLuint val ) -{ - switch (val & PRIM3D_MASK) { - case PRIM3D_TRILIST: return "TRILIST"; break; - case PRIM3D_TRISTRIP: return "TRISTRIP"; break; - case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break; - case PRIM3D_TRIFAN: return "TRIFAN"; break; - case PRIM3D_POLY: return "POLY"; break; - case PRIM3D_LINELIST: return "LINELIST"; break; - case PRIM3D_LINESTRIP: return "LINESTRIP"; break; - case PRIM3D_RECTLIST: return "RECTLIST"; break; - case PRIM3D_POINTLIST: return "POINTLIST"; break; - case PRIM3D_DIB: return "DIB"; break; - case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break; - case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break; - default: return "????"; break; - } -} - -static GLboolean debug_prim( struct debug_stream *stream, const char *name, - GLboolean dump_floats, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - const char *prim = get_prim_name( ptr[0] ); - GLuint i; - - - - PRINTF("%s %s (%d dwords):\n", name, prim, len); - PRINTF("\t0x%08x\n", ptr[0]); - for (i = 1; i < len; i++) { - if (dump_floats) - PRINTF("\t0x%08x // %f\n", ptr[i], *(GLfloat *)&ptr[i]); - else - PRINTF("\t0x%08x\n", ptr[i]); - } - - - PRINTF("\n"); - - stream->offset += len * sizeof(GLuint); - - return GL_TRUE; -} - - - - -static GLboolean debug_program( struct debug_stream *stream, const char *name, GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - - if (len == 0) { - PRINTF("Error - zero length packet (0x%08x)\n", stream->ptr[0]); - assert(0); - return GL_FALSE; - } - - if (stream->print_addresses) - PRINTF("%08x: ", stream->offset); - - PRINTF("%s (%d dwords):\n", name, len); - i915_disassemble_program( ptr, len ); - - stream->offset += len * sizeof(GLuint); - return GL_TRUE; -} - - -static GLboolean debug_chain( struct debug_stream *stream, const char *name, GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - GLuint old_offset = stream->offset + len * sizeof(GLuint); - GLuint i; - - PRINTF("%s (%d dwords):\n", name, len); - for (i = 0; i < len; i++) - PRINTF("\t0x%08x\n", ptr[i]); - - stream->offset = ptr[1] & ~0x3; - - if (stream->offset < old_offset) - PRINTF("\n... skipping backwards from 0x%x --> 0x%x ...\n\n", - old_offset, stream->offset ); - else - PRINTF("\n... skipping from 0x%x --> 0x%x ...\n\n", - old_offset, stream->offset ); - - - return GL_TRUE; -} - - -static GLboolean debug_variable_length_prim( struct debug_stream *stream ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - const char *prim = get_prim_name( ptr[0] ); - GLuint i, len; - - GLushort *idx = (GLushort *)(ptr+1); - for (i = 0; idx[i] != 0xffff; i++) - ; - - len = 1+(i+2)/2; - - PRINTF("3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); - for (i = 0; i < len; i++) - PRINTF("\t0x%08x\n", ptr[i]); - PRINTF("\n"); - - stream->offset += len * sizeof(GLuint); - return GL_TRUE; -} - - -#define BITS( dw, hi, lo, ... ) \ -do { \ - unsigned himask = ~0UL >> (31 - (hi)); \ - PRINTF("\t\t "); \ - PRINTF(__VA_ARGS__); \ - PRINTF(": 0x%x\n", ((dw) & himask) >> (lo)); \ -} while (0) - -#define MBZ( dw, hi, lo) do { \ - unsigned x = (dw) >> (lo); \ - unsigned lomask = (1 << (lo)) - 1; \ - unsigned himask; \ - himask = (1UL << (hi)) - 1; \ - assert ((x & himask & ~lomask) == 0); \ -} while (0) - -#define FLAG( dw, bit, ... ) \ -do { \ - if (((dw) >> (bit)) & 1) { \ - PRINTF("\t\t "); \ - PRINTF(__VA_ARGS__); \ - PRINTF("\n"); \ - } \ -} while (0) - -static GLboolean debug_load_immediate( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - GLuint bits = (ptr[0] >> 4) & 0xff; - GLuint j = 0; - - PRINTF("%s (%d dwords, flags: %x):\n", name, len, bits); - PRINTF("\t0x%08x\n", ptr[j++]); - - if (bits & (1<<0)) { - PRINTF("\t LIS0: 0x%08x\n", ptr[j]); - PRINTF("\t vb address: 0x%08x\n", (ptr[j] & ~0x3)); - BITS(ptr[j], 0, 0, "vb invalidate disable"); - j++; - } - if (bits & (1<<1)) { - PRINTF("\t LIS1: 0x%08x\n", ptr[j]); - BITS(ptr[j], 29, 24, "vb dword width"); - BITS(ptr[j], 21, 16, "vb dword pitch"); - BITS(ptr[j], 15, 0, "vb max index"); - j++; - } - if (bits & (1<<2)) { - int i; - PRINTF("\t LIS2: 0x%08x\n", ptr[j]); - for (i = 0; i < 8; i++) { - unsigned tc = (ptr[j] >> (i * 4)) & 0xf; - if (tc != 0xf) - BITS(tc, 3, 0, "tex coord %d", i); - } - j++; - } - if (bits & (1<<3)) { - PRINTF("\t LIS3: 0x%08x\n", ptr[j]); - j++; - } - if (bits & (1<<4)) { - PRINTF("\t LIS4: 0x%08x\n", ptr[j]); - BITS(ptr[j], 31, 23, "point width"); - BITS(ptr[j], 22, 19, "line width"); - FLAG(ptr[j], 18, "alpha flatshade"); - FLAG(ptr[j], 17, "fog flatshade"); - FLAG(ptr[j], 16, "spec flatshade"); - FLAG(ptr[j], 15, "rgb flatshade"); - BITS(ptr[j], 14, 13, "cull mode"); - FLAG(ptr[j], 12, "vfmt: point width"); - FLAG(ptr[j], 11, "vfmt: specular/fog"); - FLAG(ptr[j], 10, "vfmt: rgba"); - FLAG(ptr[j], 9, "vfmt: depth offset"); - BITS(ptr[j], 8, 6, "vfmt: position (2==xyzw)"); - FLAG(ptr[j], 5, "force dflt diffuse"); - FLAG(ptr[j], 4, "force dflt specular"); - FLAG(ptr[j], 3, "local depth offset enable"); - FLAG(ptr[j], 2, "vfmt: fp32 fog coord"); - FLAG(ptr[j], 1, "sprite point"); - FLAG(ptr[j], 0, "antialiasing"); - j++; - } - if (bits & (1<<5)) { - PRINTF("\t LIS5: 0x%08x\n", ptr[j]); - BITS(ptr[j], 31, 28, "rgba write disables"); - FLAG(ptr[j], 27, "force dflt point width"); - FLAG(ptr[j], 26, "last pixel enable"); - FLAG(ptr[j], 25, "global z offset enable"); - FLAG(ptr[j], 24, "fog enable"); - BITS(ptr[j], 23, 16, "stencil ref"); - BITS(ptr[j], 15, 13, "stencil test"); - BITS(ptr[j], 12, 10, "stencil fail op"); - BITS(ptr[j], 9, 7, "stencil pass z fail op"); - BITS(ptr[j], 6, 4, "stencil pass z pass op"); - FLAG(ptr[j], 3, "stencil write enable"); - FLAG(ptr[j], 2, "stencil test enable"); - FLAG(ptr[j], 1, "color dither enable"); - FLAG(ptr[j], 0, "logiop enable"); - j++; - } - if (bits & (1<<6)) { - PRINTF("\t LIS6: 0x%08x\n", ptr[j]); - FLAG(ptr[j], 31, "alpha test enable"); - BITS(ptr[j], 30, 28, "alpha func"); - BITS(ptr[j], 27, 20, "alpha ref"); - FLAG(ptr[j], 19, "depth test enable"); - BITS(ptr[j], 18, 16, "depth func"); - FLAG(ptr[j], 15, "blend enable"); - BITS(ptr[j], 14, 12, "blend func"); - BITS(ptr[j], 11, 8, "blend src factor"); - BITS(ptr[j], 7, 4, "blend dst factor"); - FLAG(ptr[j], 3, "depth write enable"); - FLAG(ptr[j], 2, "color write enable"); - BITS(ptr[j], 1, 0, "provoking vertex"); - j++; - } - - - PRINTF("\n"); - - assert(j == len); - - stream->offset += len * sizeof(GLuint); - - return GL_TRUE; -} - - - -static GLboolean debug_load_indirect( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - GLuint bits = (ptr[0] >> 8) & 0x3f; - GLuint i, j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j++]); - - for (i = 0; i < 6; i++) { - if (bits & (1<offset += len * sizeof(GLuint); - - return GL_TRUE; -} - -static void BR13( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x\n", val); - FLAG(val, 30, "clipping enable"); - BITS(val, 25, 24, "color depth (3==32bpp)"); - BITS(val, 23, 16, "raster op"); - BITS(val, 15, 0, "dest pitch"); -} - - -static void BR22( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x\n", val); - BITS(val, 31, 16, "dest y1"); - BITS(val, 15, 0, "dest x1"); -} - -static void BR23( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x\n", val); - BITS(val, 31, 16, "dest y2"); - BITS(val, 15, 0, "dest x2"); -} - -static void BR09( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x -- dest address\n", val); -} - -static void BR26( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x\n", val); - BITS(val, 31, 16, "src y1"); - BITS(val, 15, 0, "src x1"); -} - -static void BR11( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x\n", val); - BITS(val, 15, 0, "src pitch"); -} - -static void BR12( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x -- src address\n", val); -} - -static void BR16( struct debug_stream *stream, - GLuint val ) -{ - PRINTF("\t0x%08x -- color\n", val); -} - -static GLboolean debug_copy_blit( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - int j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j++]); - - BR13(stream, ptr[j++]); - BR22(stream, ptr[j++]); - BR23(stream, ptr[j++]); - BR09(stream, ptr[j++]); - BR26(stream, ptr[j++]); - BR11(stream, ptr[j++]); - BR12(stream, ptr[j++]); - - stream->offset += len * sizeof(GLuint); - assert(j == len); - return GL_TRUE; -} - -static GLboolean debug_color_blit( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - int j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j++]); - - BR13(stream, ptr[j++]); - BR22(stream, ptr[j++]); - BR23(stream, ptr[j++]); - BR09(stream, ptr[j++]); - BR16(stream, ptr[j++]); - - stream->offset += len * sizeof(GLuint); - assert(j == len); - return GL_TRUE; -} - -static GLboolean debug_modes4( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - int j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j]); - BITS(ptr[j], 21, 18, "logicop func"); - FLAG(ptr[j], 17, "stencil test mask modify-enable"); - FLAG(ptr[j], 16, "stencil write mask modify-enable"); - BITS(ptr[j], 15, 8, "stencil test mask"); - BITS(ptr[j], 7, 0, "stencil write mask"); - j++; - - stream->offset += len * sizeof(GLuint); - assert(j == len); - return GL_TRUE; -} - -static GLboolean debug_map_state( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - int j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j++]); - - { - PRINTF("\t0x%08x\n", ptr[j]); - BITS(ptr[j], 15, 0, "map mask"); - j++; - } - - while (j < len) { - { - PRINTF("\t TMn.0: 0x%08x\n", ptr[j]); - PRINTF("\t map address: 0x%08x\n", (ptr[j] & ~0x3)); - FLAG(ptr[j], 1, "vertical line stride"); - FLAG(ptr[j], 0, "vertical line stride offset"); - j++; - } - - { - PRINTF("\t TMn.1: 0x%08x\n", ptr[j]); - BITS(ptr[j], 31, 21, "height"); - BITS(ptr[j], 20, 10, "width"); - BITS(ptr[j], 9, 7, "surface format"); - BITS(ptr[j], 6, 3, "texel format"); - FLAG(ptr[j], 2, "use fence regs"); - FLAG(ptr[j], 1, "tiled surface"); - FLAG(ptr[j], 0, "tile walk ymajor"); - j++; - } - { - PRINTF("\t TMn.2: 0x%08x\n", ptr[j]); - BITS(ptr[j], 31, 21, "dword pitch"); - BITS(ptr[j], 20, 15, "cube face enables"); - BITS(ptr[j], 14, 9, "max lod"); - FLAG(ptr[j], 8, "mip layout right"); - BITS(ptr[j], 7, 0, "depth"); - j++; - } - } - - stream->offset += len * sizeof(GLuint); - assert(j == len); - return GL_TRUE; -} - -static GLboolean debug_sampler_state( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - int j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j++]); - - { - PRINTF("\t0x%08x\n", ptr[j]); - BITS(ptr[j], 15, 0, "sampler mask"); - j++; - } - - while (j < len) { - { - PRINTF("\t TSn.0: 0x%08x\n", ptr[j]); - FLAG(ptr[j], 31, "reverse gamma"); - FLAG(ptr[j], 30, "planar to packed"); - FLAG(ptr[j], 29, "yuv->rgb"); - BITS(ptr[j], 28, 27, "chromakey index"); - BITS(ptr[j], 26, 22, "base mip level"); - BITS(ptr[j], 21, 20, "mip mode filter"); - BITS(ptr[j], 19, 17, "mag mode filter"); - BITS(ptr[j], 16, 14, "min mode filter"); - BITS(ptr[j], 13, 5, "lod bias (s4.4)"); - FLAG(ptr[j], 4, "shadow enable"); - FLAG(ptr[j], 3, "max-aniso-4"); - BITS(ptr[j], 2, 0, "shadow func"); - j++; - } - - { - PRINTF("\t TSn.1: 0x%08x\n", ptr[j]); - BITS(ptr[j], 31, 24, "min lod"); - MBZ( ptr[j], 23, 18 ); - FLAG(ptr[j], 17, "kill pixel enable"); - FLAG(ptr[j], 16, "keyed tex filter mode"); - FLAG(ptr[j], 15, "chromakey enable"); - BITS(ptr[j], 14, 12, "tcx wrap mode"); - BITS(ptr[j], 11, 9, "tcy wrap mode"); - BITS(ptr[j], 8, 6, "tcz wrap mode"); - FLAG(ptr[j], 5, "normalized coords"); - BITS(ptr[j], 4, 1, "map (surface) index"); - FLAG(ptr[j], 0, "EAST deinterlacer enable"); - j++; - } - { - PRINTF("\t TSn.2: 0x%08x (default color)\n", ptr[j]); - j++; - } - } - - stream->offset += len * sizeof(GLuint); - assert(j == len); - return GL_TRUE; -} - -static GLboolean debug_dest_vars( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - int j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j++]); - - { - PRINTF("\t0x%08x\n", ptr[j]); - FLAG(ptr[j], 31, "early classic ztest"); - FLAG(ptr[j], 30, "opengl tex default color"); - FLAG(ptr[j], 29, "bypass iz"); - FLAG(ptr[j], 28, "lod preclamp"); - BITS(ptr[j], 27, 26, "dither pattern"); - FLAG(ptr[j], 25, "linear gamma blend"); - FLAG(ptr[j], 24, "debug dither"); - BITS(ptr[j], 23, 20, "dstorg x"); - BITS(ptr[j], 19, 16, "dstorg y"); - MBZ (ptr[j], 15, 15 ); - BITS(ptr[j], 14, 12, "422 write select"); - BITS(ptr[j], 11, 8, "cbuf format"); - BITS(ptr[j], 3, 2, "zbuf format"); - FLAG(ptr[j], 1, "vert line stride"); - FLAG(ptr[j], 1, "vert line stride offset"); - j++; - } - - stream->offset += len * sizeof(GLuint); - assert(j == len); - return GL_TRUE; -} - -static GLboolean debug_buf_info( struct debug_stream *stream, - const char *name, - GLuint len ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - int j = 0; - - PRINTF("%s (%d dwords):\n", name, len); - PRINTF("\t0x%08x\n", ptr[j++]); - - { - PRINTF("\t0x%08x\n", ptr[j]); - BITS(ptr[j], 28, 28, "aux buffer id"); - BITS(ptr[j], 27, 24, "buffer id (7=depth, 3=back)"); - FLAG(ptr[j], 23, "use fence regs"); - FLAG(ptr[j], 22, "tiled surface"); - FLAG(ptr[j], 21, "tile walk ymajor"); - MBZ (ptr[j], 20, 14); - BITS(ptr[j], 13, 2, "dword pitch"); - MBZ (ptr[j], 2, 0); - j++; - } - - PRINTF("\t0x%08x -- buffer base address\n", ptr[j++]); - - stream->offset += len * sizeof(GLuint); - assert(j == len); - return GL_TRUE; -} - -static GLboolean i915_debug_packet( struct debug_stream *stream ) -{ - GLuint *ptr = (GLuint *)(stream->ptr + stream->offset); - GLuint cmd = *ptr; - - switch (((cmd >> 29) & 0x7)) { - case 0x0: - switch ((cmd >> 23) & 0x3f) { - case 0x0: - return debug(stream, "MI_NOOP", 1); - case 0x3: - return debug(stream, "MI_WAIT_FOR_EVENT", 1); - case 0x4: - return debug(stream, "MI_FLUSH", 1); - case 0xA: - debug(stream, "MI_BATCH_BUFFER_END", 1); - return GL_FALSE; - case 0x22: - return debug(stream, "MI_LOAD_REGISTER_IMM", 3); - case 0x31: - return debug_chain(stream, "MI_BATCH_BUFFER_START", 2); - default: - break; - } - break; - case 0x1: - break; - case 0x2: - switch ((cmd >> 22) & 0xff) { - case 0x50: - return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); - case 0x53: - return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); - default: - return debug(stream, "blit command", (cmd & 0xff) + 2); - } - break; - case 0x3: - switch ((cmd >> 24) & 0x1f) { - case 0x6: - return debug(stream, "3DSTATE_ANTI_ALIASING", 1); - case 0x7: - return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1); - case 0x8: - return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2); - case 0x9: - return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1); - case 0xb: - return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1); - case 0xc: - return debug(stream, "3DSTATE_MODES5", 1); - case 0xd: - return debug_modes4(stream, "3DSTATE_MODES4", 1); - case 0x15: - return debug(stream, "3DSTATE_FOG_COLOR", 1); - case 0x16: - return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1); - case 0x1c: - /* 3DState16NP */ - switch((cmd >> 19) & 0x1f) { - case 0x10: - return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1); - case 0x11: - return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1); - default: - break; - } - break; - case 0x1d: - /* 3DStateMW */ - switch ((cmd >> 16) & 0xff) { - case 0x0: - return debug_map_state(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); - case 0x1: - return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); - case 0x4: - return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2); - case 0x5: - return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2); - case 0x6: - return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2); - case 0x7: - return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2); - case 0x80: - return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2); - case 0x81: - return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2); - case 0x83: - return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2); - case 0x85: - return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); - case 0x88: - return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2); - case 0x89: - return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2); - case 0x8e: - return debug_buf_info(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); - case 0x97: - return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2); - case 0x98: - return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2); - case 0x99: - return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2); - case 0x9a: - return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2); - case 0x9c: - return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2); - default: - assert(0); - return 0; - } - break; - case 0x1e: - if (cmd & (1 << 23)) - return debug(stream, "???", (cmd & 0xffff) + 1); - else - return debug(stream, "", 1); - break; - case 0x1f: - if ((cmd & (1 << 23)) == 0) - return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2); - else if (cmd & (1 << 17)) - { - if ((cmd & 0xffff) == 0) - return debug_variable_length_prim(stream); - else - return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1); - } - else - return debug_prim(stream, "3DPRIM (indirect sequential)", 0, 2); - break; - default: - return debug(stream, "", 0); - } - default: - assert(0); - return 0; - } - - assert(0); - return 0; -} - - - -void -i915_dump_batchbuffer( GLuint *start, - GLuint *end ) -{ - struct debug_stream stream; - GLuint bytes = (end - start) * 4; - GLboolean done = GL_FALSE; - - PRINTF("\n\nBATCH: (%d)\n", bytes / 4); - - stream.offset = 0; - stream.ptr = (char *)start; - stream.print_addresses = 0; - - while (!done && - stream.offset < bytes && - stream.offset >= 0) - { - if (!i915_debug_packet( &stream )) - break; - - assert(stream.offset <= bytes && - stream.offset >= 0); - } - - PRINTF("END-BATCH\n\n\n"); -} - - diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.h b/src/mesa/drivers/dri/i915tex/i915_debug.h deleted file mode 100644 index 0643a8c631..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_debug.h +++ /dev/null @@ -1,55 +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 - */ - -#ifndef I915_DEBUG_H -#define I915_DEBUG_H - -struct i915_context; - -struct debug_stream -{ - unsigned offset; /* current gtt offset */ - char *ptr; /* pointer to gtt offset zero */ - char *end; /* pointer to gtt offset zero */ - unsigned print_addresses; -}; - - - -extern void i915_disassemble_program(const unsigned *program, unsigned sz); -extern void i915_print_ureg(const char *msg, unsigned ureg); - - -void -i915_dump_batchbuffer( unsigned *start, - unsigned *end ); - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_debug_fp.c b/src/mesa/drivers/dri/i915tex/i915_debug_fp.c deleted file mode 100644 index 84347a01ef..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_debug_fp.c +++ /dev/null @@ -1,333 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include - -#include "i915_reg.h" -#include "i915_debug.h" -#include "main/imports.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_print.h" - -#define PRINTF( ... ) _mesa_printf( __VA_ARGS__ ) - -static const char *opcodes[0x20] = { - "NOP", - "ADD", - "MOV", - "MUL", - "MAD", - "DP2ADD", - "DP3", - "DP4", - "FRC", - "RCP", - "RSQ", - "EXP", - "LOG", - "CMP", - "MIN", - "MAX", - "FLR", - "MOD", - "TRC", - "SGE", - "SLT", - "TEXLD", - "TEXLDP", - "TEXLDB", - "TEXKILL", - "DCL", - "0x1a", - "0x1b", - "0x1c", - "0x1d", - "0x1e", - "0x1f", -}; - - -static const int args[0x20] = { - 0, /* 0 nop */ - 2, /* 1 add */ - 1, /* 2 mov */ - 2, /* 3 m ul */ - 3, /* 4 mad */ - 3, /* 5 dp2add */ - 2, /* 6 dp3 */ - 2, /* 7 dp4 */ - 1, /* 8 frc */ - 1, /* 9 rcp */ - 1, /* a rsq */ - 1, /* b exp */ - 1, /* c log */ - 3, /* d cmp */ - 2, /* e min */ - 2, /* f max */ - 1, /* 10 flr */ - 1, /* 11 mod */ - 1, /* 12 trc */ - 2, /* 13 sge */ - 2, /* 14 slt */ - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - - -static const char *regname[0x8] = { - "R", - "T", - "CONST", - "S", - "OC", - "OD", - "U", - "UNKNOWN", -}; - -static void -print_reg_type_nr(GLuint type, GLuint nr) -{ - switch (type) { - case REG_TYPE_T: - switch (nr) { - case T_DIFFUSE: - PRINTF("T_DIFFUSE"); - return; - case T_SPECULAR: - PRINTF("T_SPECULAR"); - return; - case T_FOG_W: - PRINTF("T_FOG_W"); - return; - default: - PRINTF("T_TEX%d", nr); - return; - } - case REG_TYPE_OC: - if (nr == 0) { - PRINTF("oC"); - return; - } - break; - case REG_TYPE_OD: - if (nr == 0) { - PRINTF("oD"); - return; - } - break; - default: - break; - } - - PRINTF("%s[%d]", regname[type], nr); -} - -#define REG_SWIZZLE_MASK 0x7777 -#define REG_NEGATE_MASK 0x8888 - -#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ - (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ - (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ - (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) - - -static void -print_reg_neg_swizzle(GLuint reg) -{ - int i; - - if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && - (reg & REG_NEGATE_MASK) == 0) - return; - - PRINTF("."); - - for (i = 3; i >= 0; i--) { - if (reg & (1 << ((i * 4) + 3))) - PRINTF("-"); - - switch ((reg >> (i * 4)) & 0x7) { - case 0: - PRINTF("x"); - break; - case 1: - PRINTF("y"); - break; - case 2: - PRINTF("z"); - break; - case 3: - PRINTF("w"); - break; - case 4: - PRINTF("0"); - break; - case 5: - PRINTF("1"); - break; - default: - PRINTF("?"); - break; - } - } -} - - -static void -print_src_reg(GLuint dword) -{ - GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; - GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; - print_reg_type_nr(type, nr); - print_reg_neg_swizzle(dword); -} - - -static void -print_dest_reg(GLuint dword) -{ - GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; - GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; - print_reg_type_nr(type, nr); - if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) - return; - PRINTF("."); - if (dword & A0_DEST_CHANNEL_X) - PRINTF("x"); - if (dword & A0_DEST_CHANNEL_Y) - PRINTF("y"); - if (dword & A0_DEST_CHANNEL_Z) - PRINTF("z"); - if (dword & A0_DEST_CHANNEL_W) - PRINTF("w"); -} - - -#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) -#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) -#define GET_SRC2_REG(r) (r) - - -static void -print_arith_op(GLuint opcode, const GLuint * program) -{ - if (opcode != A0_NOP) { - print_dest_reg(program[0]); - if (program[0] & A0_DEST_SATURATE) - PRINTF(" = SATURATE "); - else - PRINTF(" = "); - } - - PRINTF("%s ", opcodes[opcode]); - - print_src_reg(GET_SRC0_REG(program[0], program[1])); - if (args[opcode] == 1) { - PRINTF("\n"); - return; - } - - PRINTF(", "); - print_src_reg(GET_SRC1_REG(program[1], program[2])); - if (args[opcode] == 2) { - PRINTF("\n"); - return; - } - - PRINTF(", "); - print_src_reg(GET_SRC2_REG(program[2])); - PRINTF("\n"); - return; -} - - -static void -print_tex_op(GLuint opcode, const GLuint * program) -{ - print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - PRINTF(" = "); - - PRINTF("%s ", opcodes[opcode]); - - PRINTF("S[%d],", program[0] & T0_SAMPLER_NR_MASK); - - print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & - REG_TYPE_MASK, - (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); - PRINTF("\n"); -} - -static void -print_dcl_op(GLuint opcode, const GLuint * program) -{ - PRINTF("%s ", opcodes[opcode]); - print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); - PRINTF("\n"); -} - - -void -i915_disassemble_program(const GLuint * program, GLuint sz) -{ - GLuint size = program[0] & 0x1ff; - GLint i; - - PRINTF("\t\tBEGIN\n"); - - assert(size + 2 == sz); - - program++; - for (i = 1; i < sz; i += 3, program += 3) { - GLuint opcode = program[0] & (0x1f << 24); - - PRINTF("\t\t"); - - if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) - print_arith_op(opcode >> 24, program); - else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) - print_tex_op(opcode >> 24, program); - else if (opcode == D0_DCL) - print_dcl_op(opcode >> 24, program); - else - PRINTF("Unknown opcode 0x%x\n", opcode); - } - - PRINTF("\t\tEND\n\n"); -} - - diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c deleted file mode 100644 index 4c3f2236e5..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c +++ /dev/null @@ -1,1074 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/program.h" -#include "shader/programopt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" - -#include "intel_batchbuffer.h" - -#include "i915_reg.h" -#include "i915_context.h" -#include "i915_program.h" - - - -/* 1, -1/3!, 1/5!, -1/7! */ -static const GLfloat sin_constants[4] = { 1.0, - -1.0 / (3 * 2 * 1), - 1.0 / (5 * 4 * 3 * 2 * 1), - -1.0 / (7 * 6 * 5 * 4 * 3 * 2 * 1) -}; - -/* 1, -1/2!, 1/4!, -1/6! */ -static const GLfloat cos_constants[4] = { 1.0, - -1.0 / (2 * 1), - 1.0 / (4 * 3 * 2 * 1), - -1.0 / (6 * 5 * 4 * 3 * 2 * 1) -}; - -/** - * Retrieve a ureg for the given source register. Will emit - * constants, apply swizzling and negation as needed. - */ -static GLuint -src_vector(struct i915_fragment_program *p, - const struct prog_src_register *source, - const struct gl_fragment_program *program) -{ - GLuint src; - - switch (source->File) { - - /* Registers: - */ - case PROGRAM_TEMPORARY: - if (source->Index >= I915_MAX_TEMPORARY) { - i915_program_error(p, "Exceeded max temporary reg"); - return 0; - } - src = UREG(REG_TYPE_R, source->Index); - break; - case PROGRAM_INPUT: - switch (source->Index) { - case FRAG_ATTRIB_WPOS: - src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); - break; - case FRAG_ATTRIB_COL0: - src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); - break; - case FRAG_ATTRIB_COL1: - src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ); - src = swizzle(src, X, Y, Z, ONE); - break; - case FRAG_ATTRIB_FOGC: - src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W); - src = swizzle(src, W, W, W, W); - break; - case FRAG_ATTRIB_TEX0: - case FRAG_ATTRIB_TEX1: - case FRAG_ATTRIB_TEX2: - case FRAG_ATTRIB_TEX3: - case FRAG_ATTRIB_TEX4: - case FRAG_ATTRIB_TEX5: - case FRAG_ATTRIB_TEX6: - case FRAG_ATTRIB_TEX7: - src = i915_emit_decl(p, REG_TYPE_T, - T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0), - D0_CHANNEL_ALL); - break; - - default: - i915_program_error(p, "Bad source->Index"); - return 0; - } - break; - - /* Various paramters and env values. All emitted to - * hardware as program constants. - */ - case PROGRAM_LOCAL_PARAM: - src = i915_emit_param4fv(p, program->Base.LocalParams[source->Index]); - break; - - case PROGRAM_ENV_PARAM: - src = - i915_emit_param4fv(p, - p->ctx->FragmentProgram.Parameters[source-> - Index]); - break; - - case PROGRAM_CONSTANT: - case PROGRAM_STATE_VAR: - case PROGRAM_NAMED_PARAM: - src = - i915_emit_param4fv(p, - program->Base.Parameters->ParameterValues[source-> - Index]); - break; - - default: - i915_program_error(p, "Bad source->File"); - return 0; - } - - src = swizzle(src, - GET_SWZ(source->Swizzle, 0), - GET_SWZ(source->Swizzle, 1), - GET_SWZ(source->Swizzle, 2), GET_SWZ(source->Swizzle, 3)); - - if (source->NegateBase) - src = negate(src, - GET_BIT(source->NegateBase, 0), - GET_BIT(source->NegateBase, 1), - GET_BIT(source->NegateBase, 2), - GET_BIT(source->NegateBase, 3)); - - return src; -} - - -static GLuint -get_result_vector(struct i915_fragment_program *p, - const struct prog_instruction *inst) -{ - switch (inst->DstReg.File) { - case PROGRAM_OUTPUT: - switch (inst->DstReg.Index) { - case FRAG_RESULT_COLR: - return UREG(REG_TYPE_OC, 0); - case FRAG_RESULT_DEPR: - p->depth_written = 1; - return UREG(REG_TYPE_OD, 0); - default: - i915_program_error(p, "Bad inst->DstReg.Index"); - return 0; - } - case PROGRAM_TEMPORARY: - return UREG(REG_TYPE_R, inst->DstReg.Index); - default: - i915_program_error(p, "Bad inst->DstReg.File"); - return 0; - } -} - -static GLuint -get_result_flags(const struct prog_instruction *inst) -{ - GLuint flags = 0; - - if (inst->SaturateMode == SATURATE_ZERO_ONE) - flags |= A0_DEST_SATURATE; - if (inst->DstReg.WriteMask & WRITEMASK_X) - flags |= A0_DEST_CHANNEL_X; - if (inst->DstReg.WriteMask & WRITEMASK_Y) - flags |= A0_DEST_CHANNEL_Y; - if (inst->DstReg.WriteMask & WRITEMASK_Z) - flags |= A0_DEST_CHANNEL_Z; - if (inst->DstReg.WriteMask & WRITEMASK_W) - flags |= A0_DEST_CHANNEL_W; - - return flags; -} - -static GLuint -translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit) -{ - switch (bit) { - case TEXTURE_1D_INDEX: - return D0_SAMPLE_TYPE_2D; - case TEXTURE_2D_INDEX: - return D0_SAMPLE_TYPE_2D; - case TEXTURE_RECT_INDEX: - return D0_SAMPLE_TYPE_2D; - case TEXTURE_3D_INDEX: - return D0_SAMPLE_TYPE_VOLUME; - case TEXTURE_CUBE_INDEX: - return D0_SAMPLE_TYPE_CUBE; - default: - i915_program_error(p, "TexSrcBit"); - return 0; - } -} - -#define EMIT_TEX( OP ) \ -do { \ - GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget ); \ - GLuint sampler = i915_emit_decl(p, REG_TYPE_S, \ - inst->TexSrcUnit, dim); \ - GLuint coord = src_vector( p, &inst->SrcReg[0], program); \ - /* Texel lookup */ \ - \ - i915_emit_texld( p, \ - get_result_vector( p, inst ), \ - get_result_flags( inst ), \ - sampler, \ - coord, \ - OP); \ -} while (0) - -#define EMIT_ARITH( OP, N ) \ -do { \ - i915_emit_arith( p, \ - OP, \ - get_result_vector( p, inst ), \ - get_result_flags( inst ), 0, \ - (N<1)?0:src_vector( p, &inst->SrcReg[0], program), \ - (N<2)?0:src_vector( p, &inst->SrcReg[1], program), \ - (N<3)?0:src_vector( p, &inst->SrcReg[2], program)); \ -} while (0) - -#define EMIT_1ARG_ARITH( OP ) EMIT_ARITH( OP, 1 ) -#define EMIT_2ARG_ARITH( OP ) EMIT_ARITH( OP, 2 ) -#define EMIT_3ARG_ARITH( OP ) EMIT_ARITH( OP, 3 ) - - -/* Possible concerns: - * - * SIN, COS -- could use another taylor step? - * LIT -- results seem a little different to sw mesa - * LOG -- different to mesa on negative numbers, but this is conformant. - * - * Parse failures -- Mesa doesn't currently give a good indication - * internally whether a particular program string parsed or not. This - * can lead to confusion -- hopefully we cope with it ok now. - * - */ -static void -upload_program(struct i915_fragment_program *p) -{ - const struct gl_fragment_program *program = - p->ctx->FragmentProgram._Current; - const struct prog_instruction *inst = program->Base.Instructions; - -/* _mesa_debug_fp_inst(program->Base.NumInstructions, inst); */ - - /* Is this a parse-failed program? Ensure a valid program is - * loaded, as the flagging of an error isn't sufficient to stop - * this being uploaded to hardware. - */ - if (inst[0].Opcode == OPCODE_END) { - GLuint tmp = i915_get_utemp(p); - i915_emit_arith(p, - A0_MOV, - UREG(REG_TYPE_OC, 0), - A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, ONE, ZERO, ONE, ONE), 0, 0); - return; - } - - while (1) { - GLuint src0, src1, src2, flags; - GLuint tmp = 0; - - switch (inst->Opcode) { - case OPCODE_ABS: - src0 = src_vector(p, &inst->SrcReg[0], program); - i915_emit_arith(p, - A0_MAX, - get_result_vector(p, inst), - get_result_flags(inst), 0, - src0, negate(src0, 1, 1, 1, 1), 0); - break; - - case OPCODE_ADD: - EMIT_2ARG_ARITH(A0_ADD); - break; - - case OPCODE_CMP: - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - src2 = src_vector(p, &inst->SrcReg[2], program); - i915_emit_arith(p, A0_CMP, get_result_vector(p, inst), get_result_flags(inst), 0, src0, src2, src1); /* NOTE: order of src2, src1 */ - break; - - case OPCODE_COS: - src0 = src_vector(p, &inst->SrcReg[0], program); - tmp = i915_get_utemp(p); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - src0, i915_emit_const1f(p, 1.0 / (M_PI)), 0); - - i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); - - /* By choosing different taylor constants, could get rid of this mul: - */ - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, i915_emit_const1f(p, (M_PI)), 0); - - /* - * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 - * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 - * t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 - * result = DP4 t0, cos_constants - */ - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XY, 0, - swizzle(tmp, X, X, ONE, ONE), - swizzle(tmp, X, ONE, ONE, ONE), 0); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XYZ, 0, - swizzle(tmp, X, Y, X, ONE), - swizzle(tmp, X, X, ONE, ONE), 0); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XYZ, 0, - swizzle(tmp, X, X, Z, ONE), - swizzle(tmp, Z, ONE, ONE, ONE), 0); - - i915_emit_arith(p, - A0_DP4, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(tmp, ONE, Z, Y, X), - i915_emit_const4fv(p, cos_constants), 0); - - break; - - case OPCODE_DP3: - EMIT_2ARG_ARITH(A0_DP3); - break; - - case OPCODE_DP4: - EMIT_2ARG_ARITH(A0_DP4); - break; - - case OPCODE_DPH: - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - - i915_emit_arith(p, - A0_DP4, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(src0, X, Y, Z, ONE), src1, 0); - break; - - case OPCODE_DST: - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - - /* result[0] = 1 * 1; - * result[1] = a[1] * b[1]; - * result[2] = a[2] * 1; - * result[3] = 1 * b[3]; - */ - i915_emit_arith(p, - A0_MUL, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(src0, ONE, Y, Z, ONE), - swizzle(src1, ONE, Y, ONE, W), 0); - break; - - case OPCODE_EX2: - src0 = src_vector(p, &inst->SrcReg[0], program); - - i915_emit_arith(p, - A0_EXP, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(src0, X, X, X, X), 0, 0); - break; - - case OPCODE_FLR: - EMIT_1ARG_ARITH(A0_FLR); - break; - - case OPCODE_FRC: - EMIT_1ARG_ARITH(A0_FRC); - break; - - case OPCODE_KIL: - src0 = src_vector(p, &inst->SrcReg[0], program); - tmp = i915_get_utemp(p); - - i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ - 0, src0, T0_TEXKILL); - break; - - case OPCODE_LG2: - src0 = src_vector(p, &inst->SrcReg[0], program); - - i915_emit_arith(p, - A0_LOG, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(src0, X, X, X, X), 0, 0); - break; - - case OPCODE_LIT: - src0 = src_vector(p, &inst->SrcReg[0], program); - tmp = i915_get_utemp(p); - - /* tmp = max( a.xyzw, a.00zw ) - * XXX: Clamp tmp.w to -128..128 - * tmp.y = log(tmp.y) - * tmp.y = tmp.w * tmp.y - * tmp.y = exp(tmp.y) - * result = cmp (a.11-x1, a.1x01, a.1xy1 ) - */ - i915_emit_arith(p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0, - src0, swizzle(src0, ZERO, ZERO, Z, W), 0); - - i915_emit_arith(p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0, - swizzle(tmp, Y, Y, Y, Y), 0, 0); - - i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0, - swizzle(tmp, ZERO, Y, ZERO, ZERO), - swizzle(tmp, ZERO, W, ZERO, ZERO), 0); - - i915_emit_arith(p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0, - swizzle(tmp, Y, Y, Y, Y), 0, 0); - - i915_emit_arith(p, A0_CMP, - get_result_vector(p, inst), - get_result_flags(inst), 0, - negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0), - swizzle(tmp, ONE, X, ZERO, ONE), - swizzle(tmp, ONE, X, Y, ONE)); - - break; - - case OPCODE_LRP: - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - src2 = src_vector(p, &inst->SrcReg[2], program); - flags = get_result_flags(inst); - tmp = i915_get_utemp(p); - - /* b*a + c*(1-a) - * - * b*a + c - ca - * - * tmp = b*a + c, - * result = (-c)*a + tmp - */ - i915_emit_arith(p, A0_MAD, tmp, - flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2); - - i915_emit_arith(p, A0_MAD, - get_result_vector(p, inst), - flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp); - break; - - case OPCODE_MAD: - EMIT_3ARG_ARITH(A0_MAD); - break; - - case OPCODE_MAX: - EMIT_2ARG_ARITH(A0_MAX); - break; - - case OPCODE_MIN: - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - tmp = i915_get_utemp(p); - flags = get_result_flags(inst); - - i915_emit_arith(p, - A0_MAX, - tmp, flags & A0_DEST_CHANNEL_ALL, 0, - negate(src0, 1, 1, 1, 1), - negate(src1, 1, 1, 1, 1), 0); - - i915_emit_arith(p, - A0_MOV, - get_result_vector(p, inst), - flags, 0, negate(tmp, 1, 1, 1, 1), 0, 0); - break; - - case OPCODE_MOV: - EMIT_1ARG_ARITH(A0_MOV); - break; - - case OPCODE_MUL: - EMIT_2ARG_ARITH(A0_MUL); - break; - - case OPCODE_POW: - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - tmp = i915_get_utemp(p); - flags = get_result_flags(inst); - - /* XXX: masking on intermediate values, here and elsewhere. - */ - i915_emit_arith(p, - A0_LOG, - tmp, A0_DEST_CHANNEL_X, 0, - swizzle(src0, X, X, X, X), 0, 0); - - i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, src1, 0); - - - i915_emit_arith(p, - A0_EXP, - get_result_vector(p, inst), - flags, 0, swizzle(tmp, X, X, X, X), 0, 0); - - break; - - case OPCODE_RCP: - src0 = src_vector(p, &inst->SrcReg[0], program); - - i915_emit_arith(p, - A0_RCP, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(src0, X, X, X, X), 0, 0); - break; - - case OPCODE_RSQ: - - src0 = src_vector(p, &inst->SrcReg[0], program); - - i915_emit_arith(p, - A0_RSQ, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(src0, X, X, X, X), 0, 0); - break; - - case OPCODE_SCS: - src0 = src_vector(p, &inst->SrcReg[0], program); - tmp = i915_get_utemp(p); - - /* - * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 - * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x - * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x - * scs.x = DP4 t1, sin_constants - * t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 - * scs.y = DP4 t1, cos_constants - */ - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XY, 0, - swizzle(src0, X, X, ONE, ONE), - swizzle(src0, X, ONE, ONE, ONE), 0); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X, Y, X, Y), - swizzle(tmp, X, X, ONE, ONE), 0); - - if (inst->DstReg.WriteMask & WRITEMASK_Y) { - GLuint tmp1; - - if (inst->DstReg.WriteMask & WRITEMASK_X) - tmp1 = i915_get_utemp(p); - else - tmp1 = tmp; - - i915_emit_arith(p, - A0_MUL, - tmp1, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X, Y, Y, W), - swizzle(tmp, X, Z, ONE, ONE), 0); - - i915_emit_arith(p, - A0_DP4, - get_result_vector(p, inst), - A0_DEST_CHANNEL_Y, 0, - swizzle(tmp1, W, Z, Y, X), - i915_emit_const4fv(p, sin_constants), 0); - } - - if (inst->DstReg.WriteMask & WRITEMASK_X) { - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XYZ, 0, - swizzle(tmp, X, X, Z, ONE), - swizzle(tmp, Z, ONE, ONE, ONE), 0); - - i915_emit_arith(p, - A0_DP4, - get_result_vector(p, inst), - A0_DEST_CHANNEL_X, 0, - swizzle(tmp, ONE, Z, Y, X), - i915_emit_const4fv(p, cos_constants), 0); - } - break; - - case OPCODE_SGE: - EMIT_2ARG_ARITH(A0_SGE); - break; - - case OPCODE_SIN: - src0 = src_vector(p, &inst->SrcReg[0], program); - tmp = i915_get_utemp(p); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - src0, i915_emit_const1f(p, 1.0 / (M_PI)), 0); - - i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); - - /* By choosing different taylor constants, could get rid of this mul: - */ - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_X, 0, - tmp, i915_emit_const1f(p, (M_PI)), 0); - - /* - * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 - * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x - * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x - * result = DP4 t1.wzyx, sin_constants - */ - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_XY, 0, - swizzle(tmp, X, X, ONE, ONE), - swizzle(tmp, X, ONE, ONE, ONE), 0); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X, Y, X, Y), - swizzle(tmp, X, X, ONE, ONE), 0); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(tmp, X, Y, Y, W), - swizzle(tmp, X, Z, ONE, ONE), 0); - - i915_emit_arith(p, - A0_DP4, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(tmp, W, Z, Y, X), - i915_emit_const4fv(p, sin_constants), 0); - break; - - case OPCODE_SLT: - EMIT_2ARG_ARITH(A0_SLT); - break; - - case OPCODE_SUB: - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - - i915_emit_arith(p, - A0_ADD, - get_result_vector(p, inst), - get_result_flags(inst), 0, - src0, negate(src1, 1, 1, 1, 1), 0); - break; - - case OPCODE_SWZ: - EMIT_1ARG_ARITH(A0_MOV); /* extended swizzle handled natively */ - break; - - case OPCODE_TEX: - EMIT_TEX(T0_TEXLD); - break; - - case OPCODE_TXB: - EMIT_TEX(T0_TEXLDB); - break; - - case OPCODE_TXP: - EMIT_TEX(T0_TEXLDP); - break; - - case OPCODE_XPD: - /* Cross product: - * result.x = src0.y * src1.z - src0.z * src1.y; - * result.y = src0.z * src1.x - src0.x * src1.z; - * result.z = src0.x * src1.y - src0.y * src1.x; - * result.w = undef; - */ - src0 = src_vector(p, &inst->SrcReg[0], program); - src1 = src_vector(p, &inst->SrcReg[1], program); - tmp = i915_get_utemp(p); - - i915_emit_arith(p, - A0_MUL, - tmp, A0_DEST_CHANNEL_ALL, 0, - swizzle(src0, Z, X, Y, ONE), - swizzle(src1, Y, Z, X, ONE), 0); - - i915_emit_arith(p, - A0_MAD, - get_result_vector(p, inst), - get_result_flags(inst), 0, - swizzle(src0, Y, Z, X, ONE), - swizzle(src1, Z, X, Y, ONE), - negate(tmp, 1, 1, 1, 0)); - break; - - case OPCODE_END: - return; - - default: - i915_program_error(p, "bad opcode"); - return; - } - - inst++; - i915_release_utemps(p); - } -} - -/* Rather than trying to intercept and jiggle depth writes during - * emit, just move the value into its correct position at the end of - * the program: - */ -static void -fixup_depth_write(struct i915_fragment_program *p) -{ - if (p->depth_written) { - GLuint depth = UREG(REG_TYPE_OD, 0); - - i915_emit_arith(p, - A0_MOV, - depth, A0_DEST_CHANNEL_W, 0, - swizzle(depth, X, Y, Z, Z), 0, 0); - } -} - - -static void -check_wpos(struct i915_fragment_program *p) -{ - GLuint inputs = p->FragProg.Base.InputsRead; - GLint i; - - p->wpos_tex = -1; - - for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { - if (inputs & FRAG_BIT_TEX(i)) - continue; - else if (inputs & FRAG_BIT_WPOS) { - p->wpos_tex = i; - inputs &= ~FRAG_BIT_WPOS; - } - } - - if (inputs & FRAG_BIT_WPOS) { - i915_program_error(p, "No free texcoord for wpos value"); - } -} - - -static void -translate_program(struct i915_fragment_program *p) -{ - struct i915_context *i915 = I915_CONTEXT(p->ctx); - - i915_init_program(i915, p); - check_wpos(p); - upload_program(p); - fixup_depth_write(p); - i915_fini_program(p); - - p->translated = 1; -} - - -static void -track_params(struct i915_fragment_program *p) -{ - GLint i; - - if (p->nr_params) - _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters); - - for (i = 0; i < p->nr_params; i++) { - GLint reg = p->param[i].reg; - COPY_4V(p->constant[reg], p->param[i].values); - } - - p->params_uptodate = 1; - p->on_hardware = 0; /* overkill */ -} - - -static void -i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_context *i915 = I915_CONTEXT(ctx); - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - - if (i915->current_program == p) - return; - - if (i915->current_program) { - i915->current_program->on_hardware = 0; - i915->current_program->params_uptodate = 0; - } - - i915->current_program = p; - - assert(p->on_hardware == 0); - assert(p->params_uptodate == 0); - - } -} - -static struct gl_program * -i915NewProgram(GLcontext * ctx, GLenum target, GLuint id) -{ - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), - target, id); - - case GL_FRAGMENT_PROGRAM_ARB:{ - struct i915_fragment_program *prog = - CALLOC_STRUCT(i915_fragment_program); - if (prog) { - i915_init_program(I915_CONTEXT(ctx), prog); - - return _mesa_init_fragment_program(ctx, &prog->FragProg, - target, id); - } - else - return NULL; - } - - default: - /* Just fallback: - */ - return _mesa_new_program(ctx, target, id); - } -} - -static void -i915DeleteProgram(GLcontext * ctx, struct gl_program *prog) -{ - if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_context *i915 = I915_CONTEXT(ctx); - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - - if (i915->current_program == p) - i915->current_program = 0; - } - - _mesa_delete_program(ctx, prog); -} - - -static GLboolean -i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - - if (!p->translated) - translate_program(p); - - return !p->error; - } - else - return GL_TRUE; -} - -static void -i915ProgramStringNotify(GLcontext * ctx, - GLenum target, struct gl_program *prog) -{ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - struct i915_fragment_program *p = (struct i915_fragment_program *) prog; - p->translated = 0; - - /* Hack: make sure fog is correctly enabled according to this - * fragment program's fog options. - */ - if (p->FragProg.FogOption) { - /* add extra instructions to do fog, then turn off FogOption field */ - _mesa_append_fog_code(ctx, &p->FragProg); - p->FragProg.FogOption = GL_NONE; - } - } - - _tnl_program_string(ctx, target, prog); -} - - -void -i915ValidateFragmentProgram(struct i915_context *i915) -{ - GLcontext *ctx = &i915->intel.ctx; - struct intel_context *intel = intel_context(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - - struct i915_fragment_program *p = - (struct i915_fragment_program *) ctx->FragmentProgram._Current; - - const GLuint inputsRead = p->FragProg.Base.InputsRead; - GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; - GLuint s2 = S2_TEXCOORD_NONE; - int i, offset = 0; - - if (i915->current_program != p) { - if (i915->current_program) { - i915->current_program->on_hardware = 0; - i915->current_program->params_uptodate = 0; - } - - i915->current_program = p; - } - - - /* Important: - */ - VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; - - if (!p->translated) - translate_program(p); - - intel->vertex_attr_count = 0; - intel->wpos_offset = 0; - intel->wpos_size = 0; - intel->coloroffset = 0; - intel->specoffset = 0; - - if (inputsRead & FRAG_BITS_TEX_ANY) { - EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); - } - else { - EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); - } - - if (inputsRead & FRAG_BIT_COL0) { - intel->coloroffset = offset / 4; - EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); - } - - if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) || - i915->vertex_fog != I915_FOG_NONE) { - - if (inputsRead & FRAG_BIT_COL1) { - intel->specoffset = offset / 4; - EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); - } - else - EMIT_PAD(3); - - if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) - EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); - else - EMIT_PAD(1); - } - - /* XXX this was disabled, but enabling this code helped fix the Glean - * tfragprog1 fog tests. - */ -#if 1 - if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { - EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); - } -#endif - - for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { - if (inputsRead & FRAG_BIT_TEX(i)) { - int sz = VB->TexCoordPtr[i]->size; - - s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); - s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); - - EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); - } - else if (i == p->wpos_tex) { - - /* If WPOS is required, duplicate the XYZ position data in an - * unused texture coordinate: - */ - s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); - s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); - - intel->wpos_offset = offset; - intel->wpos_size = 3 * sizeof(GLuint); - - EMIT_PAD(intel->wpos_size); - } - } - - if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || - s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - int k; - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - /* Must do this *after* statechange, so as not to affect - * buffered vertices reliant on the old state: - */ - intel->vertex_size = _tnl_install_attrs(&intel->ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0); - - intel->vertex_size >>= 2; - - i915->state.Ctx[I915_CTXREG_LIS2] = s2; - i915->state.Ctx[I915_CTXREG_LIS4] = s4; - - k = intel->vtbl.check_vertex_size(intel, intel->vertex_size); - assert(k); - } - - if (!p->params_uptodate) - track_params(p); - - if (!p->on_hardware) - i915_upload_program(i915, p); -} - -void -i915InitFragProgFuncs(struct dd_function_table *functions) -{ - functions->BindProgram = i915BindProgram; - functions->NewProgram = i915NewProgram; - functions->DeleteProgram = i915DeleteProgram; - functions->IsProgramNative = i915IsProgramNative; - functions->ProgramStringNotify = i915ProgramStringNotify; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c deleted file mode 100644 index a739bd6581..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_metaops.c +++ /dev/null @@ -1,509 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "utils.h" - -#include "intel_screen.h" -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_regions.h" -#include "intel_rotate.h" - -#include "i915_context.h" -#include "i915_reg.h" - -/* We touch almost everything: - */ -#define ACTIVE (I915_UPLOAD_INVARIENT | \ - I915_UPLOAD_CTX | \ - I915_UPLOAD_BUFFERS | \ - I915_UPLOAD_STIPPLE | \ - I915_UPLOAD_PROGRAM | \ - I915_UPLOAD_FOG | \ - I915_UPLOAD_TEX(0)) - -#define SET_STATE( i915, STATE ) \ -do { \ - i915->current->emitted &= ~ACTIVE; \ - i915->current = &i915->STATE; \ - i915->current->emitted &= ~ACTIVE; \ -} while (0) - - -static void -meta_no_stencil_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_no_depth_write(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - -static void -meta_depth_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) - * ctx->Driver.DepthMask( ctx, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | - S6_DEPTH_WRITE_ENABLE); - - /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) - */ - i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->meta.Ctx[I915_CTXREG_LIS6] |= - COMPAREFUNC_ALWAYS << S6_DEPTH_TEST_FUNC_SHIFT; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -/* Set stencil unit to replace always with the reference value. - */ -static void -meta_stencil_replace(struct intel_context *intel, - GLuint s_mask, GLuint s_clear) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint op = STENCILOP_REPLACE; - GLuint func = COMPAREFUNC_ALWAYS; - - /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - - /* ctx->Driver.StencilMask( ctx, s_mask ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(s_mask)); - - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) - */ - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); - - - /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) - */ - i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff)); - - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | - (func << S5_STENCIL_TEST_FUNC_SHIFT)); - - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - -static void -meta_color_mask(struct intel_context *intel, GLboolean state) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - const GLuint mask = (S5_WRITEDISABLE_RED | - S5_WRITEDISABLE_GREEN | - S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA); - - /* Copy colormask state from "regular" hw context. - */ - if (state) { - i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; - i915->meta.Ctx[I915_CTXREG_LIS5] |= - (i915->state.Ctx[I915_CTXREG_LIS5] & mask); - } - else - i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -static void -meta_import_pixel_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(i915->meta.Fog, i915->state.Fog, I915_FOG_SETUP_SIZE * 4); - - i915->meta.Ctx[I915_CTXREG_LIS5] = i915->state.Ctx[I915_CTXREG_LIS5]; - i915->meta.Ctx[I915_CTXREG_LIS6] = i915->state.Ctx[I915_CTXREG_LIS6]; - i915->meta.Ctx[I915_CTXREG_STATE4] = i915->state.Ctx[I915_CTXREG_STATE4]; - i915->meta.Ctx[I915_CTXREG_BLENDCOLOR1] = - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]; - i915->meta.Ctx[I915_CTXREG_IAB] = i915->state.Ctx[I915_CTXREG_IAB]; - - i915->meta.Buffer[I915_DESTREG_SENABLE] = - i915->state.Buffer[I915_DESTREG_SENABLE]; - i915->meta.Buffer[I915_DESTREG_SR1] = i915->state.Buffer[I915_DESTREG_SR1]; - i915->meta.Buffer[I915_DESTREG_SR2] = i915->state.Buffer[I915_DESTREG_SR2]; - - i915->meta.emitted &= ~I915_UPLOAD_FOG; - i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - - -#define REG( type, nr ) (((type)<<5)|(nr)) - -#define REG_R(x) REG(REG_TYPE_R, x) -#define REG_T(x) REG(REG_TYPE_T, x) -#define REG_CONST(x) REG(REG_TYPE_CONST, x) -#define REG_S(x) REG(REG_TYPE_S, x) -#define REG_OC REG(REG_TYPE_OC, 0) -#define REG_OD REG(REG_TYPE_OD, 0) -#define REG_U(x) REG(REG_TYPE_U, x) - -#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) -#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) -#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) -#define REG_T_TEX(x) REG(REG_TYPE_T, x) - - -#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) -#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) -#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) -#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) -#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) -#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) -#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) - -#define T0_SAMPLER( unit ) ((unit)<ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare incoming diffuse color: - */ - (D0_DCL | D0_DECL_REG(REG_T_DIFFUSE) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = mov(t_diffuse) - */ - (A0_MOV | - A0_DEST_REG(REG_OC) | - A0_DEST_CHANNEL_ALL | A0_SRC0_REG(REG_T_DIFFUSE)), - (A1_SRC0_XYZW), - 0, - }; - - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - -static void -meta_texture_blend_replace(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - static const GLuint prog[] = { - _3DSTATE_PIXEL_SHADER_PROGRAM, - - /* Declare the sampler: - */ - (D0_DCL | D0_DECL_REG(REG_S(0)) | D0_SAMPLE_TYPE_2D | D0_CHANNEL_NONE), - D1_MBZ, - D2_MBZ, - - /* Declare the interpolated texture coordinate: - */ - (D0_DCL | D0_DECL_REG(REG_T_TEX(0)) | D0_CHANNEL_ALL), - D1_MBZ, - D2_MBZ, - - /* output-color = texld(sample0, texcoord0) - */ - (T0_TEXLD | T0_DEST_REG(REG_OC) | T0_SAMPLER(0)), - T1_ADDRESS_REG(REG_TYPE_T, 0), - T2_MBZ - }; - - memcpy(i915->meta.Program, prog, sizeof(prog)); - i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); - i915->meta.Program[0] |= i915->meta.ProgramSize - 2; - i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; -} - - - - - -/* Set up an arbitary piece of memory as a rectangular texture - * (including the front or back buffer). - */ -static GLboolean -meta_tex_rect_source(struct intel_context *intel, - dri_bo *buffer, - GLuint offset, - GLuint pitch, GLuint height, GLenum format, GLenum type) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint unit = 0; - GLint numLevels = 1; - GLuint *state = i915->meta.Tex[0]; - GLuint textureFormat; - GLuint cpp; - - /* A full implementation of this would do the upload through - * glTexImage2d, and get all the conversion operations at that - * point. We are restricted, but still at least have access to the - * fragment program swizzle. - */ - switch (format) { - case GL_BGRA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_RGBA: - switch (type) { - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_BYTE: - textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); - cpp = 4; - break; - default: - return GL_FALSE; - } - break; - case GL_BGR: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5_REV: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - case GL_RGB: - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); - cpp = 2; - break; - default: - return GL_FALSE; - } - break; - - default: - return GL_FALSE; - } - - - if ((pitch * cpp) & 3) { - _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); - return GL_FALSE; - } - -/* intel_region_release(&i915->meta.tex_region[0]); */ -/* intel_region_reference(&i915->meta.tex_region[0], region); */ - i915->meta.tex_buffer[0] = buffer; - i915->meta.tex_offset[0] = offset; - - state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | - ((pitch - 1) << MS3_WIDTH_SHIFT) | - textureFormat | MS3_USE_FENCE_REGS); - - state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | - MS4_CUBE_FACE_ENA_MASK | - ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); - - state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | - (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); - - state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | - (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); - - state[I915_TEXREG_SS4] = 0; - - i915->meta.emitted &= ~I915_UPLOAD_TEX(0); - return GL_TRUE; -} - - -/** - * Set the color and depth drawing region for meta ops. - */ -static void -meta_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->meta, color_region, depth_region); -} - - -static void -set_vertex_format(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - i915->meta.Ctx[I915_CTXREG_LIS2] = - (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | - S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | - S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); - - i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; - - i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | S4_VFMT_XYZ); - - i915->meta.emitted &= ~I915_UPLOAD_CTX; -} - - - -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void -install_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - memcpy(&i915->meta, &i915->initial, sizeof(i915->meta)); - i915->meta.active = ACTIVE; - i915->meta.emitted = 0; - - SET_STATE(i915, meta); - set_vertex_format(intel); - meta_no_texture(intel); -} - -static void -leave_meta_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - intel_region_release(&i915->meta.draw_region); - intel_region_release(&i915->meta.depth_region); -/* intel_region_release(&i915->meta.tex_region[0]); */ - SET_STATE(i915, state); -} - - - -void -i915InitMetaFuncs(struct i915_context *i915) -{ - i915->intel.vtbl.install_meta_state = install_meta_state; - i915->intel.vtbl.leave_meta_state = leave_meta_state; - i915->intel.vtbl.meta_no_depth_write = meta_no_depth_write; - i915->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; - i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; - i915->intel.vtbl.meta_depth_replace = meta_depth_replace; - i915->intel.vtbl.meta_color_mask = meta_color_mask; - i915->intel.vtbl.meta_no_texture = meta_no_texture; - i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; - i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; - i915->intel.vtbl.meta_draw_region = meta_draw_region; - i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c deleted file mode 100644 index ed45e4f806..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_program.c +++ /dev/null @@ -1,515 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include - -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "tnl/t_context.h" -#include "intel_batchbuffer.h" - -#include "i915_reg.h" -#include "i915_context.h" -#include "i915_program.h" - - -#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) -#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) -#define A1_SRC0( reg ) (((reg)&UREG_MASK)<>UREG_A1_SRC1_SHIFT_LEFT) -#define A2_SRC1( reg ) (((reg)&UREG_MASK)<>UREG_A2_SRC2_SHIFT_LEFT) - -/* These are special, and don't have swizzle/negate bits. - */ -#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<temp_flag); - if (!bit) { - fprintf(stderr, "%s: out of temporaries\n", __FILE__); - exit(1); - } - - p->temp_flag |= 1 << (bit - 1); - return UREG(REG_TYPE_R, (bit - 1)); -} - - -GLuint -i915_get_utemp(struct i915_fragment_program * p) -{ - int bit = ffs(~p->utemp_flag); - if (!bit) { - fprintf(stderr, "%s: out of temporaries\n", __FILE__); - exit(1); - } - - p->utemp_flag |= 1 << (bit - 1); - return UREG(REG_TYPE_U, (bit - 1)); -} - -void -i915_release_utemps(struct i915_fragment_program *p) -{ - p->utemp_flag = ~0x7; -} - - -GLuint -i915_emit_decl(struct i915_fragment_program *p, - GLuint type, GLuint nr, GLuint d0_flags) -{ - GLuint reg = UREG(type, nr); - - if (type == REG_TYPE_T) { - if (p->decl_t & (1 << nr)) - return reg; - - p->decl_t |= (1 << nr); - } - else if (type == REG_TYPE_S) { - if (p->decl_s & (1 << nr)) - return reg; - - p->decl_s |= (1 << nr); - } - else - return reg; - - *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); - *(p->decl++) = D1_MBZ; - *(p->decl++) = D2_MBZ; - - p->nr_decl_insn++; - return reg; -} - -GLuint -i915_emit_arith(struct i915_fragment_program * p, - GLuint op, - GLuint dest, - GLuint mask, - GLuint saturate, GLuint src0, GLuint src1, GLuint src2) -{ - GLuint c[3]; - GLuint nr_const = 0; - - assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); - dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); - assert(dest); - - if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) - c[nr_const++] = 0; - if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) - c[nr_const++] = 1; - if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) - c[nr_const++] = 2; - - /* Recursively call this function to MOV additional const values - * into temporary registers. Use utemp registers for this - - * currently shouldn't be possible to run out, but keep an eye on - * this. - */ - if (nr_const > 1) { - GLuint s[3], first, i, old_utemp_flag; - - s[0] = src0; - s[1] = src1; - s[2] = src2; - old_utemp_flag = p->utemp_flag; - - first = GET_UREG_NR(s[c[0]]); - for (i = 1; i < nr_const; i++) { - if (GET_UREG_NR(s[c[i]]) != first) { - GLuint tmp = i915_get_utemp(p); - - i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, - s[c[i]], 0, 0); - s[c[i]] = tmp; - } - } - - src0 = s[0]; - src1 = s[1]; - src2 = s[2]; - p->utemp_flag = old_utemp_flag; /* restore */ - } - - *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); - *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); - *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); - - p->nr_alu_insn++; - return dest; -} - -GLuint i915_emit_texld( struct i915_fragment_program *p, - GLuint dest, - GLuint destmask, - GLuint sampler, - GLuint coord, - GLuint op ) -{ - if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { - /* No real way to work around this in the general case - need to - * allocate and declare a new temporary register (a utemp won't - * do). Will fallback for now. - */ - i915_program_error(p, "Can't (yet) swizzle TEX arguments"); - return 0; - } - - /* Don't worry about saturate as we only support - */ - if (destmask != A0_DEST_CHANNEL_ALL) { - GLuint tmp = i915_get_utemp(p); - i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); - i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); - return dest; - } - else { - assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); - assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); - - if (GET_UREG_TYPE(coord) != REG_TYPE_T) { - p->nr_tex_indirect++; - } - - *(p->csr++) = (op | - T0_DEST( dest ) | - T0_SAMPLER( sampler )); - - *(p->csr++) = T1_ADDRESS_REG( coord ); - *(p->csr++) = T2_MBZ; - - p->nr_tex_insn++; - return dest; - } -} - - -GLuint -i915_emit_const1f(struct i915_fragment_program * p, GLfloat c0) -{ - GLint reg, idx; - - if (c0 == 0.0) - return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); - if (c0 == 1.0) - return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) - continue; - for (idx = 0; idx < 4; idx++) { - if (!(p->constant_flags[reg] & (1 << idx)) || - p->constant[reg][idx] == c0) { - p->constant[reg][idx] = c0; - p->constant_flags[reg] |= 1 << idx; - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); - } - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - -GLuint -i915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1) -{ - GLint reg, idx; - - if (c0 == 0.0) - return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); - if (c0 == 1.0) - return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); - - if (c1 == 0.0) - return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); - if (c1 == 1.0) - return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf || - p->constant_flags[reg] == I915_CONSTFLAG_PARAM) - continue; - for (idx = 0; idx < 3; idx++) { - if (!(p->constant_flags[reg] & (3 << idx))) { - p->constant[reg][idx] = c0; - p->constant[reg][idx + 1] = c1; - p->constant_flags[reg] |= 3 << idx; - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, - ONE); - } - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - - -GLuint -i915_emit_const4f(struct i915_fragment_program * p, - GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3) -{ - GLint reg; - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0xf && - p->constant[reg][0] == c0 && - p->constant[reg][1] == c1 && - p->constant[reg][2] == c2 && p->constant[reg][3] == c3) { - return UREG(REG_TYPE_CONST, reg); - } - else if (p->constant_flags[reg] == 0) { - p->constant[reg][0] = c0; - p->constant[reg][1] = c1; - p->constant[reg][2] = c2; - p->constant[reg][3] = c3; - p->constant_flags[reg] = 0xf; - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return UREG(REG_TYPE_CONST, reg); - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - -GLuint -i915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c) -{ - return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); -} - - -GLuint -i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values) -{ - GLint reg, i; - - for (i = 0; i < p->nr_params; i++) { - if (p->param[i].values == values) - return UREG(REG_TYPE_CONST, p->param[i].reg); - } - - - for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { - if (p->constant_flags[reg] == 0) { - p->constant_flags[reg] = I915_CONSTFLAG_PARAM; - i = p->nr_params++; - - p->param[i].values = values; - p->param[i].reg = reg; - p->params_uptodate = 0; - - if (reg + 1 > p->nr_constants) - p->nr_constants = reg + 1; - return UREG(REG_TYPE_CONST, reg); - } - } - - fprintf(stderr, "%s: out of constants\n", __FUNCTION__); - p->error = 1; - return 0; -} - - - -void -i915_program_error(struct i915_fragment_program *p, const char *msg) -{ - _mesa_problem(NULL, "i915_program_error: %s", msg); - p->error = 1; -} - - -void -i915_init_program(struct i915_context *i915, struct i915_fragment_program *p) -{ - GLcontext *ctx = &i915->intel.ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - - p->translated = 0; - p->params_uptodate = 0; - p->on_hardware = 0; - p->error = 0; - - p->nr_tex_indirect = 1; /* correct? */ - p->nr_tex_insn = 0; - p->nr_alu_insn = 0; - p->nr_decl_insn = 0; - - p->ctx = ctx; - memset(p->constant_flags, 0, sizeof(p->constant_flags)); - - p->nr_constants = 0; - p->csr = p->program; - p->decl = p->declarations; - p->decl_s = 0; - p->decl_t = 0; - p->temp_flag = 0xffff000; - p->utemp_flag = ~0x7; - p->wpos_tex = -1; - p->depth_written = 0; - p->nr_params = 0; - - p->src_texture = UREG_BAD; - p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE); - p->last_tex_stage = 0; - p->VB = &tnl->vb; - - *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; -} - - -void -i915_fini_program(struct i915_fragment_program *p) -{ - GLuint program_size = p->csr - p->program; - GLuint decl_size = p->decl - p->declarations; - - if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) - i915_program_error(p, "Exceeded max nr indirect texture lookups"); - - if (p->nr_tex_insn > I915_MAX_TEX_INSN) - i915_program_error(p, "Exceeded max TEX instructions"); - - if (p->nr_alu_insn > I915_MAX_ALU_INSN) - i915_program_error(p, "Exceeded max ALU instructions"); - - if (p->nr_decl_insn > I915_MAX_DECL_INSN) - i915_program_error(p, "Exceeded max DECL instructions"); - - if (p->error) { - p->FragProg.Base.NumNativeInstructions = 0; - p->FragProg.Base.NumNativeAluInstructions = 0; - p->FragProg.Base.NumNativeTexInstructions = 0; - p->FragProg.Base.NumNativeTexIndirections = 0; - } - else { - p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + - p->nr_tex_insn + - p->nr_decl_insn); - p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn; - p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn; - p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect; - } - - p->declarations[0] |= program_size + decl_size - 2; -} - -void -i915_upload_program(struct i915_context *i915, - struct i915_fragment_program *p) -{ - GLuint program_size = p->csr - p->program; - GLuint decl_size = p->decl - p->declarations; - - FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error); - - /* Could just go straight to the batchbuffer from here: - */ - if (i915->state.ProgramSize != (program_size + decl_size) || - memcmp(i915->state.Program + decl_size, p->program, - program_size * sizeof(int)) != 0) { - I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM); - memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int)); - memcpy(i915->state.Program + decl_size, p->program, - program_size * sizeof(int)); - i915->state.ProgramSize = decl_size + program_size; - } - - /* Always seemed to get a failure if I used memcmp() to - * shortcircuit this state upload. Needs further investigation? - */ - if (p->nr_constants) { - GLuint nr = p->nr_constants; - - I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); - I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); - - i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); - i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1); - - memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr)); - i915->state.ConstantSize = 2 + (nr) * 4; - - if (0) { - GLuint i; - for (i = 0; i < nr; i++) { - fprintf(stderr, "const[%d]: %f %f %f %f\n", i, - p->constant[i][0], - p->constant[i][1], p->constant[i][2], p->constant[i][3]); - } - } - } - else { - I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); - } - - p->on_hardware = 1; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.h b/src/mesa/drivers/dri/i915tex/i915_program.h deleted file mode 100644 index 3c12b34f16..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_program.h +++ /dev/null @@ -1,160 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef I915_PROGRAM_H -#define I915_PROGRAM_H - -#include "i915_context.h" -#include "i915_reg.h" - - - -/* Having zero and one in here makes the definition of swizzle a lot - * easier. - */ -#define UREG_TYPE_SHIFT 29 -#define UREG_NR_SHIFT 24 -#define UREG_CHANNEL_X_NEGATE_SHIFT 23 -#define UREG_CHANNEL_X_SHIFT 20 -#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 -#define UREG_CHANNEL_Y_SHIFT 16 -#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 -#define UREG_CHANNEL_Z_SHIFT 12 -#define UREG_CHANNEL_W_NEGATE_SHIFT 11 -#define UREG_CHANNEL_W_SHIFT 8 -#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 -#define UREG_CHANNEL_ZERO_SHIFT 4 -#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 -#define UREG_CHANNEL_ONE_SHIFT 0 - -#define UREG_BAD 0xffffffff /* not a valid ureg */ - -#define X SRC_X -#define Y SRC_Y -#define Z SRC_Z -#define W SRC_W -#define ZERO SRC_ZERO -#define ONE SRC_ONE - -/* Construct a ureg: - */ -#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ - ((nr) << UREG_NR_SHIFT) | \ - (X << UREG_CHANNEL_X_SHIFT) | \ - (Y << UREG_CHANNEL_Y_SHIFT) | \ - (Z << UREG_CHANNEL_Z_SHIFT) | \ - (W << UREG_CHANNEL_W_SHIFT) | \ - (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ - (ONE << UREG_CHANNEL_ONE_SHIFT)) - -#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) -#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) - -#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) -#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) - - - -#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 - -/* One neat thing about the UREG representation: - */ -static INLINE int -swizzle(int reg, int x, int y, int z, int w) -{ - return ((reg & ~UREG_XYZW_CHANNEL_MASK) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | - CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); -} - -/* Another neat thing about the UREG representation: - */ -static INLINE int -negate(int reg, int x, int y, int z, int w) -{ - return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) | - ((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) | - ((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) | - ((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT)); -} - - -extern GLuint i915_get_temp(struct i915_fragment_program *p); -extern GLuint i915_get_utemp(struct i915_fragment_program *p); -extern void i915_release_utemps(struct i915_fragment_program *p); - - -extern GLuint i915_emit_texld(struct i915_fragment_program *p, - GLuint dest, - GLuint destmask, - GLuint sampler, GLuint coord, GLuint op); - -extern GLuint i915_emit_arith(struct i915_fragment_program *p, - GLuint op, - GLuint dest, - GLuint mask, - GLuint saturate, - GLuint src0, GLuint src1, GLuint src2); - -extern GLuint i915_emit_decl(struct i915_fragment_program *p, - GLuint type, GLuint nr, GLuint d0_flags); - - -extern GLuint i915_emit_const1f(struct i915_fragment_program *p, GLfloat c0); - -extern GLuint i915_emit_const2f(struct i915_fragment_program *p, - GLfloat c0, GLfloat c1); - -extern GLuint i915_emit_const4fv(struct i915_fragment_program *p, - const GLfloat * c); - -extern GLuint i915_emit_const4f(struct i915_fragment_program *p, - GLfloat c0, GLfloat c1, - GLfloat c2, GLfloat c3); - - -extern GLuint i915_emit_param4fv(struct i915_fragment_program *p, - const GLfloat * values); - -extern void i915_program_error(struct i915_fragment_program *p, - const char *msg); - -extern void i915_init_program(struct i915_context *i915, - struct i915_fragment_program *p); - -extern void i915_upload_program(struct i915_context *i915, - struct i915_fragment_program *p); - -extern void i915_fini_program(struct i915_fragment_program *p); - - - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_reg.h b/src/mesa/drivers/dri/i915tex/i915_reg.h deleted file mode 100644 index a9fa56e8a6..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_reg.h +++ /dev/null @@ -1,866 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef _I915_REG_H_ -#define _I915_REG_H_ - - -#include "intel_reg.h" - -#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) - -#define CMD_3D (0x3<<29) - -#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) -#define PRIM3D_TRILIST (0x0<<18) -#define PRIM3D_TRISTRIP (0x1<<18) -#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) -#define PRIM3D_TRIFAN (0x3<<18) -#define PRIM3D_POLY (0x4<<18) -#define PRIM3D_LINELIST (0x5<<18) -#define PRIM3D_LINESTRIP (0x6<<18) -#define PRIM3D_RECTLIST (0x7<<18) -#define PRIM3D_POINTLIST (0x8<<18) -#define PRIM3D_DIB (0x9<<18) -#define PRIM3D_CLEAR_RECT (0xa<<18) -#define PRIM3D_ZONE_INIT (0xd<<18) -#define PRIM3D_MASK (0x1f<<18) - -/* p137 */ -#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) -#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) -#define AA_LINE_ECAAR_WIDTH_0_5 0 -#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) -#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) -#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) -#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) -#define AA_LINE_REGION_WIDTH_0_5 0 -#define AA_LINE_REGION_WIDTH_1_0 (1<<6) -#define AA_LINE_REGION_WIDTH_2_0 (2<<6) -#define AA_LINE_REGION_WIDTH_4_0 (3<<6) - -/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ -#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) -#define BFO_ENABLE_STENCIL_REF (1<<23) -#define BFO_STENCIL_REF_SHIFT 15 -#define BFO_STENCIL_REF_MASK (0xff<<15) -#define BFO_ENABLE_STENCIL_FUNCS (1<<14) -#define BFO_STENCIL_TEST_SHIFT 11 -#define BFO_STENCIL_TEST_MASK (0x7<<11) -#define BFO_STENCIL_FAIL_SHIFT 8 -#define BFO_STENCIL_FAIL_MASK (0x7<<8) -#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 -#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) -#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 -#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) -#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) -#define BFO_STENCIL_TWO_SIDE (1<<0) - - -/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ -#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) -#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) -#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) -#define BFM_STENCIL_TEST_MASK_SHIFT 8 -#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) -#define BFM_STENCIL_WRITE_MASK_SHIFT 0 -#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) - - - -/* 3DSTATE_BIN_CONTROL p141 */ - -/* p143 */ -#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) -/* Dword 1 */ -#define BUF_3D_ID_COLOR_BACK (0x3<<24) -#define BUF_3D_ID_DEPTH (0x7<<24) -#define BUF_3D_USE_FENCE (1<<23) -#define BUF_3D_TILED_SURFACE (1<<22) -#define BUF_3D_TILE_WALK_X 0 -#define BUF_3D_TILE_WALK_Y (1<<21) -#define BUF_3D_PITCH(x) (((x)/4)<<2) -/* Dword 2 */ -#define BUF_3D_ADDR(x) ((x) & ~0x3) - - -/* 3DSTATE_CHROMA_KEY */ - -/* 3DSTATE_CLEAR_PARAMETERS, p150 */ -/* - * Sets the color, depth and stencil clear values used by the - * CLEAR_RECT and ZONE_INIT primitive types, respectively. These - * primitives set override most 3d state and only take a minimal x/y - * vertex. The color/z/stencil information is supplied here and - * therefore cannot vary per vertex. - */ -#define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) -/* Dword 1 */ -#define CLEARPARAM_CLEAR_RECT (1 << 16) -#define CLEARPARAM_ZONE_INIT (0 << 16) -#define CLEARPARAM_WRITE_COLOR (1 << 2) -#define CLEARPARAM_WRITE_DEPTH (1 << 1) -#define CLEARPARAM_WRITE_STENCIL (1 << 0) - -/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ -#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) - - - -/* 3DSTATE_COORD_SET_BINDINGS, p154 */ -#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) -#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) - -/* p156 */ -#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) - -/* p157 */ -#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) - -/* p158 */ -#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) - - -/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ -#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) -/* scale in dword 1 */ - - -/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ -#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | 0x2) - -/* p161 */ -#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) -/* Dword 1 */ -#define TEX_DEFAULT_COLOR_OGL (0<<30) -#define TEX_DEFAULT_COLOR_D3D (1<<30) -#define ZR_EARLY_DEPTH (1<<29) -#define LOD_PRECLAMP_OGL (1<<28) -#define LOD_PRECLAMP_D3D (0<<28) -#define DITHER_FULL_ALWAYS (0<<26) -#define DITHER_FULL_ON_FB_BLEND (1<<26) -#define DITHER_CLAMPED_ALWAYS (2<<26) -#define LINEAR_GAMMA_BLEND_32BPP (1<<25) -#define DEBUG_DISABLE_ENH_DITHER (1<<24) -#define DSTORG_HORT_BIAS(x) ((x)<<20) -#define DSTORG_VERT_BIAS(x) ((x)<<16) -#define COLOR_4_2_2_CHNL_WRT_ALL 0 -#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) -#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) -#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) -#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) -#define COLR_BUF_8BIT 0 -#define COLR_BUF_RGB555 (1<<8) -#define COLR_BUF_RGB565 (2<<8) -#define COLR_BUF_ARGB8888 (3<<8) -#define DEPTH_FRMT_16_FIXED 0 -#define DEPTH_FRMT_16_FLOAT (1<<2) -#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) -#define VERT_LINE_STRIDE_1 (1<<1) -#define VERT_LINE_STRIDE_0 (0<<1) -#define VERT_LINE_STRIDE_OFS_1 1 -#define VERT_LINE_STRIDE_OFS_0 0 - -/* p166 */ -#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) -/* Dword 1 */ -#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) -#define DRAW_DITHER_OFS_X(x) ((x)<<26) -#define DRAW_DITHER_OFS_Y(x) ((x)<<24) -/* Dword 2 */ -#define DRAW_YMIN(x) ((x)<<16) -#define DRAW_XMIN(x) (x) -/* Dword 3 */ -#define DRAW_YMAX(x) ((x)<<16) -#define DRAW_XMAX(x) (x) -/* Dword 4 */ -#define DRAW_YORG(x) ((x)<<16) -#define DRAW_XORG(x) (x) - - -/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ - -/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ - - -/* _3DSTATE_FOG_COLOR, p173 */ -#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) -#define FOG_COLOR_RED(x) ((x)<<16) -#define FOG_COLOR_GREEN(x) ((x)<<8) -#define FOG_COLOR_BLUE(x) (x) - -/* _3DSTATE_FOG_MODE, p174 */ -#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) -/* Dword 1 */ -#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) -#define FMC1_FOGFUNC_VERTEX (0<<28) -#define FMC1_FOGFUNC_PIXEL_EXP (1<<28) -#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) -#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) -#define FMC1_FOGFUNC_MASK (3<<28) -#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) -#define FMC1_FOGINDEX_Z (0<<25) -#define FMC1_FOGINDEX_W (1<<25) -#define FMC1_C1_C2_MODIFY_ENABLE (1<<24) -#define FMC1_DENSITY_MODIFY_ENABLE (1<<23) -#define FMC1_C1_ONE (1<<13) -#define FMC1_C1_MASK (0xffff<<4) -/* Dword 2 */ -#define FMC2_C2_ONE (1<<16) -/* Dword 3 */ -#define FMC3_D_ONE (1<<16) - - - -/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ -#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) -#define IAB_MODIFY_ENABLE (1<<23) -#define IAB_ENABLE (1<<22) -#define IAB_MODIFY_FUNC (1<<21) -#define IAB_FUNC_SHIFT 16 -#define IAB_MODIFY_SRC_FACTOR (1<<11) -#define IAB_SRC_FACTOR_SHIFT 6 -#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) -#define IAB_MODIFY_DST_FACTOR (1<<5) -#define IAB_DST_FACTOR_SHIFT 0 -#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) - - -#define BLENDFUNC_ADD 0x0 -#define BLENDFUNC_SUBTRACT 0x1 -#define BLENDFUNC_REVERSE_SUBTRACT 0x2 -#define BLENDFUNC_MIN 0x3 -#define BLENDFUNC_MAX 0x4 -#define BLENDFUNC_MASK 0x7 - -/* 3DSTATE_LOAD_INDIRECT, p180 */ - -#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) -#define LI0_STATE_STATIC_INDIRECT (0x01<<8) -#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) -#define LI0_STATE_SAMPLER (0x04<<8) -#define LI0_STATE_MAP (0x08<<8) -#define LI0_STATE_PROGRAM (0x10<<8) -#define LI0_STATE_CONSTANTS (0x20<<8) - -#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) -#define SIS0_FORCE_LOAD (1<<1) -#define SIS0_BUFFER_VALID (1<<0) -#define SIS1_BUFFER_LENGTH(x) ((x)&0xff) - -#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) -#define DIS0_BUFFER_RESET (1<<1) -#define DIS0_BUFFER_VALID (1<<0) - -#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) -#define SSB0_FORCE_LOAD (1<<1) -#define SSB0_BUFFER_VALID (1<<0) -#define SSB1_BUFFER_LENGTH(x) ((x)&0xff) - -#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) -#define MSB0_FORCE_LOAD (1<<1) -#define MSB0_BUFFER_VALID (1<<0) -#define MSB1_BUFFER_LENGTH(x) ((x)&0xff) - -#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) -#define PSP0_FORCE_LOAD (1<<1) -#define PSP0_BUFFER_VALID (1<<0) -#define PSP1_BUFFER_LENGTH(x) ((x)&0xff) - -#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) -#define PSC0_FORCE_LOAD (1<<1) -#define PSC0_BUFFER_VALID (1<<0) -#define PSC1_BUFFER_LENGTH(x) ((x)&0xff) - - - - - -/* _3DSTATE_RASTERIZATION_RULES */ -#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) -#define ENABLE_POINT_RASTER_RULE (1<<15) -#define OGL_POINT_RASTER_RULE (1<<13) -#define ENABLE_TEXKILL_3D_4D (1<<10) -#define TEXKILL_3D (0<<9) -#define TEXKILL_4D (1<<9) -#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) -#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) -#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) -#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) - -/* _3DSTATE_SCISSOR_ENABLE, p256 */ -#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) -#define ENABLE_SCISSOR_RECT ((1<<1) | 1) -#define DISABLE_SCISSOR_RECT (1<<1) - -/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ -#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) -/* Dword 1 */ -#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) -#define SCISSOR_RECT_0_XMIN(x) (x) -/* Dword 2 */ -#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) -#define SCISSOR_RECT_0_XMAX(x) (x) - -/* p189 */ -#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) -#define I1_LOAD_S(n) (1<<(4+n)) - -#define S0_VB_OFFSET_MASK 0xffffffc -#define S0_AUTO_CACHE_INV_DISABLE (1<<0) - -#define S1_VERTEX_WIDTH_SHIFT 24 -#define S1_VERTEX_WIDTH_MASK (0x3f<<24) -#define S1_VERTEX_PITCH_SHIFT 16 -#define S1_VERTEX_PITCH_MASK (0x3f<<16) - -#define TEXCOORDFMT_2D 0x0 -#define TEXCOORDFMT_3D 0x1 -#define TEXCOORDFMT_4D 0x2 -#define TEXCOORDFMT_1D 0x3 -#define TEXCOORDFMT_2D_16 0x4 -#define TEXCOORDFMT_4D_16 0x5 -#define TEXCOORDFMT_NOT_PRESENT 0xf -#define S2_TEXCOORD_FMT0_MASK 0xf -#define S2_TEXCOORD_FMT1_SHIFT 4 -#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) -#define S2_TEXCOORD_NONE (~0) - -/* S3 not interesting */ - -#define S4_POINT_WIDTH_SHIFT 23 -#define S4_POINT_WIDTH_MASK (0x1ff<<23) -#define S4_LINE_WIDTH_SHIFT 19 -#define S4_LINE_WIDTH_ONE (0x2<<19) -#define S4_LINE_WIDTH_MASK (0xf<<19) -#define S4_FLATSHADE_ALPHA (1<<18) -#define S4_FLATSHADE_FOG (1<<17) -#define S4_FLATSHADE_SPECULAR (1<<16) -#define S4_FLATSHADE_COLOR (1<<15) -#define S4_CULLMODE_BOTH (0<<13) -#define S4_CULLMODE_NONE (1<<13) -#define S4_CULLMODE_CW (2<<13) -#define S4_CULLMODE_CCW (3<<13) -#define S4_CULLMODE_MASK (3<<13) -#define S4_VFMT_POINT_WIDTH (1<<12) -#define S4_VFMT_SPEC_FOG (1<<11) -#define S4_VFMT_COLOR (1<<10) -#define S4_VFMT_DEPTH_OFFSET (1<<9) -#define S4_VFMT_XYZ (1<<6) -#define S4_VFMT_XYZW (2<<6) -#define S4_VFMT_XY (3<<6) -#define S4_VFMT_XYW (4<<6) -#define S4_VFMT_XYZW_MASK (7<<6) -#define S4_FORCE_DEFAULT_DIFFUSE (1<<5) -#define S4_FORCE_DEFAULT_SPECULAR (1<<4) -#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) -#define S4_VFMT_FOG_PARAM (1<<2) -#define S4_SPRITE_POINT_ENABLE (1<<1) -#define S4_LINE_ANTIALIAS_ENABLE (1<<0) - -#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ - S4_VFMT_SPEC_FOG | \ - S4_VFMT_COLOR | \ - S4_VFMT_DEPTH_OFFSET | \ - S4_VFMT_XYZW_MASK | \ - S4_VFMT_FOG_PARAM) - - -#define S5_WRITEDISABLE_ALPHA (1<<31) -#define S5_WRITEDISABLE_RED (1<<30) -#define S5_WRITEDISABLE_GREEN (1<<29) -#define S5_WRITEDISABLE_BLUE (1<<28) -#define S5_WRITEDISABLE_MASK (0xf<<28) -#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) -#define S5_LAST_PIXEL_ENABLE (1<<26) -#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) -#define S5_FOG_ENABLE (1<<24) -#define S5_STENCIL_REF_SHIFT 16 -#define S5_STENCIL_REF_MASK (0xff<<16) -#define S5_STENCIL_TEST_FUNC_SHIFT 13 -#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) -#define S5_STENCIL_FAIL_SHIFT 10 -#define S5_STENCIL_FAIL_MASK (0x7<<10) -#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 -#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) -#define S5_STENCIL_PASS_Z_PASS_SHIFT 4 -#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) -#define S5_STENCIL_WRITE_ENABLE (1<<3) -#define S5_STENCIL_TEST_ENABLE (1<<2) -#define S5_COLOR_DITHER_ENABLE (1<<1) -#define S5_LOGICOP_ENABLE (1<<0) - - -#define S6_ALPHA_TEST_ENABLE (1<<31) -#define S6_ALPHA_TEST_FUNC_SHIFT 28 -#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) -#define S6_ALPHA_REF_SHIFT 20 -#define S6_ALPHA_REF_MASK (0xff<<20) -#define S6_DEPTH_TEST_ENABLE (1<<19) -#define S6_DEPTH_TEST_FUNC_SHIFT 16 -#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) -#define S6_CBUF_BLEND_ENABLE (1<<15) -#define S6_CBUF_BLEND_FUNC_SHIFT 12 -#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) -#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 -#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) -#define S6_CBUF_DST_BLEND_FACT_SHIFT 4 -#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) -#define S6_DEPTH_WRITE_ENABLE (1<<3) -#define S6_COLOR_WRITE_ENABLE (1<<2) -#define S6_TRISTRIP_PV_SHIFT 0 -#define S6_TRISTRIP_PV_MASK (0x3<<0) - -#define S7_DEPTH_OFFSET_CONST_MASK ~0 - - -/* Helper macros for blend factors - */ -#define DST_BLND_FACT(f) ((f)<= 0.0) ? src1 : src2 */ -#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ -#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ -#define A0_FLR (0x10<<24) /* dst = floor(src0) */ -#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ -#define A0_TRC (0x12<<24) /* dst = int(src0) */ -#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ -#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ -#define A0_DEST_SATURATE (1<<22) -#define A0_DEST_TYPE_SHIFT 19 -/* Allow: R, OC, OD, U */ -#define A0_DEST_NR_SHIFT 14 -/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ -#define A0_DEST_CHANNEL_X (1<<10) -#define A0_DEST_CHANNEL_Y (2<<10) -#define A0_DEST_CHANNEL_Z (4<<10) -#define A0_DEST_CHANNEL_W (8<<10) -#define A0_DEST_CHANNEL_ALL (0xf<<10) -#define A0_DEST_CHANNEL_SHIFT 10 -#define A0_SRC0_TYPE_SHIFT 7 -#define A0_SRC0_NR_SHIFT 2 - -#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) -#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) - - -#define SRC_X 0 -#define SRC_Y 1 -#define SRC_Z 2 -#define SRC_W 3 -#define SRC_ZERO 4 -#define SRC_ONE 5 - -#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) -#define A1_SRC0_CHANNEL_X_SHIFT 28 -#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) -#define A1_SRC0_CHANNEL_Y_SHIFT 24 -#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) -#define A1_SRC0_CHANNEL_Z_SHIFT 20 -#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) -#define A1_SRC0_CHANNEL_W_SHIFT 16 -#define A1_SRC1_TYPE_SHIFT 13 -#define A1_SRC1_NR_SHIFT 8 -#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) -#define A1_SRC1_CHANNEL_X_SHIFT 4 -#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) -#define A1_SRC1_CHANNEL_Y_SHIFT 0 - -#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) -#define A2_SRC1_CHANNEL_Z_SHIFT 28 -#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) -#define A2_SRC1_CHANNEL_W_SHIFT 24 -#define A2_SRC2_TYPE_SHIFT 21 -#define A2_SRC2_NR_SHIFT 16 -#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) -#define A2_SRC2_CHANNEL_X_SHIFT 12 -#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) -#define A2_SRC2_CHANNEL_Y_SHIFT 8 -#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) -#define A2_SRC2_CHANNEL_Z_SHIFT 4 -#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) -#define A2_SRC2_CHANNEL_W_SHIFT 0 - - - -/* Texture instructions */ -#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared - * sampler and address, and output - * filtered texel data to destination - * register */ -#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a - * perspective divide of the texture - * coordinate .xyz values by .w before - * sampling. */ -#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the - * computed LOD by w. Only S4.6 two's - * comp is used. This implies that a - * float to fixed conversion is - * done. */ -#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling - * operation. Simply kills the pixel - * if any channel of the address - * register is < 0.0. */ -#define T0_DEST_TYPE_SHIFT 19 -/* Allow: R, OC, OD, U */ -/* Note: U (unpreserved) regs do not retain their values between - * phases (cannot be used for feedback) - * - * Note: oC and OD registers can only be used as the destination of a - * texture instruction once per phase (this is an implementation - * restriction). - */ -#define T0_DEST_NR_SHIFT 14 -/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ -#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ -#define T0_SAMPLER_NR_MASK (0xf<<0) - -#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ -/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ -#define T1_ADDRESS_REG_NR_SHIFT 17 -#define T2_MBZ 0 - -/* Declaration instructions */ -#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) - * register or an s (sampler) - * register. */ -#define D0_SAMPLE_TYPE_SHIFT 22 -#define D0_SAMPLE_TYPE_2D (0x0<<22) -#define D0_SAMPLE_TYPE_CUBE (0x1<<22) -#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) -#define D0_SAMPLE_TYPE_MASK (0x3<<22) - -#define D0_TYPE_SHIFT 19 -/* Allow: T, S */ -#define D0_NR_SHIFT 14 -/* Allow T: 0..10, S: 0..15 */ -#define D0_CHANNEL_X (1<<10) -#define D0_CHANNEL_Y (2<<10) -#define D0_CHANNEL_Z (4<<10) -#define D0_CHANNEL_W (8<<10) -#define D0_CHANNEL_ALL (0xf<<10) -#define D0_CHANNEL_NONE (0<<10) - -#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) -#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) - -/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse - * or specular declarations. - * - * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) - * - * Must be zero for S (sampler) dcls - */ -#define D1_MBZ 0 -#define D2_MBZ 0 - - - -/* p207 */ -#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) - -#define MS1_MAPMASK_SHIFT 0 -#define MS1_MAPMASK_MASK (0x8fff<<0) - -#define MS2_UNTRUSTED_SURFACE (1<<31) -#define MS2_ADDRESS_MASK 0xfffffffc -#define MS2_VERTICAL_LINE_STRIDE (1<<1) -#define MS2_VERTICAL_OFFSET (1<<1) - -#define MS3_HEIGHT_SHIFT 21 -#define MS3_WIDTH_SHIFT 10 -#define MS3_PALETTE_SELECT (1<<9) -#define MS3_MAPSURF_FORMAT_SHIFT 7 -#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) -#define MAPSURF_8BIT (1<<7) -#define MAPSURF_16BIT (2<<7) -#define MAPSURF_32BIT (3<<7) -#define MAPSURF_422 (5<<7) -#define MAPSURF_COMPRESSED (6<<7) -#define MAPSURF_4BIT_INDEXED (7<<7) -#define MS3_MT_FORMAT_MASK (0x7 << 3) -#define MS3_MT_FORMAT_SHIFT 3 -#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ -#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ -#define MT_8BIT_L8 (1<<3) -#define MT_8BIT_A8 (4<<3) -#define MT_8BIT_MONO8 (5<<3) -#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ -#define MT_16BIT_ARGB1555 (1<<3) -#define MT_16BIT_ARGB4444 (2<<3) -#define MT_16BIT_AY88 (3<<3) -#define MT_16BIT_88DVDU (5<<3) -#define MT_16BIT_BUMP_655LDVDU (6<<3) -#define MT_16BIT_I16 (7<<3) -#define MT_16BIT_L16 (8<<3) -#define MT_16BIT_A16 (9<<3) -#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ -#define MT_32BIT_ABGR8888 (1<<3) -#define MT_32BIT_XRGB8888 (2<<3) -#define MT_32BIT_XBGR8888 (3<<3) -#define MT_32BIT_QWVU8888 (4<<3) -#define MT_32BIT_AXVU8888 (5<<3) -#define MT_32BIT_LXVU8888 (6<<3) -#define MT_32BIT_XLVU8888 (7<<3) -#define MT_32BIT_ARGB2101010 (8<<3) -#define MT_32BIT_ABGR2101010 (9<<3) -#define MT_32BIT_AWVU2101010 (0xA<<3) -#define MT_32BIT_GR1616 (0xB<<3) -#define MT_32BIT_VU1616 (0xC<<3) -#define MT_32BIT_xI824 (0xD<<3) -#define MT_32BIT_xA824 (0xE<<3) -#define MT_32BIT_xL824 (0xF<<3) -#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ -#define MT_422_YCRCB_NORMAL (1<<3) -#define MT_422_YCRCB_SWAPUV (2<<3) -#define MT_422_YCRCB_SWAPUVY (3<<3) -#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ -#define MT_COMPRESS_DXT2_3 (1<<3) -#define MT_COMPRESS_DXT4_5 (2<<3) -#define MT_COMPRESS_FXT1 (3<<3) -#define MT_COMPRESS_DXT1_RGB (4<<3) -#define MS3_USE_FENCE_REGS (1<<2) -#define MS3_TILED_SURFACE (1<<1) -#define MS3_TILE_WALK (1<<0) - -#define MS4_PITCH_SHIFT 21 -#define MS4_CUBE_FACE_ENA_NEGX (1<<20) -#define MS4_CUBE_FACE_ENA_POSX (1<<19) -#define MS4_CUBE_FACE_ENA_NEGY (1<<18) -#define MS4_CUBE_FACE_ENA_POSY (1<<17) -#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) -#define MS4_CUBE_FACE_ENA_POSZ (1<<15) -#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) -#define MS4_MAX_LOD_SHIFT 9 -#define MS4_MAX_LOD_MASK (0x3f<<9) -#define MS4_MIP_LAYOUT_LEGACY (0<<8) -#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) -#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) -#define MS4_VOLUME_DEPTH_SHIFT 0 -#define MS4_VOLUME_DEPTH_MASK (0xff<<0) - -/* p244 */ -#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) - -#define SS1_MAPMASK_SHIFT 0 -#define SS1_MAPMASK_MASK (0x8fff<<0) - -#define SS2_REVERSE_GAMMA_ENABLE (1<<31) -#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) -#define SS2_COLORSPACE_CONVERSION (1<<29) -#define SS2_CHROMAKEY_SHIFT 27 -#define SS2_BASE_MIP_LEVEL_SHIFT 22 -#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) -#define SS2_MIP_FILTER_SHIFT 20 -#define SS2_MIP_FILTER_MASK (0x3<<20) -#define MIPFILTER_NONE 0 -#define MIPFILTER_NEAREST 1 -#define MIPFILTER_LINEAR 3 -#define SS2_MAG_FILTER_SHIFT 17 -#define SS2_MAG_FILTER_MASK (0x7<<17) -#define FILTER_NEAREST 0 -#define FILTER_LINEAR 1 -#define FILTER_ANISOTROPIC 2 -#define FILTER_4X4_1 3 -#define FILTER_4X4_2 4 -#define FILTER_4X4_FLAT 5 -#define FILTER_6X5_MONO 6 /* XXX - check */ -#define SS2_MIN_FILTER_SHIFT 14 -#define SS2_MIN_FILTER_MASK (0x7<<14) -#define SS2_LOD_BIAS_SHIFT 5 -#define SS2_LOD_BIAS_ONE (0x10<<5) -#define SS2_LOD_BIAS_MASK (0x1ff<<5) -/* Shadow requires: - * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format - * FILTER_4X4_x MIN and MAG filters - */ -#define SS2_SHADOW_ENABLE (1<<4) -#define SS2_MAX_ANISO_MASK (1<<3) -#define SS2_MAX_ANISO_2 (0<<3) -#define SS2_MAX_ANISO_4 (1<<3) -#define SS2_SHADOW_FUNC_SHIFT 0 -#define SS2_SHADOW_FUNC_MASK (0x7<<0) -/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ - -#define SS3_MIN_LOD_SHIFT 24 -#define SS3_MIN_LOD_ONE (0x10<<24) -#define SS3_MIN_LOD_MASK (0xff<<24) -#define SS3_KILL_PIXEL_ENABLE (1<<17) -#define SS3_TCX_ADDR_MODE_SHIFT 12 -#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) -#define TEXCOORDMODE_WRAP 0 -#define TEXCOORDMODE_MIRROR 1 -#define TEXCOORDMODE_CLAMP_EDGE 2 -#define TEXCOORDMODE_CUBE 3 -#define TEXCOORDMODE_CLAMP_BORDER 4 -#define TEXCOORDMODE_MIRROR_ONCE 5 -#define SS3_TCY_ADDR_MODE_SHIFT 9 -#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) -#define SS3_TCZ_ADDR_MODE_SHIFT 6 -#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) -#define SS3_NORMALIZED_COORDS (1<<5) -#define SS3_TEXTUREMAP_INDEX_SHIFT 1 -#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) -#define SS3_DEINTERLACER_ENABLE (1<<0) - -#define SS4_BORDER_COLOR_MASK (~0) - -/* 3DSTATE_SPAN_STIPPLE, p258 - */ -#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) -#define ST1_ENABLE (1<<16) -#define ST1_MASK (0xffff) - -#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) -#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) -#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) - - -#define MI_FLUSH ((0<<29)|(4<<23)) -#define FLUSH_MAP_CACHE (1<<0) -#define INHIBIT_FLUSH_RENDER_CACHE (1<<2) - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c deleted file mode 100644 index e5d8d27993..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ /dev/null @@ -1,1014 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "dd.h" -#include "tnl/tnl.h" -#include "tnl/t_context.h" - -#include "texmem.h" - -#include "drivers/common/driverfuncs.h" - -#include "intel_fbo.h" -#include "intel_screen.h" -#include "intel_batchbuffer.h" - -#include "i915_context.h" -#include "i915_reg.h" - -#define FILE_DEBUG_FLAG DEBUG_STATE - -static void -i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, - GLuint mask) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - - mask = mask & 0xff; - - DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(func), ref, mask); - - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(mask)); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | - S5_STENCIL_TEST_FUNC_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | - (test << - S5_STENCIL_TEST_FUNC_SHIFT)); -} - -static void -i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - DBG("%s : mask 0x%x\n", __FUNCTION__, mask); - - mask = mask & 0xff; - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(mask)); -} - - -static void -i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, - GLenum zpass) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int fop = intel_translate_stencil_op(fail); - int dfop = intel_translate_stencil_op(zfail); - int dpop = intel_translate_stencil_op(zpass); - - - DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(fail), - _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | - S5_STENCIL_PASS_Z_FAIL_MASK | - S5_STENCIL_PASS_Z_PASS_MASK); - - i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | - (dfop << - S5_STENCIL_PASS_Z_FAIL_SHIFT) | - (dpop << - S5_STENCIL_PASS_Z_PASS_SHIFT)); -} - -static void -i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - GLubyte refByte; - - UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | - S6_ALPHA_REF_MASK); - i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | - (((GLuint) refByte) << - S6_ALPHA_REF_SHIFT)); -} - -/* This function makes sure that the proper enables are - * set for LogicOp, Independant Alpha Blend, and Blending. - * It needs to be called from numerous places where we - * could change the LogicOp or Independant Alpha Blend without subsequent - * calls to glEnable. - */ -static void -i915EvalLogicOpBlendState(GLcontext * ctx) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (RGBA_LOGICOP_ENABLED(ctx)) { - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; - } - else { - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; - - if (ctx->Color.BlendEnabled) { - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; - } - else { - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; - } - } -} - -static void -i915BlendColor(GLcontext * ctx, const GLfloat color[4]) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLubyte r, g, b, a; - - DBG("%s\n", __FUNCTION__); - - UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = - (a << 24) | (r << 16) | (g << 8) | b; -} - - -#define DST_BLND_FACT(f) ((f)<state.Ctx[I915_CTXREG_IAB] & - ~(IAB_SRC_FACTOR_MASK | - IAB_DST_FACTOR_MASK | - (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); - - GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & - ~(S6_CBUF_SRC_BLEND_FACT_MASK | - S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); - - GLuint eqRGB = ctx->Color.BlendEquationRGB; - GLuint eqA = ctx->Color.BlendEquationA; - GLuint srcRGB = ctx->Color.BlendSrcRGB; - GLuint dstRGB = ctx->Color.BlendDstRGB; - GLuint srcA = ctx->Color.BlendSrcA; - GLuint dstA = ctx->Color.BlendDstA; - - if (eqRGB == GL_MIN || eqRGB == GL_MAX) { - srcRGB = dstRGB = GL_ONE; - } - - if (eqA == GL_MIN || eqA == GL_MAX) { - srcA = dstA = GL_ONE; - } - - lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); - lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); - lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; - - iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); - iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); - iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; - - if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) - iab |= IAB_ENABLE; - - if (iab != i915->state.Ctx[I915_CTXREG_IAB] || - lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_IAB] = iab; - i915->state.Ctx[I915_CTXREG_LIS6] = lis6; - } - - /* This will catch a logicop blend equation */ - i915EvalLogicOpBlendState(ctx); -} - - -static void -i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB, - GLenum dstRGB, GLenum srcA, GLenum dstA) -{ - i915UpdateBlendState(ctx); -} - - -static void -i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA) -{ - i915UpdateBlendState(ctx); -} - - -static void -i915DepthFunc(GLcontext * ctx, GLenum func) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int test = intel_translate_compare_func(func); - - DBG("%s\n", __FUNCTION__); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; - i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; -} - -static void -i915DepthMask(GLcontext * ctx, GLboolean flag) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - DBG("%s flag (%d)\n", __FUNCTION__, flag); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (flag && ctx->Depth.Test) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; -} - -/* ============================================================= - * Polygon stipple - * - * The i915 supports a 4x4 stipple natively, GL wants 32x32. - * Fortunately stipple is usually a repeating pattern. - */ -static void -i915PolygonStipple(GLcontext * ctx, const GLubyte * mask) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - const GLubyte *m = mask; - GLubyte p[4]; - int i, j, k; - int active = (ctx->Polygon.StippleFlag && - i915->intel.reduced_primitive == GL_TRIANGLES); - GLuint newMask; - - if (active) { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; - } - - p[0] = mask[12] & 0xf; - p[0] |= p[0] << 4; - p[1] = mask[8] & 0xf; - p[1] |= p[1] << 4; - p[2] = mask[4] & 0xf; - p[2] |= p[2] << 4; - p[3] = mask[0] & 0xf; - p[3] |= p[3] << 4; - - for (k = 0; k < 8; k++) - for (j = 3; j >= 0; j--) - for (i = 0; i < 4; i++, m++) - if (*m != p[j]) { - i915->intel.hw_stipple = 0; - return; - } - - newMask = (((p[0] & 0xf) << 0) | - ((p[1] & 0xf) << 4) | - ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); - - - if (newMask == 0xffff || newMask == 0x0) { - /* this is needed to make conform pass */ - i915->intel.hw_stipple = 0; - return; - } - - i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; - i915->state.Stipple[I915_STPREG_ST1] |= newMask; - i915->intel.hw_stipple = 1; - - if (active) - i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; -} - - -/* ============================================================= - * Hardware clipping - */ -static void -i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int x1, y1, x2, y2; - - if (!ctx->DrawBuffer) - return; - - DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); - - if (ctx->DrawBuffer->Name == 0) { - x1 = x; - y1 = ctx->DrawBuffer->Height - (y + h); - x2 = x + w - 1; - y2 = y1 + h - 1; - DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); - } - else { - /* FBO - not inverted - */ - x1 = x; - y1 = y; - x2 = x + w - 1; - y2 = y + h - 1; - DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); - } - - x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); - y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); - x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); - y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); - - DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); - - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); - i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); -} - -static void -i915LogicOp(GLcontext * ctx, GLenum opcode) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int tmp = intel_translate_logic_op(opcode); - - DBG("%s\n", __FUNCTION__); - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; - i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); -} - - - -static void -i915CullFaceFrontFace(GLcontext * ctx, GLenum unused) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLuint mode; - - DBG("%s %d\n", __FUNCTION__, - ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); - - if (!ctx->Polygon.CullFlag) { - mode = S4_CULLMODE_NONE; - } - else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { - mode = S4_CULLMODE_CW; - - if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - if (ctx->Polygon.CullFaceMode == GL_FRONT) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - if (ctx->Polygon.FrontFace != GL_CCW) - mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); - } - else { - mode = S4_CULLMODE_BOTH; - } - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; - i915->state.Ctx[I915_CTXREG_LIS4] |= mode; -} - -static void -i915LineWidth(GLcontext * ctx, GLfloat widthf) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; - int width; - - DBG("%s\n", __FUNCTION__); - - width = (int) (widthf * 2); - CLAMP_SELF(width, 1, 0xf); - lis4 |= width << S4_LINE_WIDTH_SHIFT; - - if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] = lis4; - } -} - -static void -i915PointSize(GLcontext * ctx, GLfloat size) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; - GLint point_size = (int) size; - - DBG("%s\n", __FUNCTION__); - - CLAMP_SELF(point_size, 1, 255); - lis4 |= point_size << S4_POINT_WIDTH_SHIFT; - - if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS4] = lis4; - } -} - - -/* ============================================================= - * Color masks - */ - -static void -i915ColorMask(GLcontext * ctx, - GLboolean r, GLboolean g, GLboolean b, GLboolean a) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; - - DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, - a); - - if (!r) - tmp |= S5_WRITEDISABLE_RED; - if (!g) - tmp |= S5_WRITEDISABLE_GREEN; - if (!b) - tmp |= S5_WRITEDISABLE_BLUE; - if (!a) - tmp |= S5_WRITEDISABLE_ALPHA; - - if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - i915->state.Ctx[I915_CTXREG_LIS5] = tmp; - } -} - -static void -update_specular(GLcontext * ctx) -{ - /* A hack to trigger the rebuild of the fragment program. - */ - intel_context(ctx)->NewGLState |= _NEW_TEXTURE; -} - -static void -i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) -{ - DBG("%s\n", __FUNCTION__); - - if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { - update_specular(ctx); - } -} - -static void -i915ShadeModel(GLcontext * ctx, GLenum mode) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - - if (mode == GL_SMOOTH) { - i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); - } - else { - i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | - S4_FLATSHADE_COLOR | - S4_FLATSHADE_SPECULAR); - } -} - -/* ============================================================= - * Fog - */ -void -i915_update_fog(GLcontext * ctx) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - GLenum mode; - GLboolean enabled; - GLboolean try_pixel_fog; - - if (ctx->FragmentProgram._Active) { - /* Pull in static fog state from program */ - mode = ctx->FragmentProgram._Current->FogOption; - enabled = (mode != GL_NONE); - try_pixel_fog = 0; - } - else { - enabled = ctx->Fog.Enabled; - mode = ctx->Fog.Mode; -#if 0 - /* XXX - DISABLED -- Need ortho fallback */ - try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT - && ctx->Hint.Fog == GL_NICEST); -#else - try_pixel_fog = 0; -#endif - } - - if (!enabled) { - i915->vertex_fog = I915_FOG_NONE; - } - else if (try_pixel_fog) { - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; - i915->vertex_fog = I915_FOG_PIXEL; - - switch (mode) { - case GL_LINEAR: - if (ctx->Fog.End <= ctx->Fog.Start) { - /* XXX - this won't work with fragment programs. Need to - * either fallback or append fog instructions to end of - * program in the case of linear fog. - */ - printf("vertex fog!\n"); - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; - i915->vertex_fog = I915_FOG_VERTEX; - } - else { - GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); - GLfloat c1 = ctx->Fog.End * c2; - - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; - i915->state.Fog[I915_FOGREG_MODE1] |= - ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; - - if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE2] - = (GLuint) (c2 * FMC2_C2_ONE); - } - else { - fi_type fi; - fi.f = c2; - i915->state.Fog[I915_FOGREG_MODE2] = fi.i; - } - } - break; - case GL_EXP: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; - break; - case GL_EXP2: - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; - break; - default: - break; - } - } - else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; - i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; - i915->vertex_fog = I915_FOG_VERTEX; - } - - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); - if (enabled) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; - - /* Always enable pixel fog. Vertex fog using fog coord will conflict - * with fog code appended onto fragment program. - */ - _tnl_allow_vertex_fog( ctx, 0 ); - _tnl_allow_pixel_fog( ctx, 1 ); -} - -static void -i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - switch (pname) { - case GL_FOG_COORDINATE_SOURCE_EXT: - case GL_FOG_MODE: - case GL_FOG_START: - case GL_FOG_END: - break; - - case GL_FOG_DENSITY: - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - - if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { - i915->state.Fog[I915_FOGREG_MODE3] = - (GLuint) (ctx->Fog.Density * FMC3_D_ONE); - } - else { - fi_type fi; - fi.f = ctx->Fog.Density; - i915->state.Fog[I915_FOGREG_MODE3] = fi.i; - } - break; - - case GL_FOG_COLOR: - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_COLOR] = - (_3DSTATE_FOG_COLOR_CMD | - ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | - ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | - ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); - break; - - default: - break; - } -} - -static void -i915Hint(GLcontext * ctx, GLenum target, GLenum state) -{ - switch (target) { - case GL_FOG_HINT: - break; - default: - break; - } -} - -/* ============================================================= - */ - -static void -i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - switch (cap) { - case GL_TEXTURE_2D: - break; - - case GL_LIGHTING: - case GL_COLOR_SUM: - update_specular(ctx); - break; - - case GL_ALPHA_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; - break; - - case GL_BLEND: - i915EvalLogicOpBlendState(ctx); - break; - - case GL_COLOR_LOGIC_OP: - i915EvalLogicOpBlendState(ctx); - - /* Logicop doesn't seem to work at 16bpp: - */ - if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ - FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); - break; - - case GL_FRAGMENT_PROGRAM_ARB: - break; - - case GL_DITHER: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; - break; - - case GL_DEPTH_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; - - i915DepthMask(ctx, ctx->Depth.Mask); - break; - - case GL_SCISSOR_TEST: - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - if (state) - i915->state.Buffer[I915_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); - else - i915->state.Buffer[I915_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - break; - - case GL_LINE_SMOOTH: - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; - else - i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; - break; - - case GL_FOG: - break; - - case GL_CULL_FACE: - i915CullFaceFrontFace(ctx, 0); - break; - - case GL_STENCIL_TEST: - { - GLboolean hw_stencil = GL_FALSE; - if (ctx->DrawBuffer) { - struct intel_renderbuffer *irbStencil - = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); - hw_stencil = (irbStencil && irbStencil->region); - } - if (hw_stencil) { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - if (state) - i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - else - i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | - S5_STENCIL_WRITE_ENABLE); - } - else { - FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); - } - } - break; - - case GL_POLYGON_STIPPLE: - /* The stipple command worked on my 855GM box, but not my 845G. - * I'll do more testing later to find out exactly which hardware - * supports it. Disabled for now. - */ - if (i915->intel.hw_stipple && - i915->intel.reduced_primitive == GL_TRIANGLES) { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - if (state) - i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; - else - i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; - } - break; - - case GL_POLYGON_SMOOTH: - break; - - case GL_POINT_SMOOTH: - break; - - default: - ; - } -} - - -static void -i915_init_packets(struct i915_context *i915) -{ - intelScreenPrivate *screen = i915->intel.intelScreen; - - /* Zero all state */ - memset(&i915->state, 0, sizeof(i915->state)); - - - { - I915_STATECHANGE(i915, I915_UPLOAD_CTX); - /* Probably don't want to upload all this stuff every time one - * piece changes. - */ - i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | - I1_LOAD_S(2) | - I1_LOAD_S(4) | - I1_LOAD_S(5) | I1_LOAD_S(6) | (3)); - i915->state.Ctx[I915_CTXREG_LIS2] = 0; - i915->state.Ctx[I915_CTXREG_LIS4] = 0; - i915->state.Ctx[I915_CTXREG_LIS5] = 0; - - if (screen->cpp == 2) /* XXX FBO fix */ - i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; - - - i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | - (2 << S6_TRISTRIP_PV_SHIFT)); - - i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | - ENABLE_LOGIC_OP_FUNC | - LOGIC_OP_FUNC(LOGICOP_COPY) | - ENABLE_STENCIL_TEST_MASK | - STENCIL_TEST_MASK(0xff) | - ENABLE_STENCIL_WRITE_MASK | - STENCIL_WRITE_MASK(0xff)); - - i915->state.Ctx[I915_CTXREG_IAB] = - (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | - IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); - - i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = - _3DSTATE_CONST_BLEND_COLOR_CMD; - i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; - - } - - { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; - } - - - { - I915_STATECHANGE(i915, I915_UPLOAD_FOG); - i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; - i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | - FMC1_FOGFUNC_VERTEX | - FMC1_FOGINDEX_MODIFY_ENABLE | - FMC1_FOGINDEX_W | - FMC1_C1_C2_MODIFY_ENABLE | - FMC1_DENSITY_MODIFY_ENABLE); - i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; - } - - - { - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); - /* color buffer offset/stride */ - i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ - i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - - i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ - i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ - BUF_3D_USE_FENCE); - - i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; - - /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ -#if 0 /* seems we don't need this */ - switch (screen->fbFormat) { - case DV_PF_565: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - DITHER_FULL_ALWAYS | - screen->fbFormat | - DEPTH_FRMT_16_FIXED); - break; - case DV_PF_8888: - i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - screen->fbFormat | - DEPTH_FRMT_24_FIXED_8_OTHER); - break; - } -#endif - - - /* scissor */ - i915->state.Buffer[I915_DESTREG_SENABLE] = - (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; - i915->state.Buffer[I915_DESTREG_SR1] = 0; - i915->state.Buffer[I915_DESTREG_SR2] = 0; - } - - -#if 0 - { - I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); - i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; - i915->state.Default[I915_DEFREG_C1] = 0; - i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; - i915->state.Default[I915_DEFREG_S1] = 0; - i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; - i915->state.Default[I915_DEFREG_Z1] = 0; - } -#endif - - - /* These will be emitted every at the head of every buffer, unless - * we get hardware contexts working. - */ - i915->state.active = (I915_UPLOAD_PROGRAM | - I915_UPLOAD_STIPPLE | - I915_UPLOAD_CTX | - I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT); -} - -void -i915InitStateFunctions(struct dd_function_table *functions) -{ - functions->AlphaFunc = i915AlphaFunc; - functions->BlendColor = i915BlendColor; - functions->BlendEquationSeparate = i915BlendEquationSeparate; - functions->BlendFuncSeparate = i915BlendFuncSeparate; - functions->ColorMask = i915ColorMask; - functions->CullFace = i915CullFaceFrontFace; - functions->DepthFunc = i915DepthFunc; - functions->DepthMask = i915DepthMask; - functions->Enable = i915Enable; - functions->Fogfv = i915Fogfv; - functions->FrontFace = i915CullFaceFrontFace; - functions->Hint = i915Hint; - functions->LightModelfv = i915LightModelfv; - functions->LineWidth = i915LineWidth; - functions->LogicOpcode = i915LogicOp; - functions->PointSize = i915PointSize; - functions->PolygonStipple = i915PolygonStipple; - functions->Scissor = i915Scissor; - functions->ShadeModel = i915ShadeModel; - functions->StencilFuncSeparate = i915StencilFuncSeparate; - functions->StencilMaskSeparate = i915StencilMaskSeparate; - functions->StencilOpSeparate = i915StencilOpSeparate; -} - - -void -i915InitState(struct i915_context *i915) -{ - GLcontext *ctx = &i915->intel.ctx; - - i915_init_packets(i915); - - _mesa_init_driver_state(ctx); - - memcpy(&i915->initial, &i915->state, sizeof(i915->state)); - i915->current = &i915->state; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c deleted file mode 100644 index 59e148ca04..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_tex.c +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "simple_list.h" -#include "enums.h" -#include "image.h" -#include "texstore.h" -#include "texformat.h" -#include "texmem.h" -#include "swrast/swrast.h" - -#include "mm.h" - -#include "intel_ioctl.h" - -#include "i915_context.h" -#include "i915_reg.h" - - - -static void -i915TexEnv(GLcontext * ctx, GLenum target, - GLenum pname, const GLfloat * param) -{ - struct i915_context *i915 = I915_CONTEXT(ctx); - - switch (pname) { - case GL_TEXTURE_LOD_BIAS:{ - GLuint unit = ctx->Texture.CurrentUnit; - GLint b = (int) ((*param) * 16.0); - if (b > 255) - b = 255; - if (b < -256) - b = -256; - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->lodbias_ss2[unit] = - ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); - break; - } - - default: - break; - } -} - - -void -i915InitTextureFuncs(struct dd_function_table *functions) -{ - functions->TexEnv = i915TexEnv; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c deleted file mode 100644 index 7b761a7b22..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c +++ /dev/null @@ -1,343 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Code to layout images in a mipmap tree for i915 and i945 - * respectively. - */ - -#include "intel_mipmap_tree.h" -#include "intel_tex_layout.h" -#include "macros.h" -#include "intel_context.h" - -#define FILE_DEBUG_FLAG DEBUG_TEXTURE - -static GLint initial_offsets[6][2] = { {0, 0}, -{0, 2}, -{1, 0}, -{1, 2}, -{1, 1}, -{1, 3} -}; - - -static GLint step_offsets[6][2] = { {0, 2}, -{0, 2}, -{-1, 2}, -{-1, 2}, -{-1, 1}, -{-1, 1} -}; - -GLboolean -i915_miptree_layout(struct intel_mipmap_tree * mt) -{ - GLint level; - - switch (mt->target) { - case GL_TEXTURE_CUBE_MAP:{ - const GLuint dim = mt->width0; - GLuint face; - GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; - - assert(lvlWidth == lvlHeight); /* cubemap images are square */ - - /* double pitch for cube layouts */ - mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; - mt->total_height = dim * 4; - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_level_info(mt, level, 6, - 0, 0, - /*OLD: mt->pitch, mt->total_height,*/ - lvlWidth, lvlHeight, - 1); - lvlWidth /= 2; - lvlHeight /= 2; - } - - for (face = 0; face < 6; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_image_offset(mt, level, face, x, y); - - if (d == 0) - _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", - face, level, mt->first_level, mt->last_level); - - d >>= 1; - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - } - } - break; - } - case GL_TEXTURE_3D:{ - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; - GLuint stack_height = 0; - - /* Calculate the size of a single slice. - */ - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - - /* XXX: hardware expects/requires 9 levels at minimum. - */ - for (level = mt->first_level; level <= MAX2(8, mt->last_level); - level++) { - intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height, - width, height, depth); - - - stack_height += MAX2(2, height); - - width = minify(width); - height = minify(height); - depth = minify(depth); - } - - /* Fixup depth image_offsets: - */ - depth = mt->depth0; - for (level = mt->first_level; level <= mt->last_level; level++) { - GLuint i; - for (i = 0; i < depth; i++) - intel_miptree_set_image_offset(mt, level, i, - 0, i * stack_height); - - depth = minify(depth); - } - - - /* Multiply slice size by texture depth for total size. It's - * remarkable how wasteful of memory the i915 texture layouts - * are. They are largely fixed in the i945. - */ - mt->total_height = stack_height * mt->depth0; - break; - } - - default:{ - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint img_height; - - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_level_info(mt, level, 1, - 0, mt->total_height, - width, height, 1); - - if (mt->compressed) - img_height = MAX2(1, height / 4); - else - img_height = (MAX2(2, height) + 1) & ~1; - - mt->total_height += img_height; - - width = minify(width); - height = minify(height); - } - break; - } - } - DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, - mt->pitch, - mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); - - return GL_TRUE; -} - - -GLboolean -i945_miptree_layout(struct intel_mipmap_tree * mt) -{ - GLint level; - - switch (mt->target) { - case GL_TEXTURE_CUBE_MAP:{ - const GLuint dim = mt->width0; - GLuint face; - GLuint lvlWidth = mt->width0, lvlHeight = mt->height0; - - assert(lvlWidth == lvlHeight); /* cubemap images are square */ - - /* Depending on the size of the largest images, pitch can be - * determined either by the old-style packing of cubemap faces, - * or the final row of 4x4, 2x2 and 1x1 faces below this. - */ - if (dim > 32) - mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; - else - mt->pitch = 14 * 8; - - mt->total_height = dim * 4 + 4; - - /* Set all the levels to effectively occupy the whole rectangular region. - */ - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_level_info(mt, level, 6, - 0, 0, - lvlWidth, lvlHeight, 1); - lvlWidth /= 2; - lvlHeight /= 2; - } - - - for (face = 0; face < 6; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - if (dim == 4 && face >= 4) { - y = mt->total_height - 4; - x = (face - 4) * 8; - } - else if (dim < 4 && (face > 0 || mt->first_level > 0)) { - y = mt->total_height - 4; - x = face * 8; - } - - for (level = mt->first_level; level <= mt->last_level; level++) { - intel_miptree_set_image_offset(mt, level, face, x, y); - - d >>= 1; - - switch (d) { - case 4: - switch (face) { - case FACE_POS_X: - case FACE_NEG_X: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - case FACE_POS_Y: - case FACE_NEG_Y: - y += 12; - x -= 8; - break; - case FACE_POS_Z: - case FACE_NEG_Z: - y = mt->total_height - 4; - x = (face - 4) * 8; - break; - } - - case 2: - y = mt->total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - break; - } - case GL_TEXTURE_3D:{ - GLuint width = mt->width0; - GLuint height = mt->height0; - GLuint depth = mt->depth0; - GLuint pack_x_pitch, pack_x_nr; - GLuint pack_y_pitch; - GLuint level; - - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; - - pack_y_pitch = MAX2(mt->height0, 2); - pack_x_pitch = mt->pitch; - pack_x_nr = 1; - - for (level = mt->first_level; level <= mt->last_level; level++) { - GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6; - GLint x = 0; - GLint y = 0; - GLint q, j; - - intel_miptree_set_level_info(mt, level, nr_images, - 0, mt->total_height, - width, height, depth); - - for (q = 0; q < nr_images;) { - for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { - intel_miptree_set_image_offset(mt, level, q, x, y); - x += pack_x_pitch; - } - - x = 0; - y += pack_y_pitch; - } - - - mt->total_height += y; - - if (pack_x_pitch > 4) { - pack_x_pitch >>= 1; - pack_x_nr <<= 1; - assert(pack_x_pitch * pack_x_nr <= mt->pitch); - } - - if (pack_y_pitch > 2) { - pack_y_pitch >>= 1; - } - - width = minify(width); - height = minify(height); - depth = minify(depth); - } - break; - } - - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_RECTANGLE_ARB: - i945_miptree_layout_2d(mt); - break; - default: - _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); - } - - DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, - mt->pitch, - mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); - - return GL_TRUE; -} diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c deleted file mode 100644 index 09684e87b4..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_texstate.c +++ /dev/null @@ -1,359 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "mtypes.h" -#include "enums.h" -#include "texformat.h" -#include "dri_bufmgr.h" - -#include "intel_mipmap_tree.h" -#include "intel_tex.h" - -#include "i915_context.h" -#include "i915_reg.h" - - -static GLuint -translate_texture_format(GLuint mesa_format) -{ - switch (mesa_format) { - case MESA_FORMAT_L8: - return MAPSURF_8BIT | MT_8BIT_L8; - case MESA_FORMAT_I8: - return MAPSURF_8BIT | MT_8BIT_I8; - case MESA_FORMAT_A8: - return MAPSURF_8BIT | MT_8BIT_A8; - case MESA_FORMAT_AL88: - return MAPSURF_16BIT | MT_16BIT_AY88; - case MESA_FORMAT_RGB565: - return MAPSURF_16BIT | MT_16BIT_RGB565; - case MESA_FORMAT_ARGB1555: - return MAPSURF_16BIT | MT_16BIT_ARGB1555; - case MESA_FORMAT_ARGB4444: - return MAPSURF_16BIT | MT_16BIT_ARGB4444; - case MESA_FORMAT_ARGB8888: - return MAPSURF_32BIT | MT_32BIT_ARGB8888; - case MESA_FORMAT_YCBCR_REV: - return (MAPSURF_422 | MT_422_YCRCB_NORMAL); - case MESA_FORMAT_YCBCR: - return (MAPSURF_422 | MT_422_YCRCB_SWAPY); - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); - case MESA_FORMAT_Z16: - return (MAPSURF_16BIT | MT_16BIT_L16); - case MESA_FORMAT_RGBA_DXT1: - case MESA_FORMAT_RGB_DXT1: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - case MESA_FORMAT_RGBA_DXT3: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - case MESA_FORMAT_RGBA_DXT5: - return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); - case MESA_FORMAT_Z24_S8: - return (MAPSURF_32BIT | MT_32BIT_xL824); - default: - fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); - abort(); - return 0; - } -} - - - - -/* The i915 (and related graphics cores) do not support GL_CLAMP. The - * Intel drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - */ -static GLuint -translate_wrap_mode(GLenum wrap) -{ - switch (wrap) { - case GL_REPEAT: - return TEXCOORDMODE_WRAP; - case GL_CLAMP: - return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ - case GL_CLAMP_TO_EDGE: - return TEXCOORDMODE_CLAMP_EDGE; - case GL_CLAMP_TO_BORDER: - return TEXCOORDMODE_CLAMP_BORDER; - case GL_MIRRORED_REPEAT: - return TEXCOORDMODE_MIRROR; - default: - return TEXCOORDMODE_WRAP; - } -} - - - -/* Recalculate all state from scratch. Perhaps not the most - * efficient, but this has gotten complex enough that we need - * something which is understandable and reliable. - */ -static GLboolean -i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) -{ - GLcontext *ctx = &intel->ctx; - struct i915_context *i915 = i915_context(ctx); - struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; - struct intel_texture_object *intelObj = intel_texture_object(tObj); - struct gl_texture_image *firstImage; - GLuint *state = i915->state.Tex[unit], format, pitch; - - memset(state, 0, sizeof(state)); - - /*We need to refcount these. */ - - if (i915->state.tex_buffer[unit] != NULL) { - dri_bo_unreference(i915->state.tex_buffer[unit]); - i915->state.tex_buffer[unit] = NULL; - } - - if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit)) - return GL_FALSE; - - /* Get first image here, since intelObj->firstLevel will get set in - * the intel_finalize_mipmap_tree() call above. - */ - firstImage = tObj->Image[0][intelObj->firstLevel]; - - if (intelObj->imageOverride) { - i915->state.tex_buffer[unit] = NULL; - i915->state.tex_offset[unit] = intelObj->textureOffset; - - switch (intelObj->depthOverride) { - case 32: - format = MAPSURF_32BIT | MT_32BIT_ARGB8888; - break; - case 24: - default: - format = MAPSURF_32BIT | MT_32BIT_XRGB8888; - break; - case 16: - format = MAPSURF_16BIT | MT_16BIT_RGB565; - break; - } - - pitch = intelObj->pitchOverride; - } else { - dri_bo_reference(intelObj->mt->region->buffer); - i915->state.tex_buffer[unit] = intelObj->mt->region->buffer; - i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, - 0, intelObj-> - firstLevel); - - format = translate_texture_format(firstImage->TexFormat->MesaFormat); - pitch = intelObj->mt->pitch * intelObj->mt->cpp; - } - - state[I915_TEXREG_MS3] = - (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | - ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format | - MS3_USE_FENCE_REGS); - - state[I915_TEXREG_MS4] = - ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK | - ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) << - MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - 1) << - MS4_VOLUME_DEPTH_SHIFT)); - - - { - GLuint minFilt, mipFilt, magFilt; - - switch (tObj->MinFilter) { - case GL_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NONE; - break; - case GL_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_LINEAR; - break; - default: - return GL_FALSE; - } - - if (tObj->MaxAnisotropy > 1.0) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - switch (tObj->MagFilter) { - case GL_NEAREST: - magFilt = FILTER_NEAREST; - break; - case GL_LINEAR: - magFilt = FILTER_LINEAR; - break; - default: - return GL_FALSE; - } - } - - state[I915_TEXREG_SS2] = i915->lodbias_ss2[unit]; - - /* YUV conversion: - */ - if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || - firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) - state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION; - - /* Shadow: - */ - if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && - tObj->Target != GL_TEXTURE_3D) { - - state[I915_TEXREG_SS2] |= - (SS2_SHADOW_ENABLE | - intel_translate_compare_func(tObj->CompareFunc)); - - minFilt = FILTER_4X4_FLAT; - magFilt = FILTER_4X4_FLAT; - } - - state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | - (mipFilt << SS2_MIP_FILTER_SHIFT) | - (magFilt << SS2_MAG_FILTER_SHIFT)); - } - - { - GLenum ws = tObj->WrapS; - GLenum wt = tObj->WrapT; - GLenum wr = tObj->WrapR; - - - /* 3D textures don't seem to respect the border color. - * Fallback if there's ever a danger that they might refer to - * it. - * - * Effectively this means fallback on 3D clamp or - * clamp_to_border. - */ - if (tObj->Target == GL_TEXTURE_3D && - (tObj->MinFilter != GL_NEAREST || - tObj->MagFilter != GL_NEAREST) && - (ws == GL_CLAMP || - wt == GL_CLAMP || - wr == GL_CLAMP || - ws == GL_CLAMP_TO_BORDER || - wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER)) - return GL_FALSE; - - - state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */ - - state[I915_TEXREG_SS3] |= - ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | - (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | - (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); - - state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); - } - - - state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], - tObj->_BorderChan[1], - tObj->_BorderChan[2], - tObj->_BorderChan[3]); - - - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); - /* memcmp was already disabled, but definitely won't work as the - * region might now change and that wouldn't be detected: - */ - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - - -#if 0 - DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]); - DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]); - DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]); - DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]); - DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]); - DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]); -#endif - - return GL_TRUE; -} - - - - -void -i915UpdateTextureState(struct intel_context *intel) -{ - GLboolean ok = GL_TRUE; - GLuint i; - - for (i = 0; i < I915_TEX_UNITS && ok; i++) { - switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { - case TEXTURE_1D_BIT: - case TEXTURE_2D_BIT: - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS); - break; - case TEXTURE_RECT_BIT: - ok = i915_update_tex_unit(intel, i, 0); - break; - case 0:{ - struct i915_context *i915 = i915_context(&intel->ctx); - if (i915->state.active & I915_UPLOAD_TEX(i)) - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); - - if (i915->state.tex_buffer[i] != NULL) { - dri_bo_unreference(i915->state.tex_buffer[i]); - i915->state.tex_buffer[i] = NULL; - } - - break; - } - default: - ok = GL_FALSE; - break; - } - } - - FALLBACK(intel, I915_FALLBACK_TEXTURE, !ok); -} diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c deleted file mode 100644 index 35757e17eb..0000000000 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ /dev/null @@ -1,571 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - - -#include "glheader.h" -#include "mtypes.h" -#include "imports.h" -#include "macros.h" -#include "colormac.h" - -#include "tnl/t_context.h" -#include "tnl/t_vertex.h" - -#include "intel_batchbuffer.h" -#include "intel_tex.h" -#include "intel_regions.h" - -#include "i915_reg.h" -#include "i915_context.h" - -static void -i915_render_prevalidate(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - - i915ValidateFragmentProgram(i915); -} - -static void -i915_render_start(struct intel_context *intel) -{ -} - - -static void -i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; - - st1 &= ~ST1_ENABLE; - - switch (rprim) { - case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */ - case GL_TRIANGLES: - if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) - st1 |= ST1_ENABLE; - break; - case GL_LINES: - case GL_POINTS: - default: - break; - } - - i915->intel.reduced_primitive = rprim; - - if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { - INTEL_FIREVERTICES(intel); - - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST1] = st1; - } -} - - -/* Pull apart the vertex format registers and figure out how large a - * vertex is supposed to be. - */ -static GLboolean -i915_check_vertex_size(struct intel_context *intel, GLuint expected) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; - int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; - int i, sz = 0; - - switch (lis4 & S4_VFMT_XYZW_MASK) { - case S4_VFMT_XY: - sz = 2; - break; - case S4_VFMT_XYZ: - sz = 3; - break; - case S4_VFMT_XYW: - sz = 3; - break; - case S4_VFMT_XYZW: - sz = 4; - break; - default: - fprintf(stderr, "no xyzw specified\n"); - return 0; - } - - if (lis4 & S4_VFMT_SPEC_FOG) - sz++; - if (lis4 & S4_VFMT_COLOR) - sz++; - if (lis4 & S4_VFMT_DEPTH_OFFSET) - sz++; - if (lis4 & S4_VFMT_POINT_WIDTH) - sz++; - if (lis4 & S4_VFMT_FOG_PARAM) - sz++; - - for (i = 0; i < 8; i++) { - switch (lis2 & S2_TEXCOORD_FMT0_MASK) { - case TEXCOORDFMT_2D: - sz += 2; - break; - case TEXCOORDFMT_3D: - sz += 3; - break; - case TEXCOORDFMT_4D: - sz += 4; - break; - case TEXCOORDFMT_1D: - sz += 1; - break; - case TEXCOORDFMT_2D_16: - sz += 1; - break; - case TEXCOORDFMT_4D_16: - sz += 2; - break; - case TEXCOORDFMT_NOT_PRESENT: - break; - default: - fprintf(stderr, "bad texcoord fmt %d\n", i); - return GL_FALSE; - } - lis2 >>= S2_TEXCOORD_FMT1_SHIFT; - } - - if (sz != expected) - fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); - - return sz == expected; -} - - -static void -i915_emit_invarient_state(struct intel_context *intel) -{ - BATCH_LOCALS; - - BEGIN_BATCH(200, 0); - - OUT_BATCH(_3DSTATE_AA_CMD | - AA_LINE_ECAAR_WIDTH_ENABLE | - AA_LINE_ECAAR_WIDTH_1_0 | - AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); - - OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DFLT_Z_CMD); - OUT_BATCH(0); - - /* Don't support texture crossbar yet */ - OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | - CSB_TCB(0, 0) | - CSB_TCB(1, 1) | - CSB_TCB(2, 2) | - CSB_TCB(3, 3) | - CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); - - OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | - ENABLE_POINT_RASTER_RULE | - OGL_POINT_RASTER_RULE | - ENABLE_LINE_STRIP_PROVOKE_VRTX | - ENABLE_TRI_FAN_PROVOKE_VRTX | - LINE_STRIP_PROVOKE_VRTX(1) | - TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); - - /* Need to initialize this to zero. - */ - OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0)); - OUT_BATCH(0); - - /* XXX: Use this */ - OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); - - OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); - OUT_BATCH(0); - OUT_BATCH(0); - - OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); - - OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ - OUT_BATCH(0); - - - /* Don't support twosided stencil yet */ - OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); - OUT_BATCH(0); - - ADVANCE_BATCH(); -} - - -#define emit(intel, state, size ) \ - intel_batchbuffer_data(intel->batch, state, size, 0 ) - -static GLuint -get_dirty(struct i915_hw_state *state) -{ - GLuint dirty; - - /* Workaround the multitex hang - if one texture unit state is - * modified, emit all texture units. - */ - dirty = state->active & ~state->emitted; - if (dirty & I915_UPLOAD_TEX_ALL) - state->emitted &= ~I915_UPLOAD_TEX_ALL; - dirty = state->active & ~state->emitted; - return dirty; -} - - -static GLuint -get_state_size(struct i915_hw_state *state) -{ - GLuint dirty = get_dirty(state); - GLuint i; - GLuint sz = 0; - - if (dirty & I915_UPLOAD_INVARIENT) - sz += 30 * 4; - - if (dirty & I915_UPLOAD_CTX) - sz += sizeof(state->Ctx); - - if (dirty & I915_UPLOAD_BUFFERS) - sz += sizeof(state->Buffer); - - if (dirty & I915_UPLOAD_STIPPLE) - sz += sizeof(state->Stipple); - - if (dirty & I915_UPLOAD_FOG) - sz += sizeof(state->Fog); - - if (dirty & I915_UPLOAD_TEX_ALL) { - int nr = 0; - for (i = 0; i < I915_TEX_UNITS; i++) - if (dirty & I915_UPLOAD_TEX(i)) - nr++; - - sz += (2 + nr * 3) * sizeof(GLuint) * 2; - } - - if (dirty & I915_UPLOAD_CONSTANTS) - sz += state->ConstantSize * sizeof(GLuint); - - if (dirty & I915_UPLOAD_PROGRAM) - sz += state->ProgramSize * sizeof(GLuint); - - return sz; -} - - -/* Push the state into the sarea and/or texture memory. - */ -static void -i915_emit_state(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - struct i915_hw_state *state = i915->current; - int i; - GLuint dirty; - BATCH_LOCALS; - - /* We don't hold the lock at this point, so want to make sure that - * there won't be a buffer wrap. - * - * It might be better to talk about explicit places where - * scheduling is allowed, rather than assume that it is whenever a - * batchbuffer fills up. - */ - intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); - - /* Do this here as we may have flushed the batchbuffer above, - * causing more state to be dirty! - */ - dirty = get_dirty(state); - state->emitted |= dirty; - - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); - - if (dirty & I915_UPLOAD_INVARIENT) { - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); - i915_emit_invarient_state(intel); - } - - if (dirty & I915_UPLOAD_CTX) { - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "I915_UPLOAD_CTX:\n"); - - emit(intel, state->Ctx, sizeof(state->Ctx)); - } - - if (dirty & I915_UPLOAD_BUFFERS) { - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); - BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, 0); - OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); - OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); - OUT_RELOC(state->draw_region->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - state->draw_region->draw_offset); - - if (state->depth_region) { - OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); - OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); - OUT_RELOC(state->depth_region->buffer, - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - state->depth_region->draw_offset); - } - - OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); - OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); - OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]); - OUT_BATCH(state->Buffer[I915_DESTREG_SR0]); - OUT_BATCH(state->Buffer[I915_DESTREG_SR1]); - OUT_BATCH(state->Buffer[I915_DESTREG_SR2]); - ADVANCE_BATCH(); - } - - if (dirty & I915_UPLOAD_STIPPLE) { - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); - emit(intel, state->Stipple, sizeof(state->Stipple)); - } - - if (dirty & I915_UPLOAD_FOG) { - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "I915_UPLOAD_FOG:\n"); - emit(intel, state->Fog, sizeof(state->Fog)); - } - - /* Combine all the dirty texture state into a single command to - * avoid lockups on I915 hardware. - */ - if (dirty & I915_UPLOAD_TEX_ALL) { - int nr = 0; - - for (i = 0; i < I915_TEX_UNITS; i++) - if (dirty & I915_UPLOAD_TEX(i)) - nr++; - - BEGIN_BATCH(2 + nr * 3, 0); - OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); - OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); - for (i = 0; i < I915_TEX_UNITS; i++) - if (dirty & I915_UPLOAD_TEX(i)) { - - if (state->tex_buffer[i]) { - OUT_RELOC(state->tex_buffer[i], - DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - state->tex_offset[i]); - } - else if (state == &i915->meta) { - assert(i == 0); - OUT_BATCH(0); - } - else { - OUT_BATCH(state->tex_offset[i]); - } - - OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); - OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); - } - ADVANCE_BATCH(); - - BEGIN_BATCH(2 + nr * 3, 0); - OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); - OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); - for (i = 0; i < I915_TEX_UNITS; i++) - if (dirty & I915_UPLOAD_TEX(i)) { - OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); - OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); - OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); - } - ADVANCE_BATCH(); - } - - if (dirty & I915_UPLOAD_CONSTANTS) { - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); - emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint)); - } - - if (dirty & I915_UPLOAD_PROGRAM) { - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); - - assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize); - - emit(intel, state->Program, state->ProgramSize * sizeof(GLuint)); - if (INTEL_DEBUG & DEBUG_STATE) - i915_disassemble_program(state->Program, state->ProgramSize); - } - - assert(get_dirty(state) == 0); -} - -static void -i915_destroy_context(struct intel_context *intel) -{ - GLuint i; - struct i915_context *i915 = i915_context(&intel->ctx); - - for (i = 0; i < I915_TEX_UNITS; i++) { - if (i915->state.tex_buffer[i] != NULL) { - dri_bo_unreference(i915->state.tex_buffer[i]); - i915->state.tex_buffer[i] = NULL; - } - } - - _tnl_free_vertices(&intel->ctx); -} - - -/** - * Set the drawing regions for the color and depth/stencil buffers. - * This involves setting the pitch, cpp and buffer ID/location. - * Also set pixel format for color and Z rendering - * Used for setting both regular and meta state. - */ -void -i915_state_draw_region(struct intel_context *intel, - struct i915_hw_state *state, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - GLuint value; - - ASSERT(state == &i915->state || state == &i915->meta); - - if (state->draw_region != color_region) { - intel_region_release(&state->draw_region); - intel_region_reference(&state->draw_region, color_region); - } - if (state->depth_region != depth_region) { - intel_region_release(&state->depth_region); - intel_region_reference(&state->depth_region, depth_region); - } - - /* - * Set stride/cpp values - */ - if (color_region) { - state->Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - state->Buffer[I915_DESTREG_CBUFADDR1] = - (BUF_3D_ID_COLOR_BACK | - BUF_3D_PITCH(color_region->pitch * color_region->cpp) | - BUF_3D_USE_FENCE); - } - - if (depth_region) { - state->Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; - state->Buffer[I915_DESTREG_DBUFADDR1] = - (BUF_3D_ID_DEPTH | - BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | - BUF_3D_USE_FENCE); - } - - /* - * Compute/set I915_DESTREG_DV1 value - */ - value = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); - if (color_region && color_region->cpp == 4) { - value |= DV_PF_8888; - } - else { - value |= (DITHER_FULL_ALWAYS | DV_PF_565); - } - if (depth_region && depth_region->cpp == 4) { - value |= DEPTH_FRMT_24_FIXED_8_OTHER; - } - else { - value |= DEPTH_FRMT_16_FIXED; - } - state->Buffer[I915_DESTREG_DV1] = value; - - I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); -} - - -static void -i915_set_draw_region(struct intel_context *intel, - struct intel_region *color_region, - struct intel_region *depth_region) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915_state_draw_region(intel, &i915->state, color_region, depth_region); -} - - - -static void -i915_lost_hardware(struct intel_context *intel) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - i915->state.emitted = 0; -} - -static GLuint -i915_flush_cmd(void) -{ - return MI_FLUSH | FLUSH_MAP_CACHE; -} - -static void -i915_assert_not_dirty( struct intel_context *intel ) -{ - struct i915_context *i915 = i915_context(&intel->ctx); - struct i915_hw_state *state = i915->current; - GLuint dirty = get_dirty(state); - assert(!dirty); -} - - -void -i915InitVtbl(struct i915_context *i915) -{ - i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; - i915->intel.vtbl.destroy = i915_destroy_context; - i915->intel.vtbl.emit_state = i915_emit_state; - i915->intel.vtbl.lost_hardware = i915_lost_hardware; - i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; - i915->intel.vtbl.render_start = i915_render_start; - i915->intel.vtbl.render_prevalidate = i915_render_prevalidate; - i915->intel.vtbl.set_draw_region = i915_set_draw_region; - i915->intel.vtbl.update_texture_state = i915UpdateTextureState; - i915->intel.vtbl.flush_cmd = i915_flush_cmd; - i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c deleted file mode 100644 index 8ee48b5a68..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_decode.h" -#include "i915_debug.h" - -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - - if (batch->buf != NULL) { - dri_bo_unreference(batch->buf); - batch->buf = NULL; - } - - batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", - intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT); - dri_bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - batch->size = intel->intelScreen->maxBatchSize; - batch->ptr = batch->map; -} - -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - batch->last_fence = NULL; - intel_batchbuffer_reset(batch); - - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - dri_fence_wait(batch->last_fence); - dri_fence_unreference(batch->last_fence); - batch->last_fence = NULL; - } - if (batch->map) { - dri_bo_unmap(batch->buf); - batch->map = NULL; - } - dri_bo_unreference(batch->buf); - batch->buf = NULL; - free(batch); -} - -static int -relocation_sort(const void *a_in, const void *b_in) { - const struct buffer_reloc *a = a_in, *b = b_in; - - return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; -} - - -/* TODO: Push this whole function into bufmgr. - */ -static void -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - GLuint *ptr; - GLuint i; - struct intel_context *intel = batch->intel; - dri_fence *fo; - GLboolean performed_rendering = GL_FALSE; - - assert(batch->buf->virtual != NULL); - ptr = batch->buf->virtual; - - /* Sort our relocation list in terms of referenced buffer pointer. - * This lets us uniquely validate the buffers with the sum of all the flags, - * while avoiding O(n^2) on number of relocations. - */ - qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), - relocation_sort); - - /* Perform the necessary validations of buffers, and enter the relocations - * in the batchbuffer. - */ - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - - if (r->validate_flags & DRM_BO_FLAG_WRITE) - performed_rendering = GL_TRUE; - - /* If this is the first time we've seen this buffer in the relocation - * list, figure out our flags and validate it. - */ - if (i == 0 || batch->reloc[i - 1].buf != r->buf) { - uint32_t validate_flags; - int j, ret; - - /* Accumulate the flags we need for validating this buffer. */ - validate_flags = r->validate_flags; - for (j = i + 1; j < batch->nr_relocs; j++) { - if (batch->reloc[j].buf != r->buf) - break; - validate_flags |= batch->reloc[j].validate_flags; - } - - /* Validate. If we fail, fence to clear the unfenced list and bail - * out. - */ - ret = dri_bo_validate(r->buf, validate_flags); - if (ret != 0) { - dri_bo_unmap(batch->buf); - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "batchbuffer failure fence", GL_TRUE); - dri_fence_unreference(fo); - goto done; - } - } - ptr[r->offset / 4] = r->buf->offset + r->delta; - dri_bo_unreference(r->buf); - } - - dri_bo_unmap(batch->buf); - batch->map = NULL; - batch->ptr = NULL; - - dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); - - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { - intel_batch_ioctl(batch->intel, - batch->buf->offset, - used, ignore_cliprects, allow_unlock); - } - - /* Associate a fence with the validated buffers, and note that we included - * a flush at the end. - */ - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "Batch fence", GL_TRUE); - - if (performed_rendering) { - dri_fence_unreference(batch->last_fence); - batch->last_fence = fo; - } else { - /* If we didn't validate any buffers for writing by the card, we don't - * need to track the fence for glFinish(). - */ - dri_fence_unreference(fo); - } - - if (intel->numClipRects == 0 && !ignore_cliprects) { - if (allow_unlock) { - /* If we are not doing any actual user-visible rendering, - * do a sched_yield to keep the app from pegging the cpu while - * achieving nothing. - */ - UNLOCK_HARDWARE(intel); - sched_yield(); - LOCK_HARDWARE(intel); - } - intel->vtbl.lost_hardware(intel); - } - -done: - if (INTEL_DEBUG & DEBUG_BATCH) { - dri_bo_map(batch->buf, GL_FALSE); - intel_decode(ptr, used / 4, batch->buf->offset); - dri_bo_unmap(batch->buf); - } -} - - -void -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; - GLboolean was_locked = intel->locked; - - if (used == 0) - return; - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ - if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - LOCK_HARDWARE(intel); - - do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - intel_batchbuffer_flush(batch); - if (batch->last_fence != NULL) - dri_fence_wait(batch->last_fence); -} - - -/* This is the only way buffers get added to the validate list. - */ -GLboolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint delta) -{ - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - - assert(batch->nr_relocs <= MAX_RELOCS); - - dri_bo_reference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - r->validate_flags = flags; - - batch->ptr += 4; - return GL_TRUE; -} - - - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - __memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h deleted file mode 100644 index 850a91e1c9..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "mtypes.h" -#include "dri_bufmgr.h" - -struct intel_context; - -#define BATCH_SZ 16384 -#define BATCH_RESERVED 16 - -#define MAX_RELOCS 4096 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct buffer_reloc -{ - dri_bo *buf; - GLuint offset; - GLuint delta; /* not needed? */ - GLuint validate_flags; -}; - -struct intel_batchbuffer -{ - struct intel_context *intel; - - dri_bo *buf; - dri_fence *last_fence; - GLuint flags; - - drmBOList list; - GLuint list_count; - GLubyte *map; - GLubyte *ptr; - - struct buffer_reloc reloc[MAX_RELOCS]; - GLuint nr_relocs; - GLuint size; -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -void intel_batchbuffer_flush(struct intel_batchbuffer *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint offset); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... - */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; -} - -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - assert(sz < batch->size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) - intel_batchbuffer_flush(batch); - - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: - */ -#define BATCH_LOCALS - -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) - -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) - -#define OUT_RELOC(buf, flags, delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ -} while (0) - -#define ADVANCE_BATCH() do { } while(0) - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c deleted file mode 100644 index 5d97f08434..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_blit.c +++ /dev/null @@ -1,493 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include -#include - -#include "mtypes.h" -#include "context.h" -#include "enums.h" - -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_context.h" -#include "intel_fbo.h" -#include "intel_reg.h" -#include "intel_regions.h" -#include "vblank.h" - -#define FILE_DEBUG_FLAG DEBUG_BLIT - -/** - * Copy the back color buffer to the front color buffer. - * Used for SwapBuffers(). - */ -void -intelCopyBuffer(const __DRIdrawablePrivate * dPriv, - const drm_clip_rect_t * rect) -{ - - struct intel_context *intel; - const intelScreenPrivate *intelScreen; - - DBG("%s\n", __FUNCTION__); - - assert(dPriv); - - intel = intelScreenContext(dPriv->driScreenPriv->private); - if (!intel) - return; - - intelScreen = intel->intelScreen; - - if (intel->last_swap_fence) { - dri_fence_wait(intel->last_swap_fence); - dri_fence_unreference(intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - intel->last_swap_fence = intel->first_swap_fence; - intel->first_swap_fence = NULL; - - /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets - * should work regardless. - */ - LOCK_HARDWARE(intel); - - if (dPriv && dPriv->numClipRects) { - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - const struct intel_region *frontRegion - = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT); - const struct intel_region *backRegion - = intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT); - const int nbox = dPriv->numClipRects; - const drm_clip_rect_t *pbox = dPriv->pClipRects; - const int pitch = frontRegion->pitch; - const int cpp = frontRegion->cpp; - int BR13, CMD; - int i; - - ASSERT(intel_fb); - ASSERT(intel_fb->Base.Name == 0); /* Not a user-created FBO */ - ASSERT(frontRegion); - ASSERT(backRegion); - ASSERT(frontRegion->pitch == backRegion->pitch); - ASSERT(frontRegion->cpp == backRegion->cpp); - - if (cpp == 2) { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - } - else { - BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); - CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - } - - for (i = 0; i < nbox; i++, pbox++) { - drm_clip_rect_t box; - - if (pbox->x1 > pbox->x2 || - pbox->y1 > pbox->y2 || - pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height) - continue; - - box = *pbox; - - if (rect) { - if (rect->x1 > box.x1) - box.x1 = rect->x1; - if (rect->y1 > box.y1) - box.y1 = rect->y1; - if (rect->x2 < box.x2) - box.x2 = rect->x2; - if (rect->y2 < box.y2) - box.y2 = rect->y2; - - if (box.x1 > box.x2 || box.y1 > box.y2) - continue; - } - - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((pbox->y1 << 16) | pbox->x1); - OUT_BATCH((pbox->y2 << 16) | pbox->x2); - - OUT_RELOC(frontRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - 0); - OUT_BATCH((pbox->y1 << 16) | pbox->x1); - OUT_BATCH(BR13 & 0xffff); - OUT_RELOC(backRegion->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - 0); - - ADVANCE_BATCH(); - } - - if (intel->first_swap_fence) - dri_fence_unreference(intel->first_swap_fence); - intel_batchbuffer_flush(intel->batch); - intel->first_swap_fence = intel->batch->last_fence; - dri_fence_reference(intel->first_swap_fence); - } - - UNLOCK_HARDWARE(intel); -} - - - - -void -intelEmitFillBlit(struct intel_context *intel, - GLuint cpp, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - GLshort x, GLshort y, GLshort w, GLshort h, GLuint color) -{ - GLuint BR13, CMD; - BATCH_LOCALS; - - dst_pitch *= cpp; - - switch (cpp) { - case 1: - case 2: - case 3: - BR13 = dst_pitch | (0xF0 << 16) | (1 << 24); - CMD = XY_COLOR_BLT_CMD; - break; - case 4: - BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25); - CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB); - break; - default: - return; - } - - DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", - __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); - - - BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((y << 16) | x); - OUT_BATCH(((y + h) << 16) | (x + w)); - OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); - OUT_BATCH(color); - ADVANCE_BATCH(); -} - - -static GLuint translate_raster_op(GLenum logicop) -{ - switch(logicop) { - case GL_CLEAR: return 0x00; - case GL_AND: return 0x88; - case GL_AND_REVERSE: return 0x44; - case GL_COPY: return 0xCC; - case GL_AND_INVERTED: return 0x22; - case GL_NOOP: return 0xAA; - case GL_XOR: return 0x66; - case GL_OR: return 0xEE; - case GL_NOR: return 0x11; - case GL_EQUIV: return 0x99; - case GL_INVERT: return 0x55; - case GL_OR_REVERSE: return 0xDD; - case GL_COPY_INVERTED: return 0x33; - case GL_OR_INVERTED: return 0xBB; - case GL_NAND: return 0x77; - case GL_SET: return 0xFF; - default: return 0; - } -} - - -/* Copy BitBlt - */ -void -intelEmitCopyBlit(struct intel_context *intel, - GLuint cpp, - GLshort src_pitch, - dri_bo *src_buffer, - GLuint src_offset, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - GLshort src_x, GLshort src_y, - GLshort dst_x, GLshort dst_y, - GLshort w, GLshort h, - GLenum logic_op) -{ - GLuint CMD, BR13; - int dst_y2 = dst_y + h; - int dst_x2 = dst_x + w; - BATCH_LOCALS; - - - DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", - __FUNCTION__, - src_buffer, src_pitch, src_offset, src_x, src_y, - dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); - - src_pitch *= cpp; - dst_pitch *= cpp; - - switch (cpp) { - case 1: - case 2: - case 3: - BR13 = (((GLint) dst_pitch) & 0xffff) | - (translate_raster_op(logic_op) << 16) | (1 << 24); - CMD = XY_SRC_COPY_BLT_CMD; - break; - case 4: - BR13 = - (((GLint) dst_pitch) & 0xffff) | - (translate_raster_op(logic_op) << 16) | (1 << 24) | (1 << 25); - CMD = - (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | - XY_SRC_COPY_BLT_WRITE_RGB); - break; - default: - return; - } - - if (dst_y2 < dst_y || dst_x2 < dst_x) { - return; - } - - /* Initial y values don't seem to work with negative pitches. If - * we adjust the offsets manually (below), it seems to work fine. - * - * On the other hand, if we always adjust, the hardware doesn't - * know which blit directions to use, so overlapping copypixels get - * the wrong result. - */ - if (dst_pitch > 0 && src_pitch > 0) { - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((dst_y << 16) | dst_x); - OUT_BATCH((dst_y2 << 16) | dst_x2); - OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, dst_offset); - OUT_BATCH((src_y << 16) | src_x); - OUT_BATCH(((GLint) src_pitch & 0xffff)); - OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, src_offset); - ADVANCE_BATCH(); - } - else { - BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((0 << 16) | dst_x); - OUT_BATCH((h << 16) | dst_x2); - OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - dst_offset + dst_y * dst_pitch); - OUT_BATCH((0 << 16) | src_x); - OUT_BATCH(((GLint) src_pitch & 0xffff)); - OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, - src_offset + src_y * src_pitch); - ADVANCE_BATCH(); - } -} - - -/** - * Use blitting to clear the renderbuffers named by 'flags'. - * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferMask field - * since that might include software renderbuffers or renderbuffers - * which we're clearing with triangles. - * \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear - */ -void -intelClearWithBlit(GLcontext * ctx, GLbitfield mask) -{ - struct intel_context *intel = intel_context(ctx); - struct gl_framebuffer *fb = ctx->DrawBuffer; - GLuint clear_depth; - GLbitfield skipBuffers = 0; - BATCH_LOCALS; - - DBG("%s %x\n", __FUNCTION__, mask); - - /* - * Compute values for clearing the buffers. - */ - clear_depth = 0; - if (mask & BUFFER_BIT_DEPTH) { - clear_depth = (GLuint) (fb->_DepthMax * ctx->Depth.Clear); - } - if (mask & BUFFER_BIT_STENCIL) { - clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; - } - - /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in - * the loop below. - */ - if ((mask & BUFFER_BIT_DEPTH) && (mask & BUFFER_BIT_STENCIL)) { - skipBuffers = BUFFER_BIT_STENCIL; - } - - /* XXX Move this flush/lock into the following conditional? */ - intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - - if (intel->numClipRects) { - GLint cx, cy, cw, ch; - drm_clip_rect_t clear; - int i; - - /* Get clear bounds after locking */ - cx = fb->_Xmin; - cy = fb->_Ymin; - cw = fb->_Xmax - cx; - ch = fb->_Ymax - cy; - - if (fb->Name == 0) { - /* clearing a window */ - - /* flip top to bottom */ - clear.x1 = cx + intel->drawX; - clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; - } - else { - /* clearing FBO */ - assert(intel->numClipRects == 1); - assert(intel->pClipRects == &intel->fboRect); - clear.x1 = cx; - clear.y1 = cy; - clear.x2 = clear.x1 + cw; - clear.y2 = clear.y1 + ch; - /* no change to mask */ - } - - for (i = 0; i < intel->numClipRects; i++) { - const drm_clip_rect_t *box = &intel->pClipRects[i]; - drm_clip_rect_t b; - GLuint buf; - GLuint clearMask = mask; /* use copy, since we modify it below */ - GLboolean all = (cw == fb->Width && ch == fb->Height); - - if (!all) { - intel_intersect_cliprects(&b, &clear, box); - } - else { - b = *box; - } - - if (0) - _mesa_printf("clear %d,%d..%d,%d, mask %x\n", - b.x1, b.y1, b.x2, b.y2, mask); - - /* Loop over all renderbuffers */ - for (buf = 0; buf < BUFFER_COUNT && clearMask; buf++) { - const GLbitfield bufBit = 1 << buf; - if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { - /* OK, clear this renderbuffer */ - struct intel_region *irb_region = - intel_get_rb_region(fb, buf); - dri_bo *write_buffer = - intel_region_buffer(intel->intelScreen, irb_region, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - - GLuint clearVal; - GLint pitch, cpp; - GLuint BR13, CMD; - - ASSERT(irb_region); - - pitch = irb_region->pitch; - cpp = irb_region->cpp; - - DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", - __FUNCTION__, - irb_region->buffer, (pitch * cpp), - irb_region->draw_offset, - b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1); - - - /* Setup the blit command */ - if (cpp == 4) { - BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25); - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - CMD = XY_COLOR_BLT_CMD; - if (clearMask & BUFFER_BIT_DEPTH) - CMD |= XY_COLOR_BLT_WRITE_RGB; - if (clearMask & BUFFER_BIT_STENCIL) - CMD |= XY_COLOR_BLT_WRITE_ALPHA; - } - else { - /* clearing RGBA */ - CMD = (XY_COLOR_BLT_CMD | - XY_COLOR_BLT_WRITE_ALPHA | - XY_COLOR_BLT_WRITE_RGB); - } - } - else { - ASSERT(cpp == 2 || cpp == 0); - BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); - CMD = XY_COLOR_BLT_CMD; - } - - if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { - clearVal = clear_depth; - } - else { - clearVal = (cpp == 4) - ? intel->ClearColor8888 : intel->ClearColor565; - } - /* - _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", - buf, irb->Base.Name); - */ - intel_wait_flips(intel, INTEL_BATCH_NO_CLIPRECTS); - - BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); - OUT_BATCH(CMD); - OUT_BATCH(BR13); - OUT_BATCH((b.y1 << 16) | b.x1); - OUT_BATCH((b.y2 << 16) | b.x2); - OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, - irb_region->draw_offset); - OUT_BATCH(clearVal); - ADVANCE_BATCH(); - clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ - } - } - } - intel_batchbuffer_flush(intel->batch); - } - - UNLOCK_HARDWARE(intel); -} diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.h b/src/mesa/drivers/dri/i915tex/intel_blit.h deleted file mode 100644 index a66af86359..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_blit.h +++ /dev/null @@ -1,62 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_BLIT_H -#define INTEL_BLIT_H - -#include "intel_context.h" -#include "intel_ioctl.h" -#include "dri_bufmgr.h" - -extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv, - const drm_clip_rect_t * rect); - -extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); - -extern void intelEmitCopyBlit(struct intel_context *intel, - GLuint cpp, - GLshort src_pitch, - dri_bo *src_buffer, - GLuint src_offset, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - GLshort srcx, GLshort srcy, - GLshort dstx, GLshort dsty, - GLshort w, GLshort h, - GLenum logicop ); - -extern void intelEmitFillBlit(struct intel_context *intel, - GLuint cpp, - GLshort dst_pitch, - dri_bo *dst_buffer, - GLuint dst_offset, - GLshort x, GLshort y, - GLshort w, GLshort h, GLuint color); - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c deleted file mode 100644 index 3c73c402d9..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "imports.h" -#include "mtypes.h" -#include "bufferobj.h" - -#include "intel_context.h" -#include "intel_buffer_objects.h" -#include "intel_regions.h" -#include "dri_bufmgr.h" - -/** Allocates a new dri_bo to store the data for the buffer object. */ -static void -intel_bufferobj_alloc_buffer(struct intel_context *intel, - struct intel_buffer_object *intel_obj) -{ - intel_obj->buffer = dri_bo_alloc(intel->intelScreen->bufmgr, "bufferobj", - intel_obj->Base.Size, 64, - DRM_BO_FLAG_MEM_TT); -} - -/** - * There is some duplication between mesa's bufferobjects and our - * bufmgr buffers. Both have an integer handle and a hashtable to - * lookup an opaque structure. It would be nice if the handles and - * internal structure where somehow shared. - */ -static struct gl_buffer_object * -intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) -{ - struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object); - - _mesa_initialize_buffer_object(&obj->Base, name, target); - - obj->buffer = NULL; - - return &obj->Base; -} - -/* Break the COW tie to the region. The region gets to keep the data. - */ -void -intel_bufferobj_release_region(struct intel_context *intel, - struct intel_buffer_object *intel_obj) -{ - assert(intel_obj->region->buffer == intel_obj->buffer); - intel_obj->region->pbo = NULL; - intel_obj->region = NULL; - - dri_bo_unreference(intel_obj->buffer); - intel_obj->buffer = NULL; -} - -/* Break the COW tie to the region. Both the pbo and the region end - * up with a copy of the data. - */ -void -intel_bufferobj_cow(struct intel_context *intel, - struct intel_buffer_object *intel_obj) -{ - assert(intel_obj->region); - intel_region_cow(intel->intelScreen, intel_obj->region); -} - - -/** - * Deallocate/free a vertex/pixel buffer object. - * Called via glDeleteBuffersARB(). - */ -static void -intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - - assert(intel_obj); - - if (intel_obj->region) { - intel_bufferobj_release_region(intel, intel_obj); - } - else if (intel_obj->buffer) { - dri_bo_unreference(intel_obj->buffer); - } - - _mesa_free(intel_obj); -} - - - -/** - * Allocate space for and store data in a buffer object. Any data that was - * previously stored in the buffer object is lost. If data is NULL, - * memory will be allocated, but no copy will occur. - * Called via glBufferDataARB(). - */ -static void -intel_bufferobj_data(GLcontext * ctx, - GLenum target, - GLsizeiptrARB size, - const GLvoid * data, - GLenum usage, struct gl_buffer_object *obj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - - intel_obj->Base.Size = size; - intel_obj->Base.Usage = usage; - - if (intel_obj->region) - intel_bufferobj_release_region(intel, intel_obj); - - if (intel_obj->buffer != NULL && intel_obj->buffer->size != size) { - dri_bo_unreference(intel_obj->buffer); - intel_obj->buffer = NULL; - } - - intel_bufferobj_alloc_buffer(intel, intel_obj); - - if (data != NULL) - dri_bo_subdata(intel_obj->buffer, 0, size, data); -} - - -/** - * Replace data in a subrange of buffer object. If the data range - * specified by size + offset extends beyond the end of the buffer or - * if data is NULL, no copy is performed. - * Called via glBufferSubDataARB(). - */ -static void -intel_bufferobj_subdata(GLcontext * ctx, - GLenum target, - GLintptrARB offset, - GLsizeiptrARB size, - const GLvoid * data, struct gl_buffer_object *obj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - - assert(intel_obj); - - if (intel_obj->region) - intel_bufferobj_cow(intel, intel_obj); - - dri_bo_subdata(intel_obj->buffer, offset, size, data); -} - - -/** - * Called via glGetBufferSubDataARB(). - */ -static void -intel_bufferobj_get_subdata(GLcontext * ctx, - GLenum target, - GLintptrARB offset, - GLsizeiptrARB size, - GLvoid * data, struct gl_buffer_object *obj) -{ - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - - assert(intel_obj); - dri_bo_get_subdata(intel_obj->buffer, offset, size, data); -} - - - -/** - * Called via glMapBufferARB(). - */ -static void * -intel_bufferobj_map(GLcontext * ctx, - GLenum target, - GLenum access, struct gl_buffer_object *obj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - - /* XXX: Translate access to flags arg below: - */ - assert(intel_obj); - - if (intel_obj->region) - intel_bufferobj_cow(intel, intel_obj); - - if (intel_obj->buffer == NULL) { - obj->Pointer = NULL; - return NULL; - } - - dri_bo_map(intel_obj->buffer, GL_TRUE); - obj->Pointer = intel_obj->buffer->virtual; - return obj->Pointer; -} - - -/** - * Called via glMapBufferARB(). - */ -static GLboolean -intel_bufferobj_unmap(GLcontext * ctx, - GLenum target, struct gl_buffer_object *obj) -{ - struct intel_buffer_object *intel_obj = intel_buffer_object(obj); - - assert(intel_obj); - if (intel_obj->buffer != NULL) { - assert(obj->Pointer); - dri_bo_unmap(intel_obj->buffer); - obj->Pointer = NULL; - } - return GL_TRUE; -} - -dri_bo * -intel_bufferobj_buffer(struct intel_context *intel, - struct intel_buffer_object *intel_obj, GLuint flag) -{ - if (intel_obj->region) { - if (flag == INTEL_WRITE_PART) - intel_bufferobj_cow(intel, intel_obj); - else if (flag == INTEL_WRITE_FULL) { - intel_bufferobj_release_region(intel, intel_obj); - intel_bufferobj_alloc_buffer(intel, intel_obj); - } - } - - return intel_obj->buffer; -} - -void -intel_bufferobj_init(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - - ctx->Driver.NewBufferObject = intel_bufferobj_alloc; - ctx->Driver.DeleteBuffer = intel_bufferobj_free; - ctx->Driver.BufferData = intel_bufferobj_data; - ctx->Driver.BufferSubData = intel_bufferobj_subdata; - ctx->Driver.GetBufferSubData = intel_bufferobj_get_subdata; - ctx->Driver.MapBuffer = intel_bufferobj_map; - ctx->Driver.UnmapBuffer = intel_bufferobj_unmap; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h deleted file mode 100644 index db579a8ae4..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h +++ /dev/null @@ -1,86 +0,0 @@ - /************************************************************************** - * - * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_BUFFEROBJ_H -#define INTEL_BUFFEROBJ_H - -#include "mtypes.h" - -struct intel_context; -struct intel_region; -struct gl_buffer_object; - - -/** - * Intel vertex/pixel buffer object, derived from Mesa's gl_buffer_object. - */ -struct intel_buffer_object -{ - struct gl_buffer_object Base; - dri_bo *buffer; /* the low-level buffer manager's buffer handle */ - - struct intel_region *region; /* Is there a zero-copy texture - associated with this (pixel) - buffer object? */ -}; - - -/* Get the bm buffer associated with a GL bufferobject: - */ -dri_bo *intel_bufferobj_buffer(struct intel_context *intel, - struct intel_buffer_object - *obj, GLuint flag); - -/* Hook the bufferobject implementation into mesa: - */ -void intel_bufferobj_init(struct intel_context *intel); - - - -/* Are the obj->Name tests necessary? Unfortunately yes, mesa - * allocates a couple of gl_buffer_object structs statically, and - * the Name == 0 test is the only way to identify them and avoid - * casting them erroneously to our structs. - */ -static INLINE struct intel_buffer_object * -intel_buffer_object(struct gl_buffer_object *obj) -{ - if (obj->Name) - return (struct intel_buffer_object *) obj; - else - return NULL; -} - -/* Helpers for zerocopy image uploads. See also intel_regions.h: - */ -void intel_bufferobj_cow(struct intel_context *intel, - struct intel_buffer_object *intel_obj); -void intel_bufferobj_release_region(struct intel_context *intel, - struct intel_buffer_object *intel_obj); - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c deleted file mode 100644 index cb151ab94d..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.c +++ /dev/null @@ -1,1193 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_depthstencil.h" -#include "intel_fbo.h" -#include "intel_tris.h" -#include "intel_regions.h" -#include "intel_batchbuffer.h" -#include "intel_reg.h" -#include "context.h" -#include "utils.h" -#include "drirenderbuffer.h" -#include "framebuffer.h" -#include "swrast/swrast.h" -#include "vblank.h" - - -/* This block can be removed when libdrm >= 2.3.1 is required */ - -#ifndef DRM_VBLANK_FLIP - -#define DRM_VBLANK_FLIP 0x8000000 - -typedef struct drm_i915_flip { - int planes; -} drm_i915_flip_t; - -#undef DRM_IOCTL_I915_FLIP -#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \ - drm_i915_flip_t) - -#endif - - -/** - * XXX move this into a new dri/common/cliprects.c file. - */ -GLboolean -intel_intersect_cliprects(drm_clip_rect_t * dst, - const drm_clip_rect_t * a, - const drm_clip_rect_t * b) -{ - GLint bx = b->x1; - GLint by = b->y1; - GLint bw = b->x2 - bx; - GLint bh = b->y2 - by; - - if (bx < a->x1) - bw -= a->x1 - bx, bx = a->x1; - if (by < a->y1) - bh -= a->y1 - by, by = a->y1; - if (bx + bw > a->x2) - bw = a->x2 - bx; - if (by + bh > a->y2) - bh = a->y2 - by; - if (bw <= 0) - return GL_FALSE; - if (bh <= 0) - return GL_FALSE; - - dst->x1 = bx; - dst->y1 = by; - dst->x2 = bx + bw; - dst->y2 = by + bh; - - return GL_TRUE; -} - -/** - * Return pointer to current color drawing region, or NULL. - */ -struct intel_region * -intel_drawbuf_region(struct intel_context *intel) -{ - struct intel_renderbuffer *irbColor = - intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]); - if (irbColor) - return irbColor->region; - else - return NULL; -} - -/** - * Return pointer to current color reading region, or NULL. - */ -struct intel_region * -intel_readbuf_region(struct intel_context *intel) -{ - struct intel_renderbuffer *irb - = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer); - if (irb) - return irb->region; - else - return NULL; -} - - - -/** - * Update the following fields for rendering to a user-created FBO: - * intel->numClipRects - * intel->pClipRects - * intel->drawX - * intel->drawY - */ -static void -intelSetRenderbufferClipRects(struct intel_context *intel) -{ - assert(intel->ctx.DrawBuffer->Width > 0); - assert(intel->ctx.DrawBuffer->Height > 0); - intel->fboRect.x1 = 0; - intel->fboRect.y1 = 0; - intel->fboRect.x2 = intel->ctx.DrawBuffer->Width; - intel->fboRect.y2 = intel->ctx.DrawBuffer->Height; - intel->numClipRects = 1; - intel->pClipRects = &intel->fboRect; - intel->drawX = 0; - intel->drawY = 0; -} - - -/** - * As above, but for rendering to front buffer of a window. - * \sa intelSetRenderbufferClipRects - */ -static void -intelSetFrontClipRects(struct intel_context *intel) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - if (!dPriv) - return; - - intel->numClipRects = dPriv->numClipRects; - intel->pClipRects = dPriv->pClipRects; - intel->drawX = dPriv->x; - intel->drawY = dPriv->y; -} - - -/** - * As above, but for rendering to back buffer of a window. - */ -static void -intelSetBackClipRects(struct intel_context *intel) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - struct intel_framebuffer *intel_fb; - - if (!dPriv) - return; - - intel_fb = dPriv->driverPrivate; - - if (intel_fb->pf_active || dPriv->numBackClipRects == 0) { - /* use the front clip rects */ - intel->numClipRects = dPriv->numClipRects; - intel->pClipRects = dPriv->pClipRects; - intel->drawX = dPriv->x; - intel->drawY = dPriv->y; - } - else { - /* use the back clip rects */ - intel->numClipRects = dPriv->numBackClipRects; - intel->pClipRects = dPriv->pBackClipRects; - intel->drawX = dPriv->backX; - intel->drawY = dPriv->backY; - } -} - - -/** - * This will be called whenever the currently bound window is moved/resized. - * XXX: actually, it seems to NOT be called when the window is only moved (BP). - */ -void -intelWindowMoved(struct intel_context *intel) -{ - GLcontext *ctx = &intel->ctx; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - - if (!intel->ctx.DrawBuffer) { - /* when would this happen? -BP */ - intelSetFrontClipRects(intel); - } - else if (intel->ctx.DrawBuffer->Name != 0) { - /* drawing to user-created FBO - do nothing */ - /* Cliprects would be set from intelDrawBuffer() */ - } - else { - /* drawing to a window */ - switch (intel_fb->Base._ColorDrawBufferMask[0]) { - case BUFFER_BIT_FRONT_LEFT: - intelSetFrontClipRects(intel); - break; - case BUFFER_BIT_BACK_LEFT: - intelSetBackClipRects(intel); - break; - default: - /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ - intelSetFrontClipRects(intel); - } - } - - if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) { - drmI830Sarea *sarea = intel->sarea; - drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, - .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; - drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y, - .x2 = sarea->planeA_x + sarea->planeA_w, - .y2 = sarea->planeA_y + sarea->planeA_h }; - drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y, - .x2 = sarea->planeB_x + sarea->planeB_w, - .y2 = sarea->planeB_y + sarea->planeB_h }; - GLint areaA = driIntersectArea( drw_rect, planeA_rect ); - GLint areaB = driIntersectArea( drw_rect, planeB_rect ); - GLuint flags = intel_fb->vblank_flags; - GLboolean pf_active; - GLint pf_planes; - - /* Update page flipping info - */ - pf_planes = 0; - - if (areaA > 0) - pf_planes |= 1; - - if (areaB > 0) - pf_planes |= 2; - - intel_fb->pf_current_page = (intel->sarea->pf_current_page >> - (intel_fb->pf_planes & 0x2)) & 0x3; - - intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2; - - pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes; - - if (INTEL_DEBUG & DEBUG_LOCK) - if (pf_active != intel_fb->pf_active) - _mesa_printf("%s - Page flipping %sactive\n", __progname, - pf_active ? "" : "in"); - - if (pf_active) { - /* Sync pages between planes if flipping on both at the same time */ - if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes && - (intel->sarea->pf_current_page & 0x3) != - (((intel->sarea->pf_current_page) >> 2) & 0x3)) { - drm_i915_flip_t flip; - - if (intel_fb->pf_current_page == - (intel->sarea->pf_current_page & 0x3)) { - /* XXX: This is ugly, but emitting two flips 'in a row' can cause - * lockups for unknown reasons. - */ - intel->sarea->pf_current_page = - intel->sarea->pf_current_page & 0x3; - intel->sarea->pf_current_page |= - ((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % - intel_fb->pf_num_pages) << 2; - - flip.planes = 0x2; - } else { - intel->sarea->pf_current_page = - intel->sarea->pf_current_page & (0x3 << 2); - intel->sarea->pf_current_page |= - (intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % - intel_fb->pf_num_pages; - - flip.planes = 0x1; - } - - drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); - } - - intel_fb->pf_planes = pf_planes; - } - - intel_fb->pf_active = pf_active; - intel_flip_renderbuffers(intel_fb); - intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); - - /* Update vblank info - */ - if (areaB > areaA || (areaA == areaB && areaB > 0)) { - flags = intel_fb->vblank_flags | VBLANK_FLAG_SECONDARY; - } else { - flags = intel_fb->vblank_flags & ~VBLANK_FLAG_SECONDARY; - } - - if (flags != intel_fb->vblank_flags && intel_fb->vblank_flags && - !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ)) { - drmVBlank vbl; - int i; - - vbl.request.type = DRM_VBLANK_ABSOLUTE; - - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { - vbl.request.type |= DRM_VBLANK_SECONDARY; - } - - for (i = 0; i < intel_fb->pf_num_pages; i++) { - if (!intel_fb->color_rb[i] || - (intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <= - (1<<23)) - continue; - - vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending; - drmWaitVBlank(intel->driFd, &vbl); - } - - intel_fb->vblank_flags = flags; - driGetCurrentVBlank(dPriv, intel_fb->vblank_flags, &intel_fb->vbl_seq); - intel_fb->vbl_waited = intel_fb->vbl_seq; - - for (i = 0; i < intel_fb->pf_num_pages; i++) { - if (intel_fb->color_rb[i]) - intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited; - } - } - } else { - intel_fb->vblank_flags &= ~VBLANK_FLAG_SECONDARY; - } - - /* Update Mesa's notion of window size */ - driUpdateFramebufferSize(ctx, dPriv); - intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */ - - /* Update hardware scissor */ - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); - - /* Re-calculate viewport related state */ - ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); -} - - - -/* A true meta version of this would be very simple and additionally - * machine independent. Maybe we'll get there one day. - */ -static void -intelClearWithTris(struct intel_context *intel, GLbitfield mask) -{ - GLcontext *ctx = &intel->ctx; - struct gl_framebuffer *fb = ctx->DrawBuffer; - drm_clip_rect_t clear; - - if (INTEL_DEBUG & DEBUG_BLIT) - _mesa_printf("%s 0x%x\n", __FUNCTION__, mask); - - LOCK_HARDWARE(intel); - - /* XXX FBO: was: intel->driDrawable->numClipRects */ - if (intel->numClipRects) { - GLint cx, cy, cw, ch; - GLuint buf; - - intel->vtbl.install_meta_state(intel); - - /* Get clear bounds after locking */ - cx = fb->_Xmin; - cy = fb->_Ymin; - ch = fb->_Ymax - cx; - cw = fb->_Xmax - cy; - - /* note: regardless of 'all', cx, cy, cw, ch are now correct */ - clear.x1 = cx; - clear.y1 = cy; - clear.x2 = cx + cw; - clear.y2 = cy + ch; - - /* Back and stencil cliprects are the same. Try and do both - * buffers at once: - */ - if (mask & - (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { - struct intel_region *backRegion = - intel_get_rb_region(fb, BUFFER_BACK_LEFT); - struct intel_region *depthRegion = - intel_get_rb_region(fb, BUFFER_DEPTH); - const GLuint clearColor = (backRegion && backRegion->cpp == 4) - ? intel->ClearColor8888 : intel->ClearColor565; - - intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); - - if (mask & BUFFER_BIT_BACK_LEFT) - intel->vtbl.meta_color_mask(intel, GL_TRUE); - else - intel->vtbl.meta_color_mask(intel, GL_FALSE); - - if (mask & BUFFER_BIT_STENCIL) - intel->vtbl.meta_stencil_replace(intel, - intel->ctx.Stencil.WriteMask[0], - intel->ctx.Stencil.Clear); - else - intel->vtbl.meta_no_stencil_write(intel); - - if (mask & BUFFER_BIT_DEPTH) - intel->vtbl.meta_depth_replace(intel); - else - intel->vtbl.meta_no_depth_write(intel); - - /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the - * drawing origin may not be correctly emitted. - */ - intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, intel->ctx.Depth.Clear, clearColor, 0, 0, 0, 0); /* texcoords */ - - mask &= - ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); - } - - /* clear the remaining (color) renderbuffers */ - for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { - const GLuint bufBit = 1 << buf; - if (mask & bufBit) { - struct intel_renderbuffer *irbColor = - intel_renderbuffer(fb->Attachment[buf].Renderbuffer); - GLuint color = (irbColor->region->cpp == 4) - ? intel->ClearColor8888 : intel->ClearColor565; - - ASSERT(irbColor); - - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_color_mask(intel, GL_TRUE); - intel->vtbl.meta_draw_region(intel, irbColor->region, NULL); - - /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the - * drawing origin may not be correctly emitted. - */ - intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, 0, /* depth clear val */ - color, 0, 0, 0, 0); /* texcoords */ - - mask &= ~bufBit; - } - } - - intel->vtbl.leave_meta_state(intel); - intel_batchbuffer_flush(intel->batch); - } - UNLOCK_HARDWARE(intel); -} - - - - -/** - * Copy the window contents named by dPriv to the rotated (or reflected) - * color buffer. - * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source. - */ -void -intelRotateWindow(struct intel_context *intel, - __DRIdrawablePrivate * dPriv, GLuint srcBuf) -{ - intelScreenPrivate *screen = intel->intelScreen; - drm_clip_rect_t fullRect; - struct intel_framebuffer *intel_fb; - struct intel_region *src; - const drm_clip_rect_t *clipRects; - int numClipRects; - int i; - GLenum format, type; - - int xOrig, yOrig; - int origNumClipRects; - drm_clip_rect_t *origRects; - - /* - * set up hardware state - */ - intelFlush(&intel->ctx); - - LOCK_HARDWARE(intel); - - if (!intel->numClipRects) { - UNLOCK_HARDWARE(intel); - return; - } - - intel->vtbl.install_meta_state(intel); - - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_color_mask(intel, GL_FALSE); - - - /* save current drawing origin and cliprects (restored at end) */ - xOrig = intel->drawX; - yOrig = intel->drawY; - origNumClipRects = intel->numClipRects; - origRects = intel->pClipRects; - - /* - * set drawing origin, cliprects for full-screen access to rotated screen - */ - fullRect.x1 = 0; - fullRect.y1 = 0; - fullRect.x2 = screen->rotatedWidth; - fullRect.y2 = screen->rotatedHeight; - intel->drawX = 0; - intel->drawY = 0; - intel->numClipRects = 1; - intel->pClipRects = &fullRect; - - intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ - - intel_fb = dPriv->driverPrivate; - - if ((srcBuf == BUFFER_BIT_BACK_LEFT && !intel_fb->pf_active)) { - src = intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT); - clipRects = dPriv->pBackClipRects; - numClipRects = dPriv->numBackClipRects; - } - else { - src = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT); - clipRects = dPriv->pClipRects; - numClipRects = dPriv->numClipRects; - } - - if (src->cpp == 4) { - format = GL_BGRA; - type = GL_UNSIGNED_BYTE; - } - else { - format = GL_BGR; - type = GL_UNSIGNED_SHORT_5_6_5_REV; - } - - /* set the whole screen up as a texture to avoid alignment issues */ - intel->vtbl.meta_tex_rect_source(intel, - src->buffer, - screen->width, - screen->height, src->pitch, format, type); - - intel->vtbl.meta_texture_blend_replace(intel); - - /* - * loop over the source window's cliprects - */ - for (i = 0; i < numClipRects; i++) { - int srcX0 = clipRects[i].x1; - int srcY0 = clipRects[i].y1; - int srcX1 = clipRects[i].x2; - int srcY1 = clipRects[i].y2; - GLfloat verts[4][2], tex[4][2]; - int j; - - /* build vertices for four corners of clip rect */ - verts[0][0] = srcX0; - verts[0][1] = srcY0; - verts[1][0] = srcX1; - verts[1][1] = srcY0; - verts[2][0] = srcX1; - verts[2][1] = srcY1; - verts[3][0] = srcX0; - verts[3][1] = srcY1; - - /* .. and texcoords */ - tex[0][0] = srcX0; - tex[0][1] = srcY0; - tex[1][0] = srcX1; - tex[1][1] = srcY0; - tex[2][0] = srcX1; - tex[2][1] = srcY1; - tex[3][0] = srcX0; - tex[3][1] = srcY1; - - /* transform coords to rotated screen coords */ - - for (j = 0; j < 4; j++) { - matrix23TransformCoordf(&screen->rotMatrix, - &verts[j][0], &verts[j][1]); - } - - /* draw polygon to map source image to dest region */ - intel_meta_draw_poly(intel, 4, verts, 0, 0, tex); - - } /* cliprect loop */ - - intel->vtbl.leave_meta_state(intel); - intel_batchbuffer_flush(intel->batch); - - /* restore original drawing origin and cliprects */ - intel->drawX = xOrig; - intel->drawY = yOrig; - intel->numClipRects = origNumClipRects; - intel->pClipRects = origRects; - - UNLOCK_HARDWARE(intel); -} - - -/** - * Called by ctx->Driver.Clear. - */ -static void -intelClear(GLcontext *ctx, GLbitfield mask) -{ - struct intel_context *intel = intel_context(ctx); - const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); - GLbitfield tri_mask = 0; - GLbitfield blit_mask = 0; - GLbitfield swrast_mask = 0; - struct gl_framebuffer *fb = ctx->DrawBuffer; - GLuint i; - - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* HW color buffers (front, back, aux, generic FBO, etc) */ - if (colorMask == ~0) { - /* clear all R,G,B,A */ - /* XXX FBO: need to check if colorbuffers are software RBOs! */ - blit_mask |= (mask & BUFFER_BITS_COLOR); - } - else { - /* glColorMask in effect */ - tri_mask |= (mask & BUFFER_BITS_COLOR); - } - - /* HW stencil */ - if (mask & BUFFER_BIT_STENCIL) { - const struct intel_region *stencilRegion - = intel_get_rb_region(fb, BUFFER_STENCIL); - if (stencilRegion) { - /* have hw stencil */ - if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { - /* not clearing all stencil bits, so use triangle clearing */ - tri_mask |= BUFFER_BIT_STENCIL; - } - else { - /* clearing all stencil bits, use blitting */ - blit_mask |= BUFFER_BIT_STENCIL; - } - } - } - - /* HW depth */ - if (mask & BUFFER_BIT_DEPTH) { - /* clear depth with whatever method is used for stencil (see above) */ - if (tri_mask & BUFFER_BIT_STENCIL) - tri_mask |= BUFFER_BIT_DEPTH; - else - blit_mask |= BUFFER_BIT_DEPTH; - } - - /* SW fallback clearing */ - swrast_mask = mask & ~tri_mask & ~blit_mask; - - for (i = 0; i < BUFFER_COUNT; i++) { - GLuint bufBit = 1 << i; - if ((blit_mask | tri_mask) & bufBit) { - if (!fb->Attachment[i].Renderbuffer->ClassID) { - blit_mask &= ~bufBit; - tri_mask &= ~bufBit; - swrast_mask |= bufBit; - } - } - } - - - intelFlush(ctx); /* XXX intelClearWithBlit also does this */ - - if (blit_mask) - intelClearWithBlit(ctx, blit_mask); - - if (tri_mask) - intelClearWithTris(intel, tri_mask); - - if (swrast_mask) - _swrast_Clear(ctx, swrast_mask); -} - - -/* Emit wait for pending flips */ -void -intel_wait_flips(struct intel_context *intel, GLuint batch_flags) -{ - struct intel_framebuffer *intel_fb = - (struct intel_framebuffer *) intel->ctx.DrawBuffer; - struct intel_renderbuffer *intel_rb = - intel_get_renderbuffer(&intel_fb->Base, - intel_fb->Base._ColorDrawBufferMask[0] == - BUFFER_BIT_FRONT_LEFT ? BUFFER_FRONT_LEFT : - BUFFER_BACK_LEFT); - - if (intel_fb->Base.Name == 0 && intel_rb->pf_pending == intel_fb->pf_seq) { - GLint pf_planes = intel_fb->pf_planes; - BATCH_LOCALS; - - /* Wait for pending flips to take effect */ - BEGIN_BATCH(2, batch_flags); - OUT_BATCH(pf_planes & 0x1 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP) - : 0); - OUT_BATCH(pf_planes & 0x2 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_B_FLIP) - : 0); - ADVANCE_BATCH(); - - intel_rb->pf_pending--; - } -} - - -/* Flip the front & back buffers - */ -static GLboolean -intelPageFlip(const __DRIdrawablePrivate * dPriv) -{ - struct intel_context *intel; - int ret; - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - - if (INTEL_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; - - if (intel->intelScreen->drmMinor < 9) - return GL_FALSE; - - intelFlush(&intel->ctx); - - ret = 0; - - LOCK_HARDWARE(intel); - - if (dPriv->numClipRects && intel_fb->pf_active) { - drm_i915_flip_t flip; - - flip.planes = intel_fb->pf_planes; - - ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); - } - - UNLOCK_HARDWARE(intel); - - if (ret || !intel_fb->pf_active) - return GL_FALSE; - - if (!dPriv->numClipRects) { - usleep(10000); /* throttle invisible client 10ms */ - } - - intel_fb->pf_current_page = (intel->sarea->pf_current_page >> - (intel_fb->pf_planes & 0x2)) & 0x3; - - if (dPriv->numClipRects != 0) { - intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->pf_pending = - intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->pf_pending = - ++intel_fb->pf_seq; - } - - intel_flip_renderbuffers(intel_fb); - intel_draw_buffer(&intel->ctx, &intel_fb->Base); - - return GL_TRUE; -} - -#if 0 -void -intelSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - if (dPriv->driverPrivate) { - const struct gl_framebuffer *fb - = (struct gl_framebuffer *) dPriv->driverPrivate; - if (fb->Visual.doubleBufferMode) { - GET_CURRENT_CONTEXT(ctx); - if (ctx && ctx->DrawBuffer == fb) { - _mesa_notifySwapBuffers(ctx); /* flush pending rendering */ - } - if (intel->doPageFlip) { - intelPageFlip(dPriv); - } - else { - intelCopyBuffer(dPriv); - } - } - } - else { - _mesa_problem(NULL, - "dPriv has no gl_framebuffer pointer in intelSwapBuffers"); - } -} -#else -/* Trunk version: - */ - -static GLboolean -intelScheduleSwap(const __DRIdrawablePrivate * dPriv, GLboolean *missed_target) -{ - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - unsigned int interval = driGetVBlankInterval(dPriv, intel_fb->vblank_flags); - struct intel_context *intel = - intelScreenContext(dPriv->driScreenPriv->private); - const intelScreenPrivate *intelScreen = intel->intelScreen; - unsigned int target; - drm_i915_vblank_swap_t swap; - GLboolean ret; - - if (!intel_fb->vblank_flags || - (intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) || - intelScreen->current_rotation != 0 || - intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6)) - return GL_FALSE; - - swap.seqtype = DRM_VBLANK_ABSOLUTE; - - if (intel_fb->vblank_flags & VBLANK_FLAG_SYNC) { - swap.seqtype |= DRM_VBLANK_NEXTONMISS; - } else if (interval == 0) { - return GL_FALSE; - } - - swap.drawable = dPriv->hHWDrawable; - target = swap.sequence = intel_fb->vbl_seq + interval; - - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { - swap.seqtype |= DRM_VBLANK_SECONDARY; - } - - LOCK_HARDWARE(intel); - - intel_batchbuffer_flush(intel->batch); - - if ( intel_fb->pf_active ) { - swap.seqtype |= DRM_VBLANK_FLIP; - - intel_fb->pf_current_page = (((intel->sarea->pf_current_page >> - (intel_fb->pf_planes & 0x2)) & 0x3) + 1) % - intel_fb->pf_num_pages; - } - - if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, - sizeof(swap))) { - intel_fb->vbl_seq = swap.sequence; - swap.sequence -= target; - *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); - - intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending = - intel_get_renderbuffer(&intel_fb->Base, - BUFFER_FRONT_LEFT)->vbl_pending = - intel_fb->vbl_seq; - - if (swap.seqtype & DRM_VBLANK_FLIP) { - intel_flip_renderbuffers(intel_fb); - intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); - } - - ret = GL_TRUE; - } else { - if (swap.seqtype & DRM_VBLANK_FLIP) { - intel_fb->pf_current_page = ((intel->sarea->pf_current_page >> - (intel_fb->pf_planes & 0x2)) & 0x3) % - intel_fb->pf_num_pages; - } - - ret = GL_FALSE; - } - - UNLOCK_HARDWARE(intel); - - return ret; -} - -void -intelSwapBuffers(__DRIdrawablePrivate * dPriv) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - GET_CURRENT_CONTEXT(ctx); - struct intel_context *intel; - - if (ctx == NULL) - return; - - intel = intel_context(ctx); - - if (ctx->Visual.doubleBufferMode) { - intelScreenPrivate *screen = intel->intelScreen; - GLboolean missed_target; - struct intel_framebuffer *intel_fb = dPriv->driverPrivate; - int64_t ust; - - _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ - - if (screen->current_rotation != 0 || - !intelScheduleSwap(dPriv, &missed_target)) { - driWaitForVBlank(dPriv, &intel_fb->vbl_seq, intel_fb->vblank_flags, - &missed_target); - - if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) { - intelCopyBuffer(dPriv, NULL); - } - - if (screen->current_rotation != 0) { - intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); - } - } - - intel_fb->swap_count++; - (*dri_interface->getUST) (&ust); - if (missed_target) { - intel_fb->swap_missed_count++; - intel_fb->swap_missed_ust = ust - intel_fb->swap_ust; - } - - intel_fb->swap_ust = ust; - } - } - else { - /* XXX this shouldn't be an error but we can't handle it for now */ - fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); - } -} -#endif - -void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - struct intel_context *intel = - (struct intel_context *) dPriv->driContextPriv->driverPrivate; - GLcontext *ctx = &intel->ctx; - - if (ctx->Visual.doubleBufferMode) { - drm_clip_rect_t rect; - rect.x1 = x + dPriv->x; - rect.y1 = (dPriv->h - y - h) + dPriv->y; - rect.x2 = rect.x1 + w; - rect.y2 = rect.y1 + h; - _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ - intelCopyBuffer(dPriv, &rect); - } - } - else { - /* XXX this shouldn't be an error but we can't handle it for now */ - fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); - } -} - - -/** - * Update the hardware state for drawing into a window or framebuffer object. - * - * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other - * places within the driver. - * - * Basically, this needs to be called any time the current framebuffer - * changes, the renderbuffers change, or we need to draw into different - * color buffers. - */ -void -intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *colorRegion, *depthRegion = NULL; - struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; - int front = 0; /* drawing to front color buffer? */ - - if (!fb) { - /* this can happen during the initial context initialization */ - return; - } - - /* Do this here, note core Mesa, since this function is called from - * many places within the driver. - */ - if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ - _mesa_update_framebuffer(ctx); - /* this updates the DrawBuffer's Width/Height if it's a FBO */ - _mesa_update_draw_buffer_bounds(ctx); - } - - if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - /* this may occur when we're called by glBindFrameBuffer() during - * the process of someone setting up renderbuffers, etc. - */ - /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ - return; - } - - if (fb->Name) - intel_validate_paired_depth_stencil(ctx, fb); - - /* - * How many color buffers are we drawing into? - */ - if (fb->_NumColorDrawBuffers[0] != 1 -#if 0 - /* XXX FBO temporary - always use software rendering */ - || 1 -#endif - ) { - /* writing to 0 or 2 or 4 color buffers */ - /*_mesa_debug(ctx, "Software rendering\n");*/ - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); - front = 1; /* might not have back color buffer */ - } - else { - /* draw to exactly one color buffer */ - /*_mesa_debug(ctx, "Hardware rendering\n");*/ - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); - if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { - front = 1; - } - } - - /* - * Get the intel_renderbuffer for the colorbuffer we're drawing into. - * And set up cliprects. - */ - if (fb->Name == 0) { - /* drawing to window system buffer */ - if (front) { - intelSetFrontClipRects(intel); - colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); - } - else { - intelSetBackClipRects(intel); - colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); - } - } - else { - /* drawing to user-created FBO */ - struct intel_renderbuffer *irb; - intelSetRenderbufferClipRects(intel); - irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]); - colorRegion = (irb && irb->region) ? irb->region : NULL; - } - - /* Update culling direction which changes depending on the - * orientation of the buffer: - */ - if (ctx->Driver.FrontFace) - ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); - else - ctx->NewState |= _NEW_POLYGON; - - if (!colorRegion) { - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); - } - else { - FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); - } - - /*** - *** Get depth buffer region and check if we need a software fallback. - *** Note that the depth buffer is usually a DEPTH_STENCIL buffer. - ***/ - if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { - irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped); - if (irbDepth && irbDepth->region) { - FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); - depthRegion = irbDepth->region; - } - else { - FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE); - depthRegion = NULL; - } - } - else { - /* not using depth buffer */ - FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); - depthRegion = NULL; - } - - /*** - *** Stencil buffer - *** This can only be hardware accelerated if we're using a - *** combined DEPTH_STENCIL buffer (for now anyway). - ***/ - if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { - irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); - if (irbStencil && irbStencil->region) { - ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); - /* need to re-compute stencil hw state */ - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - if (!depthRegion) - depthRegion = irbStencil->region; - } - else { - FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); - } - } - else { - /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ - FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); - /* need to re-compute stencil hw state */ - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - } - - /* - * Update depth test state - */ - if (ctx->Depth.Test && fb->Visual.depthBits > 0) { - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE); - } - else { - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE); - } - - /** - ** Release old regions, reference new regions - **/ -#if 0 /* XXX FBO: this seems to be redundant with i915_state_draw_region() */ - if (intel->draw_region != colorRegion) { - intel_region_release(&intel->draw_region); - intel_region_reference(&intel->draw_region, colorRegion); - } - if (intel->intelScreen->depth_region != depthRegion) { - intel_region_release(&intel->intelScreen->depth_region); - intel_region_reference(&intel->intelScreen->depth_region, depthRegion); - } -#endif - - intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); - - /* update viewport since it depends on window size */ - ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height); - - /* Update hardware scissor */ - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); -} - - -static void -intelDrawBuffer(GLcontext * ctx, GLenum mode) -{ - intel_draw_buffer(ctx, ctx->DrawBuffer); -} - - -static void -intelReadBuffer(GLcontext * ctx, GLenum mode) -{ - if (ctx->ReadBuffer == ctx->DrawBuffer) { - /* This will update FBO completeness status. - * A framebuffer will be incomplete if the GL_READ_BUFFER setting - * refers to a missing renderbuffer. Calling glReadBuffer can set - * that straight and can make the drawing buffer complete. - */ - intel_draw_buffer(ctx, ctx->DrawBuffer); - } - /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc) - * reference ctx->ReadBuffer and do appropriate state checks. - */ -} - - -void -intelInitBufferFuncs(struct dd_function_table *functions) -{ - functions->Clear = intelClear; - functions->DrawBuffer = intelDrawBuffer; - functions->ReadBuffer = intelReadBuffer; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.h b/src/mesa/drivers/dri/i915tex/intel_buffers.h deleted file mode 100644 index 3b686cb5c1..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_buffers.h +++ /dev/null @@ -1,59 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_BUFFERS_H -#define INTEL_BUFFERS_H - - -struct intel_context; -struct intel_framebuffer; - - -extern GLboolean -intel_intersect_cliprects(drm_clip_rect_t * dest, - const drm_clip_rect_t * a, - const drm_clip_rect_t * b); - -extern struct intel_region *intel_readbuf_region(struct intel_context *intel); - -extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); - -extern void intel_wait_flips(struct intel_context *intel, GLuint batch_flags); - -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void intelWindowMoved(struct intel_context *intel); - -extern void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb); - -extern void intelInitBufferFuncs(struct dd_function_table *functions); - -extern void -intelRotateWindow(struct intel_context *intel, - __DRIdrawablePrivate * dPriv, GLuint srcBuf); - -#endif /* INTEL_BUFFERS_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c deleted file mode 100644 index 16fbe38e64..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ /dev/null @@ -1,797 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "matrix.h" -#include "simple_list.h" -#include "extensions.h" -#include "framebuffer.h" -#include "imports.h" -#include "points.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" - -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" - -#include "drivers/common/driverfuncs.h" - -#include "intel_screen.h" - -#include "i830_dri.h" - -#include "intel_buffers.h" -#include "intel_tex.h" -#include "intel_span.h" -#include "intel_tris.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_pixel.h" -#include "intel_regions.h" -#include "intel_buffer_objects.h" -#include "intel_fbo.h" -#include "intel_decode.h" - -#include "drirenderbuffer.h" -#include "vblank.h" -#include "utils.h" -#include "xmlpool.h" /* for symbolic values of enum-type options */ -#ifndef INTEL_DEBUG -int INTEL_DEBUG = (0); -#endif - -#define need_GL_ARB_multisample -#define need_GL_ARB_point_parameters -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_buffer_object -#define need_GL_ARB_vertex_program -#define need_GL_ARB_window_pos -#define need_GL_EXT_blend_color -#define need_GL_EXT_blend_equation_separate -#define need_GL_EXT_blend_func_separate -#define need_GL_EXT_blend_minmax -#define need_GL_EXT_cull_vertex -#define need_GL_EXT_fog_coord -#define need_GL_EXT_framebuffer_object -#define need_GL_EXT_multi_draw_arrays -#define need_GL_EXT_secondary_color -#define need_GL_NV_vertex_program -#include "extension_helper.h" - - -#define DRIVER_DATE "20061102" - -_glthread_Mutex lockMutex; -static GLboolean lockMutexInit = GL_FALSE; - - -static const GLubyte * -intelGetString(GLcontext * ctx, GLenum name) -{ - const char *chipset; - static char buffer[128]; - - switch (name) { - case GL_VENDOR: - return (GLubyte *) "Tungsten Graphics, Inc"; - break; - - case GL_RENDERER: - switch (intel_context(ctx)->intelScreen->deviceID) { - case PCI_CHIP_845_G: - chipset = "Intel(R) 845G"; - break; - case PCI_CHIP_I830_M: - chipset = "Intel(R) 830M"; - break; - case PCI_CHIP_I855_GM: - chipset = "Intel(R) 852GM/855GM"; - break; - case PCI_CHIP_I865_G: - chipset = "Intel(R) 865G"; - break; - case PCI_CHIP_I915_G: - chipset = "Intel(R) 915G"; - break; - case PCI_CHIP_I915_GM: - chipset = "Intel(R) 915GM"; - break; - case PCI_CHIP_I945_G: - chipset = "Intel(R) 945G"; - break; - case PCI_CHIP_I945_GM: - chipset = "Intel(R) 945GM"; - break; - case PCI_CHIP_I945_GME: - chipset = "Intel(R) 945GME"; - break; - case PCI_CHIP_G33_G: - chipset = "Intel(R) G33"; - break; - case PCI_CHIP_Q35_G: - chipset = "Intel(R) Q35"; - break; - case PCI_CHIP_Q33_G: - chipset = "Intel(R) Q33"; - break; - default: - chipset = "Unknown Intel Chipset"; - break; - } - - (void) driGetRendererString(buffer, chipset, DRIVER_DATE, 0); - return (GLubyte *) buffer; - - default: - return NULL; - } -} - - -/** - * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. - */ -const struct dri_extension card_extensions[] = { - {"GL_ARB_multisample", GL_ARB_multisample_functions}, - {"GL_ARB_multitexture", NULL}, - {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, - {"GL_ARB_texture_border_clamp", NULL}, - {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, - {"GL_ARB_texture_cube_map", NULL}, - {"GL_ARB_texture_env_add", NULL}, - {"GL_ARB_texture_env_combine", NULL}, - {"GL_ARB_texture_env_dot3", NULL}, - {"GL_ARB_texture_mirrored_repeat", NULL}, - {"GL_ARB_texture_rectangle", NULL}, - {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, - {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, - {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", - GL_EXT_blend_equation_separate_functions}, - {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, - {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, - {"GL_EXT_blend_subtract", NULL}, - {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, - {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, - {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, -#if 1 /* XXX FBO temporary? */ - {"GL_EXT_packed_depth_stencil", NULL}, -#endif - {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, - {"GL_EXT_stencil_wrap", NULL}, - {"GL_EXT_texture_edge_clamp", NULL}, - {"GL_EXT_texture_env_combine", NULL}, - {"GL_EXT_texture_env_dot3", NULL}, - {"GL_EXT_texture_filter_anisotropic", NULL}, - {"GL_EXT_texture_lod_bias", NULL}, - {"GL_3DFX_texture_compression_FXT1", NULL}, - {"GL_APPLE_client_storage", NULL}, - {"GL_MESA_pack_invert", NULL}, - {"GL_MESA_ycbcr_texture", NULL}, - {"GL_NV_blend_square", NULL}, - {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, - {"GL_NV_vertex_program1_1", NULL}, -/* { "GL_SGIS_generate_mipmap", NULL }, */ - {NULL, NULL} -}; - -const struct dri_extension ttm_extensions[] = { - {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, - {NULL, NULL} -}; - -extern const struct tnl_pipeline_stage _intel_render_stage; - -static const struct tnl_pipeline_stage *intel_pipeline[] = { - &_tnl_vertex_transform_stage, - &_tnl_vertex_cull_stage, - &_tnl_normal_transform_stage, - &_tnl_lighting_stage, - &_tnl_fog_coordinate_stage, - &_tnl_texgen_stage, - &_tnl_texture_transform_stage, - &_tnl_point_attenuation_stage, - &_tnl_vertex_program_stage, -#if 1 - &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */ -#endif - &_tnl_render_stage, - 0, -}; - - -static const struct dri_debug_control debug_control[] = { - {"tex", DEBUG_TEXTURE}, - {"state", DEBUG_STATE}, - {"ioctl", DEBUG_IOCTL}, - {"blit", DEBUG_BLIT}, - {"mip", DEBUG_MIPTREE}, - {"fall", DEBUG_FALLBACKS}, - {"verb", DEBUG_VERBOSE}, - {"bat", DEBUG_BATCH}, - {"pix", DEBUG_PIXEL}, - {"buf", DEBUG_BUFMGR}, - {"reg", DEBUG_REGION}, - {"fbo", DEBUG_FBO}, - {"lock", DEBUG_LOCK}, - {NULL, 0} -}; - - -static void -intelInvalidateState(GLcontext * ctx, GLuint new_state) -{ - _swrast_InvalidateState(ctx, new_state); - _swsetup_InvalidateState(ctx, new_state); - _vbo_InvalidateState(ctx, new_state); - _tnl_InvalidateState(ctx, new_state); - _tnl_invalidate_vertex_state(ctx, new_state); - intel_context(ctx)->NewGLState |= new_state; -} - - -void -intelFlush(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - - if (intel->Fallback) - _swrast_flush(ctx); - - INTEL_FIREVERTICES(intel); - - if (intel->batch->map != intel->batch->ptr) - intel_batchbuffer_flush(intel->batch); - - /* XXX: Need to do an MI_FLUSH here. - */ -} - - -/** - * Check if we need to rotate/warp the front color buffer to the - * rotated screen. We generally need to do this when we get a glFlush - * or glFinish after drawing to the front color buffer. - */ -static void -intelCheckFrontRotate(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == - BUFFER_BIT_FRONT_LEFT) { - intelScreenPrivate *screen = intel->intelScreen; - if (screen->current_rotation != 0) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); - } - } -} - - -/** - * Called via glFlush. - */ -static void -intelglFlush(GLcontext * ctx) -{ - intelFlush(ctx); - intelCheckFrontRotate(ctx); -} - -void -intelFinish(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - intelFlush(ctx); - if (intel->batch->last_fence) { - dri_fence_wait(intel->batch->last_fence); - dri_fence_unreference(intel->batch->last_fence); - intel->batch->last_fence = NULL; - } - intelCheckFrontRotate(ctx); -} - - -void -intelInitDriverFunctions(struct dd_function_table *functions) -{ - _mesa_init_driver_functions(functions); - - functions->Flush = intelglFlush; - functions->Finish = intelFinish; - functions->GetString = intelGetString; - functions->UpdateState = intelInvalidateState; - functions->CopyColorTable = _swrast_CopyColorTable; - functions->CopyColorSubTable = _swrast_CopyColorSubTable; - functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; - functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; - - intelInitTextureFuncs(functions); - intelInitPixelFuncs(functions); - intelInitStateFuncs(functions); - intelInitBufferFuncs(functions); -} - - -GLboolean -intelInitContext(struct intel_context *intel, - const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate, - struct dd_function_table *functions) -{ - GLcontext *ctx = &intel->ctx; - GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; - drmI830Sarea *saPriv = (drmI830Sarea *) - (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); - int fthrottle_mode; - - if (!_mesa_initialize_context(&intel->ctx, - mesaVis, shareCtx, - functions, (void *) intel)) - return GL_FALSE; - - driContextPriv->driverPrivate = intel; - intel->intelScreen = intelScreen; - intel->driScreen = sPriv; - intel->sarea = saPriv; - - intel->width = intelScreen->width; - intel->height = intelScreen->height; - intel->current_rotation = intelScreen->current_rotation; - - if (!lockMutexInit) { - lockMutexInit = GL_TRUE; - _glthread_INIT_MUTEX(lockMutex); - } - - driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, - intel->driScreen->myNum, "i915"); - - ctx->Const.MaxTextureMaxAnisotropy = 2.0; - - /* This doesn't yet catch all non-conformant rendering, but it's a - * start. - */ - if (getenv("INTEL_STRICT_CONFORMANCE")) { - intel->strict_conformance = 1; - } - - ctx->Const.MinLineWidth = 1.0; - ctx->Const.MinLineWidthAA = 1.0; - ctx->Const.MaxLineWidth = 3.0; - ctx->Const.MaxLineWidthAA = 3.0; - ctx->Const.LineWidthGranularity = 1.0; - - ctx->Const.MinPointSize = 1.0; - ctx->Const.MinPointSizeAA = 1.0; - ctx->Const.MaxPointSize = 255.0; - ctx->Const.MaxPointSizeAA = 3.0; - ctx->Const.PointSizeGranularity = 1.0; - - /* reinitialize the context point state. - * It depend on constants in __GLcontextRec::Const - */ - _mesa_init_point(ctx); - - ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ - - /* Initialize the software rasterizer and helper modules. */ - _swrast_CreateContext(ctx); - _vbo_CreateContext(ctx); - _tnl_CreateContext(ctx); - _swsetup_CreateContext(ctx); - - /* Install the customized pipeline: */ - _tnl_destroy_pipeline(ctx); - _tnl_install_pipeline(ctx, intel_pipeline); - - /* Configure swrast to match hardware characteristics: */ - _swrast_allow_pixel_fog(ctx, GL_FALSE); - _swrast_allow_vertex_fog(ctx, GL_TRUE); - - /* Dri stuff */ - intel->hHWContext = driContextPriv->hHWContext; - intel->driFd = sPriv->fd; - intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; - - intel->hw_stipple = 1; - - /* XXX FBO: this doesn't seem to be used anywhere */ - switch (mesaVis->depthBits) { - case 0: /* what to do in this case? */ - case 16: - intel->polygon_offset_scale = 1.0 / 0xffff; - break; - case 24: - intel->polygon_offset_scale = 2.0 / 0xffffff; /* req'd to pass glean */ - break; - default: - assert(0); - break; - } - - /* Initialize swrast, tnl driver tables: */ - intelInitSpanFuncs(ctx); - intelInitTriFuncs(ctx); - - - intel->RenderIndex = ~0; - - fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); - intel->irqsEmitted = 0; - - intel->do_irqs = (intel->intelScreen->irq_active && - fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); - - intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); - - _math_matrix_ctr(&intel->ViewportMatrix); - - /* Disable imaging extension until convolution is working in - * teximage paths: - */ - driInitExtensions(ctx, card_extensions, -/* GL_TRUE, */ - GL_FALSE); - - if (intelScreen->ttm) - driInitExtensions(ctx, ttm_extensions, GL_FALSE); - - - intel->batch = intel_batchbuffer_alloc(intel); - intel->last_swap_fence = NULL; - intel->first_swap_fence = NULL; - - intel_bufferobj_init(intel); - intel_fbo_init(intel); - - if (intel->ctx.Mesa_DXTn) { - _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); - _mesa_enable_extension(ctx, "GL_S3_s3tc"); - } - else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) { - _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); - } - - intel->prim.primitive = ~0; - - -#if DO_DEBUG - INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); -#endif - - if (getenv("INTEL_NO_RAST")) { - fprintf(stderr, "disabling 3D rasterization\n"); - FALLBACK(intel, INTEL_FALLBACK_USER, 1); - } - - return GL_TRUE; -} - -void -intelDestroyContext(__DRIcontextPrivate * driContextPriv) -{ - struct intel_context *intel = - (struct intel_context *) driContextPriv->driverPrivate; - - assert(intel); /* should never be null */ - if (intel) { - GLboolean release_texture_heaps; - - INTEL_FIREVERTICES(intel); - - intel->vtbl.destroy(intel); - - release_texture_heaps = (intel->ctx.Shared->RefCount == 1); - _swsetup_DestroyContext(&intel->ctx); - _tnl_DestroyContext(&intel->ctx); - _vbo_DestroyContext(&intel->ctx); - - _swrast_DestroyContext(&intel->ctx); - intel->Fallback = 0; /* don't call _swrast_Flush later */ - - intel_batchbuffer_free(intel->batch); - - if (intel->last_swap_fence) { - dri_fence_wait(intel->last_swap_fence); - dri_fence_unreference(intel->last_swap_fence); - intel->last_swap_fence = NULL; - } - if (intel->first_swap_fence) { - dri_fence_wait(intel->first_swap_fence); - dri_fence_unreference(intel->first_swap_fence); - intel->first_swap_fence = NULL; - } - - - if (release_texture_heaps) { - /* This share group is about to go away, free our private - * texture object data. - */ - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "do something to free texture heaps\n"); - } - - /* free the Mesa context */ - _mesa_free_context_data(&intel->ctx); - } -} - -GLboolean -intelUnbindContext(__DRIcontextPrivate * driContextPriv) -{ - return GL_TRUE; -} - -GLboolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv) -{ - - if (driContextPriv) { - struct intel_context *intel = - (struct intel_context *) driContextPriv->driverPrivate; - struct intel_framebuffer *intel_fb = - (struct intel_framebuffer *) driDrawPriv->driverPrivate; - GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate; - - - /* XXX FBO temporary fix-ups! */ - /* if the renderbuffers don't have regions, init them from the context */ - { - struct intel_renderbuffer *irbDepth - = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); - struct intel_renderbuffer *irbStencil - = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); - - if (intel_fb->color_rb[0] && !intel_fb->color_rb[0]->region) { - intel_region_reference(&intel_fb->color_rb[0]->region, - intel->intelScreen->front_region); - } - if (intel_fb->color_rb[1] && !intel_fb->color_rb[1]->region) { - intel_region_reference(&intel_fb->color_rb[1]->region, - intel->intelScreen->back_region); - } - if (intel_fb->color_rb[2] && !intel_fb->color_rb[2]->region) { - intel_region_reference(&intel_fb->color_rb[2]->region, - intel->intelScreen->third_region); - } - if (irbDepth && !irbDepth->region) { - intel_region_reference(&irbDepth->region, intel->intelScreen->depth_region); - } - if (irbStencil && !irbStencil->region) { - intel_region_reference(&irbStencil->region, intel->intelScreen->depth_region); - } - } - - /* set GLframebuffer size to match window, if needed */ - driUpdateFramebufferSize(&intel->ctx, driDrawPriv); - - if (driReadPriv != driDrawPriv) { - driUpdateFramebufferSize(&intel->ctx, driReadPriv); - } - - _mesa_make_current(&intel->ctx, &intel_fb->Base, readFb); - - /* The drawbuffer won't always be updated by _mesa_make_current: - */ - if (intel->ctx.DrawBuffer == &intel_fb->Base) { - - if (intel->driDrawable != driDrawPriv) { - if (driDrawPriv->pdraw->swap_interval == (unsigned)-1) { - int i; - - intel_fb->vblank_flags = (intel->intelScreen->irq_active != 0) - ? driGetDefaultVBlankFlags(&intel->optionCache) - : VBLANK_FLAG_NO_IRQ; - - (*dri_interface->getUST) (&intel_fb->swap_ust); - driDrawableInitVBlank(driDrawPriv, intel_fb->vblank_flags, - &intel_fb->vbl_seq); - intel_fb->vbl_waited = intel_fb->vbl_seq; - - for (i = 0; i < (intel->intelScreen->third.handle ? 3 : 2); i++) { - if (intel_fb->color_rb[i]) - intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_seq; - } - } - intel->driDrawable = driDrawPriv; - intelWindowMoved(intel); - } - - intel_draw_buffer(&intel->ctx, &intel_fb->Base); - } - } - else { - _mesa_make_current(NULL, NULL, NULL); - } - - return GL_TRUE; -} - -static void -intelContendedLock(struct intel_context *intel, GLuint flags) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - __DRIscreenPrivate *sPriv = intel->driScreen; - intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; - drmI830Sarea *sarea = intel->sarea; - - drmGetLock(intel->driFd, intel->hHWContext, flags); - - if (INTEL_DEBUG & DEBUG_LOCK) - _mesa_printf("%s - got contended lock\n", __progname); - - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - if (dPriv) - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); - - /* If the last consumer of the texture memory wasn't us, notify the fake - * bufmgr and record the new owner. We should have the memory shared - * between contexts of a single fake bufmgr, but this will at least make - * things correct for now. - */ - if (!intel->intelScreen->ttm && sarea->texAge != intel->hHWContext) { - sarea->texAge = intel->hHWContext; - dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); - if (INTEL_DEBUG & DEBUG_BATCH) - intel_decode_context_reset(); - } - - if (sarea->width != intelScreen->width || - sarea->height != intelScreen->height || - sarea->rotation != intelScreen->current_rotation) { - - intelUpdateScreenRotation(sPriv, sarea); - } - - if (sarea->width != intel->width || - sarea->height != intel->height || - sarea->rotation != intel->current_rotation) { - int numClipRects = intel->numClipRects; - - /* - * FIXME: Really only need to do this when drawing to a - * common back- or front buffer. - */ - - /* - * This will essentially drop the outstanding batchbuffer on the floor. - */ - intel->numClipRects = 0; - - if (intel->Fallback) - _swrast_flush(&intel->ctx); - - INTEL_FIREVERTICES(intel); - - if (intel->batch->map != intel->batch->ptr) - intel_batchbuffer_flush(intel->batch); - - intel->numClipRects = numClipRects; - - /* force window update */ - intel->lastStamp = 0; - - intel->width = sarea->width; - intel->height = sarea->height; - intel->current_rotation = sarea->rotation; - } - - /* Drawable changed? - */ - if (dPriv && intel->lastStamp != dPriv->lastStamp) { - intelWindowMoved(intel); - intel->lastStamp = dPriv->lastStamp; - } -} - - - -/* Lock the hardware and validate our state. - */ -void LOCK_HARDWARE( struct intel_context *intel ) -{ - char __ret=0; - struct intel_framebuffer *intel_fb = NULL; - struct intel_renderbuffer *intel_rb = NULL; - _glthread_LOCK_MUTEX(lockMutex); - assert(!intel->locked); - - if (intel->driDrawable) { - intel_fb = intel->driDrawable->driverPrivate; - - if (intel_fb) - intel_rb = - intel_get_renderbuffer(&intel_fb->Base, - intel_fb->Base._ColorDrawBufferMask[0] == - BUFFER_BIT_FRONT_LEFT ? BUFFER_FRONT_LEFT : - BUFFER_BACK_LEFT); - } - - if (intel_rb && intel_fb->vblank_flags && - !(intel_fb->vblank_flags & VBLANK_FLAG_NO_IRQ) && - (intel_fb->vbl_waited - intel_rb->vbl_pending) > (1<<23)) { - drmVBlank vbl; - - vbl.request.type = DRM_VBLANK_ABSOLUTE; - - if ( intel_fb->vblank_flags & VBLANK_FLAG_SECONDARY ) { - vbl.request.type |= DRM_VBLANK_SECONDARY; - } - - vbl.request.sequence = intel_rb->vbl_pending; - drmWaitVBlank(intel->driFd, &vbl); - intel_fb->vbl_waited = vbl.reply.sequence; - } - - DRM_CAS(intel->driHwLock, intel->hHWContext, - (DRM_LOCK_HELD|intel->hHWContext), __ret); - - if (__ret) - intelContendedLock( intel, 0 ); - - if (INTEL_DEBUG & DEBUG_LOCK) - _mesa_printf("%s - locked\n", __progname); - - intel->locked = 1; -} - - - /* Unlock the hardware using the global current context - */ -void UNLOCK_HARDWARE( struct intel_context *intel ) -{ - intel->locked = 0; - - DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); - - _glthread_UNLOCK_MUTEX(lockMutex); - - if (INTEL_DEBUG & DEBUG_LOCK) - _mesa_printf("%s - unlocked\n", __progname); -} - diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h deleted file mode 100644 index 1e9ccd5cdc..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ /dev/null @@ -1,498 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTELCONTEXT_INC -#define INTELCONTEXT_INC - - - -#include "mtypes.h" -#include "drm.h" -#include "mm.h" -#include "texmem.h" - -#include "intel_screen.h" -#include "i915_drm.h" -#include "i830_common.h" -#include "tnl/t_vertex.h" - -#define TAG(x) intel##x -#include "tnl_dd/t_dd_vertex.h" -#undef TAG - -#define DV_PF_555 (1<<8) -#define DV_PF_565 (2<<8) -#define DV_PF_8888 (3<<8) - -struct intel_region; -struct intel_context; - -typedef void (*intel_tri_func) (struct intel_context *, intelVertex *, - intelVertex *, intelVertex *); -typedef void (*intel_line_func) (struct intel_context *, intelVertex *, - intelVertex *); -typedef void (*intel_point_func) (struct intel_context *, intelVertex *); - -#define INTEL_FALLBACK_DRAW_BUFFER 0x1 -#define INTEL_FALLBACK_READ_BUFFER 0x2 -#define INTEL_FALLBACK_DEPTH_BUFFER 0x4 -#define INTEL_FALLBACK_STENCIL_BUFFER 0x8 -#define INTEL_FALLBACK_USER 0x10 -#define INTEL_FALLBACK_RENDERMODE 0x20 - -extern void intelFallback(struct intel_context *intel, GLuint bit, - GLboolean mode); -#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode ) - - -#define INTEL_WRITE_PART 0x1 -#define INTEL_WRITE_FULL 0x2 -#define INTEL_READ 0x4 - -struct intel_texture_object -{ - struct gl_texture_object base; /* The "parent" object */ - - /* The mipmap tree must include at least these levels once - * validated: - */ - GLuint firstLevel; - GLuint lastLevel; - - /* Offset for firstLevel image: - */ - GLuint textureOffset; - - /* On validation any active images held in main memory or in other - * regions will be copied to this region and the old storage freed. - */ - struct intel_mipmap_tree *mt; - - GLboolean imageOverride; - GLint depthOverride; - GLuint pitchOverride; -}; - - - -struct intel_texture_image -{ - struct gl_texture_image base; - - /* These aren't stored in gl_texture_image - */ - GLuint level; - GLuint face; - - /* If intelImage->mt != NULL, image data is stored here. - * Else if intelImage->base.Data != NULL, image is stored there. - * Else there is no image data. - */ - struct intel_mipmap_tree *mt; -}; - - -#define INTEL_MAX_FIXUP 64 - -struct intel_context -{ - GLcontext ctx; /* the parent class */ - - struct - { - void (*destroy) (struct intel_context * intel); - void (*emit_state) (struct intel_context * intel); - void (*lost_hardware) (struct intel_context * intel); - void (*update_texture_state) (struct intel_context * intel); - - void (*render_start) (struct intel_context * intel); - void (*render_prevalidate) (struct intel_context * intel); - void (*set_draw_region) (struct intel_context * intel, - struct intel_region * draw_region, - struct intel_region * depth_region); - - GLuint(*flush_cmd) (void); - - void (*reduced_primitive_state) (struct intel_context * intel, - GLenum rprim); - - GLboolean(*check_vertex_size) (struct intel_context * intel, - GLuint expected); - - - /* Metaops: - */ - void (*install_meta_state) (struct intel_context * intel); - void (*leave_meta_state) (struct intel_context * intel); - - void (*meta_draw_region) (struct intel_context * intel, - struct intel_region * draw_region, - struct intel_region * depth_region); - - void (*meta_color_mask) (struct intel_context * intel, GLboolean); - - void (*meta_stencil_replace) (struct intel_context * intel, - GLuint mask, GLuint clear); - - void (*meta_depth_replace) (struct intel_context * intel); - - void (*meta_texture_blend_replace) (struct intel_context * intel); - - void (*meta_no_stencil_write) (struct intel_context * intel); - void (*meta_no_depth_write) (struct intel_context * intel); - void (*meta_no_texture) (struct intel_context * intel); - - void (*meta_import_pixel_state) (struct intel_context * intel); - - GLboolean(*meta_tex_rect_source) (struct intel_context * intel, - dri_bo * buffer, - GLuint offset, - GLuint pitch, - GLuint height, - GLenum format, GLenum type); - void (*rotate_window) (struct intel_context * intel, - __DRIdrawablePrivate * dPriv, GLuint srcBuf); - - void (*assert_not_dirty) (struct intel_context *intel); - - } vtbl; - - GLint refcount; - GLuint Fallback; - GLuint NewGLState; - - dri_fence *last_swap_fence; - dri_fence *first_swap_fence; - - struct intel_batchbuffer *batch; - - struct - { - GLuint id; - GLuint primitive; - GLubyte *start_ptr; - void (*flush) (struct intel_context *); - } prim; - - GLboolean locked; - char *prevLockFile; - int prevLockLine; - - GLuint ClearColor565; - GLuint ClearColor8888; - - /* Offsets of fields within the current vertex: - */ - GLuint coloroffset; - GLuint specoffset; - GLuint wpos_offset; - GLuint wpos_size; - - struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; - GLuint vertex_attr_count; - - GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */ - - GLboolean hw_stipple; - GLboolean strict_conformance; - - /* State for intelvb.c and inteltris.c. - */ - GLuint RenderIndex; - GLmatrix ViewportMatrix; - GLenum render_primitive; - GLenum reduced_primitive; - GLuint vertex_size; - GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ - -#if 0 - struct intel_region *front_region; /* XXX FBO: obsolete */ - struct intel_region *rotated_region; /* XXX FBO: obsolete */ - struct intel_region *back_region; /* XXX FBO: obsolete */ - struct intel_region *draw_region; /* XXX FBO: rename to color_region */ - struct intel_region *depth_region; /**< currently bound depth/Z region */ -#endif - - /* Fallback rasterization functions - */ - intel_point_func draw_point; - intel_line_func draw_line; - intel_tri_func draw_tri; - - /* These refer to the current drawing buffer: - */ - int drawX, drawY; /**< origin of drawing area within region */ - GLuint numClipRects; /**< cliprects for drawing */ - drm_clip_rect_t *pClipRects; - drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ - - int perf_boxes; - - GLuint do_usleeps; - int do_irqs; - GLuint irqsEmitted; - - drm_context_t hHWContext; - drmLock *driHwLock; - int driFd; - - __DRIdrawablePrivate *driDrawable; - __DRIscreenPrivate *driScreen; - intelScreenPrivate *intelScreen; - drmI830Sarea *sarea; - - GLuint lastStamp; - - /** - * Configuration cache - */ - driOptionCache optionCache; - - /* Rotation. Need to match that of the - * current screen. - */ - - int width; - int height; - int current_rotation; -}; - -/* These are functions now: - */ -void LOCK_HARDWARE( struct intel_context *intel ); -void UNLOCK_HARDWARE( struct intel_context *intel ); - -extern char *__progname; - - -#define SUBPIXEL_X 0.125 -#define SUBPIXEL_Y 0.125 - -#define INTEL_FIREVERTICES(intel) \ -do { \ - if ((intel)->prim.flush) \ - (intel)->prim.flush(intel); \ -} while (0) - -/* ================================================================ - * Color packing: - */ - -#define INTEL_PACKCOLOR4444(r,g,b,a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) - -#define INTEL_PACKCOLOR1555(r,g,b,a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) - -#define INTEL_PACKCOLOR565(r,g,b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) - -#define INTEL_PACKCOLOR8888(r,g,b,a) \ - ((a<<24) | (r<<16) | (g<<8) | b) - - - -/* ================================================================ - * From linux kernel i386 header files, copes with odd sizes better - * than COPY_DWORDS would: - * XXX Put this in src/mesa/main/imports.h ??? - */ -#if defined(i386) || defined(__i386__) -static INLINE void * -__memcpy(void *to, const void *from, size_t n) -{ - int d0, d1, d2; - __asm__ __volatile__("rep ; movsl\n\t" - "testb $2,%b4\n\t" - "je 1f\n\t" - "movsw\n" - "1:\ttestb $1,%b4\n\t" - "je 2f\n\t" - "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) - :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) - :"memory"); - return (to); -} -#else -#define __memcpy(a,b,c) memcpy(a,b,c) -#endif - - - -/* ================================================================ - * Debugging: - */ -#define DO_DEBUG 1 -#if DO_DEBUG -extern int INTEL_DEBUG; -#else -#define INTEL_DEBUG 0 -#endif - -#define DEBUG_TEXTURE 0x1 -#define DEBUG_STATE 0x2 -#define DEBUG_IOCTL 0x4 -#define DEBUG_BLIT 0x8 -#define DEBUG_MIPTREE 0x10 -#define DEBUG_FALLBACKS 0x20 -#define DEBUG_VERBOSE 0x40 -#define DEBUG_BATCH 0x80 -#define DEBUG_PIXEL 0x100 -#define DEBUG_BUFMGR 0x200 -#define DEBUG_REGION 0x400 -#define DEBUG_FBO 0x800 -#define DEBUG_LOCK 0x1000 - -#define DBG(...) do { if (INTEL_DEBUG & FILE_DEBUG_FLAG) _mesa_printf(__VA_ARGS__); } while(0) - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GME 0x27AE -#define PCI_CHIP_G33_G 0x29C2 -#define PCI_CHIP_Q35_G 0x29B2 -#define PCI_CHIP_Q33_G 0x29D2 - - -/* ================================================================ - * intel_context.c: - */ - -extern GLboolean intelInitContext(struct intel_context *intel, - const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate, - struct dd_function_table *functions); - -extern void intelGetLock(struct intel_context *intel, GLuint flags); - -extern void intelFinish(GLcontext * ctx); -extern void intelFlush(GLcontext * ctx); - -extern void intelInitDriverFunctions(struct dd_function_table *functions); - - -/* ================================================================ - * intel_state.c: - */ -extern void intelInitStateFuncs(struct dd_function_table *functions); - -#define COMPAREFUNC_ALWAYS 0 -#define COMPAREFUNC_NEVER 0x1 -#define COMPAREFUNC_LESS 0x2 -#define COMPAREFUNC_EQUAL 0x3 -#define COMPAREFUNC_LEQUAL 0x4 -#define COMPAREFUNC_GREATER 0x5 -#define COMPAREFUNC_NOTEQUAL 0x6 -#define COMPAREFUNC_GEQUAL 0x7 - -#define STENCILOP_KEEP 0 -#define STENCILOP_ZERO 0x1 -#define STENCILOP_REPLACE 0x2 -#define STENCILOP_INCRSAT 0x3 -#define STENCILOP_DECRSAT 0x4 -#define STENCILOP_INCR 0x5 -#define STENCILOP_DECR 0x6 -#define STENCILOP_INVERT 0x7 - -#define LOGICOP_CLEAR 0 -#define LOGICOP_NOR 0x1 -#define LOGICOP_AND_INV 0x2 -#define LOGICOP_COPY_INV 0x3 -#define LOGICOP_AND_RVRSE 0x4 -#define LOGICOP_INV 0x5 -#define LOGICOP_XOR 0x6 -#define LOGICOP_NAND 0x7 -#define LOGICOP_AND 0x8 -#define LOGICOP_EQUIV 0x9 -#define LOGICOP_NOOP 0xa -#define LOGICOP_OR_INV 0xb -#define LOGICOP_COPY 0xc -#define LOGICOP_OR_RVRSE 0xd -#define LOGICOP_OR 0xe -#define LOGICOP_SET 0xf - -#define BLENDFACT_ZERO 0x01 -#define BLENDFACT_ONE 0x02 -#define BLENDFACT_SRC_COLR 0x03 -#define BLENDFACT_INV_SRC_COLR 0x04 -#define BLENDFACT_SRC_ALPHA 0x05 -#define BLENDFACT_INV_SRC_ALPHA 0x06 -#define BLENDFACT_DST_ALPHA 0x07 -#define BLENDFACT_INV_DST_ALPHA 0x08 -#define BLENDFACT_DST_COLR 0x09 -#define BLENDFACT_INV_DST_COLR 0x0a -#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b -#define BLENDFACT_CONST_COLOR 0x0c -#define BLENDFACT_INV_CONST_COLOR 0x0d -#define BLENDFACT_CONST_ALPHA 0x0e -#define BLENDFACT_INV_CONST_ALPHA 0x0f -#define BLENDFACT_MASK 0x0f - -#define MI_BATCH_BUFFER_END (0xA<<23) - - -extern int intel_translate_compare_func(GLenum func); -extern int intel_translate_stencil_op(GLenum op); -extern int intel_translate_blend_factor(GLenum factor); -extern int intel_translate_logic_op(GLenum opcode); - - -/*====================================================================== - * Inline conversion functions. - * These are better-typed than the macros used previously: - */ -static INLINE struct intel_context * -intel_context(GLcontext * ctx) -{ - return (struct intel_context *) ctx; -} - -static INLINE struct intel_texture_object * -intel_texture_object(struct gl_texture_object *obj) -{ - return (struct intel_texture_object *) obj; -} - -static INLINE struct intel_texture_image * -intel_texture_image(struct gl_texture_image *img) -{ - return (struct intel_texture_image *) img; -} - -extern struct intel_renderbuffer *intel_renderbuffer(struct gl_renderbuffer - *rb); - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_decode.c b/src/mesa/drivers/dri/i915tex/intel_decode.c deleted file mode 100644 index bf3387b28e..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_decode.c +++ /dev/null @@ -1,832 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/* - * Copyright © 2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Eric Anholt - * - */ - -/** @file intel_decode.c - * This file contains code to print out batchbuffer contents in a - * human-readable format. - * - * The current version only supports i915 packets, and only pretty-prints a - * subset of them. The intention is for it to make just a best attempt to - * decode, but never crash in the process. - */ - -#include -#include -#include - -#include "intel_decode.h" -#include "i915_reg.h" - -#define BUFFER_FAIL(_count, _len, _name) do { \ - fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ - (_name), (_count), (_len)); \ - (*failures)++; \ - return count; \ -} while (0) - -static FILE *out; -static uint32_t saved_s2 = 0, saved_s4 = 0; -static char saved_s2_set = 0, saved_s4_set = 0; - -static float -int_as_float(uint32_t intval) -{ - union intfloat { - uint32_t i; - float f; - } uval; - - uval.i = intval; - return uval.f; -} - -static void -instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, - char *fmt, ...) -{ - va_list va; - - fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); - va_start(va, fmt); - vfprintf(out, fmt, va); - va_end(va); -} - - -static int -decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_mi[] = { - { 0x08, 1, 1, "MI_ARB_ON_OFF" }, - { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, - { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, - { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, - { 0x04, 1, 1, "MI_FLUSH" }, - { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, - { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, - { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, - { 0x00, 1, 1, "MI_NOOP" }, - { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, - { 0x07, 1, 1, "MI_REPORT_HEAD" }, - { 0x18, 2, 2, "MI_SET_CONTEXT" }, - { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, - { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, - { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, - { 0x02, 1, 1, "MI_USER_INTERRUPT" }, - { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, - }; - - - for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); - opcode++) { - if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { - unsigned int len = 1, i; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); - if (opcodes_mi[opcode].max_len > 1) { - len = (data[0] & 0x000000ff) + 2; - if (len < opcodes_mi[opcode].min_len || - len > opcodes_mi[opcode].max_len) - { - fprintf(out, "Bad length in %s\n", - opcodes_mi[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_mi[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode, len; - char *format; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_2d[] = { - { 0x40, 5, 5, "COLOR_BLT" }, - { 0x43, 6, 6, "SRC_COPY_BLT" }, - { 0x01, 8, 8, "XY_SETUP_BLT" }, - { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, - { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, - { 0x24, 2, 2, "XY_PIXEL_BLT" }, - { 0x25, 3, 3, "XY_SCANLINES_BLT" }, - { 0x26, 4, 4, "Y_TEXT_BLT" }, - { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, - { 0x50, 6, 6, "XY_COLOR_BLT" }, - { 0x51, 6, 6, "XY_PAT_BLT" }, - { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, - { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, - { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, - { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, - { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, - { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, - { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, - { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, - { 0x55, 9, 9, "XY_FULL_BLT" }, - { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, - { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, - { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, - { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, - { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, - }; - - switch ((data[0] & 0x1fc00000) >> 22) { - case 0x50: - instr_out(data, hw_offset, 0, - "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", - (data[0] & (1 << 20)) ? "en" : "dis", - (data[0] & (1 << 21)) ? "en" : "dis"); - - len = (data[0] & 0x000000ff) + 2; - if (len != 6) - fprintf(out, "Bad count in XY_COLOR_BLT\n"); - if (count < 6) - BUFFER_FAIL(count, len, "XY_COLOR_BLT"); - - switch ((data[1] >> 24) & 0x3) { - case 0: - format="8"; - break; - case 1: - format="565"; - break; - case 2: - format="1555"; - break; - case 3: - format="8888"; - break; - } - - instr_out(data, hw_offset, 1, "format %s, pitch %d, " - "clipping %sabled\n", format, - data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); - instr_out(data, hw_offset, 2, "(%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 3, "(%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); - instr_out(data, hw_offset, 5, "color\n"); - return len; - case 0x53: - instr_out(data, hw_offset, 0, - "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", - (data[0] & (1 << 20)) ? "en" : "dis", - (data[0] & (1 << 21)) ? "en" : "dis"); - - len = (data[0] & 0x000000ff) + 2; - if (len != 8) - fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); - if (count < 8) - BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); - - switch ((data[1] >> 24) & 0x3) { - case 0: - format="8"; - break; - case 1: - format="565"; - break; - case 2: - format="1555"; - break; - case 3: - format="8888"; - break; - } - - instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " - "clipping %sabled\n", format, - data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); - instr_out(data, hw_offset, 2, "dst (%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 3, "dst (%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); - instr_out(data, hw_offset, 5, "src (%d,%d)\n", - data[5] & 0xffff, data[5] >> 16); - instr_out(data, hw_offset, 6, "src pitch %d\n", - data[6] & 0xffff); - instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); - return len; - } - - for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); - opcode++) { - if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { - unsigned int i; - - len = 1; - instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); - if (opcodes_2d[opcode].max_len > 1) { - len = (data[0] & 0x000000ff) + 2; - if (len < opcodes_2d[opcode].min_len || - len > opcodes_2d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_2d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - switch ((data[0] & 0x00f80000) >> 19) { - case 0x11: - instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); - return 1; - case 0x10: - instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); - return 1; - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int len, i, c, opcode, word, map, sampler, instr; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_3d_1d[] = { - { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, - { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, - { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, - { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, - { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, - { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, - { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, - { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, - { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, - { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, - { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, - { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, - { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, - { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, - { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, - { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, - { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, - }; - - switch ((data[0] & 0x00ff0000) >> 16) { - case 0x07: - /* This instruction is unusual. A 0 length means just 1 DWORD instead of - * 2. The 0 length is specified in one place to be unsupported, but - * stated to be required in another, and 0 length LOAD_INDIRECTs appear - * to cause no harm at least. - */ - instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); - len = (data[0] & 0x000000ff) + 1; - i = 1; - if (data[0] & (0x01 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "SIS.0\n"); - instr_out(data, hw_offset, i++, "SIS.1\n"); - } - if (data[0] & (0x02 << 8)) { - if (i + 1 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "DIS.0\n"); - } - if (data[0] & (0x04 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "SSB.0\n"); - instr_out(data, hw_offset, i++, "SSB.1\n"); - } - if (data[0] & (0x08 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "MSB.0\n"); - instr_out(data, hw_offset, i++, "MSB.1\n"); - } - if (data[0] & (0x10 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "PSP.0\n"); - instr_out(data, hw_offset, i++, "PSP.1\n"); - } - if (data[0] & (0x20 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "PSC.0\n"); - instr_out(data, hw_offset, i++, "PSC.1\n"); - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); - (*failures)++; - return len; - } - return len; - case 0x04: - instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); - len = (data[0] & 0x0000000f) + 2; - i = 1; - for (word = 0; word <= 7; word++) { - if (data[0] & (1 << (4 + word))) { - if (i >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); - - /* save vertex state for decode */ - if (word == 2) { - saved_s2_set = 1; - saved_s2 = data[i]; - } - if (word == 4) { - saved_s4_set = 1; - saved_s4 = data[i]; - } - - instr_out(data, hw_offset, i++, "S%d\n", word); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); - (*failures)++; - } - return len; - case 0x00: - instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); - len = (data[0] & 0x0000003f) + 2; - - i = 1; - for (map = 0; map <= 15; map++) { - if (data[1] & (1 << map)) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); - instr_out(data, hw_offset, i++, "map %d MS2\n", map); - instr_out(data, hw_offset, i++, "map %d MS3\n", map); - instr_out(data, hw_offset, i++, "map %d MS4\n", map); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); - (*failures)++; - return len; - } - return len; - case 0x06: - instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); - len = (data[0] & 0x000000ff) + 2; - - i = 1; - for (c = 0; c <= 31; c++) { - if (data[1] & (1 << c)) { - if (i + 4 >= count) - BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); - instr_out(data, hw_offset, i, "C%d.X = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.Y = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.Z = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.W = %f\n", - c, int_as_float(data[i])); - i++; - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); - (*failures)++; - } - return len; - case 0x05: - instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); - len = (data[0] & 0x000000ff) + 2; - if ((len - 1) % 3 != 0 || len > 370) { - fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); - (*failures)++; - } - i = 1; - for (instr = 0; instr < (len - 1) / 3; instr++) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - } - return len; - case 0x01: - instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); - len = (data[0] & 0x0000003f) + 2; - i = 1; - for (sampler = 0; sampler <= 15; sampler++) { - if (data[1] & (1 << sampler)) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); - instr_out(data, hw_offset, i++, "sampler %d SS2\n", - sampler); - instr_out(data, hw_offset, i++, "sampler %d SS3\n", - sampler); - instr_out(data, hw_offset, i++, "sampler %d SS4\n", - sampler); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); - (*failures)++; - } - return len; - } - - for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); - opcode++) - { - if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { - len = 1; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); - if (opcodes_3d_1d[opcode].max_len > 1) { - len = (data[0] & 0x0000ffff) + 2; - if (len < opcodes_3d_1d[opcode].min_len || - len > opcodes_3d_1d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", - opcodes_3d_1d[opcode].name); - (*failures)++; - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, - int *failures) -{ - char immediate = (data[0] & (1 << 23)) == 0; - unsigned int len, i; - char *primtype; - - switch ((data[0] >> 18) & 0xf) { - case 0x0: primtype = "TRILIST"; break; - case 0x1: primtype = "TRISTRIP"; break; - case 0x2: primtype = "TRISTRIP_REVERSE"; break; - case 0x3: primtype = "TRIFAN"; break; - case 0x4: primtype = "POLYGON"; break; - case 0x5: primtype = "LINELIST"; break; - case 0x6: primtype = "LINESTRIP"; break; - case 0x7: primtype = "RECTLIST"; break; - case 0x8: primtype = "POINTLIST"; break; - case 0x9: primtype = "DIB"; break; - case 0xa: primtype = "CLEAR_RECT"; break; - default: primtype = "unknown"; break; - } - - /* XXX: 3DPRIM_DIB not supported */ - if (immediate) { - len = (data[0] & 0x0003ffff) + 2; - instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); - if (count < len) - BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); - if (!saved_s2_set || !saved_s4_set) { - fprintf(out, "unknown vertex format\n"); - for (i = 1; i < len; i++) { - instr_out(data, hw_offset, i, - " vertex data (%f float)\n", - int_as_float(data[i])); - } - } else { - unsigned int vertex = 0; - for (i = 1; i < len;) { - unsigned int tc; - -#define VERTEX_OUT(fmt, ...) do { \ - if (i < len) \ - instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ - else \ - fprintf(out, " missing data in V%d\n", vertex); \ - i++; \ -} while (0) - - VERTEX_OUT("X = %f", int_as_float(data[i])); - VERTEX_OUT("Y = %f", int_as_float(data[i])); - switch (saved_s4 >> 6 & 0x7) { - case 0x1: - VERTEX_OUT("Z = %f", int_as_float(data[i])); - break; - case 0x2: - VERTEX_OUT("Z = %f", int_as_float(data[i])); - VERTEX_OUT("W = %f", int_as_float(data[i])); - break; - case 0x3: - break; - case 0x4: - VERTEX_OUT("W = %f", int_as_float(data[i])); - break; - default: - fprintf(out, "bad S4 position mask\n"); - } - - if (saved_s4 & (1 << 10)) { - VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " - "B=0x%02x)", - data[i] >> 24, - (data[i] >> 16) & 0xff, - (data[i] >> 8) & 0xff, - data[i] & 0xff); - } - if (saved_s4 & (1 << 11)) { - VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " - "B=0x%02x)", - data[i] >> 24, - (data[i] >> 16) & 0xff, - (data[i] >> 8) & 0xff, - data[i] & 0xff); - } - if (saved_s4 & (1 << 12)) - VERTEX_OUT("width = 0x%08x)", data[i]); - - for (tc = 0; tc <= 7; tc++) { - switch ((saved_s2 >> (tc * 4)) & 0xf) { - case 0x0: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - break; - case 0x1: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); - break; - case 0x2: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); - break; - case 0x3: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - break; - case 0x4: - VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); - break; - case 0x5: - VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); - VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); - break; - case 0xf: - break; - default: - fprintf(out, "bad S2.T%d format\n", tc); - } - } - vertex++; - } - } - } else { - /* indirect vertices */ - len = data[0] & 0x0000ffff; /* index count */ - if (data[0] & (1 << 17)) { - /* random vertex access */ - if (count < (len + 1) / 2 + 1) { - BUFFER_FAIL(count, (len + 1) / 2 + 1, - "3DPRIMITIVE random indirect"); - } - instr_out(data, hw_offset, 0, - "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); - if (len == 0) { - /* vertex indices continue until 0xffff is found */ - for (i = 1; i < count; i++) { - if ((data[i] & 0xffff) == 0xffff) { - instr_out(data, hw_offset, i, - " indices: (terminator)\n"); - return i; - } else if ((data[i] >> 16) == 0xffff) { - instr_out(data, hw_offset, i, - " indices: 0x%04x, " - "(terminator)\n", - data[i] & 0xffff); - return i; - } else { - instr_out(data, hw_offset, i, - " indices: 0x%04x, 0x%04x\n", - data[i] & 0xffff, data[i] >> 16); - } - } - fprintf(out, - "3DPRIMITIVE: no terminator found in index buffer\n"); - (*failures)++; - return count; - } else { - /* fixed size vertex index buffer */ - for (i = 0; i < len; i += 2) { - if (i * 2 == len - 1) { - instr_out(data, hw_offset, i, - " indices: 0x%04x\n", - data[i] & 0xffff); - } else { - instr_out(data, hw_offset, i, - " indices: 0x%04x, 0x%04x\n", - data[i] & 0xffff, data[i] >> 16); - } - } - } - return (len + 1) / 2 + 1; - } else { - /* sequential vertex access */ - if (count < 2) - BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); - instr_out(data, hw_offset, 0, - "3DPRIMITIVE sequential indirect %s, %d starting from " - "%d\n", primtype, len, data[1] & 0xffff); - instr_out(data, hw_offset, 1, " start\n"); - return 2; - } - } - - return len; -} - -static int -decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_3d[] = { - { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, - { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, - { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, - { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, - { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, - { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, - { 0x0d, 1, 1, "3DSTATE_MODES_4" }, - { 0x0c, 1, 1, "3DSTATE_MODES_5" }, - { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, - }; - - switch ((data[0] & 0x1f000000) >> 24) { - case 0x1f: - return decode_3d_primitive(data, count, hw_offset, failures); - case 0x1d: - return decode_3d_1d(data, count, hw_offset, failures); - case 0x1c: - return decode_3d_1c(data, count, hw_offset, failures); - } - - for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); - opcode++) { - if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { - unsigned int len = 1, i; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); - if (opcodes_3d[opcode].max_len > 1) { - len = (data[0] & 0xff) + 2; - if (len < opcodes_3d[opcode].min_len || - len > opcodes_3d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_3d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - return len; - } - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -/** - * Decodes an i830-i915 batch buffer, writing the output to stdout. - * - * \param data batch buffer contents - * \param count number of DWORDs to decode in the batch buffer - * \param hw_offset hardware address for the buffer - */ -int -intel_decode(uint32_t *data, int count, uint32_t hw_offset) -{ - int index = 0; - int failures = 0; - - out = stdout; - - while (index < count) { - switch ((data[index] & 0xe0000000) >> 29) { - case 0x0: - index += decode_mi(data + index, count - index, - hw_offset + index * 4, &failures); - break; - case 0x2: - index += decode_2d(data + index, count - index, - hw_offset + index * 4, &failures); - break; - case 0x3: - index += decode_3d(data + index, count - index, - hw_offset + index * 4, &failures); - break; - default: - instr_out(data, hw_offset, index, "UNKNOWN\n"); - failures++; - index++; - break; - } - fflush(out); - } - - return failures; -} - -void intel_decode_context_reset() -{ - saved_s2_set = 0; - saved_s4_set = 1; -} - diff --git a/src/mesa/drivers/dri/i915tex/intel_decode.h b/src/mesa/drivers/dri/i915tex/intel_decode.h deleted file mode 100644 index ef0cba153c..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_decode.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Eric Anholt - * - */ - -int intel_decode(uint32_t *data, int count, uint32_t hw_offset); -void intel_decode_context_reset(); diff --git a/src/mesa/drivers/dri/i915tex/intel_depthstencil.c b/src/mesa/drivers/dri/i915tex/intel_depthstencil.c deleted file mode 100644 index d269a85a3c..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_depthstencil.c +++ /dev/null @@ -1,282 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "imports.h" -#include "context.h" -#include "depthstencil.h" -#include "fbobject.h" -#include "framebuffer.h" -#include "hash.h" -#include "mtypes.h" -#include "renderbuffer.h" - -#include "intel_context.h" -#include "intel_fbo.h" -#include "intel_depthstencil.h" -#include "intel_regions.h" - - -/** - * The GL_EXT_framebuffer_object allows the user to create their own - * framebuffer objects consisting of color renderbuffers (0 or more), - * depth renderbuffers (0 or 1) and stencil renderbuffers (0 or 1). - * - * The spec considers depth and stencil renderbuffers to be totally independent - * buffers. In reality, most graphics hardware today uses a combined - * depth+stencil buffer (one 32-bit pixel = 24 bits of Z + 8 bits of stencil). - * - * This causes difficulty because the user may create some number of depth - * renderbuffers and some number of stencil renderbuffers and bind them - * together in framebuffers in any combination. - * - * This code manages all that. - * - * 1. Depth renderbuffers are always allocated in hardware as 32bpp - * GL_DEPTH24_STENCIL8 buffers. - * - * 2. Stencil renderbuffers are initially allocated in software as 8bpp - * GL_STENCIL_INDEX8 buffers. - * - * 3. Depth and Stencil renderbuffers use the PairedStencil and PairedDepth - * fields (respectively) to indicate if the buffer's currently paired - * with another stencil or depth buffer (respectively). - * - * 4. When a depth and stencil buffer are initially both attached to the - * current framebuffer, we merge the stencil buffer values into the - * depth buffer (really a depth+stencil buffer). The then hardware uses - * the combined buffer. - * - * 5. Whenever a depth or stencil buffer is reallocated (with - * glRenderbufferStorage) we undo the pairing and copy the stencil values - * from the combined depth/stencil buffer back to the stencil-only buffer. - * - * 6. We also undo the pairing when we find a change in buffer bindings. - * - * 7. If a framebuffer is only using a depth renderbuffer (no stencil), we - * just use the combined depth/stencil buffer and ignore the stencil values. - * - * 8. If a framebuffer is only using a stencil renderbuffer (no depth) we have - * to promote the 8bpp software stencil buffer to a 32bpp hardware - * depth+stencil buffer. - * - */ - - - -static void -map_regions(GLcontext * ctx, - struct intel_renderbuffer *depthRb, - struct intel_renderbuffer *stencilRb) -{ - struct intel_context *intel = intel_context(ctx); - if (depthRb && depthRb->region) { - intel_region_map(intel->intelScreen, depthRb->region); - depthRb->pfMap = depthRb->region->map; - depthRb->pfPitch = depthRb->region->pitch; - } - if (stencilRb && stencilRb->region) { - intel_region_map(intel->intelScreen, stencilRb->region); - stencilRb->pfMap = stencilRb->region->map; - stencilRb->pfPitch = stencilRb->region->pitch; - } -} - -static void -unmap_regions(GLcontext * ctx, - struct intel_renderbuffer *depthRb, - struct intel_renderbuffer *stencilRb) -{ - struct intel_context *intel = intel_context(ctx); - if (depthRb && depthRb->region) { - intel_region_unmap(intel->intelScreen, depthRb->region); - depthRb->pfMap = NULL; - depthRb->pfPitch = 0; - } - if (stencilRb && stencilRb->region) { - intel_region_unmap(intel->intelScreen, stencilRb->region); - stencilRb->pfMap = NULL; - stencilRb->pfPitch = 0; - } -} - - - -/** - * Undo the pairing/interleaving between depth and stencil buffers. - * irb should be a depth/stencil or stencil renderbuffer. - */ -void -intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb) -{ - if (irb->PairedStencil) { - /* irb is a depth/stencil buffer */ - struct gl_renderbuffer *stencilRb; - struct intel_renderbuffer *stencilIrb; - - ASSERT(irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - - stencilRb = _mesa_lookup_renderbuffer(ctx, irb->PairedStencil); - stencilIrb = intel_renderbuffer(stencilRb); - if (stencilIrb) { - /* need to extract stencil values from the depth buffer */ - ASSERT(stencilIrb->PairedDepth == irb->Base.Name); - map_regions(ctx, irb, stencilIrb); - _mesa_extract_stencil(ctx, &irb->Base, &stencilIrb->Base); - unmap_regions(ctx, irb, stencilIrb); - stencilIrb->PairedDepth = 0; - } - irb->PairedStencil = 0; - } - else if (irb->PairedDepth) { - /* irb is a stencil buffer */ - struct gl_renderbuffer *depthRb; - struct intel_renderbuffer *depthIrb; - - ASSERT(irb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || - irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - - depthRb = _mesa_lookup_renderbuffer(ctx, irb->PairedDepth); - depthIrb = intel_renderbuffer(depthRb); - if (depthIrb) { - /* need to extract stencil values from the depth buffer */ - ASSERT(depthIrb->PairedStencil == irb->Base.Name); - map_regions(ctx, depthIrb, irb); - _mesa_extract_stencil(ctx, &depthIrb->Base, &irb->Base); - unmap_regions(ctx, depthIrb, irb); - depthIrb->PairedStencil = 0; - } - irb->PairedDepth = 0; - } - else { - _mesa_problem(ctx, "Problem in undo_depth_stencil_pairing"); - } - - ASSERT(irb->PairedStencil == 0); - ASSERT(irb->PairedDepth == 0); -} - - -/** - * Examine the depth and stencil renderbuffers which are attached to the - * framebuffer. If both depth and stencil are attached, make sure that the - * renderbuffers are 'paired' (combined). If only depth or only stencil is - * attached, undo any previous pairing. - * - * Must be called if NewState & _NEW_BUFFER (when renderbuffer attachments - * change, for example). - */ -void -intel_validate_paired_depth_stencil(GLcontext * ctx, - struct gl_framebuffer *fb) -{ - struct intel_renderbuffer *depthRb, *stencilRb; - - depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH); - stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); - - if (depthRb && stencilRb) { - if (depthRb == stencilRb) { - /* Using a user-created combined depth/stencil buffer. - * Nothing to do. - */ - ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_STENCIL_EXT); - ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - } - else { - /* Separate depth/stencil buffers, need to interleave now */ - ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_COMPONENT); - ASSERT(stencilRb->Base._BaseFormat == GL_STENCIL_INDEX); - /* may need to interleave depth/stencil now */ - if (depthRb->PairedStencil == stencilRb->Base.Name) { - /* OK, the depth and stencil buffers are already interleaved */ - ASSERT(stencilRb->PairedDepth == depthRb->Base.Name); - } - else { - /* need to setup new pairing/interleaving */ - if (depthRb->PairedStencil) { - intel_unpair_depth_stencil(ctx, depthRb); - } - if (stencilRb->PairedDepth) { - intel_unpair_depth_stencil(ctx, stencilRb); - } - - ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - ASSERT(stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || - stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - - /* establish new pairing: interleave stencil into depth buffer */ - map_regions(ctx, depthRb, stencilRb); - _mesa_insert_stencil(ctx, &depthRb->Base, &stencilRb->Base); - unmap_regions(ctx, depthRb, stencilRb); - depthRb->PairedStencil = stencilRb->Base.Name; - stencilRb->PairedDepth = depthRb->Base.Name; - } - - } - } - else if (depthRb) { - /* Depth buffer but no stencil buffer. - * We'll use a GL_DEPTH24_STENCIL8 buffer and ignore the stencil bits. - */ - /* can't assert this until storage is allocated: - ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - */ - /* intel_undo any previous pairing */ - if (depthRb->PairedStencil) { - intel_unpair_depth_stencil(ctx, depthRb); - } - } - else if (stencilRb) { - /* Stencil buffer but no depth buffer. - * Since h/w doesn't typically support just 8bpp stencil w/out Z, - * we'll use a GL_DEPTH24_STENCIL8 buffer and ignore the depth bits. - */ - /* undo any previous pairing */ - if (stencilRb->PairedDepth) { - intel_unpair_depth_stencil(ctx, stencilRb); - } - if (stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT) { - /* promote buffer to GL_DEPTH24_STENCIL8 for hw rendering */ - _mesa_promote_stencil(ctx, &stencilRb->Base); - ASSERT(stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); - } - } - - /* Finally, update the fb->_DepthBuffer and fb->_StencilBuffer fields */ - _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); - if (depthRb && depthRb->PairedStencil) - _mesa_update_stencil_buffer(ctx, fb, BUFFER_DEPTH); - else - _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); - - - /* The hardware should use fb->Attachment[BUFFER_DEPTH].Renderbuffer - * first, if present, then fb->Attachment[BUFFER_STENCIL].Renderbuffer - * if present. - */ -} diff --git a/src/mesa/drivers/dri/i915tex/intel_depthstencil.h b/src/mesa/drivers/dri/i915tex/intel_depthstencil.h deleted file mode 100644 index 2d3fc48b3a..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_depthstencil.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef INTEL_DEPTH_STENCIL_H -#define INTEL_DEPTH_STENCIL_H - - -extern void -intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb); - -extern void -intel_validate_paired_depth_stencil(GLcontext * ctx, - struct gl_framebuffer *fb); - - -#endif /* INTEL_DEPTH_STENCIL_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c deleted file mode 100644 index 6f99f401c7..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.c +++ /dev/null @@ -1,687 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "imports.h" -#include "mtypes.h" -#include "fbobject.h" -#include "framebuffer.h" -#include "renderbuffer.h" -#include "context.h" -#include "texformat.h" -#include "texrender.h" - -#include "intel_context.h" -#include "intel_buffers.h" -#include "intel_depthstencil.h" -#include "intel_fbo.h" -#include "intel_mipmap_tree.h" -#include "intel_regions.h" -#include "intel_span.h" - - -#define FILE_DEBUG_FLAG DEBUG_FBO - -#define INTEL_RB_CLASS 0x12345678 - - -/* XXX FBO: move this to intel_context.h (inlined) */ -/** - * Return a gl_renderbuffer ptr casted to intel_renderbuffer. - * NULL will be returned if the rb isn't really an intel_renderbuffer. - * This is determiend by checking the ClassID. - */ -struct intel_renderbuffer * -intel_renderbuffer(struct gl_renderbuffer *rb) -{ - struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; - if (irb && irb->Base.ClassID == INTEL_RB_CLASS) { - /*_mesa_warning(NULL, "Returning non-intel Rb\n");*/ - return irb; - } - else - return NULL; -} - - -struct intel_renderbuffer * -intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex) -{ - return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); -} - - -void -intel_flip_renderbuffers(struct intel_framebuffer *intel_fb) -{ - int current_page = intel_fb->pf_current_page; - int next_page = (current_page + 1) % intel_fb->pf_num_pages; - struct gl_renderbuffer *tmp_rb; - - /* Exchange renderbuffers if necessary but make sure their reference counts - * are preserved. - */ - if (intel_fb->color_rb[current_page] && - intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer != - &intel_fb->color_rb[current_page]->Base) { - tmp_rb = NULL; - _mesa_reference_renderbuffer(&tmp_rb, - intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); - tmp_rb = &intel_fb->color_rb[current_page]->Base; - _mesa_reference_renderbuffer( - &intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer, tmp_rb); - _mesa_reference_renderbuffer(&tmp_rb, NULL); - } - - if (intel_fb->color_rb[next_page] && - intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer != - &intel_fb->color_rb[next_page]->Base) { - tmp_rb = NULL; - _mesa_reference_renderbuffer(&tmp_rb, - intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); - tmp_rb = &intel_fb->color_rb[next_page]->Base; - _mesa_reference_renderbuffer( - &intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer, tmp_rb); - _mesa_reference_renderbuffer(&tmp_rb, NULL); - } -} - - -struct intel_region * -intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) -{ - struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex); - - if (irb) - return irb->region; - else - return NULL; -} - - - -/** - * Create a new framebuffer object. - */ -static struct gl_framebuffer * -intel_new_framebuffer(GLcontext * ctx, GLuint name) -{ - /* Only drawable state in intel_framebuffer at this time, just use Mesa's - * class - */ - return _mesa_new_framebuffer(ctx, name); -} - - -static void -intel_delete_renderbuffer(struct gl_renderbuffer *rb) -{ - GET_CURRENT_CONTEXT(ctx); - struct intel_context *intel = intel_context(ctx); - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - - ASSERT(irb); - - if (irb->PairedStencil || irb->PairedDepth) { - intel_unpair_depth_stencil(ctx, irb); - } - - if (intel && irb->region) { - intel_region_release(&irb->region); - } - - _mesa_free(irb); -} - - - -/** - * Return a pointer to a specific pixel in a renderbuffer. - */ -static void * -intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb, - GLint x, GLint y) -{ - /* By returning NULL we force all software rendering to go through - * the span routines. - */ - return NULL; -} - - - -/** - * Called via glRenderbufferStorageEXT() to set the format and allocate - * storage for a user-created renderbuffer. - */ -static GLboolean -intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, - GLuint width, GLuint height) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_renderbuffer *irb = intel_renderbuffer(rb); - GLboolean softwareBuffer = GL_FALSE; - int cpp; - - ASSERT(rb->Name != 0); - - switch (internalFormat) { - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - rb->_ActualFormat = GL_RGB5; - rb->DataType = GL_UNSIGNED_BYTE; - rb->RedBits = 5; - rb->GreenBits = 6; - rb->BlueBits = 5; - cpp = 2; - break; - case GL_RGB: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - rb->_ActualFormat = GL_RGBA8; - rb->DataType = GL_UNSIGNED_BYTE; - rb->RedBits = 8; - rb->GreenBits = 8; - rb->BlueBits = 8; - rb->AlphaBits = 8; - cpp = 4; - break; - case GL_STENCIL_INDEX: - case GL_STENCIL_INDEX1_EXT: - case GL_STENCIL_INDEX4_EXT: - case GL_STENCIL_INDEX8_EXT: - case GL_STENCIL_INDEX16_EXT: - /* alloc a depth+stencil buffer */ - rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; - rb->DataType = GL_UNSIGNED_INT_24_8_EXT; - rb->StencilBits = 8; - cpp = 4; - break; - case GL_DEPTH_COMPONENT16: - rb->_ActualFormat = GL_DEPTH_COMPONENT16; - rb->DataType = GL_UNSIGNED_SHORT; - rb->DepthBits = 16; - cpp = 2; - break; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; - rb->DataType = GL_UNSIGNED_INT_24_8_EXT; - rb->DepthBits = 24; - cpp = 4; - break; - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: - rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; - rb->DataType = GL_UNSIGNED_INT_24_8_EXT; - rb->DepthBits = 24; - rb->StencilBits = 8; - cpp = 4; - break; - default: - _mesa_problem(ctx, - "Unexpected format in intel_alloc_renderbuffer_storage"); - return GL_FALSE; - } - - intelFlush(ctx); - - /* free old region */ - if (irb->region) { - intel_region_release(&irb->region); - } - - /* allocate new memory region/renderbuffer */ - if (softwareBuffer) { - return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, - width, height); - } - else { - /* Choose a pitch to match hardware requirements: - */ - GLuint pitch = ((cpp * width + 63) & ~63) / cpp; - - /* alloc hardware renderbuffer */ - DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, - height, pitch); - - irb->region = intel_region_alloc(intel->intelScreen, cpp, pitch, height); - if (!irb->region) - return GL_FALSE; /* out of memory? */ - - ASSERT(irb->region->buffer); - - rb->Width = width; - rb->Height = height; - - /* This sets the Get/PutRow/Value functions */ - intel_set_span_functions(&irb->Base); - - return GL_TRUE; - } -} - - - -/** - * Called for each hardware renderbuffer when a _window_ is resized. - * Just update fields. - * Not used for user-created renderbuffers! - */ -static GLboolean -intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, GLuint width, GLuint height) -{ - ASSERT(rb->Name == 0); - rb->Width = width; - rb->Height = height; - rb->_ActualFormat = internalFormat; - - return GL_TRUE; -} - -static void -intel_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb, - GLuint width, GLuint height) -{ - struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)fb; - int i; - - _mesa_resize_framebuffer(ctx, fb, width, height); - - fb->Initialized = GL_TRUE; /* XXX remove someday */ - - if (fb->Name != 0) { - return; - } - - /* Make sure all window system renderbuffers are up to date */ - for (i = 0; i < 3; i++) { - struct gl_renderbuffer *rb = &intel_fb->color_rb[i]->Base; - - /* only resize if size is changing */ - if (rb && (rb->Width != width || rb->Height != height)) { - rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height); - } - } -} - -static GLboolean -intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, - GLenum internalFormat, GLuint width, GLuint height) -{ - _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); - return GL_FALSE; -} - - - -/** - * Create a new intel_renderbuffer which corresponds to an on-screen window, - * not a user-created renderbuffer. - * \param width the screen width - * \param height the screen height - */ -struct intel_renderbuffer * -intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, - int offset, int pitch, int cpp, void *map) -{ - GET_CURRENT_CONTEXT(ctx); - - struct intel_renderbuffer *irb; - const GLuint name = 0; - - irb = CALLOC_STRUCT(intel_renderbuffer); - if (!irb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); - return NULL; - } - - _mesa_init_renderbuffer(&irb->Base, name); - irb->Base.ClassID = INTEL_RB_CLASS; - - switch (intFormat) { - case GL_RGB5: - irb->Base._ActualFormat = GL_RGB5; - irb->Base._BaseFormat = GL_RGBA; - irb->Base.RedBits = 5; - irb->Base.GreenBits = 6; - irb->Base.BlueBits = 5; - irb->Base.DataType = GL_UNSIGNED_BYTE; - cpp = 2; - break; - case GL_RGBA8: - irb->Base._ActualFormat = GL_RGBA8; - irb->Base._BaseFormat = GL_RGBA; - irb->Base.RedBits = 8; - irb->Base.GreenBits = 8; - irb->Base.BlueBits = 8; - irb->Base.AlphaBits = 8; - irb->Base.DataType = GL_UNSIGNED_BYTE; - cpp = 4; - break; - case GL_STENCIL_INDEX8_EXT: - irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT; - irb->Base._BaseFormat = GL_STENCIL_INDEX; - irb->Base.StencilBits = 8; - irb->Base.DataType = GL_UNSIGNED_BYTE; - cpp = 1; - break; - case GL_DEPTH_COMPONENT16: - irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; - irb->Base._BaseFormat = GL_DEPTH_COMPONENT; - irb->Base.DepthBits = 16; - irb->Base.DataType = GL_UNSIGNED_SHORT; - cpp = 2; - break; - case GL_DEPTH_COMPONENT24: - irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - irb->Base._BaseFormat = GL_DEPTH_COMPONENT; - irb->Base.DepthBits = 24; - irb->Base.DataType = GL_UNSIGNED_INT; - cpp = 4; - break; - case GL_DEPTH24_STENCIL8_EXT: - irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; - irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; - irb->Base.DepthBits = 24; - irb->Base.StencilBits = 8; - irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; - cpp = 4; - break; - default: - _mesa_problem(NULL, - "Unexpected intFormat in intel_create_renderbuffer"); - return NULL; - } - - irb->Base.InternalFormat = intFormat; - - /* intel-specific methods */ - irb->Base.Delete = intel_delete_renderbuffer; - irb->Base.AllocStorage = intel_alloc_window_storage; - irb->Base.GetPointer = intel_get_pointer; - /* This sets the Get/PutRow/Value functions */ - intel_set_span_functions(&irb->Base); - - irb->pfMap = map; - irb->pfPitch = pitch / cpp; /* in pixels */ - -#if 00 - irb->region = intel_region_create_static(intel, - DRM_MM_TT, - offset, map, cpp, width, height); -#endif - - return irb; -} - - -/** - * Create a new renderbuffer object. - * Typically called via glBindRenderbufferEXT(). - */ -static struct gl_renderbuffer * -intel_new_renderbuffer(GLcontext * ctx, GLuint name) -{ - /*struct intel_context *intel = intel_context(ctx); */ - struct intel_renderbuffer *irb; - - irb = CALLOC_STRUCT(intel_renderbuffer); - if (!irb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); - return NULL; - } - - _mesa_init_renderbuffer(&irb->Base, name); - irb->Base.ClassID = INTEL_RB_CLASS; - - /* intel-specific methods */ - irb->Base.Delete = intel_delete_renderbuffer; - irb->Base.AllocStorage = intel_alloc_renderbuffer_storage; - irb->Base.GetPointer = intel_get_pointer; - /* span routines set in alloc_storage function */ - - return &irb->Base; -} - - -/** - * Called via glBindFramebufferEXT(). - */ -static void -intel_bind_framebuffer(GLcontext * ctx, GLenum target, - struct gl_framebuffer *fb, struct gl_framebuffer *fbread) -{ - if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { - intel_draw_buffer(ctx, fb); - /* Integer depth range depends on depth buffer bits */ - ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far); - } - else { - /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ - } -} - - -/** - * Called via glFramebufferRenderbufferEXT(). - */ -static void -intel_framebuffer_renderbuffer(GLcontext * ctx, - struct gl_framebuffer *fb, - GLenum attachment, struct gl_renderbuffer *rb) -{ - DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); - - intelFlush(ctx); - - _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); - intel_draw_buffer(ctx, fb); -} - - -/** - * When glFramebufferTexture[123]D is called this function sets up the - * gl_renderbuffer wrapper around the texture image. - * This will have the region info needed for hardware rendering. - */ -static struct intel_renderbuffer * -intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) -{ - const GLuint name = ~0; /* not significant, but distinct for debugging */ - struct intel_renderbuffer *irb; - - /* make an intel_renderbuffer to wrap the texture image */ - irb = CALLOC_STRUCT(intel_renderbuffer); - if (!irb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); - return NULL; - } - - _mesa_init_renderbuffer(&irb->Base, name); - irb->Base.ClassID = INTEL_RB_CLASS; - - if (texImage->TexFormat == &_mesa_texformat_argb8888) { - irb->Base._ActualFormat = GL_RGBA8; - irb->Base._BaseFormat = GL_RGBA; - DBG("Render to RGBA8 texture OK\n"); - } - else if (texImage->TexFormat == &_mesa_texformat_rgb565) { - irb->Base._ActualFormat = GL_RGB5; - irb->Base._BaseFormat = GL_RGB; - DBG("Render to RGB5 texture OK\n"); - } - else if (texImage->TexFormat == &_mesa_texformat_z16) { - irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; - irb->Base._BaseFormat = GL_DEPTH_COMPONENT; - DBG("Render to DEPTH16 texture OK\n"); - } - else { - DBG("Render to texture BAD FORMAT %d\n", - texImage->TexFormat->MesaFormat); - _mesa_free(irb); - return NULL; - } - - irb->Base.InternalFormat = irb->Base._ActualFormat; - irb->Base.Width = texImage->Width; - irb->Base.Height = texImage->Height; - irb->Base.DataType = GL_UNSIGNED_BYTE; /* FBO XXX fix */ - irb->Base.RedBits = texImage->TexFormat->RedBits; - irb->Base.GreenBits = texImage->TexFormat->GreenBits; - irb->Base.BlueBits = texImage->TexFormat->BlueBits; - irb->Base.AlphaBits = texImage->TexFormat->AlphaBits; - irb->Base.DepthBits = texImage->TexFormat->DepthBits; - - irb->Base.Delete = intel_delete_renderbuffer; - irb->Base.AllocStorage = intel_nop_alloc_storage; - intel_set_span_functions(&irb->Base); - - irb->RenderToTexture = GL_TRUE; - - return irb; -} - - -/** - * Called by glFramebufferTexture[123]DEXT() (and other places) to - * prepare for rendering into texture memory. This might be called - * many times to choose different texture levels, cube faces, etc - * before intel_finish_render_texture() is ever called. - */ -static void -intel_render_texture(GLcontext * ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att) -{ - struct gl_texture_image *newImage - = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; - struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); - struct intel_texture_image *intel_image; - GLuint imageOffset; - - (void) fb; - - ASSERT(newImage); - - if (!irb) { - irb = intel_wrap_texture(ctx, newImage); - if (irb) { - /* bind the wrapper to the attachment point */ - _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base); - } - else { - /* fallback to software rendering */ - _mesa_render_texture(ctx, fb, att); - return; - } - } - - DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", - _glthread_GetID(), - att->Texture->Name, newImage->Width, newImage->Height, - irb->Base.RefCount); - - /* point the renderbufer's region to the texture image region */ - intel_image = intel_texture_image(newImage); - if (irb->region != intel_image->mt->region) { - if (irb->region) - intel_region_release(&irb->region); - intel_region_reference(&irb->region, intel_image->mt->region); - } - - /* compute offset of the particular 2D image within the texture region */ - imageOffset = intel_miptree_image_offset(intel_image->mt, - att->CubeMapFace, - att->TextureLevel); - - if (att->Texture->Target == GL_TEXTURE_3D) { - const GLuint *offsets = intel_miptree_depth_offsets(intel_image->mt, - att->TextureLevel); - imageOffset += offsets[att->Zoffset]; - } - - /* store that offset in the region */ - intel_image->mt->region->draw_offset = imageOffset; - - /* update drawing region, etc */ - intel_draw_buffer(ctx, fb); -} - - -/** - * Called by Mesa when rendering to a texture is done. - */ -static void -intel_finish_render_texture(GLcontext * ctx, - struct gl_renderbuffer_attachment *att) -{ - struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); - - DBG("End render texture (tid %x) tex %u\n", _glthread_GetID(), att->Texture->Name); - - if (irb) { - /* just release the region */ - intel_region_release(&irb->region); - } - else if (att->Renderbuffer) { - /* software fallback */ - _mesa_finish_render_texture(ctx, att); - /* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */ - } -} - - -/** - * Do one-time context initializations related to GL_EXT_framebuffer_object. - * Hook in device driver functions. - */ -void -intel_fbo_init(struct intel_context *intel) -{ - intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; - intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; - intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; - intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; - intel->ctx.Driver.RenderTexture = intel_render_texture; - intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; - intel->ctx.Driver.ResizeBuffers = intel_resize_buffers; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.h b/src/mesa/drivers/dri/i915tex/intel_fbo.h deleted file mode 100644 index 411d634231..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_fbo.h +++ /dev/null @@ -1,115 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_FBO_H -#define INTEL_FBO_H - - -struct intel_context; -struct intel_region; - -/** - * Intel framebuffer, derived from gl_framebuffer. - */ -struct intel_framebuffer -{ - struct gl_framebuffer Base; - - struct intel_renderbuffer *color_rb[3]; - - /* Drawable page flipping state */ - GLboolean pf_active; - GLuint pf_seq; - GLint pf_planes; - GLint pf_current_page; - GLint pf_num_pages; - - /* VBI - */ - GLuint vbl_seq; - GLuint vblank_flags; - GLuint vbl_waited; - - int64_t swap_ust; - int64_t swap_missed_ust; - - GLuint swap_count; - GLuint swap_missed_count; -}; - - -/** - * Intel renderbuffer, derived from gl_renderbuffer. - * Note: The PairedDepth and PairedStencil fields use renderbuffer IDs, - * not pointers because in some circumstances a deleted renderbuffer could - * result in a dangling pointer here. - */ -struct intel_renderbuffer -{ - struct gl_renderbuffer Base; - struct intel_region *region; - void *pfMap; /* possibly paged flipped map pointer */ - GLuint pfPitch; /* possibly paged flipped pitch */ - GLboolean RenderToTexture; /* RTT? */ - - GLuint PairedDepth; /**< only used if this is a depth renderbuffer */ - GLuint PairedStencil; /**< only used if this is a stencil renderbuffer */ - - GLuint pf_pending; /**< sequence number of pending flip */ - - GLuint vbl_pending; /**< vblank sequence number of pending flip */ -}; - - -extern struct intel_renderbuffer *intel_create_renderbuffer(GLenum intFormat, - GLsizei width, - GLsizei height, - int offset, - int pitch, - int cpp, - void *map); - - -extern void intel_fbo_init(struct intel_context *intel); - - -/* XXX make inline or macro */ -extern struct intel_renderbuffer *intel_get_renderbuffer(struct gl_framebuffer - *fb, - GLuint attIndex); - -extern void intel_flip_renderbuffers(struct intel_framebuffer *intel_fb); - - -/* XXX make inline or macro */ -extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb, - GLuint attIndex); - - - - -#endif /* INTEL_FBO_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.c b/src/mesa/drivers/dri/i915tex/intel_ioctl.c deleted file mode 100644 index 6e76737c78..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_ioctl.c +++ /dev/null @@ -1,135 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include -#include -#include -#include - -#include "mtypes.h" -#include "context.h" -#include "swrast/swrast.h" - -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_regions.h" -#include "drm.h" - -#define FILE_DEBUG_FLAG DEBUG_IOCTL - -int -intelEmitIrqLocked(intelScreenPrivate *intelScreen) -{ - drmI830IrqEmit ie; - int ret, seq; - - ie.irq_seq = &seq; - - ret = drmCommandWriteRead(intelScreen->driScrnPriv->fd, - DRM_I830_IRQ_EMIT, &ie, sizeof(ie)); - if (ret) { - fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); - exit(1); - } - - DBG("%s --> %d\n", __FUNCTION__, seq); - - return seq; -} - -void -intelWaitIrq(intelScreenPrivate *intelScreen, int seq) -{ - drm_i915_irq_wait_t iw; - int ret; - - DBG("%s %d\n", __FUNCTION__, seq); - - iw.irq_seq = seq; - - do { - ret = drmCommandWrite(intelScreen->driScrnPriv->fd, - DRM_I830_IRQ_WAIT, &iw, sizeof(iw)); - } while (ret == -EAGAIN || ret == -EINTR); - - if (ret) { - fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); - exit(1); - } -} - - -void -intel_batch_ioctl(struct intel_context *intel, - GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - drmI830BatchBuffer batch; - - assert(intel->locked); - assert(used); - - DBG("%s used %d offset %x..%x ignore_cliprects %d\n", - __FUNCTION__, - used, start_offset, start_offset + used, ignore_cliprects); - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - - - batch.start = start_offset; - batch.used = used; - batch.cliprects = intel->pClipRects; - batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - batch.DR1 = 0; - batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | - (((GLuint) intel->drawY) << 16)); - - DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", - __FUNCTION__, - batch.start, - batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); - - if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, - sizeof(batch))) { - fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } - - /* FIXME: use hardware contexts to avoid 'losing' hardware after - * each buffer flush. - */ - intel->vtbl.lost_hardware(intel); -} diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.h b/src/mesa/drivers/dri/i915tex/intel_ioctl.h deleted file mode 100644 index 7a5b175ed1..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_ioctl.h +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_IOCTL_H -#define INTEL_IOCTL_H - -#include "intel_context.h" - -void intelWaitIrq(intelScreenPrivate *intelScreen, int seq); -int intelEmitIrqLocked(intelScreenPrivate *intelScreen); - -void intel_batch_ioctl(struct intel_context *intel, - GLuint start_offset, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock); -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c deleted file mode 100644 index 74f6b2d851..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c +++ /dev/null @@ -1,371 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_context.h" -#include "intel_mipmap_tree.h" -#include "intel_regions.h" -#include "enums.h" - -#define FILE_DEBUG_FLAG DEBUG_MIPTREE - -static GLenum -target_to_target(GLenum target) -{ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - return GL_TEXTURE_CUBE_MAP_ARB; - default: - return target; - } -} - -struct intel_mipmap_tree * -intel_miptree_create(struct intel_context *intel, - GLenum target, - GLenum internal_format, - GLuint first_level, - GLuint last_level, - GLuint width0, - GLuint height0, - GLuint depth0, GLuint cpp, GLuint compress_byte) -{ - GLboolean ok; - struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); - - DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); - - mt->target = target_to_target(target); - mt->internal_format = internal_format; - mt->first_level = first_level; - mt->last_level = last_level; - mt->width0 = width0; - mt->height0 = height0; - mt->depth0 = depth0; - mt->cpp = compress_byte ? compress_byte : cpp; - mt->compressed = compress_byte ? 1 : 0; - mt->refcount = 1; - - switch (intel->intelScreen->deviceID) { - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - ok = i945_miptree_layout(mt); - break; - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - case PCI_CHIP_I830_M: - case PCI_CHIP_I855_GM: - case PCI_CHIP_I865_G: - default: - /* All the i830 chips and the i915 use this layout: - */ - ok = i915_miptree_layout(mt); - break; - } - - if (ok) { - if (!mt->compressed) { - /* XXX: Align pitch to multiple of 64 bytes for now to allow - * render-to-texture to work in all cases. This should probably be - * replaced at some point by some scheme to only do this when really - * necessary. - */ - mt->pitch = ((mt->pitch * cpp + 63) & ~63) / cpp; - } - - mt->region = intel_region_alloc(intel->intelScreen, - mt->cpp, mt->pitch, mt->total_height); - } - - if (!mt->region) { - free(mt); - return NULL; - } - - return mt; -} - - -void -intel_miptree_reference(struct intel_mipmap_tree **dst, - struct intel_mipmap_tree *src) -{ - src->refcount++; - *dst = src; - DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount); -} - -void -intel_miptree_release(struct intel_context *intel, - struct intel_mipmap_tree **mt) -{ - if (!*mt) - return; - - DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1); - if (--(*mt)->refcount <= 0) { - GLuint i; - - DBG("%s deleting %p\n", __FUNCTION__, *mt); - - intel_region_release(&((*mt)->region)); - - for (i = 0; i < MAX_TEXTURE_LEVELS; i++) - if ((*mt)->level[i].image_offset) - free((*mt)->level[i].image_offset); - - free(*mt); - } - *mt = NULL; -} - - - - -/* Can the image be pulled into a unified mipmap tree. This mirrors - * the completeness test in a lot of ways. - * - * Not sure whether I want to pass gl_texture_image here. - */ -GLboolean -intel_miptree_match_image(struct intel_mipmap_tree *mt, - struct gl_texture_image *image, - GLuint face, GLuint level) -{ - /* Images with borders are never pulled into mipmap trees. - */ - if (image->Border) - return GL_FALSE; - - if (image->InternalFormat != mt->internal_format || - image->IsCompressed != mt->compressed) - return GL_FALSE; - - /* Test image dimensions against the base level image adjusted for - * minification. This will also catch images not present in the - * tree, changed targets, etc. - */ - if (image->Width != mt->level[level].width || - image->Height != mt->level[level].height || - image->Depth != mt->level[level].depth) - return GL_FALSE; - - return GL_TRUE; -} - - -void -intel_miptree_set_level_info(struct intel_mipmap_tree *mt, - GLuint level, - GLuint nr_images, - GLuint x, GLuint y, GLuint w, GLuint h, GLuint d) -{ - - mt->level[level].width = w; - mt->level[level].height = h; - mt->level[level].depth = d; - mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; - mt->level[level].nr_images = nr_images; - - DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, - level, w, h, d, x, y, mt->level[level].level_offset); - - /* Not sure when this would happen, but anyway: - */ - if (mt->level[level].image_offset) { - free(mt->level[level].image_offset); - mt->level[level].image_offset = NULL; - } - - assert(nr_images); - - mt->level[level].image_offset = malloc(nr_images * sizeof(GLuint)); - mt->level[level].image_offset[0] = 0; -} - - - -void -intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, - GLuint level, GLuint img, GLuint x, GLuint y) -{ - if (img == 0 && level == 0) - assert(x == 0 && y == 0); - - assert(img < mt->level[level].nr_images); - - mt->level[level].image_offset[img] = (x + y * mt->pitch); - - DBG("%s level %d img %d pos %d,%d image_offset %x\n", - __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); -} - - -/* Although we use the image_offset[] array to store relative offsets - * to cube faces, Mesa doesn't know anything about this and expects - * each cube face to be treated as a separate image. - * - * These functions present that view to mesa: - */ -const GLuint * -intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level) -{ - static const GLuint zero = 0; - - if (mt->target != GL_TEXTURE_3D || mt->level[level].nr_images == 1) - return &zero; - else - return mt->level[level].image_offset; -} - - -GLuint -intel_miptree_image_offset(struct intel_mipmap_tree * mt, - GLuint face, GLuint level) -{ - if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) - return (mt->level[level].level_offset + - mt->level[level].image_offset[face] * mt->cpp); - else - return mt->level[level].level_offset; -} - - - -/** - * Map a teximage in a mipmap tree. - * \param row_stride returns row stride in bytes - * \param image_stride returns image stride in bytes (for 3D textures). - * \return address of mapping - */ -GLubyte * -intel_miptree_image_map(struct intel_context * intel, - struct intel_mipmap_tree * mt, - GLuint face, - GLuint level, - GLuint * row_stride, GLuint * image_offsets) -{ - DBG("%s \n", __FUNCTION__); - - if (row_stride) - *row_stride = mt->pitch * mt->cpp; - - if (image_offsets) - memcpy(image_offsets, mt->level[level].image_offset, - mt->level[level].depth * sizeof(GLuint)); - - return (intel_region_map(intel->intelScreen, mt->region) + - intel_miptree_image_offset(mt, face, level)); -} - -void -intel_miptree_image_unmap(struct intel_context *intel, - struct intel_mipmap_tree *mt) -{ - DBG("%s\n", __FUNCTION__); - intel_region_unmap(intel->intelScreen, mt->region); -} - - - -/* Upload data for a particular image. - */ -void -intel_miptree_image_data(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, - GLuint level, - void *src, - GLuint src_row_pitch, GLuint src_image_pitch) -{ - GLuint depth = dst->level[level].depth; - GLuint dst_offset = intel_miptree_image_offset(dst, face, level); - const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); - GLuint i; - GLuint height = 0; - - DBG("%s\n", __FUNCTION__); - for (i = 0; i < depth; i++) { - height = dst->level[level].height; - if(dst->compressed) - height /= 4; - intel_region_data(intel->intelScreen, dst->region, - dst_offset + dst_depth_offset[i], /* dst_offset */ - 0, 0, /* dstx, dsty */ - src, - src_row_pitch, - 0, 0, /* source x, y */ - dst->level[level].width, height); /* width, height */ - - src += src_image_pitch * dst->cpp; - } -} - -extern GLuint intel_compressed_alignment(GLenum); -/* Copy mipmap image between trees - */ -void -intel_miptree_image_copy(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, GLuint level, - struct intel_mipmap_tree *src) -{ - GLuint width = src->level[level].width; - GLuint height = src->level[level].height; - GLuint depth = src->level[level].depth; - GLuint dst_offset = intel_miptree_image_offset(dst, face, level); - GLuint src_offset = intel_miptree_image_offset(src, face, level); - const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); - const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); - GLuint i; - - if (dst->compressed) { - GLuint alignment = intel_compressed_alignment(dst->internal_format); - height = (height + 3) / 4; - width = ((width + alignment - 1) & ~(alignment - 1)); - } - - for (i = 0; i < depth; i++) { - intel_region_copy(intel->intelScreen, - dst->region, dst_offset + dst_depth_offset[i], - 0, - 0, - src->region, src_offset + src_depth_offset[i], - 0, 0, width, height); - } - -} diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h deleted file mode 100644 index ecdb7be244..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h +++ /dev/null @@ -1,198 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_MIPMAP_TREE_H -#define INTEL_MIPMAP_TREE_H - -#include "intel_regions.h" - -/* A layer on top of the intel_regions code which adds: - * - * - Code to size and layout a region to hold a set of mipmaps. - * - Query to determine if a new image fits in an existing tree. - * - More refcounting - * - maybe able to remove refcounting from intel_region? - * - ? - * - * The fixed mipmap layout of intel hardware where one offset - * specifies the position of all images in a mipmap hierachy - * complicates the implementation of GL texture image commands, - * compared to hardware where each image is specified with an - * independent offset. - * - * In an ideal world, each texture object would be associated with a - * single bufmgr buffer or 2d intel_region, and all the images within - * the texture object would slot into the tree as they arrive. The - * reality can be a little messier, as images can arrive from the user - * with sizes that don't fit in the existing tree, or in an order - * where the tree layout cannot be guessed immediately. - * - * This structure encodes an idealized mipmap tree. The GL image - * commands build these where possible, otherwise store the images in - * temporary system buffers. - */ - - -/** - * Describes the location of each texture image within a texture region. - */ -struct intel_mipmap_level -{ - GLuint level_offset; - GLuint width; - GLuint height; - GLuint depth; - GLuint nr_images; - - /* Explicitly store the offset of each image for each cube face or - * depth value. Pretty much have to accept that hardware formats - * are going to be so diverse that there is no unified way to - * compute the offsets of depth/cube images within a mipmap level, - * so have to store them as a lookup table: - */ - GLuint *image_offset; -}; - -struct intel_mipmap_tree -{ - /* Effectively the key: - */ - GLenum target; - GLenum internal_format; - - GLuint first_level; - GLuint last_level; - - GLuint width0, height0, depth0; /**< Level zero image dimensions */ - GLuint cpp; - GLboolean compressed; - - /* Derived from the above: - */ - GLuint pitch; - GLuint depth_pitch; /* per-image on i945? */ - GLuint total_height; - - /* Includes image offset tables: - */ - struct intel_mipmap_level level[MAX_TEXTURE_LEVELS]; - - /* The data is held here: - */ - struct intel_region *region; - - /* These are also refcounted: - */ - GLuint refcount; -}; - - - -struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, - GLenum target, - GLenum internal_format, - GLuint first_level, - GLuint last_level, - GLuint width0, - GLuint height0, - GLuint depth0, - GLuint cpp, - GLuint compress_byte); - -void intel_miptree_reference(struct intel_mipmap_tree **dst, - struct intel_mipmap_tree *src); - -void intel_miptree_release(struct intel_context *intel, - struct intel_mipmap_tree **mt); - -/* Check if an image fits an existing mipmap tree layout - */ -GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt, - struct gl_texture_image *image, - GLuint face, GLuint level); - -/* Return a pointer to an image within a tree. Return image stride as - * well. - */ -GLubyte *intel_miptree_image_map(struct intel_context *intel, - struct intel_mipmap_tree *mt, - GLuint face, - GLuint level, - GLuint * row_stride, GLuint * image_stride); - -void intel_miptree_image_unmap(struct intel_context *intel, - struct intel_mipmap_tree *mt); - - -/* Return the linear offset of an image relative to the start of the - * tree: - */ -GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, - GLuint face, GLuint level); - -/* Return pointers to each 2d slice within an image. Indexed by depth - * value. - */ -const GLuint *intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, - GLuint level); - - -void intel_miptree_set_level_info(struct intel_mipmap_tree *mt, - GLuint level, - GLuint nr_images, - GLuint x, GLuint y, - GLuint w, GLuint h, GLuint d); - -void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, - GLuint level, - GLuint img, GLuint x, GLuint y); - - -/* Upload an image into a tree - */ -void intel_miptree_image_data(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, - GLuint level, - void *src, - GLuint src_row_pitch, GLuint src_image_pitch); - -/* Copy an image between two trees - */ -void intel_miptree_image_copy(struct intel_context *intel, - struct intel_mipmap_tree *dst, - GLuint face, GLuint level, - struct intel_mipmap_tree *src); - -/* i915_mipmap_tree.c: - */ -GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt); -GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt); - - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel.c b/src/mesa/drivers/dri/i915tex/intel_pixel.c deleted file mode 100644 index 9018e3daef..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_pixel.c +++ /dev/null @@ -1,120 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portionsalloc - * 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 "enums.h" -#include "state.h" -#include "swrast/swrast.h" - -#include "intel_context.h" -#include "intel_pixel.h" -#include "intel_regions.h" - - -/** - * Check if any fragment operations are in effect which might effect - * glDraw/CopyPixels. - */ -GLboolean -intel_check_blit_fragment_ops(GLcontext * ctx) -{ - if (ctx->NewState) - _mesa_update_state(ctx); - - /* XXX Note: Scissor could be done with the blitter: - */ - return !(ctx->_ImageTransferState || - ctx->Color.AlphaEnabled || - ctx->Depth.Test || - ctx->Fog.Enabled || - ctx->Scissor.Enabled || - ctx->Stencil.Enabled || - !ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3] || - ctx->Texture._EnabledUnits || - ctx->FragmentProgram._Enabled || - ctx->Color.BlendEnabled); -} - - -GLboolean -intel_check_meta_tex_fragment_ops(GLcontext * ctx) -{ - if (ctx->NewState) - _mesa_update_state(ctx); - - /* Some of _ImageTransferState (scale, bias) could be done with - * fragment programs on i915. - */ - return !(ctx->_ImageTransferState || ctx->Fog.Enabled || /* not done yet */ - ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled); -} - -/* The intel_region struct doesn't really do enough to capture the - * format of the pixels in the region. For now this code assumes that - * the region is a display surface and hence is either ARGB8888 or - * RGB565. - * XXX FBO: If we'd pass in the intel_renderbuffer instead of region, we'd - * know the buffer's pixel format. - * - * \param format as given to glDraw/ReadPixels - * \param type as given to glDraw/ReadPixels - */ -GLboolean -intel_check_blit_format(struct intel_region * region, - GLenum format, GLenum type) -{ - if (region->cpp == 4 && - (type == GL_UNSIGNED_INT_8_8_8_8_REV || - type == GL_UNSIGNED_BYTE) && format == GL_BGRA) { - return GL_TRUE; - } - - if (region->cpp == 2 && - type == GL_UNSIGNED_SHORT_5_6_5_REV && format == GL_BGR) { - return GL_TRUE; - } - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: bad format for blit (cpp %d, type %s format %s)\n", - __FUNCTION__, region->cpp, - _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); - - return GL_FALSE; -} - - -void -intelInitPixelFuncs(struct dd_function_table *functions) -{ - functions->Accum = _swrast_Accum; - functions->Bitmap = _swrast_Bitmap; - functions->CopyPixels = intelCopyPixels; - functions->ReadPixels = intelReadPixels; - functions->DrawPixels = intelDrawPixels; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel.h b/src/mesa/drivers/dri/i915tex/intel_pixel.h deleted file mode 100644 index a6fcf90ce0..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_pixel.h +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_PIXEL_H -#define INTEL_PIXEL_H - -#include "mtypes.h" - -void intelInitPixelFuncs(struct dd_function_table *functions); - -GLboolean intel_check_blit_fragment_ops(GLcontext * ctx); - -GLboolean intel_check_meta_tex_fragment_ops(GLcontext * ctx); - -GLboolean intel_check_blit_format(struct intel_region *region, - GLenum format, GLenum type); - - -void intelReadPixels(GLcontext * ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid * pixels); - -void intelDrawPixels(GLcontext * ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, - GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid * pixels); - -void intelCopyPixels(GLcontext * ctx, - GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint destx, GLint desty, GLenum type); - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c deleted file mode 100644 index 65bf338589..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c +++ /dev/null @@ -1,350 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portionsalloc - * 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 "glheader.h" -#include "enums.h" -#include "image.h" -#include "colormac.h" -#include "mtypes.h" -#include "macros.h" -#include "bufferobj.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_regions.h" -#include "intel_buffer_objects.h" - - - -#define FILE_DEBUG_FLAG DEBUG_PIXEL - - -/* Unlike the other intel_pixel_* functions, the expectation here is - * that the incoming data is not in a PBO. With the XY_TEXT blit - * method, there's no benefit haveing it in a PBO, but we could - * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit - * PBO bitmaps. I think they are probably pretty rare though - I - * wonder if Xgl uses them? - */ -static const GLubyte *map_pbo( GLcontext *ctx, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap ) -{ - GLubyte *buf; - - if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, - GL_COLOR_INDEX, GL_BITMAP, - (GLvoid *) bitmap)) { - _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)"); - return NULL; - } - - buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, - GL_READ_ONLY_ARB, - unpack->BufferObj); - if (!buf) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); - return NULL; - } - - return ADD_POINTERS(buf, bitmap); -} - -static GLboolean test_bit( const GLubyte *src, - GLuint bit ) -{ - return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0; -} - -static void set_bit( GLubyte *dest, - GLuint bit ) -{ - dest[bit/8] |= 1 << (bit % 8); -} - -static int align(int x, int align) -{ - return (x + align - 1) & ~(align - 1); -} - -/* Extract a rectangle's worth of data from the bitmap. Called - * per-cliprect. - */ -static GLuint get_bitmap_rect(GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap, - GLuint x, GLuint y, - GLuint w, GLuint h, - GLubyte *dest, - GLuint row_align, - GLboolean invert) -{ - GLuint src_offset = (x + unpack->SkipPixels) & 0x7; - GLuint mask = unpack->LsbFirst ? 0 : 7; - GLuint bit = 0; - GLint row, col; - GLint first, last; - GLint incr; - GLuint count = 0; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n", - __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask); - - if (invert) { - first = h-1; - last = 0; - incr = -1; - } - else { - first = 0; - last = h-1; - incr = 1; - } - - /* Require that dest be pre-zero'd. - */ - for (row = first; row != (last+incr); row += incr) { - const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, - width, height, - GL_COLOR_INDEX, GL_BITMAP, - y + row, x); - - for (col = 0; col < w; col++, bit++) { - if (test_bit(rowsrc, (col + src_offset) ^ mask)) { - set_bit(dest, bit ^ 7); - count++; - } - } - - if (row_align) - bit = (bit + row_align - 1) & ~(row_align - 1); - } - - return count; -} - - - - -/* - * Render a bitmap. - */ -static GLboolean -do_blit_bitmap( GLcontext *ctx, - GLint dstx, GLint dsty, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap ) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *dst = intel_drawbuf_region(intel); - - union { - GLuint ui; - GLubyte ub[4]; - } color; - - - if (unpack->BufferObj->Name) { - bitmap = map_pbo(ctx, width, height, unpack, bitmap); - if (bitmap == NULL) - return GL_TRUE; /* even though this is an error, we're done */ - } - - UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], ctx->Current.RasterColor[2]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], ctx->Current.RasterColor[1]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], ctx->Current.RasterColor[0]); - UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], ctx->Current.RasterColor[3]); - - /* Does zoom apply to bitmaps? - */ - if (!intel_check_blit_fragment_ops(ctx) || - ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != 1.0F) - return GL_FALSE; - - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t dest_rect; - GLint nbox = dPriv->numClipRects; - GLint srcx = 0, srcy = 0; - GLint orig_screen_x1, orig_screen_y2; - GLuint i; - - - orig_screen_x1 = dPriv->x + dstx; - orig_screen_y2 = dPriv->y + (dPriv->h - dsty); - - /* Do scissoring in GL coordinates: - */ -x if (ctx->Scissor.Enabled) - { - GLint x = ctx->Scissor.X; - GLint y = ctx->Scissor.Y; - GLuint w = ctx->Scissor.Width; - GLuint h = ctx->Scissor.Height; - - if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) - goto out; - } - - /* Convert from GL to hardware coordinates: - */ - dsty = dPriv->y + (dPriv->h - dsty - height); - dstx = dPriv->x + dstx; - - dest_rect.x1 = dstx; - dest_rect.y1 = dsty; - dest_rect.x2 = dstx + width; - dest_rect.y2 = dsty + height; - - for (i = 0; i < nbox; i++) { - drm_clip_rect_t rect; - int box_w, box_h; - GLint px, py; - GLuint stipple[32]; - - if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) - continue; - - /* Now go back to GL coordinates to figure out what subset of - * the bitmap we are uploading for this cliprect: - */ - box_w = rect.x2 - rect.x1; - box_h = rect.y2 - rect.y1; - srcx = rect.x1 - orig_screen_x1; - srcy = orig_screen_y2 - rect.y2; - - -#define DY 32 -#define DX 32 - - /* Then, finally, chop it all into chunks that can be - * digested by hardware: - */ - for (py = 0; py < box_h; py += DY) { - for (px = 0; px < box_w; px += DX) { - int h = MIN2(DY, box_h - py); - int w = MIN2(DX, box_w - px); - GLuint sz = align(align(w,8) * h, 64)/8; - - assert(sz <= sizeof(stipple)); - memset(stipple, 0, sz); - - /* May need to adjust this when padding has been introduced in - * sz above: - */ - if (get_bitmap_rect(width, height, unpack, - bitmap, - srcx + px, srcy + py, w, h, - (GLubyte *)stipple, - 8, - GL_TRUE) == 0) - continue; - - /* - */ - intelEmitImmediateColorExpandBlit( intel, - dst->cpp, - (GLubyte *)stipple, - sz, - color.ui, - dst->pitch, - dst->buffer, - 0, - dst->tiled, - rect.x1 + px, - rect.y2 - (py + h), - w, h); - } - } - } - intel->need_flush = GL_TRUE; - out: - intel_batchbuffer_flush(intel->batch); - } - UNLOCK_HARDWARE(intel); - - - if (unpack->BufferObj->Name) { - /* done with PBO so unmap it now */ - ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, - unpack->BufferObj); - } - - return GL_TRUE; -} - - - - - -/* There are a large number of possible ways to implement bitmap on - * this hardware, most of them have some sort of drawback. Here are a - * few that spring to mind: - * - * Blit: - * - XY_MONO_SRC_BLT_CMD - * - use XY_SETUP_CLIP_BLT for cliprect clipping. - * - XY_TEXT_BLT - * - XY_TEXT_IMMEDIATE_BLT - * - blit per cliprect, subject to maximum immediate data size. - * - XY_COLOR_BLT - * - per pixel or run of pixels - * - XY_PIXEL_BLT - * - good for sparse bitmaps - * - * 3D engine: - * - Point per pixel - * - Translate bitmap to an alpha texture and render as a quad - * - Chop bitmap up into 32x32 squares and render w/polygon stipple. - */ -void -intelBitmap(GLcontext * ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte * pixels) -{ - if (do_blit_bitmap(ctx, x, y, width, height, - unpack, pixels)) - return; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); - - _swrast_Bitmap(ctx, x, y, width, height, unpack, pixels); -} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c deleted file mode 100644 index 9d478283e4..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c +++ /dev/null @@ -1,383 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "enums.h" -#include "image.h" -#include "state.h" -#include "mtypes.h" -#include "macros.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_buffers.h" -#include "intel_blit.h" -#include "intel_regions.h" -#include "intel_tris.h" -#include "intel_pixel.h" - -#define FILE_DEBUG_FLAG DEBUG_PIXEL - -static struct intel_region * -copypix_src_region(struct intel_context *intel, GLenum type) -{ - switch (type) { - case GL_COLOR: - return intel_readbuf_region(intel); - case GL_DEPTH: - /* Don't think this is really possible execpt at 16bpp, when we have no stencil. - */ - if (intel->intelScreen->depth_region && - intel->intelScreen->depth_region->cpp == 2) - return intel->intelScreen->depth_region; - case GL_STENCIL: - /* Don't think this is really possible. - */ - break; - case GL_DEPTH_STENCIL_EXT: - /* Does it matter whether it is stencil/depth or depth/stencil? - */ - return intel->intelScreen->depth_region; - default: - break; - } - - return NULL; -} - - -/** - * Check if any fragment operations are in effect which might effect - * glCopyPixels. Differs from intel_check_blit_fragment_ops in that - * we allow Scissor. - */ -static GLboolean -intel_check_copypixel_blit_fragment_ops(GLcontext * ctx) -{ - if (ctx->NewState) - _mesa_update_state(ctx); - - /* Could do logicop with the blitter: - */ - return !(ctx->_ImageTransferState || - ctx->Color.AlphaEnabled || - ctx->Depth.Test || - ctx->Fog.Enabled || - ctx->Stencil.Enabled || - !ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3] || - ctx->Texture._EnabledUnits || - ctx->FragmentProgram._Enabled || - ctx->Color.BlendEnabled); -} - -/* Doesn't work for overlapping regions. Could do a double copy or - * just fallback. - */ -static GLboolean -do_texture_copypixels(GLcontext * ctx, - GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint dstx, GLint dsty, GLenum type) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *dst = intel_drawbuf_region(intel); - struct intel_region *src = copypix_src_region(intel, type); - GLenum src_format; - GLenum src_type; - - DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__, - srcx, srcy, width, height, dstx, dsty); - - if (!src || !dst || type != GL_COLOR) - return GL_FALSE; - - /* Can't handle overlapping regions. Don't have sufficient control - * over rasterization to pull it off in-place. Punt on these for - * now. - * - * XXX: do a copy to a temporary. - */ - if (src->buffer == dst->buffer) { - drm_clip_rect_t srcbox; - drm_clip_rect_t dstbox; - drm_clip_rect_t tmp; - - srcbox.x1 = srcx; - srcbox.y1 = srcy; - srcbox.x2 = srcx + width; - srcbox.y2 = srcy + height; - - dstbox.x1 = dstx; - dstbox.y1 = dsty; - dstbox.x2 = dstx + width * ctx->Pixel.ZoomX; - dstbox.y2 = dsty + height * ctx->Pixel.ZoomY; - - DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2); - DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2, - width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); - - if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) { - DBG("%s: regions overlap\n", __FUNCTION__); - return GL_FALSE; - } - } - - intelFlush(&intel->ctx); - - intel->vtbl.install_meta_state(intel); - - /* Is this true? Also will need to turn depth testing on according - * to state: - */ - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_no_depth_write(intel); - - /* Set the 3d engine to draw into the destination region: - */ - intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); - - intel->vtbl.meta_import_pixel_state(intel); - - if (src->cpp == 2) { - src_format = GL_RGB; - src_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { - src_format = GL_BGRA; - src_type = GL_UNSIGNED_BYTE; - } - - /* Set the frontbuffer up as a large rectangular texture. - */ - if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0, - src->pitch, - src->height, src_format, src_type)) { - intel->vtbl.leave_meta_state(intel); - return GL_FALSE; - } - - - intel->vtbl.meta_texture_blend_replace(intel); - - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - - srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */ - - srcx += dPriv->x; - srcy += dPriv->y; - - /* Clip against the source region. This is the only source - * clipping we do. XXX: Just set the texcord wrap mode to clamp - * or similar. - * - */ - if (0) { - GLint orig_x = srcx; - GLint orig_y = srcy; - - if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, - &srcx, &srcy, &width, &height)) - goto out; - - dstx += srcx - orig_x; - dsty += (srcy - orig_y) * ctx->Pixel.ZoomY; - } - - /* Just use the regular cliprect mechanism... Does this need to - * even hold the lock??? - */ - intel_meta_draw_quad(intel, - dstx, - dstx + width * ctx->Pixel.ZoomX, - dPriv->h - (dsty + height * ctx->Pixel.ZoomY), - dPriv->h - (dsty), 0, /* XXX: what z value? */ - 0x00ff00ff, - srcx, srcx + width, srcy, srcy + height); - - out: - intel->vtbl.leave_meta_state(intel); - intel_batchbuffer_flush(intel->batch); - } - UNLOCK_HARDWARE(intel); - - DBG("%s: success\n", __FUNCTION__); - return GL_TRUE; -} - - - - - -/** - * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. - */ -static GLboolean -do_blit_copypixels(GLcontext * ctx, - GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint dstx, GLint dsty, GLenum type) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *dst = intel_drawbuf_region(intel); - struct intel_region *src = copypix_src_region(intel, type); - - /* Copypixels can be more than a straight copy. Ensure all the - * extra operations are disabled: - */ - if (!intel_check_copypixel_blit_fragment_ops(ctx) || - ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) - return GL_FALSE; - - if (!src || !dst) - return GL_FALSE; - - - - intelFlush(&intel->ctx); - - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t dest_rect; - GLint nbox = dPriv->numClipRects; - GLint delta_x = 0; - GLint delta_y = 0; - GLuint i; - - /* Do scissoring in GL coordinates: - */ - if (ctx->Scissor.Enabled) - { - GLint x = ctx->Scissor.X; - GLint y = ctx->Scissor.Y; - GLuint w = ctx->Scissor.Width; - GLuint h = ctx->Scissor.Height; - GLint dx = dstx - srcx; - GLint dy = dsty - srcy; - - if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) - goto out; - - srcx = dstx - dx; - srcy = dsty - dy; - } - - /* Convert from GL to hardware coordinates: - */ - dsty = dPriv->h - dsty - height; - srcy = dPriv->h - srcy - height; - dstx += dPriv->x; - dsty += dPriv->y; - srcx += dPriv->x; - srcy += dPriv->y; - - /* Clip against the source region. This is the only source - * clipping we do. Dst is clipped with cliprects below. - */ - { - delta_x = srcx - dstx; - delta_y = srcy - dsty; - - if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, - &srcx, &srcy, &width, &height)) - goto out; - - dstx = srcx - delta_x; - dsty = srcy - delta_y; - } - - dest_rect.x1 = dstx; - dest_rect.y1 = dsty; - dest_rect.x2 = dstx + width; - dest_rect.y2 = dsty + height; - - /* Could do slightly more clipping: Eg, take the intersection of - * the existing set of cliprects and those cliprects translated - * by delta_x, delta_y: - * - * This code will not overwrite other windows, but will - * introduce garbage when copying from obscured window regions. - */ - for (i = 0; i < nbox; i++) { - drm_clip_rect_t rect; - - if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) - continue; - - - intelEmitCopyBlit(intel, dst->cpp, - src->pitch, src->buffer, 0, - dst->pitch, dst->buffer, 0, - rect.x1 + delta_x, - rect.y1 + delta_y, /* srcx, srcy */ - rect.x1, rect.y1, /* dstx, dsty */ - rect.x2 - rect.x1, rect.y2 - rect.y1, - ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY); - } - - out: - intel_batchbuffer_flush(intel->batch); - } - UNLOCK_HARDWARE(intel); - - DBG("%s: success\n", __FUNCTION__); - return GL_TRUE; -} - - -void -intelCopyPixels(GLcontext * ctx, - GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint destx, GLint desty, GLenum type) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) - return; - - if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) - return; - - DBG("fallback to _swrast_CopyPixels\n"); - - _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); -} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c deleted file mode 100644 index afb586b4a3..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c +++ /dev/null @@ -1,388 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portionsalloc - * 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 "glheader.h" -#include "enums.h" -#include "image.h" -#include "mtypes.h" -#include "macros.h" -#include "bufferobj.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_regions.h" -#include "intel_pixel.h" -#include "intel_buffer_objects.h" -#include "intel_tris.h" - - - -static GLboolean -do_texture_drawpixels(GLcontext * ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid * pixels) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *dst = intel_drawbuf_region(intel); - struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); - GLuint rowLength = unpack->RowLength ? unpack->RowLength : width; - GLuint src_offset; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - intelFlush(&intel->ctx); - intel->vtbl.render_start(intel); - intel->vtbl.emit_state(intel); - - if (!dst) - return GL_FALSE; - - if (src) { - if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); - return GL_TRUE; - } - } - else { - /* PBO only for now: - */ -/* _mesa_printf("%s - not PBO\n", __FUNCTION__); */ - return GL_FALSE; - } - - /* There are a couple of things we can't do yet, one of which is - * set the correct state for pixel operations when GL texturing is - * enabled. That's a pretty rare state and probably not worth the - * effort. A completely device-independent version of this may do - * more. - * - * Similarly, we make no attempt to merge metaops processing with - * an enabled fragment program, though it would certainly be - * possible. - */ - if (!intel_check_meta_tex_fragment_ops(ctx)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad GL fragment state for metaops texture\n", - __FUNCTION__); - return GL_FALSE; - } - - intel->vtbl.install_meta_state(intel); - - - /* Is this true? Also will need to turn depth testing on according - * to state: - */ - intel->vtbl.meta_no_stencil_write(intel); - intel->vtbl.meta_no_depth_write(intel); - - /* Set the 3d engine to draw into the destination region: - */ - intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); - - intel->vtbl.meta_import_pixel_state(intel); - - src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, - format, type, 0, 0, 0); - - - /* Setup the pbo up as a rectangular texture, if possible. - * - * TODO: This is almost always possible if the i915 fragment - * program is adjusted to correctly swizzle the sampled colors. - * The major exception is any 24bit texture, like RGB888, for which - * there is no hardware support. - */ - if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, src_offset, - rowLength, height, format, type)) { - intel->vtbl.leave_meta_state(intel); - return GL_FALSE; - } - - intel->vtbl.meta_texture_blend_replace(intel); - - - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - GLint srcx, srcy; - GLint dstx, dsty; - - dstx = x; - dsty = dPriv->h - (y + height); - - srcx = 0; /* skiprows/pixels already done */ - srcy = 0; - - if (0) { - const GLint orig_x = dstx; - const GLint orig_y = dsty; - - if (!_mesa_clip_to_region(0, 0, dst->pitch, dst->height, - &dstx, &dsty, &width, &height)) - goto out; - - srcx += dstx - orig_x; - srcy += dsty - orig_y; - } - - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("draw %d,%d %dx%d\n", dstx, dsty, width, height); - - /* Must use the regular cliprect mechanism in order to get the - * drawing origin set correctly. Otherwise scissor state is in - * incorrect coordinate space. Does this even need to hold the - * lock??? - */ - intel_meta_draw_quad(intel, - dstx, dstx + width * ctx->Pixel.ZoomX, - dPriv->h - (y + height * ctx->Pixel.ZoomY), - dPriv->h - (y), - -ctx->Current.RasterPos[2] * .5, - 0x00ff00ff, - srcx, srcx + width, srcy + height, srcy); - out: - intel->vtbl.leave_meta_state(intel); - intel_batchbuffer_flush(intel->batch); - } - UNLOCK_HARDWARE(intel); - return GL_TRUE; -} - - - - - -/* Pros: - * - no waiting for idle before updating framebuffer. - * - * Cons: - * - if upload is by memcpy, this may actually be slower than fallback path. - * - uploads the whole image even if destination is clipped - * - * Need to benchmark. - * - * Given the questions about performance, implement for pbo's only. - * This path is definitely a win if the pbo is already in agp. If it - * turns out otherwise, we can add the code necessary to upload client - * data to agp space before performing the blit. (Though it may turn - * out to be better/simpler just to use the texture engine). - */ -static GLboolean -do_blit_drawpixels(GLcontext * ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid * pixels) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *dest = intel_drawbuf_region(intel); - struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); - GLuint src_offset; - GLuint rowLength; - dri_fence *fence = NULL; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s\n", __FUNCTION__); - - - if (!dest) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - no dest\n", __FUNCTION__); - return GL_FALSE; - } - - if (src) { - /* This validation should be done by core mesa: - */ - if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); - return GL_TRUE; - } - } - else { - /* PBO only for now: - */ - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - not PBO\n", __FUNCTION__); - return GL_FALSE; - } - - if (!intel_check_blit_format(dest, format, type)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad format for blit\n", __FUNCTION__); - return GL_FALSE; - } - - if (!intel_check_blit_fragment_ops(ctx)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad GL fragment state for blitter\n", - __FUNCTION__); - return GL_FALSE; - } - - if (ctx->Pixel.ZoomX != 1.0F) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad PixelZoomX for blit\n", __FUNCTION__); - return GL_FALSE; - } - - - if (unpack->RowLength > 0) - rowLength = unpack->RowLength; - else - rowLength = width; - - if (ctx->Pixel.ZoomY == -1.0F) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); - return GL_FALSE; /* later */ - y -= height; - } - else if (ctx->Pixel.ZoomY == 1.0F) { - rowLength = -rowLength; - } - else { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); - return GL_FALSE; - } - - src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, - format, type, 0, 0, 0); - - intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int nbox = dPriv->numClipRects; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t rect; - drm_clip_rect_t dest_rect; - dri_bo *src_buffer = intel_bufferobj_buffer(intel, src, INTEL_READ); - int i; - - dest_rect.x1 = dPriv->x + x; - dest_rect.y1 = dPriv->y + dPriv->h - (y + height); - dest_rect.x2 = dest_rect.x1 + width; - dest_rect.y2 = dest_rect.y1 + height; - - for (i = 0; i < nbox; i++) { - if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) - continue; - - intelEmitCopyBlit(intel, - dest->cpp, - rowLength, - src_buffer, src_offset, - dest->pitch, - dest->buffer, 0, - rect.x1 - dest_rect.x1, - rect.y2 - dest_rect.y2, - rect.x1, - rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1, - ctx->Color.ColorLogicOpEnabled ? - ctx->Color.LogicOp : GL_COPY); - } - intel_batchbuffer_flush(intel->batch); - fence = intel->batch->last_fence; - dri_fence_reference(fence); - } - UNLOCK_HARDWARE(intel); - - if (fence) { - dri_fence_wait(fence); - dri_fence_unreference(fence); - } - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - DONE\n", __FUNCTION__); - - return GL_TRUE; -} - - - -void -intelDrawPixels(GLcontext * ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, - GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid * pixels) -{ - if (do_blit_drawpixels(ctx, x, y, width, height, format, type, - unpack, pixels)) - return; - - if (do_texture_drawpixels(ctx, x, y, width, height, format, type, - unpack, pixels)) - return; - - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); - - if (ctx->FragmentProgram._Current == ctx->FragmentProgram._TexEnvProgram) { - /* - * We don't want the i915 texenv program to be applied to DrawPixels. - * This is really just a performance optimization (mesa will other- - * wise happily run the fragment program on each pixel in the image). - */ - struct gl_fragment_program *fpSave = ctx->FragmentProgram._Current; - /* can't just set current frag prog to 0 here as on buffer resize - we'll get new state checks which will segfault. Remains a hack. */ - ctx->FragmentProgram._Current = NULL; - ctx->FragmentProgram._UseTexEnvProgram = GL_FALSE; - ctx->FragmentProgram._Active = GL_FALSE; - _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); - ctx->FragmentProgram._Current = fpSave; - ctx->FragmentProgram._UseTexEnvProgram = GL_TRUE; - ctx->FragmentProgram._Active = GL_TRUE; - } - else { - _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); - } -} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c deleted file mode 100644 index a22844926c..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c +++ /dev/null @@ -1,319 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "enums.h" -#include "mtypes.h" -#include "macros.h" -#include "image.h" -#include "bufferobj.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_buffers.h" -#include "intel_regions.h" -#include "intel_pixel.h" -#include "intel_buffer_objects.h" - -/* For many applications, the new ability to pull the source buffers - * back out of the GTT and then do the packing/conversion operations - * in software will be as much of an improvement as trying to get the - * blitter and/or texture engine to do the work. - * - * This step is gated on private backbuffers. - * - * Obviously the frontbuffer can't be pulled back, so that is either - * an argument for blit/texture readpixels, or for blitting to a - * temporary and then pulling that back. - * - * When the destination is a pbo, however, it's not clear if it is - * ever going to be pulled to main memory (though the access param - * will be a good hint). So it sounds like we do want to be able to - * choose between blit/texture implementation on the gpu and pullback - * and cpu-based copying. - * - * Unless you can magically turn client memory into a PBO for the - * duration of this call, there will be a cpu-based copying step in - * any case. - */ - - -static GLboolean -do_texture_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - struct intel_region *dest_region) -{ -#if 0 - struct intel_context *intel = intel_context(ctx); - intelScreenPrivate *screen = intel->intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int textureFormat; - GLenum glTextureFormat; - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if (ctx->_ImageTransferState || - pack->SwapBytes || pack->LsbFirst || !pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); - - if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: couldn't set dest %s/%s\n", - __FUNCTION__, - _mesa_lookup_enum_by_nr(type), - _mesa_lookup_enum_by_nr(format)); - return GL_FALSE; - } - - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - intel->vtbl.install_meta_state(intel); - intel->vtbl.meta_no_depth_write(intel); - intel->vtbl.meta_no_stencil_write(intel); - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE(intel); - SET_STATE(i830, state); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); - - - intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); - - - /* Set the 3d engine to draw into the destination region: - */ - - intel->vtbl.meta_draw_region(intel, dest_region); - intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ - - - /* Draw a single quad, no cliprects: - */ - intel->vtbl.meta_disable_cliprects(intel); - - intel->vtbl.draw_quad(intel, - 0, width, 0, height, - 0x00ff00ff, x, x + width, y, y + height); - - intel->vtbl.leave_meta_state(intel); - } - UNLOCK_HARDWARE(intel); - - intel_region_wait_fence(ctx, dest_region); /* required by GL */ - return GL_TRUE; -#endif - - return GL_FALSE; -} - - - - -static GLboolean -do_blit_readpixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, GLvoid * pixels) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_region *src = intel_readbuf_region(intel); - struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); - GLuint dst_offset; - GLuint rowLength; - dri_fence *fence = NULL; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s\n", __FUNCTION__); - - if (!src) - return GL_FALSE; - - if (dst) { - /* XXX This validation should be done by core mesa: - */ - if (!_mesa_validate_pbo_access(2, pack, width, height, 1, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); - return GL_TRUE; - } - } - else { - /* PBO only for now: - */ - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - not PBO\n", __FUNCTION__); - return GL_FALSE; - } - - - if (ctx->_ImageTransferState || - !intel_check_blit_format(src, format, type)) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - bad format for blit\n", __FUNCTION__); - return GL_FALSE; - } - - if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: bad packing params\n", __FUNCTION__); - return GL_FALSE; - } - - if (pack->RowLength > 0) - rowLength = pack->RowLength; - else - rowLength = width; - - if (pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); - return GL_FALSE; - } - else { - rowLength = -rowLength; - } - - /* XXX 64-bit cast? */ - dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, - format, type, 0, 0, 0); - - - /* Although the blits go on the command buffer, need to do this and - * fire with lock held to guarentee cliprects are correct. - */ - intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - - if (intel->driDrawable->numClipRects) { - GLboolean all = (width * height * src->cpp == dst->Base.Size && - x == 0 && dst_offset == 0); - - dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst, - all ? INTEL_WRITE_FULL : - INTEL_WRITE_PART); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int nbox = dPriv->numClipRects; - drm_clip_rect_t *box = dPriv->pClipRects; - drm_clip_rect_t rect; - drm_clip_rect_t src_rect; - int i; - - src_rect.x1 = dPriv->x + x; - src_rect.y1 = dPriv->y + dPriv->h - (y + height); - src_rect.x2 = src_rect.x1 + width; - src_rect.y2 = src_rect.y1 + height; - - - - for (i = 0; i < nbox; i++) { - if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) - continue; - - intelEmitCopyBlit(intel, - src->cpp, - src->pitch, src->buffer, 0, - rowLength, - dst_buffer, dst_offset, - rect.x1, - rect.y1, - rect.x1 - src_rect.x1, - rect.y2 - src_rect.y2, - rect.x2 - rect.x1, rect.y2 - rect.y1, - GL_COPY); - } - - intel_batchbuffer_flush(intel->batch); - fence = intel->batch->last_fence; - dri_fence_reference(fence); - - } - UNLOCK_HARDWARE(intel); - - if (fence) { - dri_fence_wait(fence); - dri_fence_unreference(fence); - } - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s - DONE\n", __FUNCTION__); - - return GL_TRUE; -} - -void -intelReadPixels(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, GLvoid * pixels) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - intelFlush(ctx); - - if (do_blit_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; - - if (do_texture_readpixels - (ctx, x, y, width, height, format, type, pack, pixels)) - return; - - if (INTEL_DEBUG & DEBUG_PIXEL) - _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); - - _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); -} diff --git a/src/mesa/drivers/dri/i915tex/intel_reg.h b/src/mesa/drivers/dri/i915tex/intel_reg.h deleted file mode 100644 index 7828ba6ad3..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_reg.h +++ /dev/null @@ -1,88 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef _INTEL_REG_H_ -#define _INTEL_REG_H_ - - - -#define CMD_3D (0x3<<29) - - -#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24)) -#define PRIM_INDIRECT (1<<23) -#define PRIM_INLINE (0<<23) -#define PRIM_INDIRECT_SEQUENTIAL (0<<17) -#define PRIM_INDIRECT_ELTS (1<<17) - -#define PRIM3D_TRILIST (0x0<<18) -#define PRIM3D_TRISTRIP (0x1<<18) -#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) -#define PRIM3D_TRIFAN (0x3<<18) -#define PRIM3D_POLY (0x4<<18) -#define PRIM3D_LINELIST (0x5<<18) -#define PRIM3D_LINESTRIP (0x6<<18) -#define PRIM3D_RECTLIST (0x7<<18) -#define PRIM3D_POINTLIST (0x8<<18) -#define PRIM3D_DIB (0x9<<18) -#define PRIM3D_MASK (0x1f<<18) - -#define I915PACKCOLOR4444(r,g,b,a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) - -#define I915PACKCOLOR1555(r,g,b,a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) - -#define I915PACKCOLOR565(r,g,b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) - -#define I915PACKCOLOR8888(r,g,b,a) \ - ((a<<24) | (r<<16) | (g<<8) | b) - - - - -#define BR00_BITBLT_CLIENT 0x40000000 -#define BR00_OP_COLOR_BLT 0x10000000 -#define BR00_OP_SRC_COPY_BLT 0x10C00000 -#define BR13_SOLID_PATTERN 0x80000000 - -#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) -#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) -#define XY_COLOR_BLT_WRITE_RGB (1<<20) - -#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) -#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) -#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) - -#define MI_WAIT_FOR_EVENT ((0x3<<23)) -#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) -#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c deleted file mode 100644 index 4eac859a13..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_regions.c +++ /dev/null @@ -1,482 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Provide additional functionality on top of bufmgr buffers: - * - 2d semantics and blit operations - * - refcounting of buffers for multiple images in a buffer. - * - refcounting of buffer mappings. - * - some logic for moving the buffers to the best memory pools for - * given operations. - * - * Most of this is to make it easier to implement the fixed-layout - * mipmap tree required by intel hardware in the face of GL's - * programming interface where each image can be specifed in random - * order and it isn't clear what layout the tree should have until the - * last moment. - */ - -#include "intel_context.h" -#include "intel_regions.h" -#include "intel_blit.h" -#include "intel_buffer_objects.h" -#include "dri_bufmgr.h" -#include "intel_batchbuffer.h" - -#define FILE_DEBUG_FLAG DEBUG_REGION - -void -intel_region_idle(intelScreenPrivate *intelScreen, struct intel_region *region) -{ - DBG("%s\n", __FUNCTION__); - /* XXX: Using this function is likely bogus -- it ought to only have been - * used before a map, anyway, but leave this cheap implementation of it - * for now. - */ - if (region && region->buffer) { - /* Mapping it for read will ensure that any acceleration to the region - * would have landed already. - */ - dri_bo_map(region->buffer, GL_TRUE); - dri_bo_unmap(region->buffer); - } -} - -/* XXX: Thread safety? - */ -GLubyte * -intel_region_map(intelScreenPrivate *intelScreen, struct intel_region *region) -{ - DBG("%s\n", __FUNCTION__); - if (!region->map_refcount++) { - if (region->pbo) - intel_region_cow(intelScreen, region); - - dri_bo_map(region->buffer, GL_TRUE); - region->map = region->buffer->virtual; - } - - return region->map; -} - -void -intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *region) -{ - DBG("%s\n", __FUNCTION__); - if (!--region->map_refcount) { - dri_bo_unmap(region->buffer); - region->map = NULL; - } -} - -struct intel_region * -intel_region_alloc(intelScreenPrivate *intelScreen, - GLuint cpp, GLuint pitch, GLuint height) -{ - struct intel_region *region = calloc(sizeof(*region), 1); - - DBG("%s\n", __FUNCTION__); - - region->cpp = cpp; - region->pitch = pitch; - region->height = height; /* needed? */ - region->refcount = 1; - - region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", - pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); - return region; -} - -void -intel_region_reference(struct intel_region **dst, struct intel_region *src) -{ - assert(*dst == NULL); - if (src) { - src->refcount++; - *dst = src; - } -} - -void -intel_region_release(struct intel_region **region) -{ - if (!*region) - return; - - DBG("%s %d\n", __FUNCTION__, (*region)->refcount - 1); - - ASSERT((*region)->refcount > 0); - (*region)->refcount--; - - if ((*region)->refcount == 0) { - assert((*region)->map_refcount == 0); - - if ((*region)->pbo) - (*region)->pbo->region = NULL; - (*region)->pbo = NULL; - dri_bo_unreference((*region)->buffer); - free(*region); - } - *region = NULL; -} - - -struct intel_region * -intel_region_create_static(intelScreenPrivate *intelScreen, - GLuint mem_type, - unsigned int bo_handle, - GLuint offset, - void *virtual, - GLuint cpp, GLuint pitch, GLuint height) -{ - struct intel_region *region = calloc(sizeof(*region), 1); - DBG("%s\n", __FUNCTION__); - - region->cpp = cpp; - region->pitch = pitch; - region->height = height; /* needed? */ - region->refcount = 1; - - if (intelScreen->ttm) { - assert(bo_handle != -1); - region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, - "static region", - bo_handle); - } else { - region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, - "static region", - offset, pitch * cpp * height, - virtual, - DRM_BO_FLAG_MEM_TT); - } - - return region; -} - - - -void -intel_region_update_static(intelScreenPrivate *intelScreen, - struct intel_region *region, - GLuint mem_type, - unsigned int bo_handle, - GLuint offset, - void *virtual, - GLuint cpp, GLuint pitch, GLuint height) -{ - DBG("%s\n", __FUNCTION__); - - region->cpp = cpp; - region->pitch = pitch; - region->height = height; /* needed? */ - - /* - * We use a "shared" buffer type to indicate buffers created and - * shared by others. - */ - - dri_bo_unreference(region->buffer); - if (intelScreen->ttm) { - assert(bo_handle != -1); - region->buffer = dri_ttm_bo_create_from_handle(intelScreen->bufmgr, - "static region", - bo_handle); - } else { - region->buffer = dri_bo_alloc_static(intelScreen->bufmgr, - "static region", - offset, pitch * cpp * height, - virtual, - DRM_BO_FLAG_MEM_TT); - } -} - - - -/* - * XXX Move this into core Mesa? - */ -static void -_mesa_copy_rect(GLubyte * dst, - GLuint cpp, - GLuint dst_pitch, - GLuint dst_x, - GLuint dst_y, - GLuint width, - GLuint height, - const GLubyte * src, - GLuint src_pitch, GLuint src_x, GLuint src_y) -{ - GLuint i; - - dst_pitch *= cpp; - src_pitch *= cpp; - dst += dst_x * cpp; - src += src_x * cpp; - dst += dst_y * dst_pitch; - src += src_y * dst_pitch; - width *= cpp; - - if (width == dst_pitch && width == src_pitch) - memcpy(dst, src, height * width); - else { - for (i = 0; i < height; i++) { - memcpy(dst, src, width); - dst += dst_pitch; - src += src_pitch; - } - } -} - - -/* Upload data to a rectangular sub-region. Lots of choices how to do this: - * - * - memcpy by span to current destination - * - upload data as new buffer and blit - * - * Currently always memcpy. - */ -void -intel_region_data(intelScreenPrivate *intelScreen, - struct intel_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - const void *src, GLuint src_pitch, - GLuint srcx, GLuint srcy, GLuint width, GLuint height) -{ - struct intel_context *intel = intelScreenContext(intelScreen); - - DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - if (dst->pbo) { - if (dstx == 0 && - dsty == 0 && width == dst->pitch && height == dst->height) - intel_region_release_pbo(intelScreen, dst); - else - intel_region_cow(intelScreen, dst); - } - - - LOCK_HARDWARE(intel); - - _mesa_copy_rect(intel_region_map(intelScreen, dst) + dst_offset, - dst->cpp, - dst->pitch, - dstx, dsty, width, height, src, src_pitch, srcx, srcy); - - intel_region_unmap(intelScreen, dst); - - UNLOCK_HARDWARE(intel); - -} - -/* Copy rectangular sub-regions. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -void -intel_region_copy(intelScreenPrivate *intelScreen, - struct intel_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - struct intel_region *src, - GLuint src_offset, - GLuint srcx, GLuint srcy, GLuint width, GLuint height) -{ - struct intel_context *intel = intelScreenContext(intelScreen); - - DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - if (dst->pbo) { - if (dstx == 0 && - dsty == 0 && width == dst->pitch && height == dst->height) - intel_region_release_pbo(intelScreen, dst); - else - intel_region_cow(intelScreen, dst); - } - - assert(src->cpp == dst->cpp); - - intelEmitCopyBlit(intel, - dst->cpp, - src->pitch, src->buffer, src_offset, - dst->pitch, dst->buffer, dst_offset, - srcx, srcy, dstx, dsty, width, height, - GL_COPY); -} - -/* Fill a rectangular sub-region. Need better logic about when to - * push buffers into AGP - will currently do so whenever possible. - */ -void -intel_region_fill(intelScreenPrivate *intelScreen, - struct intel_region *dst, - GLuint dst_offset, - GLuint dstx, GLuint dsty, - GLuint width, GLuint height, GLuint color) -{ - struct intel_context *intel = intelScreenContext(intelScreen); - - DBG("%s\n", __FUNCTION__); - - if (intel == NULL) - return; - - if (dst->pbo) { - if (dstx == 0 && - dsty == 0 && width == dst->pitch && height == dst->height) - intel_region_release_pbo(intelScreen, dst); - else - intel_region_cow(intelScreen, dst); - } - - intelEmitFillBlit(intel, - dst->cpp, - dst->pitch, dst->buffer, dst_offset, - dstx, dsty, width, height, color); -} - -/* Attach to a pbo, discarding our data. Effectively zero-copy upload - * the pbo's data. - */ -void -intel_region_attach_pbo(intelScreenPrivate *intelScreen, - struct intel_region *region, - struct intel_buffer_object *pbo) -{ - if (region->pbo == pbo) - return; - - /* If there is already a pbo attached, break the cow tie now. - * Don't call intel_region_release_pbo() as that would - * unnecessarily allocate a new buffer we would have to immediately - * discard. - */ - if (region->pbo) { - region->pbo->region = NULL; - region->pbo = NULL; - } - - if (region->buffer) { - dri_bo_unreference(region->buffer); - region->buffer = NULL; - } - - region->pbo = pbo; - region->pbo->region = region; - dri_bo_reference(pbo->buffer); - region->buffer = pbo->buffer; -} - - -/* Break the COW tie to the pbo and allocate a new buffer. - * The pbo gets to keep the data. - */ -void -intel_region_release_pbo(intelScreenPrivate *intelScreen, - struct intel_region *region) -{ - assert(region->buffer == region->pbo->buffer); - region->pbo->region = NULL; - region->pbo = NULL; - dri_bo_unreference(region->buffer); - region->buffer = NULL; - - region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", - region->pitch * region->cpp * region->height, - 64, DRM_BO_FLAG_MEM_TT); -} - -/* Break the COW tie to the pbo. Both the pbo and the region end up - * with a copy of the data. - */ -void -intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region) -{ - struct intel_context *intel = intelScreenContext(intelScreen); - struct intel_buffer_object *pbo = region->pbo; - - if (intel == NULL) - return; - - intel_region_release_pbo(intelScreen, region); - - assert(region->cpp * region->pitch * region->height == pbo->Base.Size); - - DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size); - - /* Now blit from the texture buffer to the new buffer: - */ - - intel_batchbuffer_flush(intel->batch); - - if (!intel->locked) { - LOCK_HARDWARE(intel); - intelEmitCopyBlit(intel, - region->cpp, - region->pitch, - region->buffer, 0, - region->pitch, - pbo->buffer, 0, - 0, 0, 0, 0, - region->pitch, region->height, - GL_COPY); - - intel_batchbuffer_flush(intel->batch); - UNLOCK_HARDWARE(intel); - } - else { - intelEmitCopyBlit(intel, - region->cpp, - region->pitch, - region->buffer, 0, - region->pitch, - pbo->buffer, 0, - 0, 0, 0, 0, - region->pitch, region->height, - GL_COPY); - - intel_batchbuffer_flush(intel->batch); - } -} - -dri_bo * -intel_region_buffer(intelScreenPrivate *intelScreen, - struct intel_region *region, GLuint flag) -{ - if (region->pbo) { - if (flag == INTEL_WRITE_PART) - intel_region_cow(intelScreen, region); - else if (flag == INTEL_WRITE_FULL) - intel_region_release_pbo(intelScreen, region); - } - - return region->buffer; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h deleted file mode 100644 index 42d7b17711..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_regions.h +++ /dev/null @@ -1,143 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTEL_REGIONS_H -#define INTEL_REGIONS_H - -#include "mtypes.h" -#include "intel_screen.h" - -struct intel_context; -struct intel_buffer_object; - -/** - * A layer on top of the bufmgr buffers that adds a few useful things: - * - * - Refcounting for local buffer references. - * - Refcounting for buffer maps - * - Buffer dimensions - pitch and height. - * - Blitter commands for copying 2D regions between buffers. (really???) - */ -struct intel_region -{ - dri_bo *buffer; /**< buffer manager's buffer */ - GLuint refcount; /**< Reference count for region */ - GLuint cpp; /**< bytes per pixel */ - GLuint pitch; /**< in pixels */ - GLuint height; /**< in pixels */ - GLubyte *map; /**< only non-NULL when region is actually mapped */ - GLuint map_refcount; /**< Reference count for mapping */ - - GLuint draw_offset; /**< Offset of drawing address within the region */ - - struct intel_buffer_object *pbo; /* zero-copy uploads */ -}; - - -/* Allocate a refcounted region. Pointers to regions should only be - * copied by calling intel_reference_region(). - */ -struct intel_region *intel_region_alloc(intelScreenPrivate *intelScreen, - GLuint cpp, - GLuint pitch, GLuint height); - -void intel_region_reference(struct intel_region **dst, - struct intel_region *src); - -void intel_region_release(struct intel_region **ib); - -extern struct intel_region -*intel_region_create_static(intelScreenPrivate *intelScreen, - GLuint mem_type, - unsigned int bo_handle, - GLuint offset, - void *virtual, - GLuint cpp, - GLuint pitch, GLuint height); -extern void -intel_region_update_static(intelScreenPrivate *intelScreen, - struct intel_region *region, - GLuint mem_type, - unsigned int bo_handle, - GLuint offset, - void *virtual, - GLuint cpp, GLuint pitch, GLuint height); - - -void intel_region_idle(intelScreenPrivate *intelScreen, - struct intel_region *ib); - -/* Map/unmap regions. This is refcounted also: - */ -GLubyte *intel_region_map(intelScreenPrivate *intelScreen, - struct intel_region *ib); - -void intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *ib); - - -/* Upload data to a rectangular sub-region - */ -void intel_region_data(intelScreenPrivate *intelScreen, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - const void *src, GLuint src_stride, - GLuint srcx, GLuint srcy, GLuint width, GLuint height); - -/* Copy rectangular sub-regions - */ -void intel_region_copy(intelScreenPrivate *intelScreen, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - struct intel_region *src, - GLuint src_offset, - GLuint srcx, GLuint srcy, GLuint width, GLuint height); - -/* Fill a rectangular sub-region - */ -void intel_region_fill(intelScreenPrivate *intelScreen, - struct intel_region *dest, - GLuint dest_offset, - GLuint destx, GLuint desty, - GLuint width, GLuint height, GLuint color); - -/* Helpers for zerocopy uploads, particularly texture image uploads: - */ -void intel_region_attach_pbo(intelScreenPrivate *intelScreen, - struct intel_region *region, - struct intel_buffer_object *pbo); -void intel_region_release_pbo(intelScreenPrivate *intelScreen, - struct intel_region *region); -void intel_region_cow(intelScreenPrivate *intelScreen, - struct intel_region *region); - -dri_bo *intel_region_buffer(intelScreenPrivate *intelScreen, - struct intel_region *region, - GLuint flag); - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_render.c b/src/mesa/drivers/dri/i915tex/intel_render.c deleted file mode 100644 index c8b6d308d9..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_render.c +++ /dev/null @@ -1,244 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* - * Render unclipped vertex buffers by emitting vertices directly to - * dma buffers. Use strip/fan hardware acceleration where possible. - * - */ -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "imports.h" -#include "mtypes.h" -#include "enums.h" - -#include "tnl/t_context.h" -#include "tnl/t_vertex.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_tris.h" -#include "intel_batchbuffer.h" -#include "intel_reg.h" - -/* - * Render unclipped vertex buffers by emitting vertices directly to - * dma buffers. Use strip/fan hardware primitives where possible. - * Try to simulate missing primitives with indexed vertices. - */ -#define HAVE_POINTS 0 /* Has it, but can't use because subpixel has to - * be adjusted for points on the INTEL/I845G - */ -#define HAVE_LINES 1 -#define HAVE_LINE_STRIPS 1 -#define HAVE_TRIANGLES 1 -#define HAVE_TRI_STRIPS 1 -#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ -#define HAVE_TRI_FANS 1 -#define HAVE_POLYGONS 1 -#define HAVE_QUADS 0 -#define HAVE_QUAD_STRIPS 0 - -#define HAVE_ELTS 0 - -static GLuint hw_prim[GL_POLYGON + 1] = { - 0, - PRIM3D_LINELIST, - PRIM3D_LINESTRIP, - PRIM3D_LINESTRIP, - PRIM3D_TRILIST, - PRIM3D_TRISTRIP, - PRIM3D_TRIFAN, - 0, - 0, - PRIM3D_POLY -}; - -static const GLenum reduced_prim[GL_POLYGON + 1] = { - GL_POINTS, - GL_LINES, - GL_LINES, - GL_LINES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES -}; - -static const int scale_prim[GL_POLYGON + 1] = { - 0, /* fallback case */ - 1, - 2, - 2, - 1, - 3, - 3, - 0, /* fallback case */ - 0, /* fallback case */ - 3 -}; - - -static void -intelDmaPrimitive(struct intel_context *intel, GLenum prim) -{ - if (0) - fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); - INTEL_FIREVERTICES(intel); - intel->vtbl.reduced_primitive_state(intel, reduced_prim[prim]); - intelStartInlinePrimitive(intel, hw_prim[prim], INTEL_BATCH_CLIPRECTS); -} - - -#define LOCAL_VARS struct intel_context *intel = intel_context(ctx) -#define INIT( prim ) \ -do { \ - intelDmaPrimitive( intel, prim ); \ -} while (0) - -#define FLUSH() INTEL_FIREVERTICES(intel) - -#define GET_SUBSEQUENT_VB_MAX_VERTS() \ - ((intel->batch->size - 1500) / (intel->vertex_size*4)) -#define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS() - -#define ALLOC_VERTS( nr ) \ - intelExtendInlinePrimitive( intel, (nr) * intel->vertex_size ) - -#define EMIT_VERTS( ctx, j, nr, buf ) \ - _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf ) - -#define TAG(x) intel_##x -#include "tnl_dd/t_dd_dmatmp.h" - - -/**********************************************************************/ -/* Render pipeline stage */ -/**********************************************************************/ - -/* Heuristic to choose between the two render paths: - */ -static GLboolean -choose_render(struct intel_context *intel, struct vertex_buffer *VB) -{ - int vertsz = intel->vertex_size; - int cost_render = 0; - int cost_fallback = 0; - int nr_prims = 0; - int nr_rprims = 0; - int nr_rverts = 0; - int rprim = intel->reduced_primitive; - int i = 0; - - for (i = 0; i < VB->PrimitiveCount; i++) { - GLuint prim = VB->Primitive[i].mode; - GLuint length = VB->Primitive[i].count; - - if (!length) - continue; - - nr_prims++; - nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK]; - - if (reduced_prim[prim & PRIM_MODE_MASK] != rprim) { - nr_rprims++; - rprim = reduced_prim[prim & PRIM_MODE_MASK]; - } - } - - /* One point for each generated primitive: - */ - cost_render = nr_prims; - cost_fallback = nr_rprims; - - /* One point for every 1024 dwords (4k) of dma: - */ - cost_render += (vertsz * i) / 1024; - cost_fallback += (vertsz * nr_rverts) / 1024; - - if (0) - fprintf(stderr, "cost render: %d fallback: %d\n", - cost_render, cost_fallback); - - if (cost_render > cost_fallback) - return GL_FALSE; - - return GL_TRUE; -} - - -static GLboolean -intel_run_render(GLcontext * ctx, struct tnl_pipeline_stage *stage) -{ - struct intel_context *intel = intel_context(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLuint i; - - intel->vtbl.render_prevalidate( intel ); - - /* Don't handle clipping or indexed vertices. - */ - if (intel->RenderIndex != 0 || - !intel_validate_render(ctx, VB) || !choose_render(intel, VB)) { - return GL_TRUE; - } - - tnl->clipspace.new_inputs |= VERT_BIT_POS; - - tnl->Driver.Render.Start(ctx); - - for (i = 0; i < VB->PrimitiveCount; i++) { - GLuint prim = VB->Primitive[i].mode; - GLuint start = VB->Primitive[i].start; - GLuint length = VB->Primitive[i].count; - - if (!length) - continue; - - intel_render_tab_verts[prim & PRIM_MODE_MASK] (ctx, start, - start + length, prim); - } - - tnl->Driver.Render.Finish(ctx); - - INTEL_FIREVERTICES(intel); - - return GL_FALSE; /* finished the pipe */ -} - -const struct tnl_pipeline_stage _intel_render_stage = { - "intel render", - NULL, - NULL, - NULL, - NULL, - intel_run_render /* run */ -}; diff --git a/src/mesa/drivers/dri/i915tex/intel_rotate.c b/src/mesa/drivers/dri/i915tex/intel_rotate.c deleted file mode 100644 index 12d98c4ad2..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_rotate.c +++ /dev/null @@ -1,237 +0,0 @@ - -/** - * Routines for simple 2D->2D transformations for rotated, flipped screens. - * - * XXX This code is not intel-specific. Move it into a common/utility - * someday. - */ - -#include "intel_rotate.h" - -#define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) ) - -#define ABS(A) ( ((A) < 0) ? -(A) : (A) ) - - -void -matrix23Set(struct matrix23 *m, - int m00, int m01, int m02, int m10, int m11, int m12) -{ - m->m00 = m00; - m->m01 = m01; - m->m02 = m02; - m->m10 = m10; - m->m11 = m11; - m->m12 = m12; -} - - -/* - * Transform (x,y) coordinate by the given matrix. - */ -void -matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y) -{ - const float x0 = *x; - const float y0 = *y; - - *x = m->m00 * x0 + m->m01 * y0 + m->m02; - *y = m->m10 * x0 + m->m11 * y0 + m->m12; -} - - -void -matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y) -{ - const int x0 = *x; - const int y0 = *y; - - *x = m->m00 * x0 + m->m01 * y0 + m->m02; - *y = m->m10 * x0 + m->m11 * y0 + m->m12; -} - - -/* - * Transform a width and height by the given matrix. - * XXX this could be optimized quite a bit. - */ -void -matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist) -{ - int x0 = 0, y0 = 0; - int x1 = *xDist, y1 = 0; - int x2 = 0, y2 = *yDist; - matrix23TransformCoordi(m, &x0, &y0); - matrix23TransformCoordi(m, &x1, &y1); - matrix23TransformCoordi(m, &x2, &y2); - - *xDist = (x1 - x0) + (x2 - x0); - *yDist = (y1 - y0) + (y2 - y0); - - if (*xDist < 0) - *xDist = -*xDist; - if (*yDist < 0) - *yDist = -*yDist; -} - - -/** - * Transform the rect defined by (x, y, w, h) by m. - */ -void -matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w, - int *h) -{ - int x0 = *x, y0 = *y; - int x1 = *x + *w, y1 = *y; - int x2 = *x + *w, y2 = *y + *h; - int x3 = *x, y3 = *y + *h; - matrix23TransformCoordi(m, &x0, &y0); - matrix23TransformCoordi(m, &x1, &y1); - matrix23TransformCoordi(m, &x2, &y2); - matrix23TransformCoordi(m, &x3, &y3); - *w = ABS(x1 - x0) + ABS(x2 - x1); - /**w = ABS(*w);*/ - *h = ABS(y1 - y0) + ABS(y2 - y1); - /**h = ABS(*h);*/ - *x = MIN2(x0, x1); - *x = MIN2(*x, x2); - *y = MIN2(y0, y1); - *y = MIN2(*y, y2); -} - - -/* - * Make rotation matrix for width X height screen. - */ -void -matrix23Rotate(struct matrix23 *m, int width, int height, int angle) -{ - switch (angle) { - case 0: - matrix23Set(m, 1, 0, 0, 0, 1, 0); - break; - case 90: - matrix23Set(m, 0, 1, 0, -1, 0, width); - break; - case 180: - matrix23Set(m, -1, 0, width, 0, -1, height); - break; - case 270: - matrix23Set(m, 0, -1, height, 1, 0, 0); - break; - default: - /*abort() */ ; - } -} - - -/* - * Make flip/reflection matrix for width X height screen. - */ -void -matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip) -{ - if (xflip) { - m->m00 = -1; - m->m01 = 0; - m->m02 = width - 1; - } - else { - m->m00 = 1; - m->m01 = 0; - m->m02 = 0; - } - if (yflip) { - m->m10 = 0; - m->m11 = -1; - m->m12 = height - 1; - } - else { - m->m10 = 0; - m->m11 = 1; - m->m12 = 0; - } -} - - -/* - * result = a * b - */ -void -matrix23Multiply(struct matrix23 *result, - const struct matrix23 *a, const struct matrix23 *b) -{ - result->m00 = a->m00 * b->m00 + a->m01 * b->m10; - result->m01 = a->m00 * b->m01 + a->m01 * b->m11; - result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02; - - result->m10 = a->m10 * b->m00 + a->m11 * b->m10; - result->m11 = a->m10 * b->m01 + a->m11 * b->m11; - result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12; -} - - -#if 000 - -#include - -int -main(int argc, char *argv[]) -{ - int width = 500, height = 400; - int rot; - int fx = 0, fy = 0; /* flip x and/or y ? */ - int coords[4][2]; - - /* four corner coords to test with */ - coords[0][0] = 0; - coords[0][1] = 0; - coords[1][0] = width - 1; - coords[1][1] = 0; - coords[2][0] = width - 1; - coords[2][1] = height - 1; - coords[3][0] = 0; - coords[3][1] = height - 1; - - - for (rot = 0; rot < 360; rot += 90) { - struct matrix23 rotate, flip, m; - int i; - - printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy); - - /* make transformation matrix 'm' */ - matrix23Rotate(&rotate, width, height, rot); - matrix23Flip(&flip, width, height, fx, fy); - matrix23Multiply(&m, &rotate, &flip); - - /* xform four coords */ - for (i = 0; i < 4; i++) { - int x = coords[i][0]; - int y = coords[i][1]; - matrix23TransformCoordi(&m, &x, &y); - printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y); - } - - /* xform width, height */ - { - int x = width; - int y = height; - matrix23TransformDistance(&m, &x, &y); - printf(" %d x %d -> %d x %d\n", width, height, x, y); - } - - /* xform rect */ - { - int x = 50, y = 10, w = 200, h = 100; - matrix23TransformRect(&m, &x, &y, &w, &h); - printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100, - x, y, w, h); - } - - } - - return 0; -} -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_rotate.h b/src/mesa/drivers/dri/i915tex/intel_rotate.h deleted file mode 100644 index 9c8802ca47..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_rotate.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef INTEL_ROTATE_H -#define INTEL_ROTATE_H 1 - -struct matrix23 -{ - int m00, m01, m02; - int m10, m11, m12; -}; - - - -extern void -matrix23Set(struct matrix23 *m, - int m00, int m01, int m02, int m10, int m11, int m12); - -extern void matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y); - -extern void -matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y); - -extern void -matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist); - -extern void -matrix23TransformRect(const struct matrix23 *m, - int *x, int *y, int *w, int *h); - -extern void -matrix23Rotate(struct matrix23 *m, int width, int height, int angle); - -extern void -matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip); - -extern void -matrix23Multiply(struct matrix23 *result, - const struct matrix23 *a, const struct matrix23 *b); - - -#endif /* INTEL_ROTATE_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c deleted file mode 100644 index 2721a90094..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ /dev/null @@ -1,955 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "context.h" -#include "framebuffer.h" -#include "matrix.h" -#include "renderbuffer.h" -#include "simple_list.h" -#include "utils.h" -#include "vblank.h" -#include "xmlpool.h" - - -#include "intel_screen.h" - -#include "intel_buffers.h" -#include "intel_tex.h" -#include "intel_span.h" -#include "intel_tris.h" -#include "intel_ioctl.h" -#include "intel_fbo.h" - -#include "i830_dri.h" -#include "dri_bufmgr.h" -#include "intel_regions.h" -#include "intel_batchbuffer.h" - -PUBLIC const char __driConfigOptions[] = - DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) - DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY - DRI_CONF_FORCE_S3TC_ENABLE(false) - DRI_CONF_ALLOW_LARGE_TEXTURES(1) - DRI_CONF_SECTION_END DRI_CONF_END; - const GLuint __driNConfigOptions = 4; - -#ifdef USE_NEW_INTERFACE - static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; -#endif /*USE_NEW_INTERFACE */ - - extern const struct dri_extension card_extensions[]; - -/** - * Map all the memory regions described by the screen. - * \return GL_TRUE if success, GL_FALSE if error. - */ -GLboolean -intelMapScreenRegions(__DRIscreenPrivate * sPriv) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; - - if (intelScreen->front.handle) { - if (drmMap(sPriv->fd, - intelScreen->front.handle, - intelScreen->front.size, - (drmAddress *) & intelScreen->front.map) != 0) { - _mesa_problem(NULL, "drmMap(frontbuffer) failed!"); - return GL_FALSE; - } - } - else { - _mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!"); - } - - if (0) - _mesa_printf("Back 0x%08x ", intelScreen->back.handle); - if (drmMap(sPriv->fd, - intelScreen->back.handle, - intelScreen->back.size, - (drmAddress *) & intelScreen->back.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - - if (intelScreen->third.handle) { - if (0) - _mesa_printf("Third 0x%08x ", intelScreen->third.handle); - if (drmMap(sPriv->fd, - intelScreen->third.handle, - intelScreen->third.size, - (drmAddress *) & intelScreen->third.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - } - - if (0) - _mesa_printf("Depth 0x%08x ", intelScreen->depth.handle); - if (drmMap(sPriv->fd, - intelScreen->depth.handle, - intelScreen->depth.size, - (drmAddress *) & intelScreen->depth.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - - if (0) - _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); - if (intelScreen->tex.size != 0) { - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *) & intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - } - - if (0) - printf("Mappings: front: %p back: %p third: %p depth: %p tex: %p\n", - intelScreen->front.map, - intelScreen->back.map, intelScreen->third.map, - intelScreen->depth.map, intelScreen->tex.map); - return GL_TRUE; -} - -/** Driver-specific fence emit implementation for the fake memory manager. */ -static unsigned int -intel_fence_emit(void *private) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; - unsigned int fence; - - /* XXX: Need to emit a flush, if we haven't already (at least with the - * current batchbuffer implementation, we have). - */ - - fence = intelEmitIrqLocked(intelScreen); - - return fence; -} - -/** Driver-specific fence wait implementation for the fake memory manager. */ -static int -intel_fence_wait(void *private, unsigned int cookie) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; - - intelWaitIrq(intelScreen, cookie); - - return 0; -} - -static struct intel_region * -intel_recreate_static(intelScreenPrivate *intelScreen, - struct intel_region *region, - intelRegion *region_desc, - GLuint mem_type) -{ - if (region) { - intel_region_update_static(intelScreen, region, mem_type, - region_desc->bo_handle, region_desc->offset, - region_desc->map, intelScreen->cpp, - region_desc->pitch / intelScreen->cpp, - intelScreen->height); - } else { - region = intel_region_create_static(intelScreen, mem_type, - region_desc->bo_handle, - region_desc->offset, - region_desc->map, intelScreen->cpp, - region_desc->pitch / intelScreen->cpp, - intelScreen->height); - } - - assert(region->buffer != NULL); - - return region; -} - - -/* Create intel_region structs to describe the static front,back,depth - * buffers created by the xserver. - * - * Although FBO's mean we now no longer use these as render targets in - * all circumstances, they won't go away until the back and depth - * buffers become private, and the front and rotated buffers will - * remain even then. - * - * Note that these don't allocate video memory, just describe - * allocations alread made by the X server. - */ -static void -intel_recreate_static_regions(intelScreenPrivate *intelScreen) -{ - intelScreen->front_region = - intel_recreate_static(intelScreen, - intelScreen->front_region, - &intelScreen->front, - DRM_BO_FLAG_MEM_TT); - - /* The rotated region is only used for old DDXes that didn't handle rotation -\ * on their own. - */ - if (intelScreen->driScrnPriv->ddxMinor < 8) { - intelScreen->rotated_region = - intel_recreate_static(intelScreen, - intelScreen->rotated_region, - &intelScreen->rotated, - DRM_BO_FLAG_MEM_TT); - } - - intelScreen->back_region = - intel_recreate_static(intelScreen, - intelScreen->back_region, - &intelScreen->back, - DRM_BO_FLAG_MEM_TT); - - if (intelScreen->third.handle) { - intelScreen->third_region = - intel_recreate_static(intelScreen, - intelScreen->third_region, - &intelScreen->third, - DRM_BO_FLAG_MEM_TT); - } - - /* Still assumes front.cpp == depth.cpp. We can kill this when we move to - * private buffers. - */ - intelScreen->depth_region = - intel_recreate_static(intelScreen, - intelScreen->depth_region, - &intelScreen->depth, - DRM_BO_FLAG_MEM_TT); -} - -/** - * Use the information in the sarea to update the screen parameters - * related to screen rotation. Needs to be called locked. - */ -void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; - - intelUnmapScreenRegions(intelScreen); - intelUpdateScreenFromSAREA(intelScreen, sarea); - if (!intelMapScreenRegions(sPriv)) { - fprintf(stderr, "ERROR Remapping screen regions!!!\n"); - } - intel_recreate_static_regions(intelScreen); -} - - -void -intelUnmapScreenRegions(intelScreenPrivate * intelScreen) -{ -#define REALLY_UNMAP 1 - if (intelScreen->front.map) { -#if REALLY_UNMAP - if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0) - printf("drmUnmap front failed!\n"); -#endif - intelScreen->front.map = NULL; - } - if (intelScreen->back.map) { -#if REALLY_UNMAP - if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0) - printf("drmUnmap back failed!\n"); -#endif - intelScreen->back.map = NULL; - } - if (intelScreen->third.map) { -#if REALLY_UNMAP - if (drmUnmap(intelScreen->third.map, intelScreen->third.size) != 0) - printf("drmUnmap third failed!\n"); -#endif - intelScreen->third.map = NULL; - } - if (intelScreen->depth.map) { -#if REALLY_UNMAP - drmUnmap(intelScreen->depth.map, intelScreen->depth.size); - intelScreen->depth.map = NULL; -#endif - } - if (intelScreen->tex.map) { -#if REALLY_UNMAP - drmUnmap(intelScreen->tex.map, intelScreen->tex.size); - intelScreen->tex.map = NULL; -#endif - } -} - - -static void -intelPrintDRIInfo(intelScreenPrivate * intelScreen, - __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) -{ - fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->front.size, intelScreen->front.offset, - intelScreen->front.pitch); - fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->back.size, intelScreen->back.offset, - intelScreen->back.pitch); - fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->depth.size, intelScreen->depth.offset, - intelScreen->depth.pitch); - fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n", - intelScreen->rotated.size, intelScreen->rotated.offset, - intelScreen->rotated.pitch); - fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", - intelScreen->tex.size, intelScreen->tex.offset); - fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); -} - - -static void -intelPrintSAREA(const drmI830Sarea * sarea) -{ - fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, - sarea->height); - fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); - fprintf(stderr, - "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->front_offset, sarea->front_size, - (unsigned) sarea->front_handle); - fprintf(stderr, - "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->back_offset, sarea->back_size, - (unsigned) sarea->back_handle); - fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->depth_offset, sarea->depth_size, - (unsigned) sarea->depth_handle); - fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", - sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); - fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); - fprintf(stderr, - "SAREA: rotated offset: 0x%08x size: 0x%x\n", - sarea->rotated_offset, sarea->rotated_size); - fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); -} - - -/** - * A number of the screen parameters are obtained/computed from - * information in the SAREA. This function updates those parameters. - */ -void -intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, - drmI830Sarea * sarea) -{ - intelScreen->width = sarea->width; - intelScreen->height = sarea->height; - - intelScreen->front.offset = sarea->front_offset; - intelScreen->front.pitch = sarea->pitch * intelScreen->cpp; - intelScreen->front.handle = sarea->front_handle; - intelScreen->front.size = sarea->front_size; - - intelScreen->back.offset = sarea->back_offset; - intelScreen->back.pitch = sarea->pitch * intelScreen->cpp; - intelScreen->back.handle = sarea->back_handle; - intelScreen->back.size = sarea->back_size; - - if (intelScreen->driScrnPriv->ddxMinor >= 8) { - intelScreen->third.offset = sarea->third_offset; - intelScreen->third.pitch = sarea->pitch * intelScreen->cpp; - intelScreen->third.handle = sarea->third_handle; - intelScreen->third.size = sarea->third_size; - } - - intelScreen->depth.offset = sarea->depth_offset; - intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp; - intelScreen->depth.handle = sarea->depth_handle; - intelScreen->depth.size = sarea->depth_size; - - if (intelScreen->driScrnPriv->ddxMinor >= 9) { - intelScreen->front.bo_handle = sarea->front_bo_handle; - intelScreen->back.bo_handle = sarea->back_bo_handle; - intelScreen->third.bo_handle = sarea->third_bo_handle; - intelScreen->depth.bo_handle = sarea->depth_bo_handle; - } else { - intelScreen->front.bo_handle = -1; - intelScreen->back.bo_handle = -1; - intelScreen->third.bo_handle = -1; - intelScreen->depth.bo_handle = -1; - } - - intelScreen->tex.offset = sarea->tex_offset; - intelScreen->logTextureGranularity = sarea->log_tex_granularity; - intelScreen->tex.handle = sarea->tex_handle; - intelScreen->tex.size = sarea->tex_size; - - intelScreen->rotated.offset = sarea->rotated_offset; - intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; - intelScreen->rotated.size = sarea->rotated_size; - intelScreen->current_rotation = sarea->rotation; - matrix23Rotate(&intelScreen->rotMatrix, - sarea->width, sarea->height, sarea->rotation); - intelScreen->rotatedWidth = sarea->virtualX; - intelScreen->rotatedHeight = sarea->virtualY; - - if (0) - intelPrintSAREA(sarea); -} - - -static GLboolean -intelInitDriver(__DRIscreenPrivate * sPriv) -{ - intelScreenPrivate *intelScreen; - I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; - drmI830Sarea *sarea; - - PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = - (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> - getProcAddress("glxEnableExtension")); - void *const psc = sPriv->psc->screenConfigs; - - if (sPriv->devPrivSize != sizeof(I830DRIRec)) { - fprintf(stderr, - "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); - return GL_FALSE; - } - - /* Allocate the private area */ - intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); - if (!intelScreen) { - fprintf(stderr, "\nERROR! Allocating private area failed\n"); - return GL_FALSE; - } - /* parse information in __driConfigOptions */ - driParseOptionInfo(&intelScreen->optionCache, - __driConfigOptions, __driNConfigOptions); - - intelScreen->driScrnPriv = sPriv; - sPriv->private = (void *) intelScreen; - intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; - sarea = (drmI830Sarea *) - (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); - - intelScreen->deviceID = gDRIPriv->deviceID; - if (intelScreen->deviceID == PCI_CHIP_I865_G) - intelScreen->maxBatchSize = 4096; - else - intelScreen->maxBatchSize = BATCH_SZ; - - intelScreen->mem = gDRIPriv->mem; - intelScreen->cpp = gDRIPriv->cpp; - - switch (gDRIPriv->bitsPerPixel) { - case 16: - intelScreen->fbFormat = DV_PF_565; - break; - case 32: - intelScreen->fbFormat = DV_PF_8888; - break; - default: - exit(1); - break; - } - - intelUpdateScreenFromSAREA(intelScreen, sarea); - - if (!intelMapScreenRegions(sPriv)) { - fprintf(stderr, "\nERROR! mapping regions\n"); - _mesa_free(intelScreen); - sPriv->private = NULL; - return GL_FALSE; - } - - intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; - - if (0) - intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); - - intelScreen->drmMinor = sPriv->drmMinor; - - /* Determine if IRQs are active? */ - { - int ret; - drmI830GetParam gp; - - gp.param = I830_PARAM_IRQ_ACTIVE; - gp.value = &intelScreen->irq_active; - - ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drmI830GetParam: %d\n", ret); - return GL_FALSE; - } - } - - /* Determine if batchbuffers are allowed */ - { - int ret; - drmI830GetParam gp; - - gp.param = I830_PARAM_ALLOW_BATCHBUFFER; - gp.value = &intelScreen->allow_batchbuffer; - - ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, - &gp, sizeof(gp)); - if (ret) { - fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret); - return GL_FALSE; - } - } - - if (glx_enable_extension != NULL) { - (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); - (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); - (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); - (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); - } - - /* If we've got a new enough DDX that's initializing TTM and giving us - * object handles for the shared buffers, use that. - */ - intelScreen->ttm = GL_FALSE; - if (getenv("INTEL_NO_TTM") == NULL && - intelScreen->driScrnPriv->ddxMinor >= 9 && - intelScreen->front.bo_handle != -1) { - intelScreen->bufmgr = dri_bufmgr_ttm_init(sPriv->fd, - DRM_FENCE_TYPE_EXE, - DRM_FENCE_TYPE_EXE | - DRM_I915_FENCE_TYPE_RW); - if (intelScreen->bufmgr != NULL) - intelScreen->ttm = GL_TRUE; - } - /* Otherwise, use the classic buffer manager. */ - if (intelScreen->bufmgr == NULL) { - if (intelScreen->tex.size == 0) { - fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", - __func__, __LINE__); - return GL_FALSE; - } - fprintf(stderr, "[%s:%u] Failed to init TTM buffer manager, falling back" - " to classic.\n", __func__, __LINE__); - intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, - intelScreen->tex.map, - intelScreen->tex.size, - intel_fence_emit, - intel_fence_wait, - intelScreen); - } - - intel_recreate_static_regions(intelScreen); - - return GL_TRUE; -} - - -static void -intelDestroyScreen(__DRIscreenPrivate * sPriv) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; - - intelUnmapScreenRegions(intelScreen); - - dri_bufmgr_destroy(intelScreen->bufmgr); - FREE(intelScreen); - sPriv->private = NULL; -} - - -/** - * This is called when we need to set up GL rendering to a new X window. - */ -static GLboolean -intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, - __DRIdrawablePrivate * driDrawPriv, - const __GLcontextModes * mesaVis, GLboolean isPixmap) -{ - intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private; - - if (isPixmap) { - return GL_FALSE; /* not implemented */ - } - else { - GLboolean swStencil = (mesaVis->stencilBits > 0 && - mesaVis->depthBits != 24); - GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); - - struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer); - - if (!intel_fb) - return GL_FALSE; - - _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis); - - /* setup the hardware-based renderbuffers */ - { - intel_fb->color_rb[0] - = intel_create_renderbuffer(rgbFormat, - screen->width, screen->height, - screen->front.offset, - screen->front.pitch, - screen->cpp, - screen->front.map); - intel_set_span_functions(&intel_fb->color_rb[0]->Base); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, - &intel_fb->color_rb[0]->Base); - } - - if (mesaVis->doubleBufferMode) { - intel_fb->color_rb[1] - = intel_create_renderbuffer(rgbFormat, - screen->width, screen->height, - screen->back.offset, - screen->back.pitch, - screen->cpp, - screen->back.map); - intel_set_span_functions(&intel_fb->color_rb[1]->Base); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, - &intel_fb->color_rb[1]->Base); - - if (screen->third.handle) { - struct gl_renderbuffer *tmp_rb = NULL; - - intel_fb->color_rb[2] - = intel_create_renderbuffer(rgbFormat, - screen->width, screen->height, - screen->third.offset, - screen->third.pitch, - screen->cpp, - screen->third.map); - intel_set_span_functions(&intel_fb->color_rb[2]->Base); - _mesa_reference_renderbuffer(&tmp_rb, &intel_fb->color_rb[2]->Base); - } - } - - if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { - /* combined depth/stencil buffer */ - struct intel_renderbuffer *depthStencilRb - = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, - screen->width, screen->height, - screen->depth.offset, - screen->depth.pitch, - screen->cpp, /* 4! */ - screen->depth.map); - intel_set_span_functions(&depthStencilRb->Base); - /* note: bind RB to two attachment points */ - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, - &depthStencilRb->Base); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL, - &depthStencilRb->Base); - } - else if (mesaVis->depthBits == 16) { - /* just 16-bit depth buffer, no hw stencil */ - struct intel_renderbuffer *depthRb - = intel_create_renderbuffer(GL_DEPTH_COMPONENT16, - screen->width, screen->height, - screen->depth.offset, - screen->depth.pitch, - screen->cpp, /* 2! */ - screen->depth.map); - intel_set_span_functions(&depthRb->Base); - _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base); - } - - /* now add any/all software-based renderbuffers we may need */ - _mesa_add_soft_renderbuffers(&intel_fb->Base, - GL_FALSE, /* never sw color */ - GL_FALSE, /* never sw depth */ - swStencil, mesaVis->accumRedBits > 0, - GL_FALSE, /* never sw alpha */ - GL_FALSE /* never sw aux */ ); - driDrawPriv->driverPrivate = (void *) intel_fb; - - return GL_TRUE; - } -} - -static void -intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) -{ - _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); -} - - -/** - * Get information about previous buffer swaps. - */ -static int -intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) -{ - struct intel_framebuffer *intel_fb; - - if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) - || (sInfo == NULL)) { - return -1; - } - - intel_fb = dPriv->driverPrivate; - sInfo->swap_count = intel_fb->swap_count; - sInfo->swap_ust = intel_fb->swap_ust; - sInfo->swap_missed_count = intel_fb->swap_missed_count; - - sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) - ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust) - : 0.0; - - return 0; -} - - -/* There are probably better ways to do this, such as an - * init-designated function to register chipids and createcontext - * functions. - */ -extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - - - - -static GLboolean -intelCreateContext(const __GLcontextModes * mesaVis, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate) -{ - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; - - switch (intelScreen->deviceID) { - /* Don't deal with i830 until texture work complete: - */ - case PCI_CHIP_845_G: - case PCI_CHIP_I830_M: - case PCI_CHIP_I855_GM: - case PCI_CHIP_I865_G: - return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); - - case PCI_CHIP_I915_G: - case PCI_CHIP_I915_GM: - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q35_G: - case PCI_CHIP_Q33_G: - return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate); - - default: - fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID); - return GL_FALSE; - } -} - - -static const struct __DriverAPIRec intelAPI = { - .InitDriver = intelInitDriver, - .DestroyScreen = intelDestroyScreen, - .CreateContext = intelCreateContext, - .DestroyContext = intelDestroyContext, - .CreateBuffer = intelCreateBuffer, - .DestroyBuffer = intelDestroyBuffer, - .SwapBuffers = intelSwapBuffers, - .MakeCurrent = intelMakeCurrent, - .UnbindContext = intelUnbindContext, - .GetSwapInfo = intelGetSwapInfo, - .GetMSC = driGetMSC32, - .WaitForMSC = driWaitForMSC32, - .WaitForSBC = NULL, - .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer, - .setTexOffset = intelSetTexOffset, -}; - - -static __GLcontextModes * -intelFillInModes(unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) -{ - __GLcontextModes *modes; - __GLcontextModes *m; - unsigned num_modes; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't - * support pageflipping at all. - */ - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML - }; - - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; - - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - if (depth_bits == 24) - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; - - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - num_modes = depth_buffer_factor * back_buffer_factor * 4; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - modes = - (*dri_interface->createContextModes) (num_modes, - sizeof(__GLcontextModes)); - m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_TRUE_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, GLX_DIRECT_COLOR)) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, - __LINE__); - return NULL; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for (m = modes; m != NULL; m = m->next) { - if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { - m->visualRating = GLX_SLOW_CONFIG; - } - } - - return modes; -} - - -/** - * This is the bootstrap function for the driver. libGL supplies all of the - * requisite information about the system, and the driver initializes itself. - * This routine also fills in the linked list pointed to by \c driver_modes - * with the \c __GLcontextModes that the driver can support for windows or - * pbuffers. - * - * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on - * failure. - */ -PUBLIC void * -__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, - __DRIscreen * psc, - const __GLcontextModes * modes, - const __DRIversion * ddx_version, - const __DRIversion * dri_version, - const __DRIversion * drm_version, - const __DRIframebuffer * frame_buffer, - drmAddress pSAREA, int fd, - int internal_api_version, - const __DRIinterfaceMethods * interface, - __GLcontextModes ** driver_modes) -{ - __DRIscreenPrivate *psp; - static const __DRIversion ddx_expected = { 1, 5, 0 }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 1, 5, 0 }; - - dri_interface = interface; - - if (!driCheckDriDdxDrmVersions2("i915", - dri_version, &dri_expected, - ddx_version, &ddx_expected, - drm_version, &drm_expected)) { - return NULL; - } - - psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, - ddx_version, dri_version, drm_version, - frame_buffer, pSAREA, fd, - internal_api_version, &intelAPI); - - if (psp != NULL) { - I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; - *driver_modes = intelFillInModes(dri_priv->cpp * 8, - (dri_priv->cpp == 2) ? 16 : 24, - (dri_priv->cpp == 2) ? 0 : 8, 1); - - /* Calling driInitExtensions here, with a NULL context pointer, does not actually - * enable the extensions. It just makes sure that all the dispatch offsets for all - * the extensions that *might* be enables are known. This is needed because the - * dispatch offsets need to be known when _mesa_context_create is called, but we can't - * enable the extensions until we have a context pointer. - * - * Hello chicken. Hello egg. How are you two today? - */ - driInitExtensions(NULL, card_extensions, GL_FALSE); - } - - return (void *) psp; -} - -struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) -{ - /* - * This should probably change to have the screen allocate a dummy - * context at screen creation. For now just use the current context. - */ - - GET_CURRENT_CONTEXT(ctx); - if (ctx == NULL) { - _mesa_problem(NULL, "No current context in intelScreenContext\n"); - return NULL; - } - return intel_context(ctx); -} - diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h deleted file mode 100644 index aa0ef2c509..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_screen.h +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _INTEL_INIT_H_ -#define _INTEL_INIT_H_ - -#include -#include "dri_util.h" -#include "intel_rotate.h" -#include "i830_common.h" -#include "xmlconfig.h" -#include "dri_bufmgr.h" - -/* XXX: change name or eliminate to avoid conflict with "struct - * intel_region"!!! - */ -typedef struct -{ - drm_handle_t handle; - drmSize size; /* region size in bytes */ - char *map; /* memory map */ - int offset; /* from start of video mem, in bytes */ - int pitch; /* row stride, in bytes */ - unsigned int bo_handle; /* buffer object id if available, or -1 */ -} intelRegion; - -typedef struct -{ - intelRegion front; - intelRegion back; - intelRegion third; - intelRegion rotated; - intelRegion depth; - intelRegion tex; - - struct intel_region *front_region; - struct intel_region *back_region; - struct intel_region *third_region; - struct intel_region *depth_region; - struct intel_region *rotated_region; - - int deviceID; - int width; - int height; - int mem; /* unused */ - - int cpp; /* for front and back buffers */ -/* int bitsPerPixel; */ - int fbFormat; /* XXX FBO: this is obsolete - remove after i830 updates */ - - int logTextureGranularity; - - __DRIscreenPrivate *driScrnPriv; - unsigned int sarea_priv_offset; - - int drmMinor; - - int irq_active; - int allow_batchbuffer; - - struct matrix23 rotMatrix; - - int current_rotation; /* 0, 90, 180 or 270 */ - int rotatedWidth, rotatedHeight; - - /** - * Configuration cache with default values for all contexts - */ - driOptionCache optionCache; - - dri_bufmgr *bufmgr; - unsigned int maxBatchSize; - - /** - * This value indicates that the kernel memory manager is being used - * instead of the fake client-side memory manager. - */ - GLboolean ttm; -} intelScreenPrivate; - - - -extern GLboolean intelMapScreenRegions(__DRIscreenPrivate * sPriv); - -extern void intelUnmapScreenRegions(intelScreenPrivate * intelScreen); - -extern void -intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, - drmI830Sarea * sarea); - -extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); - -extern GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); - -extern GLboolean -intelMakeCurrent(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); - -extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); - -extern void -intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); - -extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); - -extern void -intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_span.c b/src/mesa/drivers/dri/i915tex/intel_span.c deleted file mode 100644 index d1f8ef06be..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_span.c +++ /dev/null @@ -1,409 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "colormac.h" - -#include "intel_fbo.h" -#include "intel_screen.h" -#include "intel_span.h" -#include "intel_regions.h" -#include "intel_ioctl.h" -#include "intel_tex.h" - -#include "swrast/swrast.h" - -/* - break intelWriteRGBASpan_ARGB8888 -*/ - -#undef DBG -#define DBG 0 - -#define LOCAL_VARS \ - struct intel_context *intel = intel_context(ctx); \ - struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ - const GLint yScale = irb->RenderToTexture ? 1 : -1; \ - const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ - GLubyte *buf = (GLubyte *) irb->pfMap \ - + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\ - GLuint p; \ - assert(irb->pfMap);\ - (void) p; - -/* XXX FBO: this is identical to the macro in spantmp2.h except we get - * the cliprect info from the context, not the driDrawable. - * Move this into spantmp2.h someday. - */ -#define HW_CLIPLOOP() \ - do { \ - int _nc = intel->numClipRects; \ - while ( _nc-- ) { \ - int minx = intel->pClipRects[_nc].x1 - intel->drawX; \ - int miny = intel->pClipRects[_nc].y1 - intel->drawY; \ - int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \ - int maxy = intel->pClipRects[_nc].y2 - intel->drawY; - - - - -#define Y_FLIP(_y) ((_y) * yScale + yBias) - -#define HW_LOCK() - -#define HW_UNLOCK() - -/* 16 bit, RGB565 color spanline and pixel functions - */ -#define SPANTMP_PIXEL_FMT GL_RGB -#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 - -#define TAG(x) intel##x##_RGB565 -#define TAG2(x,y) intel##x##_RGB565##y -#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2) -#include "spantmp2.h" - -/* 32 bit, ARGB8888 color spanline and pixel functions - */ -#define SPANTMP_PIXEL_FMT GL_BGRA -#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV - -#define TAG(x) intel##x##_ARGB8888 -#define TAG2(x,y) intel##x##_ARGB8888##y -#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4) -#include "spantmp2.h" - - -#define LOCAL_DEPTH_VARS \ - struct intel_context *intel = intel_context(ctx); \ - struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ - const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \ - const GLint yScale = irb->RenderToTexture ? 1 : -1; \ - const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ - char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \ - (intel->drawY * pitch + intel->drawX) * irb->region->cpp; - - -#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS - -/** - ** 16-bit depthbuffer functions. - **/ -#define WRITE_DEPTH( _x, _y, d ) \ - ((GLushort *)buf)[(_x) + (_y) * pitch] = d; - -#define READ_DEPTH( d, _x, _y ) \ - d = ((GLushort *)buf)[(_x) + (_y) * pitch]; - - -#define TAG(x) intel##x##_z16 -#include "depthtmp.h" - - -/** - ** 24/8-bit interleaved depth/stencil functions - ** Note: we're actually reading back combined depth+stencil values. - ** The wrappers in main/depthstencil.c are used to extract the depth - ** and stencil values. - **/ -/* Change ZZZS -> SZZZ */ -#define WRITE_DEPTH( _x, _y, d ) { \ - GLuint tmp = ((d) >> 8) | ((d) << 24); \ - ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \ -} - -/* Change SZZZ -> ZZZS */ -#define READ_DEPTH( d, _x, _y ) { \ - GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ - d = (tmp << 8) | (tmp >> 24); \ -} - -#define TAG(x) intel##x##_z24_s8 -#include "depthtmp.h" - - -/** - ** 8-bit stencil function (XXX FBO: This is obsolete) - **/ -#define WRITE_STENCIL( _x, _y, d ) { \ - GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ - tmp &= 0xffffff; \ - tmp |= ((d) << 24); \ - ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \ -} - -#define READ_STENCIL( d, _x, _y ) \ - d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24; - -#define TAG(x) intel##x##_z24_s8 -#include "stenciltmp.h" - - - -/** - * Map or unmap all the renderbuffers which we may need during - * software rendering. - * XXX in the future, we could probably convey extra information to - * reduce the number of mappings needed. I.e. if doing a glReadPixels - * from the depth buffer, we really only need one mapping. - * - * XXX Rewrite this function someday. - * We can probably just loop over all the renderbuffer attachments, - * map/unmap all of them, and not worry about the _ColorDrawBuffers - * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields. - */ -static void -intel_map_unmap_buffers(struct intel_context *intel, GLboolean map) -{ - GLcontext *ctx = &intel->ctx; - GLuint i, j; - struct intel_renderbuffer *irb; - - /* color draw buffers */ - for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { - for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) { - struct gl_renderbuffer *rb = - ctx->DrawBuffer->_ColorDrawBuffers[i][j]; - irb = intel_renderbuffer(rb); - if (irb) { - /* this is a user-created intel_renderbuffer */ - if (irb->region) { - if (map) - intel_region_map(intel->intelScreen, irb->region); - else - intel_region_unmap(intel->intelScreen, irb->region); - irb->pfMap = irb->region->map; - irb->pfPitch = irb->region->pitch; - } - } - } - } - - /* check for render to textures */ - for (i = 0; i < BUFFER_COUNT; i++) { - struct gl_renderbuffer_attachment *att = - ctx->DrawBuffer->Attachment + i; - struct gl_texture_object *tex = att->Texture; - if (tex) { - /* render to texture */ - ASSERT(att->Renderbuffer); - if (map) { - struct gl_texture_image *texImg; - texImg = tex->Image[att->CubeMapFace][att->TextureLevel]; - intel_tex_map_images(intel, intel_texture_object(tex)); - } - else { - intel_tex_unmap_images(intel, intel_texture_object(tex)); - } - } - } - - /* color read buffers */ - irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); - if (irb && irb->region) { - if (map) - intel_region_map(intel->intelScreen, irb->region); - else - intel_region_unmap(intel->intelScreen, irb->region); - irb->pfMap = irb->region->map; - irb->pfPitch = irb->region->pitch; - } - - /* Account for front/back color page flipping. - * The span routines use the pfMap and pfPitch fields which will - * swap the front/back region map/pitch if we're page flipped. - * Do this after mapping, above, so the map field is valid. - */ -#if 0 - if (map && ctx->DrawBuffer->Name == 0) { - struct intel_renderbuffer *irbFront - = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT); - struct intel_renderbuffer *irbBack - = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT); - if (irbBack) { - /* double buffered */ - if (intel->sarea->pf_current_page == 0) { - irbFront->pfMap = irbFront->region->map; - irbFront->pfPitch = irbFront->region->pitch; - irbBack->pfMap = irbBack->region->map; - irbBack->pfPitch = irbBack->region->pitch; - } - else { - irbFront->pfMap = irbBack->region->map; - irbFront->pfPitch = irbBack->region->pitch; - irbBack->pfMap = irbFront->region->map; - irbBack->pfPitch = irbFront->region->pitch; - } - } - } -#endif - - /* depth buffer (Note wrapper!) */ - if (ctx->DrawBuffer->_DepthBuffer) { - irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); - if (irb && irb->region && irb->Base.Name != 0) { - if (map) { - intel_region_map(intel->intelScreen, irb->region); - irb->pfMap = irb->region->map; - irb->pfPitch = irb->region->pitch; - } - else { - intel_region_unmap(intel->intelScreen, irb->region); - irb->pfMap = NULL; - irb->pfPitch = 0; - } - } - } - - /* stencil buffer (Note wrapper!) */ - if (ctx->DrawBuffer->_StencilBuffer) { - irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); - if (irb && irb->region && irb->Base.Name != 0) { - if (map) { - intel_region_map(intel->intelScreen, irb->region); - irb->pfMap = irb->region->map; - irb->pfPitch = irb->region->pitch; - } - else { - intel_region_unmap(intel->intelScreen, irb->region); - irb->pfMap = NULL; - irb->pfPitch = 0; - } - } - } -} - - - -/** - * Prepare for softare rendering. Map current read/draw framebuffers' - * renderbuffes and all currently bound texture objects. - * - * Old note: Moved locking out to get reasonable span performance. - */ -void -intelSpanRenderStart(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - GLuint i; - - intelFinish(&intel->ctx); - LOCK_HARDWARE(intel); - -#if 0 - /* Just map the framebuffer and all textures. Bufmgr code will - * take care of waiting on the necessary fences: - */ - intel_region_map(intel->intelScreen, intel->front_region); - intel_region_map(intel->intelScreen, intel->back_region); - intel_region_map(intel->intelScreen, intel->intelScreen->depth_region); -#endif - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled) { - struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; - intel_tex_map_images(intel, intel_texture_object(texObj)); - } - } - - intel_map_unmap_buffers(intel, GL_TRUE); -} - -/** - * Called when done softare rendering. Unmap the buffers we mapped in - * the above function. - */ -void -intelSpanRenderFinish(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - GLuint i; - - _swrast_flush(ctx); - - /* Now unmap the framebuffer: - */ -#if 0 - intel_region_unmap(intel, intel->front_region); - intel_region_unmap(intel, intel->back_region); - intel_region_unmap(intel, intel->intelScreen->depth_region); -#endif - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled) { - struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; - intel_tex_unmap_images(intel, intel_texture_object(texObj)); - } - } - - intel_map_unmap_buffers(intel, GL_FALSE); - - UNLOCK_HARDWARE(intel); -} - - -void -intelInitSpanFuncs(GLcontext * ctx) -{ - struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); - swdd->SpanRenderStart = intelSpanRenderStart; - swdd->SpanRenderFinish = intelSpanRenderFinish; -} - - -/** - * Plug in appropriate span read/write functions for the given renderbuffer. - * These are used for the software fallbacks. - */ -void -intel_set_span_functions(struct gl_renderbuffer *rb) -{ - if (rb->_ActualFormat == GL_RGB5) { - /* 565 RGB */ - intelInitPointers_RGB565(rb); - } - else if (rb->_ActualFormat == GL_RGBA8) { - /* 8888 RGBA */ - intelInitPointers_ARGB8888(rb); - } - else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) { - intelInitDepthPointers_z16(rb); - } - else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */ - rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { - intelInitDepthPointers_z24_s8(rb); - } - else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { /* XXX FBO remove */ - intelInitStencilPointers_z24_s8(rb); - } - else { - _mesa_problem(NULL, - "Unexpected _ActualFormat in intelSetSpanFunctions"); - } -} diff --git a/src/mesa/drivers/dri/i915tex/intel_span.h b/src/mesa/drivers/dri/i915tex/intel_span.h deleted file mode 100644 index 5201f6d6c6..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_span.h +++ /dev/null @@ -1,38 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef _INTEL_SPAN_H -#define _INTEL_SPAN_H - -extern void intelInitSpanFuncs(GLcontext * ctx); - -extern void intelSpanRenderFinish(GLcontext * ctx); -extern void intelSpanRenderStart(GLcontext * ctx); - -extern void intel_set_span_functions(struct gl_renderbuffer *rb); - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c b/src/mesa/drivers/dri/i915tex/intel_state.c deleted file mode 100644 index 271511037e..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_state.c +++ /dev/null @@ -1,269 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "colormac.h" -#include "dd.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_fbo.h" -#include "intel_regions.h" -#include "swrast/swrast.h" - -int -intel_translate_compare_func(GLenum func) -{ - switch (func) { - case GL_NEVER: - return COMPAREFUNC_NEVER; - case GL_LESS: - return COMPAREFUNC_LESS; - case GL_LEQUAL: - return COMPAREFUNC_LEQUAL; - case GL_GREATER: - return COMPAREFUNC_GREATER; - case GL_GEQUAL: - return COMPAREFUNC_GEQUAL; - case GL_NOTEQUAL: - return COMPAREFUNC_NOTEQUAL; - case GL_EQUAL: - return COMPAREFUNC_EQUAL; - case GL_ALWAYS: - return COMPAREFUNC_ALWAYS; - } - - fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); - return COMPAREFUNC_ALWAYS; -} - -int -intel_translate_stencil_op(GLenum op) -{ - switch (op) { - case GL_KEEP: - return STENCILOP_KEEP; - case GL_ZERO: - return STENCILOP_ZERO; - case GL_REPLACE: - return STENCILOP_REPLACE; - case GL_INCR: - return STENCILOP_INCRSAT; - case GL_DECR: - return STENCILOP_DECRSAT; - case GL_INCR_WRAP: - return STENCILOP_INCR; - case GL_DECR_WRAP: - return STENCILOP_DECR; - case GL_INVERT: - return STENCILOP_INVERT; - default: - return STENCILOP_ZERO; - } -} - -int -intel_translate_blend_factor(GLenum factor) -{ - switch (factor) { - case GL_ZERO: - return BLENDFACT_ZERO; - case GL_SRC_ALPHA: - return BLENDFACT_SRC_ALPHA; - case GL_ONE: - return BLENDFACT_ONE; - case GL_SRC_COLOR: - return BLENDFACT_SRC_COLR; - case GL_ONE_MINUS_SRC_COLOR: - return BLENDFACT_INV_SRC_COLR; - case GL_DST_COLOR: - return BLENDFACT_DST_COLR; - case GL_ONE_MINUS_DST_COLOR: - return BLENDFACT_INV_DST_COLR; - case GL_ONE_MINUS_SRC_ALPHA: - return BLENDFACT_INV_SRC_ALPHA; - case GL_DST_ALPHA: - return BLENDFACT_DST_ALPHA; - case GL_ONE_MINUS_DST_ALPHA: - return BLENDFACT_INV_DST_ALPHA; - case GL_SRC_ALPHA_SATURATE: - return BLENDFACT_SRC_ALPHA_SATURATE; - case GL_CONSTANT_COLOR: - return BLENDFACT_CONST_COLOR; - case GL_ONE_MINUS_CONSTANT_COLOR: - return BLENDFACT_INV_CONST_COLOR; - case GL_CONSTANT_ALPHA: - return BLENDFACT_CONST_ALPHA; - case GL_ONE_MINUS_CONSTANT_ALPHA: - return BLENDFACT_INV_CONST_ALPHA; - } - - fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor); - return BLENDFACT_ZERO; -} - -int -intel_translate_logic_op(GLenum opcode) -{ - switch (opcode) { - case GL_CLEAR: - return LOGICOP_CLEAR; - case GL_AND: - return LOGICOP_AND; - case GL_AND_REVERSE: - return LOGICOP_AND_RVRSE; - case GL_COPY: - return LOGICOP_COPY; - case GL_COPY_INVERTED: - return LOGICOP_COPY_INV; - case GL_AND_INVERTED: - return LOGICOP_AND_INV; - case GL_NOOP: - return LOGICOP_NOOP; - case GL_XOR: - return LOGICOP_XOR; - case GL_OR: - return LOGICOP_OR; - case GL_OR_INVERTED: - return LOGICOP_OR_INV; - case GL_NOR: - return LOGICOP_NOR; - case GL_EQUIV: - return LOGICOP_EQUIV; - case GL_INVERT: - return LOGICOP_INV; - case GL_OR_REVERSE: - return LOGICOP_OR_RVRSE; - case GL_NAND: - return LOGICOP_NAND; - case GL_SET: - return LOGICOP_SET; - default: - return LOGICOP_SET; - } -} - - -static void -intelClearColor(GLcontext * ctx, const GLfloat color[4]) -{ - struct intel_context *intel = intel_context(ctx); - GLubyte clear[4]; - - CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); - - /* compute both 32 and 16-bit clear values */ - intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], - clear[2], clear[3]); - intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); -} - - -/** - * Update the viewport transformation matrix. Depends on: - * - viewport pos/size - * - depthrange - * - window pos/size or FBO size - */ -static void -intelCalcViewport(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - const GLfloat *v = ctx->Viewport._WindowMap.m; - const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; - GLfloat *m = intel->ViewportMatrix.m; - GLfloat yScale, yBias; - - if (ctx->DrawBuffer->Name) { - /* User created FBO */ - struct intel_renderbuffer *irb - = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]); - if (irb && !irb->RenderToTexture) { - /* y=0=top */ - yScale = -1.0; - yBias = irb->Base.Height; - } - else { - /* y=0=bottom */ - yScale = 1.0; - yBias = 0.0; - } - } - else { - /* window buffer, y=0=top */ - yScale = -1.0; - yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; - } - - m[MAT_SX] = v[MAT_SX]; - m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; - - m[MAT_SY] = v[MAT_SY] * yScale; - m[MAT_TY] = v[MAT_TY] * yScale + yBias + SUBPIXEL_Y; - - m[MAT_SZ] = v[MAT_SZ] * depthScale; - m[MAT_TZ] = v[MAT_TZ] * depthScale; -} - -static void -intelViewport(GLcontext * ctx, - GLint x, GLint y, GLsizei width, GLsizei height) -{ - intelCalcViewport(ctx); -} - -static void -intelDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) -{ - intelCalcViewport(ctx); -} - -/* Fallback to swrast for select and feedback. - */ -static void -intelRenderMode(GLcontext * ctx, GLenum mode) -{ - struct intel_context *intel = intel_context(ctx); - FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); -} - - -void -intelInitStateFuncs(struct dd_function_table *functions) -{ - functions->RenderMode = intelRenderMode; - functions->Viewport = intelViewport; - functions->DepthRange = intelDepthRange; - functions->ClearColor = intelClearColor; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_structs.h b/src/mesa/drivers/dri/i915tex/intel_structs.h deleted file mode 100644 index 522e3bd92c..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_structs.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef INTEL_STRUCTS_H -#define INTEL_STRUCTS_H - -struct br0 { - GLuint length:8; - GLuint pad0:3; - GLuint dst_tiled:1; - GLuint pad1:8; - GLuint write_rgb:1; - GLuint write_alpha:1; - GLuint opcode:7; - GLuint client:3; -}; - - -struct br13 { - GLint dest_pitch:16; - GLuint rop:8; - GLuint color_depth:2; - GLuint pad1:3; - GLuint mono_source_transparency:1; - GLuint clipping_enable:1; - GLuint pad0:1; -}; - - - -/* This is an attempt to move some of the 2D interaction in this - * driver to using structs for packets rather than a bunch of #defines - * and dwords. - */ -struct xy_color_blit { - struct br0 br0; - struct br13 br13; - - struct { - GLuint dest_x1:16; - GLuint dest_y1:16; - } dw2; - - struct { - GLuint dest_x2:16; - GLuint dest_y2:16; - } dw3; - - GLuint dest_base_addr; - GLuint color; -}; - -struct xy_src_copy_blit { - struct br0 br0; - struct br13 br13; - - struct { - GLuint dest_x1:16; - GLuint dest_y1:16; - } dw2; - - struct { - GLuint dest_x2:16; - GLuint dest_y2:16; - } dw3; - - GLuint dest_base_addr; - - struct { - GLuint src_x1:16; - GLuint src_y1:16; - } dw5; - - struct { - GLint src_pitch:16; - GLuint pad:16; - } dw6; - - GLuint src_base_addr; -}; - -struct xy_setup_blit { - struct br0 br0; - struct br13 br13; - - struct { - GLuint clip_x1:16; - GLuint clip_y1:16; - } dw2; - - struct { - GLuint clip_x2:16; - GLuint clip_y2:16; - } dw3; - - GLuint dest_base_addr; - GLuint background_color; - GLuint foreground_color; - GLuint pattern_base_addr; -}; - - -struct xy_text_immediate_blit { - struct { - GLuint length:8; - GLuint pad2:3; - GLuint dst_tiled:1; - GLuint pad1:4; - GLuint byte_packed:1; - GLuint pad0:5; - GLuint opcode:7; - GLuint client:3; - } dw0; - - struct { - GLuint dest_x1:16; - GLuint dest_y1:16; - } dw1; - - struct { - GLuint dest_x2:16; - GLuint dest_y2:16; - } dw2; - - /* Src bitmap data follows as inline dwords. - */ -}; - - -#define CLIENT_2D 0x2 -#define OPCODE_XY_SETUP_BLT 0x1 -#define OPCODE_XY_COLOR_BLT 0x50 -#define OPCODE_XY_TEXT_IMMEDIATE_BLT 0x31 - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.c b/src/mesa/drivers/dri/i915tex/intel_tex.c deleted file mode 100644 index b08dee43bc..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex.c +++ /dev/null @@ -1,192 +0,0 @@ -#include "texobj.h" -#include "intel_context.h" -#include "intel_mipmap_tree.h" -#include "intel_tex.h" - -#define FILE_DEBUG_FLAG DEBUG_TEXTURE - -static GLboolean -intelIsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) -{ -#if 0 - struct intel_context *intel = intel_context(ctx); - struct intel_texture_object *intelObj = intel_texture_object(texObj); - - return - intelObj->mt && - intelObj->mt->region && - intel_is_region_resident(intel, intelObj->mt->region); -#endif - return 1; -} - - - -static struct gl_texture_image * -intelNewTextureImage(GLcontext * ctx) -{ - DBG("%s\n", __FUNCTION__); - (void) ctx; - return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); -} - - -static struct gl_texture_object * -intelNewTextureObject(GLcontext * ctx, GLuint name, GLenum target) -{ - struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); - - DBG("%s\n", __FUNCTION__); - _mesa_initialize_texture_object(&obj->base, name, target); - - return &obj->base; -} - -static void -intelDeleteTextureObject(GLcontext *ctx, - struct gl_texture_object *texObj) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_object *intelObj = intel_texture_object(texObj); - - if (intelObj->mt) - intel_miptree_release(intel, &intelObj->mt); - - _mesa_delete_texture_object(ctx, texObj); -} - - -static void -intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_image *intelImage = intel_texture_image(texImage); - - DBG("%s\n", __FUNCTION__); - - if (intelImage->mt) { - intel_miptree_release(intel, &intelImage->mt); - } - - if (texImage->Data) { - free(texImage->Data); - texImage->Data = NULL; - } -} - - -/* The system memcpy (at least on ubuntu 5.10) has problems copying - * to agp (writecombined) memory from a source which isn't 64-byte - * aligned - there is a 4x performance falloff. - * - * The x86 __memcpy is immune to this but is slightly slower - * (10%-ish) than the system memcpy. - * - * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but - * isn't much faster than x86_memcpy for agp copies. - * - * TODO: switch dynamically. - */ -static void * -do_memcpy(void *dest, const void *src, size_t n) -{ - if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { - return __memcpy(dest, src, n); - } - else - return memcpy(dest, src, n); -} - - -#if DO_DEBUG - -#ifndef __x86_64__ -static unsigned -fastrdtsc(void) -{ - unsigned eax; - __asm__ volatile ("\t" - "pushl %%ebx\n\t" - "cpuid\n\t" ".byte 0x0f, 0x31\n\t" - "popl %%ebx\n":"=a" (eax) - :"0"(0) - :"ecx", "edx", "cc"); - - return eax; -} -#else -static unsigned -fastrdtsc(void) -{ - unsigned eax; - __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax) - :"0"(0) - :"ecx", "edx", "ebx", "cc"); - - return eax; -} -#endif - -static unsigned -time_diff(unsigned t, unsigned t2) -{ - return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1)); -} - - -static void * -timed_memcpy(void *dest, const void *src, size_t n) -{ - void *ret; - unsigned t1, t2; - double rate; - - if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) - _mesa_printf("Warning - non-aligned texture copy!\n"); - - t1 = fastrdtsc(); - ret = do_memcpy(dest, src, n); - t2 = fastrdtsc(); - - rate = time_diff(t1, t2); - rate /= (double) n; - _mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate); - return ret; -} -#endif /* DO_DEBUG */ - - -void -intelInitTextureFuncs(struct dd_function_table *functions) -{ - functions->ChooseTextureFormat = intelChooseTextureFormat; - functions->TexImage1D = intelTexImage1D; - functions->TexImage2D = intelTexImage2D; - functions->TexImage3D = intelTexImage3D; - functions->TexSubImage1D = intelTexSubImage1D; - functions->TexSubImage2D = intelTexSubImage2D; - functions->TexSubImage3D = intelTexSubImage3D; - functions->CopyTexImage1D = intelCopyTexImage1D; - functions->CopyTexImage2D = intelCopyTexImage2D; - functions->CopyTexSubImage1D = intelCopyTexSubImage1D; - functions->CopyTexSubImage2D = intelCopyTexSubImage2D; - functions->GetTexImage = intelGetTexImage; - - /* compressed texture functions */ - functions->CompressedTexImage2D = intelCompressedTexImage2D; - functions->GetCompressedTexImage = intelGetCompressedTexImage; - - functions->NewTextureObject = intelNewTextureObject; - functions->NewTextureImage = intelNewTextureImage; - functions->DeleteTexture = intelDeleteTextureObject; - functions->FreeTexImageData = intelFreeTextureImageData; - functions->UpdateTexturePalette = 0; - functions->IsTextureResident = intelIsTextureResident; - -#if DO_DEBUG - if (INTEL_DEBUG & DEBUG_BUFMGR) - functions->TextureMemCpy = timed_memcpy; - else -#endif - functions->TextureMemCpy = do_memcpy; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h deleted file mode 100644 index b77d7a1d8a..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex.h +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTELTEX_INC -#define INTELTEX_INC - -#include "mtypes.h" -#include "intel_context.h" -#include "texmem.h" - - -void intelInitTextureFuncs(struct dd_function_table *functions); - -const struct gl_texture_format *intelChooseTextureFormat(GLcontext * ctx, - GLint internalFormat, - GLenum format, - GLenum type); - - -void intelTexImage3D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexSubImage3D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexImage2D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexSubImage2D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexImage1D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelTexSubImage1D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLint border); - -void intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border); - -void intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint x, GLint y, GLsizei width); - -void intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, GLsizei width, GLsizei height); - -void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage); - -void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ); - -void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, - GLvoid *pixels, - const struct gl_texture_object *texObj, - const struct gl_texture_image *texImage); - -void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, - unsigned long long offset, GLint depth, GLuint pitch); - -GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); - -void intel_tex_map_images(struct intel_context *intel, - struct intel_texture_object *intelObj); - -void intel_tex_unmap_images(struct intel_context *intel, - struct intel_texture_object *intelObj); - -int intel_compressed_num_bytes(GLuint mesaFormat); - -#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_copy.c b/src/mesa/drivers/dri/i915tex/intel_tex_copy.c deleted file mode 100644 index b85a25642a..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex_copy.c +++ /dev/null @@ -1,302 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "mtypes.h" -#include "enums.h" -#include "image.h" -#include "teximage.h" -#include "swrast/swrast.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_buffers.h" -#include "intel_mipmap_tree.h" -#include "intel_regions.h" -#include "intel_fbo.h" -#include "intel_tex.h" -#include "intel_blit.h" -#include "intel_pixel.h" - -#define FILE_DEBUG_FLAG DEBUG_TEXTURE - -/** - * Get the intel_region which is the source for any glCopyTex[Sub]Image call. - * - * Do the best we can using the blitter. A future project is to use - * the texture engine and fragment programs for these copies. - */ -static const struct intel_region * -get_teximage_source(struct intel_context *intel, GLenum internalFormat) -{ - struct intel_renderbuffer *irb; - - DBG("%s %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(internalFormat)); - - switch (internalFormat) { - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16_ARB: - irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); - if (irb && irb->region && irb->region->cpp == 2) - return irb->region; - return NULL; - case GL_DEPTH24_STENCIL8_EXT: - case GL_DEPTH_STENCIL_EXT: - irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); - if (irb && irb->region && irb->region->cpp == 4) - return irb->region; - return NULL; - case GL_RGBA: - case GL_RGBA8: - return intel_readbuf_region(intel); - case GL_RGB: - if (intel->intelScreen->cpp == 2) - return intel_readbuf_region(intel); - return NULL; - default: - return NULL; - } -} - - -static GLboolean -do_copy_texsubimage(struct intel_context *intel, - struct intel_texture_image *intelImage, - GLenum internalFormat, - GLint dstx, GLint dsty, - GLint x, GLint y, GLsizei width, GLsizei height) -{ - GLcontext *ctx = &intel->ctx; - const struct intel_region *src = - get_teximage_source(intel, internalFormat); - - if (!intelImage->mt || !src) { - DBG("%s fail %p %p\n", __FUNCTION__, intelImage->mt, src); - return GL_FALSE; - } - - intelFlush(ctx); - LOCK_HARDWARE(intel); - { - GLuint image_offset = intel_miptree_image_offset(intelImage->mt, - intelImage->face, - intelImage->level); - const GLint orig_x = x; - const GLint orig_y = y; - const struct gl_framebuffer *fb = ctx->DrawBuffer; - - if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, - &x, &y, &width, &height)) { - /* Update dst for clipped src. Need to also clip the source rect. - */ - dstx += x - orig_x; - dsty += y - orig_y; - - if (ctx->ReadBuffer->Name == 0) { - /* reading from a window, adjust x, y */ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - GLuint window_y; - /* window_y = position of window on screen if y=0=bottom */ - window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); - y = window_y + y; - x += dPriv->x; - } - else { - /* reading from a FBO */ - /* invert Y */ - y = ctx->ReadBuffer->Height - y - 1; - } - - - /* A bit of fiddling to get the blitter to work with -ve - * pitches. But we get a nice inverted blit this way, so it's - * worth it: - */ - intelEmitCopyBlit(intel, - intelImage->mt->cpp, - -src->pitch, - src->buffer, - src->height * src->pitch * src->cpp, - intelImage->mt->pitch, - intelImage->mt->region->buffer, - image_offset, - x, y + height, dstx, dsty, width, height, - GL_COPY); /* ? */ - - intel_batchbuffer_flush(intel->batch); - } - } - - - UNLOCK_HARDWARE(intel); - -#if 0 - /* GL_SGIS_generate_mipmap -- this can be accelerated now. - * XXX Add a ctx->Driver.GenerateMipmaps() function? - */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } -#endif - - return GL_TRUE; -} - - - - - -void -intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLint border) -{ - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_object *texObj = - _mesa_select_tex_object(ctx, texUnit, target); - struct gl_texture_image *texImage = - _mesa_select_tex_image(ctx, texObj, target, level); - - if (border) - goto fail; - - /* Setup or redefine the texture object, mipmap tree and texture - * image. Don't populate yet. - */ - ctx->Driver.TexImage1D(ctx, target, level, internalFormat, - width, border, - GL_RGBA, CHAN_TYPE, NULL, - &ctx->DefaultPacking, texObj, texImage); - - if (!do_copy_texsubimage(intel_context(ctx), - intel_texture_image(texImage), - internalFormat, 0, 0, x, y, width, 1)) - goto fail; - - return; - - fail: - _swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y, - width, border); -} - -void -intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border) -{ - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_object *texObj = - _mesa_select_tex_object(ctx, texUnit, target); - struct gl_texture_image *texImage = - _mesa_select_tex_image(ctx, texObj, target, level); - - if (border) - goto fail; - - /* Setup or redefine the texture object, mipmap tree and texture - * image. Don't populate yet. - */ - ctx->Driver.TexImage2D(ctx, target, level, internalFormat, - width, height, border, - GL_RGBA, CHAN_TYPE, NULL, - &ctx->DefaultPacking, texObj, texImage); - - - if (!do_copy_texsubimage(intel_context(ctx), - intel_texture_image(texImage), - internalFormat, 0, 0, x, y, width, height)) - goto fail; - - return; - - fail: - _swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y, - width, height, border); -} - - -void -intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint x, GLint y, GLsizei width) -{ - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_object *texObj = - _mesa_select_tex_object(ctx, texUnit, target); - struct gl_texture_image *texImage = - _mesa_select_tex_image(ctx, texObj, target, level); - GLenum internalFormat = texImage->InternalFormat; - - /* XXX need to check as in above function? */ - - /* Need to check texture is compatible with source format. - */ - - if (!do_copy_texsubimage(intel_context(ctx), - intel_texture_image(texImage), - internalFormat, xoffset, 0, x, y, width, 1)) { - _swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width); - } -} - - - -void -intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, GLsizei width, GLsizei height) -{ - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_object *texObj = - _mesa_select_tex_object(ctx, texUnit, target); - struct gl_texture_image *texImage = - _mesa_select_tex_image(ctx, texObj, target, level); - GLenum internalFormat = texImage->InternalFormat; - - - /* Need to check texture is compatible with source format. - */ - - if (!do_copy_texsubimage(intel_context(ctx), - intel_texture_image(texImage), - internalFormat, - xoffset, yoffset, x, y, width, height)) { - - DBG("%s - fallback to swrast\n", __FUNCTION__); - - _swrast_copy_texsubimage2d(ctx, target, level, - xoffset, yoffset, x, y, width, height); - } -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_format.c b/src/mesa/drivers/dri/i915tex/intel_tex_format.c deleted file mode 100644 index 6e058dff69..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex_format.c +++ /dev/null @@ -1,172 +0,0 @@ -#include "intel_context.h" -#include "intel_tex.h" -#include "texformat.h" -#include "enums.h" - -/* It works out that this function is fine for all the supported - * hardware. However, there is still a need to map the formats onto - * hardware descriptors. - */ -/* Note that the i915 can actually support many more formats than - * these if we take the step of simply swizzling the colors - * immediately after sampling... - */ -const struct gl_texture_format * -intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, - GLenum format, GLenum type) -{ - struct intel_context *intel = intel_context(ctx); - const GLboolean do32bpt = (intel->intelScreen->cpp == 4); - - switch (internalFormat) { - case 4: - case GL_RGBA: - case GL_COMPRESSED_RGBA: - if (format == GL_BGRA) { - if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) { - return &_mesa_texformat_argb8888; - } - else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { - return &_mesa_texformat_argb4444; - } - else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - return &_mesa_texformat_argb1555; - } - } - return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; - - case 3: - case GL_RGB: - case GL_COMPRESSED_RGB: - if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { - return &_mesa_texformat_rgb565; - } - return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; - - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; - - case GL_RGBA4: - case GL_RGBA2: - return &_mesa_texformat_argb4444; - - case GL_RGB5_A1: - return &_mesa_texformat_argb1555; - - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - return &_mesa_texformat_argb8888; - - case GL_RGB5: - case GL_RGB4: - case GL_R3_G3_B2: - return &_mesa_texformat_rgb565; - - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - case GL_COMPRESSED_ALPHA: - return &_mesa_texformat_a8; - - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - case GL_COMPRESSED_LUMINANCE: - return &_mesa_texformat_l8; - - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - case GL_COMPRESSED_LUMINANCE_ALPHA: - return &_mesa_texformat_al88; - - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - case GL_COMPRESSED_INTENSITY: - return &_mesa_texformat_i8; - - case GL_YCBCR_MESA: - if (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE) - return &_mesa_texformat_ycbcr; - else - return &_mesa_texformat_ycbcr_rev; - - case GL_COMPRESSED_RGB_FXT1_3DFX: - return &_mesa_texformat_rgb_fxt1; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return &_mesa_texformat_rgba_fxt1; - - case GL_RGB_S3TC: - case GL_RGB4_S3TC: - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return &_mesa_texformat_rgb_dxt1; - - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return &_mesa_texformat_rgba_dxt1; - - case GL_RGBA_S3TC: - case GL_RGBA4_S3TC: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - return &_mesa_texformat_rgba_dxt3; - - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return &_mesa_texformat_rgba_dxt5; - - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - return &_mesa_texformat_z16; - - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: - return &_mesa_texformat_z24_s8; - - default: - fprintf(stderr, "unexpected texture format %s in %s\n", - _mesa_lookup_enum_by_nr(internalFormat), __FUNCTION__); - return NULL; - } - - return NULL; /* never get here */ -} - -int intel_compressed_num_bytes(GLuint mesaFormat) -{ - int bytes = 0; - switch(mesaFormat) { - - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - case MESA_FORMAT_RGB_DXT1: - case MESA_FORMAT_RGBA_DXT1: - bytes = 2; - break; - - case MESA_FORMAT_RGBA_DXT3: - case MESA_FORMAT_RGBA_DXT5: - bytes = 4; - default: - break; - } - - return bytes; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c deleted file mode 100644 index 197cf35ebe..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c +++ /dev/null @@ -1,690 +0,0 @@ - -#include -#include - -#include "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "enums.h" -#include "colortab.h" -#include "convolve.h" -#include "context.h" -#include "simple_list.h" -#include "texcompress.h" -#include "texformat.h" -#include "texobj.h" -#include "texstore.h" - -#include "intel_context.h" -#include "intel_mipmap_tree.h" -#include "intel_buffer_objects.h" -#include "intel_batchbuffer.h" -#include "intel_tex.h" -#include "intel_ioctl.h" -#include "intel_blit.h" - -#define FILE_DEBUG_FLAG DEBUG_TEXTURE - -/* Functions to store texture images. Where possible, mipmap_tree's - * will be created or further instantiated with image data, otherwise - * images will be stored in malloc'd memory. A validation step is - * required to pull those images into a mipmap tree, or otherwise - * decide a fallback is required. - */ - - -static int -logbase2(int n) -{ - GLint i = 1; - GLint log2 = 0; - - while (n > i) { - i *= 2; - log2++; - } - - return log2; -} - - -/* Otherwise, store it in memory if (Border != 0) or (any dimension == - * 1). - * - * Otherwise, if max_level >= level >= min_level, create tree with - * space for textures from min_level down to max_level. - * - * Otherwise, create tree with space for textures from (level - * 0)..(1x1). Consider pruning this tree at a validation if the - * saving is worth it. - */ -static void -guess_and_alloc_mipmap_tree(struct intel_context *intel, - struct intel_texture_object *intelObj, - struct intel_texture_image *intelImage) -{ - GLuint firstLevel; - GLuint lastLevel; - GLuint width = intelImage->base.Width; - GLuint height = intelImage->base.Height; - GLuint depth = intelImage->base.Depth; - GLuint l2width, l2height, l2depth; - GLuint i, comp_byte = 0; - - DBG("%s\n", __FUNCTION__); - - if (intelImage->base.Border) - return; - - if (intelImage->level > intelObj->base.BaseLevel && - (intelImage->base.Width == 1 || - (intelObj->base.Target != GL_TEXTURE_1D && - intelImage->base.Height == 1) || - (intelObj->base.Target == GL_TEXTURE_3D && - intelImage->base.Depth == 1))) - return; - - /* If this image disrespects BaseLevel, allocate from level zero. - * Usually BaseLevel == 0, so it's unlikely to happen. - */ - if (intelImage->level < intelObj->base.BaseLevel) - firstLevel = 0; - else - firstLevel = intelObj->base.BaseLevel; - - - /* Figure out image dimensions at start level. - */ - for (i = intelImage->level; i > firstLevel; i--) { - width <<= 1; - if (height != 1) - height <<= 1; - if (depth != 1) - depth <<= 1; - } - - /* Guess a reasonable value for lastLevel. This is probably going - * to be wrong fairly often and might mean that we have to look at - * resizable buffers, or require that buffers implement lazy - * pagetable arrangements. - */ - if ((intelObj->base.MinFilter == GL_NEAREST || - intelObj->base.MinFilter == GL_LINEAR) && - intelImage->level == firstLevel) { - lastLevel = firstLevel; - } - else { - l2width = logbase2(width); - l2height = logbase2(height); - l2depth = logbase2(depth); - lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); - } - - assert(!intelObj->mt); - if (intelImage->base.IsCompressed) - comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat); - intelObj->mt = intel_miptree_create(intel, - intelObj->base.Target, - intelImage->base.InternalFormat, - firstLevel, - lastLevel, - width, - height, - depth, - intelImage->base.TexFormat->TexelBytes, - comp_byte); - - DBG("%s - success\n", __FUNCTION__); -} - - - - -static GLuint -target_to_face(GLenum target) -{ - switch (target) { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); - default: - return 0; - } -} - -/* There are actually quite a few combinations this will work for, - * more than what I've listed here. - */ -static GLboolean -check_pbo_format(GLint internalFormat, - GLenum format, GLenum type, - const struct gl_texture_format *mesa_format) -{ - switch (internalFormat) { - case 4: - case GL_RGBA: - return (format == GL_BGRA && - (type == GL_UNSIGNED_BYTE || - type == GL_UNSIGNED_INT_8_8_8_8_REV) && - mesa_format == &_mesa_texformat_argb8888); - case 3: - case GL_RGB: - return (format == GL_RGB && - type == GL_UNSIGNED_SHORT_5_6_5 && - mesa_format == &_mesa_texformat_rgb565); - case GL_YCBCR_MESA: - return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); - default: - return GL_FALSE; - } -} - - -/* XXX: Do this for TexSubImage also: - */ -static GLboolean -try_pbo_upload(struct intel_context *intel, - struct intel_texture_image *intelImage, - const struct gl_pixelstore_attrib *unpack, - GLint internalFormat, - GLint width, GLint height, - GLenum format, GLenum type, const void *pixels) -{ - struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); - GLuint src_offset, src_stride; - GLuint dst_offset, dst_stride; - - if (!pbo || - intel->ctx._ImageTransferState || - unpack->SkipPixels || unpack->SkipRows) { - _mesa_printf("%s: failure 1\n", __FUNCTION__); - return GL_FALSE; - } - - src_offset = (GLuint) pixels; - - if (unpack->RowLength > 0) - src_stride = unpack->RowLength; - else - src_stride = width; - - dst_offset = intel_miptree_image_offset(intelImage->mt, - intelImage->face, - intelImage->level); - - dst_stride = intelImage->mt->pitch; - - intelFlush(&intel->ctx); - LOCK_HARDWARE(intel); - { - dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); - dri_bo *dst_buffer = intel_region_buffer(intel->intelScreen, - intelImage->mt->region, - INTEL_WRITE_FULL); - - - intelEmitCopyBlit(intel, - intelImage->mt->cpp, - src_stride, src_buffer, src_offset, - dst_stride, dst_buffer, dst_offset, - 0, 0, 0, 0, width, height, - GL_COPY); - - intel_batchbuffer_flush(intel->batch); - } - UNLOCK_HARDWARE(intel); - - return GL_TRUE; -} - - - -static GLboolean -try_pbo_zcopy(struct intel_context *intel, - struct intel_texture_image *intelImage, - const struct gl_pixelstore_attrib *unpack, - GLint internalFormat, - GLint width, GLint height, - GLenum format, GLenum type, const void *pixels) -{ - struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); - GLuint src_offset, src_stride; - GLuint dst_offset, dst_stride; - - if (!pbo || - intel->ctx._ImageTransferState || - unpack->SkipPixels || unpack->SkipRows) { - _mesa_printf("%s: failure 1\n", __FUNCTION__); - return GL_FALSE; - } - - src_offset = (GLuint) pixels; - - if (unpack->RowLength > 0) - src_stride = unpack->RowLength; - else - src_stride = width; - - dst_offset = intel_miptree_image_offset(intelImage->mt, - intelImage->face, - intelImage->level); - - dst_stride = intelImage->mt->pitch; - - if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) { - _mesa_printf("%s: failure 2\n", __FUNCTION__); - return GL_FALSE; - } - - intel_region_attach_pbo(intel->intelScreen, intelImage->mt->region, pbo); - - return GL_TRUE; -} - - - - - - -static void -intelTexImage(GLcontext * ctx, - GLint dims, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *unpack, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, GLsizei imageSize, int compressed) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_object *intelObj = intel_texture_object(texObj); - struct intel_texture_image *intelImage = intel_texture_image(texImage); - GLint postConvWidth = width; - GLint postConvHeight = height; - GLint texelBytes, sizeInBytes; - GLuint dstRowStride; - - - DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); - - intelFlush(ctx); - - intelImage->face = target_to_face(target); - intelImage->level = level; - - if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { - _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, - &postConvHeight); - } - - /* choose the texture format */ - texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat, - format, type); - - _mesa_set_fetch_functions(texImage, dims); - - if (texImage->TexFormat->TexelBytes == 0) { - /* must be a compressed format */ - texelBytes = 0; - texImage->IsCompressed = GL_TRUE; - texImage->CompressedSize = - ctx->Driver.CompressedTextureSize(ctx, texImage->Width, - texImage->Height, texImage->Depth, - texImage->TexFormat->MesaFormat); - } else { - texelBytes = texImage->TexFormat->TexelBytes; - - /* Minimum pitch of 32 bytes */ - if (postConvWidth * texelBytes < 32) { - postConvWidth = 32 / texelBytes; - texImage->RowStride = postConvWidth; - } - - assert(texImage->RowStride == postConvWidth); - } - - /* Release the reference to a potentially orphaned buffer. - * Release any old malloced memory. - */ - if (intelImage->mt) { - intel_miptree_release(intel, &intelImage->mt); - assert(!texImage->Data); - } - else if (texImage->Data) { - _mesa_align_free(texImage->Data); - } - - /* If this is the only texture image in the tree, could call - * bmBufferData with NULL data to free the old block and avoid - * waiting on any outstanding fences. - */ - if (intelObj->mt && - intelObj->mt->first_level == level && - intelObj->mt->last_level == level && - intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && - !intel_miptree_match_image(intelObj->mt, &intelImage->base, - intelImage->face, intelImage->level)) { - - DBG("release it\n"); - intel_miptree_release(intel, &intelObj->mt); - assert(!intelObj->mt); - } - - if (!intelObj->mt) { - guess_and_alloc_mipmap_tree(intel, intelObj, intelImage); - if (!intelObj->mt) { - DBG("guess_and_alloc_mipmap_tree: failed\n"); - } - } - - assert(!intelImage->mt); - - if (intelObj->mt && - intel_miptree_match_image(intelObj->mt, &intelImage->base, - intelImage->face, intelImage->level)) { - - intel_miptree_reference(&intelImage->mt, intelObj->mt); - assert(intelImage->mt); - } - - if (!intelImage->mt) - DBG("XXX: Image did not fit into tree - storing in local memory!\n"); - - /* PBO fastpaths: - */ - if (dims <= 2 && - intelImage->mt && - intel_buffer_object(unpack->BufferObj) && - check_pbo_format(internalFormat, format, - type, intelImage->base.TexFormat)) { - - DBG("trying pbo upload\n"); - - /* Attempt to texture directly from PBO data (zero copy upload). - * - * Currently disable as it can lead to worse as well as better - * performance (in particular when intel_region_cow() is - * required). - */ - if (intelObj->mt == intelImage->mt && - intelObj->mt->first_level == level && - intelObj->mt->last_level == level) { - - if (try_pbo_zcopy(intel, intelImage, unpack, - internalFormat, - width, height, format, type, pixels)) { - - DBG("pbo zcopy upload succeeded\n"); - return; - } - } - - - /* Otherwise, attempt to use the blitter for PBO image uploads. - */ - if (try_pbo_upload(intel, intelImage, unpack, - internalFormat, - width, height, format, type, pixels)) { - DBG("pbo upload succeeded\n"); - return; - } - - DBG("pbo upload failed\n"); - } - - - - /* intelCopyTexImage calls this function with pixels == NULL, with - * the expectation that the mipmap tree will be set up but nothing - * more will be done. This is where those calls return: - */ - if (compressed) { - pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, - unpack, - "glCompressedTexImage"); - } else { - pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, - format, type, - pixels, unpack, "glTexImage"); - } - if (!pixels) - return; - - - if (intelImage->mt) - intel_region_idle(intel->intelScreen, intelImage->mt->region); - - LOCK_HARDWARE(intel); - - if (intelImage->mt) { - texImage->Data = intel_miptree_image_map(intel, - intelImage->mt, - intelImage->face, - intelImage->level, - &dstRowStride, - intelImage->base.ImageOffsets); - } - else { - /* Allocate regular memory and store the image there temporarily. */ - if (texImage->IsCompressed) { - sizeInBytes = texImage->CompressedSize; - dstRowStride = - _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); - assert(dims != 3); - } - else { - dstRowStride = postConvWidth * texelBytes; - sizeInBytes = depth * dstRowStride * postConvHeight; - } - - texImage->Data = malloc(sizeInBytes); - } - - DBG("Upload image %dx%dx%d row_len %x " - "pitch %x\n", - width, height, depth, width * texelBytes, dstRowStride); - - /* Copy data. Would like to know when it's ok for us to eg. use - * the blitter to copy. Or, use the hardware to do the format - * conversion and copy: - */ - if (compressed) { - memcpy(texImage->Data, pixels, imageSize); - } else if (!texImage->TexFormat->StoreImage(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, unpack)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); - } - - _mesa_unmap_teximage_pbo(ctx, unpack); - - if (intelImage->mt) { - intel_miptree_image_unmap(intel, intelImage->mt); - texImage->Data = NULL; - } - - UNLOCK_HARDWARE(intel); - -#if 0 - /* GL_SGIS_generate_mipmap -- this can be accelerated now. - */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - intel_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } -#endif -} - -void -intelTexImage3D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *unpack, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - intelTexImage(ctx, 3, target, level, - internalFormat, width, height, depth, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); -} - - -void -intelTexImage2D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *unpack, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - intelTexImage(ctx, 2, target, level, - internalFormat, width, height, 1, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); -} - -void -intelTexImage1D(GLcontext * ctx, - GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint border, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *unpack, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - intelTexImage(ctx, 1, target, level, - internalFormat, width, 1, 1, border, - format, type, pixels, unpack, texObj, texImage, 0, 0); -} - -void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - intelTexImage(ctx, 2, target, level, - internalFormat, width, height, 1, border, - 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); -} - -/** - * Need to map texture image into memory before copying image data, - * then unmap it. - */ -static void -intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, int compressed) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_image *intelImage = intel_texture_image(texImage); - - /* Map */ - if (intelImage->mt) { - /* Image is stored in hardware format in a buffer managed by the - * kernel. Need to explicitly map and unmap it. - */ - intelImage->base.Data = - intel_miptree_image_map(intel, - intelImage->mt, - intelImage->face, - intelImage->level, - &intelImage->base.RowStride, - intelImage->base.ImageOffsets); - intelImage->base.RowStride /= intelImage->mt->cpp; - } - else { - /* Otherwise, the image should actually be stored in - * intelImage->base.Data. This is pretty confusing for - * everybody, I'd much prefer to separate the two functions of - * texImage->Data - storage for texture images in main memory - * and access (ie mappings) of images. In other words, we'd - * create a new texImage->Map field and leave Data simply for - * storage. - */ - assert(intelImage->base.Data); - } - - - if (compressed) { - _mesa_get_compressed_teximage(ctx, target, level, pixels, - texObj, texImage); - } else { - _mesa_get_teximage(ctx, target, level, format, type, pixels, - texObj, texImage); - } - - - /* Unmap */ - if (intelImage->mt) { - intel_miptree_image_unmap(intel, intelImage->mt); - intelImage->base.Data = NULL; - } -} - -void -intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - intel_get_tex_image(ctx, target, level, format, type, pixels, - texObj, texImage, 0); - - -} - -void -intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, - GLvoid *pixels, - const struct gl_texture_object *texObj, - const struct gl_texture_image *texImage) -{ - intel_get_tex_image(ctx, target, level, 0, 0, pixels, - texObj, texImage, 1); - -} - -void -intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, - unsigned long long offset, GLint depth, GLuint pitch) -{ - struct intel_context *intel = (struct intel_context*) - ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; - struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); - struct intel_texture_object *intelObj = intel_texture_object(tObj); - - if (!intelObj) - return; - - if (intelObj->mt) - intel_miptree_release(intel, &intelObj->mt); - - intelObj->imageOverride = GL_TRUE; - intelObj->depthOverride = depth; - intelObj->pitchOverride = pitch; - - if (offset) - intelObj->textureOffset = offset; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_layout.c b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c deleted file mode 120000 index fe61b44194..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex_layout.c +++ /dev/null @@ -1 +0,0 @@ -../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c deleted file mode 100644 index 3935787806..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c +++ /dev/null @@ -1,182 +0,0 @@ - -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "mtypes.h" -#include "texobj.h" -#include "texstore.h" -#include "enums.h" - -#include "intel_context.h" -#include "intel_tex.h" -#include "intel_mipmap_tree.h" - -#define FILE_DEBUG_FLAG DEBUG_TEXTURE - -static void -intelTexSubimage(GLcontext * ctx, - GLint dims, - GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint width, GLint height, GLint depth, - GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - struct intel_context *intel = intel_context(ctx); - struct intel_texture_image *intelImage = intel_texture_image(texImage); - GLuint dstRowStride; - - DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(target), - level, xoffset, yoffset, width, height); - - intelFlush(ctx); - - pixels = - _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, - type, pixels, packing, "glTexSubImage2D"); - if (!pixels) - return; - - if (intelImage->mt) - intel_region_idle(intel->intelScreen, intelImage->mt->region); - - LOCK_HARDWARE(intel); - - /* Map buffer if necessary. Need to lock to prevent other contexts - * from uploading the buffer under us. - */ - if (intelImage->mt) - texImage->Data = intel_miptree_image_map(intel, - intelImage->mt, - intelImage->face, - intelImage->level, - &dstRowStride, - texImage->ImageOffsets); - - assert(dstRowStride); - - if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, - xoffset, yoffset, zoffset, - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, packing)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); - } - -#if 0 - /* GL_SGIS_generate_mipmap */ - if (level == texObj->BaseLevel && texObj->GenerateMipmap) { - _mesa_generate_mipmap(ctx, target, - &ctx->Texture.Unit[ctx->Texture.CurrentUnit], - texObj); - } -#endif - - _mesa_unmap_teximage_pbo(ctx, packing); - - if (intelImage->mt) { - intel_miptree_image_unmap(intel, intelImage->mt); - texImage->Data = NULL; - } - - UNLOCK_HARDWARE(intel); -} - - - - - -void -intelTexSubImage3D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - - intelTexSubimage(ctx, 3, - target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, packing, texObj, texImage); - -} - - - -void -intelTexSubImage2D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - - intelTexSubimage(ctx, 2, - target, level, - xoffset, yoffset, 0, - width, height, 1, - format, type, pixels, packing, texObj, texImage); - -} - - -void -intelTexSubImage1D(GLcontext * ctx, - GLenum target, - GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - intelTexSubimage(ctx, 1, - target, level, - xoffset, 0, 0, - width, 1, 1, - format, type, pixels, packing, texObj, texImage); - -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c deleted file mode 100644 index af18c26d55..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ /dev/null @@ -1,272 +0,0 @@ -#include "mtypes.h" -#include "macros.h" - -#include "intel_context.h" -#include "intel_batchbuffer.h" -#include "intel_mipmap_tree.h" -#include "intel_tex.h" - -#define FILE_DEBUG_FLAG DEBUG_TEXTURE - -/** - * Compute which mipmap levels that really need to be sent to the hardware. - * This depends on the base image size, GL_TEXTURE_MIN_LOD, - * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. - */ -static void -intel_calculate_first_last_level(struct intel_texture_object *intelObj) -{ - struct gl_texture_object *tObj = &intelObj->base; - const struct gl_texture_image *const baseImage = - tObj->Image[0][tObj->BaseLevel]; - - /* These must be signed values. MinLod and MaxLod can be negative numbers, - * and having firstLevel and lastLevel as signed prevents the need for - * extra sign checks. - */ - int firstLevel; - int lastLevel; - - /* Yes, this looks overly complicated, but it's all needed. - */ - switch (tObj->Target) { - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - case GL_TEXTURE_CUBE_MAP: - if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { - /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. - */ - firstLevel = lastLevel = tObj->BaseLevel; - } - else { - firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ - } - break; - case GL_TEXTURE_RECTANGLE_NV: - case GL_TEXTURE_4D_SGIS: - firstLevel = lastLevel = 0; - break; - default: - return; - } - - /* save these values */ - intelObj->firstLevel = firstLevel; - intelObj->lastLevel = lastLevel; -} - -static void -copy_image_data_to_tree(struct intel_context *intel, - struct intel_texture_object *intelObj, - struct intel_texture_image *intelImage) -{ - if (intelImage->mt) { - /* Copy potentially with the blitter: - */ - intel_miptree_image_copy(intel, - intelObj->mt, - intelImage->face, - intelImage->level, intelImage->mt); - - intel_miptree_release(intel, &intelImage->mt); - } - else { - assert(intelImage->base.Data != NULL); - - /* More straightforward upload. - */ - intel_miptree_image_data(intel, - intelObj->mt, - intelImage->face, - intelImage->level, - intelImage->base.Data, - intelImage->base.RowStride, - intelImage->base.RowStride * - intelImage->base.Height); - _mesa_align_free(intelImage->base.Data); - intelImage->base.Data = NULL; - } - - intel_miptree_reference(&intelImage->mt, intelObj->mt); -} - - -/* - */ -GLuint -intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) -{ - struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; - struct intel_texture_object *intelObj = intel_texture_object(tObj); - int comp_byte = 0; - int cpp; - - GLuint face, i; - GLuint nr_faces = 0; - struct intel_texture_image *firstImage; - - GLboolean need_flush = GL_FALSE; - - /* We know/require this is true by now: - */ - assert(intelObj->base._Complete); - - /* What levels must the tree include at a minimum? - */ - intel_calculate_first_last_level(intelObj); - firstImage = - intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]); - - /* Fallback case: - */ - if (firstImage->base.Border) { - if (intelObj->mt) { - intel_miptree_release(intel, &intelObj->mt); - } - return GL_FALSE; - } - - - /* If both firstImage and intelObj have a tree which can contain - * all active images, favour firstImage. Note that because of the - * completeness requirement, we know that the image dimensions - * will match. - */ - if (firstImage->mt && - firstImage->mt != intelObj->mt && - firstImage->mt->first_level <= intelObj->firstLevel && - firstImage->mt->last_level >= intelObj->lastLevel) { - - if (intelObj->mt) - intel_miptree_release(intel, &intelObj->mt); - - intel_miptree_reference(&intelObj->mt, firstImage->mt); - } - - if (firstImage->base.IsCompressed) { - comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); - cpp = comp_byte; - } - else cpp = firstImage->base.TexFormat->TexelBytes; - - /* Check tree can hold all active levels. Check tree matches - * target, imageFormat, etc. - * - * XXX: For some layouts (eg i945?), the test might have to be - * first_level == firstLevel, as the tree isn't valid except at the - * original start level. Hope to get around this by - * programming minLod, maxLod, baseLevel into the hardware and - * leaving the tree alone. - */ - if (intelObj->mt && - (intelObj->mt->target != intelObj->base.Target || - intelObj->mt->internal_format != firstImage->base.InternalFormat || - intelObj->mt->first_level != intelObj->firstLevel || - intelObj->mt->last_level != intelObj->lastLevel || - intelObj->mt->width0 != firstImage->base.Width || - intelObj->mt->height0 != firstImage->base.Height || - intelObj->mt->depth0 != firstImage->base.Depth || - intelObj->mt->cpp != cpp || - intelObj->mt->compressed != firstImage->base.IsCompressed)) { - intel_miptree_release(intel, &intelObj->mt); - } - - - /* May need to create a new tree: - */ - if (!intelObj->mt) { - intelObj->mt = intel_miptree_create(intel, - intelObj->base.Target, - firstImage->base.InternalFormat, - intelObj->firstLevel, - intelObj->lastLevel, - firstImage->base.Width, - firstImage->base.Height, - firstImage->base.Depth, - cpp, - comp_byte); - } - - /* Pull in any images not in the object's tree: - */ - nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - for (face = 0; face < nr_faces; face++) { - for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { - struct intel_texture_image *intelImage = - intel_texture_image(intelObj->base.Image[face][i]); - - /* Need to import images in main memory or held in other trees. - */ - if (intelObj->mt != intelImage->mt) { - copy_image_data_to_tree(intel, intelObj, intelImage); - need_flush = GL_TRUE; - } - } - } - - if (need_flush) - intel_batchbuffer_flush(intel->batch); - - return GL_TRUE; -} - - - -void -intel_tex_map_images(struct intel_context *intel, - struct intel_texture_object *intelObj) -{ - GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - GLuint face, i; - - DBG("%s\n", __FUNCTION__); - - for (face = 0; face < nr_faces; face++) { - for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { - struct intel_texture_image *intelImage = - intel_texture_image(intelObj->base.Image[face][i]); - - if (intelImage->mt) { - intelImage->base.Data = - intel_miptree_image_map(intel, - intelImage->mt, - intelImage->face, - intelImage->level, - &intelImage->base.RowStride, - intelImage->base.ImageOffsets); - /* convert stride to texels, not bytes */ - intelImage->base.RowStride /= intelImage->mt->cpp; -/* intelImage->base.ImageStride /= intelImage->mt->cpp; */ - } - } - } -} - - - -void -intel_tex_unmap_images(struct intel_context *intel, - struct intel_texture_object *intelObj) -{ - GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - GLuint face, i; - - for (face = 0; face < nr_faces; face++) { - for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { - struct intel_texture_image *intelImage = - intel_texture_image(intelObj->base.Image[face][i]); - - if (intelImage->mt) { - intel_miptree_image_unmap(intel, intelImage->mt); - intelImage->base.Data = NULL; - } - } - } -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c deleted file mode 100644 index 5fe3d4561f..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tris.c +++ /dev/null @@ -1,1152 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "enums.h" -#include "texobj.h" -#include "state.h" -#include "dd.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/t_context.h" -#include "tnl/t_pipeline.h" -#include "tnl/t_vertex.h" - -#include "intel_screen.h" -#include "intel_context.h" -#include "intel_tris.h" -#include "intel_batchbuffer.h" -#include "intel_buffers.h" -#include "intel_reg.h" -#include "intel_span.h" -#include "intel_tex.h" - -static void intelRenderPrimitive(GLcontext * ctx, GLenum prim); -static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, - GLuint hwprim); - -/* - */ -static void -intel_flush_inline_primitive(struct intel_context *intel) -{ - GLuint used = intel->batch->ptr - intel->prim.start_ptr; - - assert(intel->prim.primitive != ~0); - -/* _mesa_printf("/\n"); */ - - if (used < 8) - goto do_discard; - - *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | - intel->prim.primitive | (used / 4 - 2)); - - goto finished; - - do_discard: - intel->batch->ptr -= used; - - finished: - intel->prim.primitive = ~0; - intel->prim.start_ptr = 0; - intel->prim.flush = 0; -} - - -/* Emit a primitive referencing vertices in a vertex buffer. - */ -void -intelStartInlinePrimitive(struct intel_context *intel, - GLuint prim, GLuint batch_flags) -{ - BATCH_LOCALS; - - intel->vtbl.emit_state(intel); - - /* Need to make sure at the very least that we don't wrap - * batchbuffers in BEGIN_BATCH below, otherwise the primitive will - * be emitted to a batchbuffer missing the required full-state - * preamble. - */ - if (intel_batchbuffer_space(intel->batch) < 100) { - intel_batchbuffer_flush(intel->batch); - intel->vtbl.emit_state(intel); - } - -/* _mesa_printf("%s *", __progname); */ - - intel_wait_flips(intel, batch_flags); - - /* Emit a slot which will be filled with the inline primitive - * command later. - */ - BEGIN_BATCH(2, batch_flags); - OUT_BATCH(0); - - intel->prim.start_ptr = intel->batch->ptr; - intel->prim.primitive = prim; - intel->prim.flush = intel_flush_inline_primitive; - - OUT_BATCH(0); - ADVANCE_BATCH(); - -/* _mesa_printf(">"); */ -} - - -void -intelWrapInlinePrimitive(struct intel_context *intel) -{ - GLuint prim = intel->prim.primitive; - GLuint batchflags = intel->batch->flags; - - intel_flush_inline_primitive(intel); - intel_batchbuffer_flush(intel->batch); - intelStartInlinePrimitive(intel, prim, batchflags); /* ??? */ -} - -GLuint * -intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords) -{ - GLuint sz = dwords * sizeof(GLuint); - GLuint *ptr; - - assert(intel->prim.flush == intel_flush_inline_primitive); - - if (intel_batchbuffer_space(intel->batch) < sz) - intelWrapInlinePrimitive(intel); - -/* _mesa_printf("."); */ - - intel->vtbl.assert_not_dirty(intel); - - ptr = (GLuint *) intel->batch->ptr; - intel->batch->ptr += sz; - - return ptr; -} - - - -/*********************************************************************** - * Emit primitives as inline vertices * - ***********************************************************************/ - -#ifdef __i386__ -#define COPY_DWORDS( j, vb, vertsize, v ) \ -do { \ - int __tmp; \ - __asm__ __volatile__( "rep ; movsl" \ - : "=%c" (j), "=D" (vb), "=S" (__tmp) \ - : "0" (vertsize), \ - "D" ((long)vb), \ - "S" ((long)v) ); \ -} while (0) -#else -#define COPY_DWORDS( j, vb, vertsize, v ) \ -do { \ - for ( j = 0 ; j < vertsize ; j++ ) { \ - vb[j] = ((GLuint *)v)[j]; \ - } \ - vb += vertsize; \ -} while (0) -#endif - -static void -intel_draw_quad(struct intel_context *intel, - intelVertexPtr v0, - intelVertexPtr v1, intelVertexPtr v2, intelVertexPtr v3) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive(intel, 6 * vertsize); - int j; - - COPY_DWORDS(j, vb, vertsize, v0); - COPY_DWORDS(j, vb, vertsize, v1); - - /* If smooth shading, draw like a trifan which gives better - * rasterization. Otherwise draw as two triangles with provoking - * vertex in third position as required for flat shading. - */ - if (intel->ctx.Light.ShadeModel == GL_FLAT) { - COPY_DWORDS(j, vb, vertsize, v3); - COPY_DWORDS(j, vb, vertsize, v1); - } - else { - COPY_DWORDS(j, vb, vertsize, v2); - COPY_DWORDS(j, vb, vertsize, v0); - } - - COPY_DWORDS(j, vb, vertsize, v2); - COPY_DWORDS(j, vb, vertsize, v3); -} - -static void -intel_draw_triangle(struct intel_context *intel, - intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive(intel, 3 * vertsize); - int j; - - COPY_DWORDS(j, vb, vertsize, v0); - COPY_DWORDS(j, vb, vertsize, v1); - COPY_DWORDS(j, vb, vertsize, v2); -} - - -static void -intel_draw_line(struct intel_context *intel, - intelVertexPtr v0, intelVertexPtr v1) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive(intel, 2 * vertsize); - int j; - - COPY_DWORDS(j, vb, vertsize, v0); - COPY_DWORDS(j, vb, vertsize, v1); -} - - -static void -intel_draw_point(struct intel_context *intel, intelVertexPtr v0) -{ - GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive(intel, vertsize); - int j; - - /* Adjust for sub pixel position -- still required for conform. */ - *(float *) &vb[0] = v0->v.x - 0.125; - *(float *) &vb[1] = v0->v.y - 0.125; - for (j = 2; j < vertsize; j++) - vb[j] = v0->ui[j]; -} - - - -/*********************************************************************** - * Fixup for ARB_point_parameters * - ***********************************************************************/ - -/* Currently not working - VERT_ATTRIB_POINTSIZE isn't correctly - * represented in the fragment program InputsRead field. - */ -static void -intel_atten_point(struct intel_context *intel, intelVertexPtr v0) -{ - GLcontext *ctx = &intel->ctx; - GLfloat psz[4], col[4], restore_psz, restore_alpha; - - _tnl_get_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); - _tnl_get_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); - - restore_psz = psz[0]; - restore_alpha = col[3]; - - if (psz[0] >= ctx->Point.Threshold) { - psz[0] = MIN2(psz[0], ctx->Point.MaxSize); - } - else { - GLfloat dsize = psz[0] / ctx->Point.Threshold; - psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); - col[3] *= dsize * dsize; - } - - if (psz[0] < 1.0) - psz[0] = 1.0; - - if (restore_psz != psz[0] || restore_alpha != col[3]) { - _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); - _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); - - intel_draw_point(intel, v0); - - psz[0] = restore_psz; - col[3] = restore_alpha; - - _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); - _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); - } - else - intel_draw_point(intel, v0); -} - - - - - -/*********************************************************************** - * Fixup for I915 WPOS texture coordinate * - ***********************************************************************/ - - - -static void -intel_wpos_triangle(struct intel_context *intel, - intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) -{ - GLuint offset = intel->wpos_offset; - GLuint size = intel->wpos_size; - - __memcpy(((char *) v0) + offset, v0, size); - __memcpy(((char *) v1) + offset, v1, size); - __memcpy(((char *) v2) + offset, v2, size); - - intel_draw_triangle(intel, v0, v1, v2); -} - - -static void -intel_wpos_line(struct intel_context *intel, - intelVertexPtr v0, intelVertexPtr v1) -{ - GLuint offset = intel->wpos_offset; - GLuint size = intel->wpos_size; - - __memcpy(((char *) v0) + offset, v0, size); - __memcpy(((char *) v1) + offset, v1, size); - - intel_draw_line(intel, v0, v1); -} - - -static void -intel_wpos_point(struct intel_context *intel, intelVertexPtr v0) -{ - GLuint offset = intel->wpos_offset; - GLuint size = intel->wpos_size; - - __memcpy(((char *) v0) + offset, v0, size); - - intel_draw_point(intel, v0); -} - - - - - - -/*********************************************************************** - * Macros for t_dd_tritmp.h to draw basic primitives * - ***********************************************************************/ - -#define TRI( a, b, c ) \ -do { \ - if (DO_FALLBACK) \ - intel->draw_tri( intel, a, b, c ); \ - else \ - intel_draw_triangle( intel, a, b, c ); \ -} while (0) - -#define QUAD( a, b, c, d ) \ -do { \ - if (DO_FALLBACK) { \ - intel->draw_tri( intel, a, b, d ); \ - intel->draw_tri( intel, b, c, d ); \ - } else \ - intel_draw_quad( intel, a, b, c, d ); \ -} while (0) - -#define LINE( v0, v1 ) \ -do { \ - if (DO_FALLBACK) \ - intel->draw_line( intel, v0, v1 ); \ - else \ - intel_draw_line( intel, v0, v1 ); \ -} while (0) - -#define POINT( v0 ) \ -do { \ - if (DO_FALLBACK) \ - intel->draw_point( intel, v0 ); \ - else \ - intel_draw_point( intel, v0 ); \ -} while (0) - - -/*********************************************************************** - * Build render functions from dd templates * - ***********************************************************************/ - -#define INTEL_OFFSET_BIT 0x01 -#define INTEL_TWOSIDE_BIT 0x02 -#define INTEL_UNFILLED_BIT 0x04 -#define INTEL_FALLBACK_BIT 0x08 -#define INTEL_MAX_TRIFUNC 0x10 - - -static struct -{ - tnl_points_func points; - tnl_line_func line; - tnl_triangle_func triangle; - tnl_quad_func quad; -} rast_tab[INTEL_MAX_TRIFUNC]; - - -#define DO_FALLBACK (IND & INTEL_FALLBACK_BIT) -#define DO_OFFSET (IND & INTEL_OFFSET_BIT) -#define DO_UNFILLED (IND & INTEL_UNFILLED_BIT) -#define DO_TWOSIDE (IND & INTEL_TWOSIDE_BIT) -#define DO_FLAT 0 -#define DO_TRI 1 -#define DO_QUAD 1 -#define DO_LINE 1 -#define DO_POINTS 1 -#define DO_FULL_QUAD 1 - -#define HAVE_RGBA 1 -#define HAVE_SPEC 1 -#define HAVE_BACK_COLORS 0 -#define HAVE_HW_FLATSHADE 1 -#define VERTEX intelVertex -#define TAB rast_tab - -/* Only used to pull back colors into vertices (ie, we know color is - * floating point). - */ -#define INTEL_COLOR( dst, src ) \ -do { \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \ -} while (0) - -#define INTEL_SPEC( dst, src ) \ -do { \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ -} while (0) - - -#define DEPTH_SCALE intel->polygon_offset_scale -#define UNFILLED_TRI unfilled_tri -#define UNFILLED_QUAD unfilled_quad -#define VERT_X(_v) _v->v.x -#define VERT_Y(_v) _v->v.y -#define VERT_Z(_v) _v->v.z -#define AREA_IS_CCW( a ) (a > 0) -#define GET_VERTEX(e) (intel->verts + (e * intel->vertex_size * sizeof(GLuint))) - -#define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c ) -#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset] -#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset] -#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx] - -#define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c ) -#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset]) -#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset] -#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx] - -#define LOCAL_VARS(n) \ - struct intel_context *intel = intel_context(ctx); \ - GLuint color[n], spec[n]; \ - GLuint coloroffset = intel->coloroffset; \ - GLboolean specoffset = intel->specoffset; \ - (void) color; (void) spec; (void) coloroffset; (void) specoffset; - - -/*********************************************************************** - * Helpers for rendering unfilled primitives * - ***********************************************************************/ - -static const GLuint hw_prim[GL_POLYGON + 1] = { - PRIM3D_POINTLIST, - PRIM3D_LINELIST, - PRIM3D_LINELIST, - PRIM3D_LINELIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST, - PRIM3D_TRILIST -}; - -#define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] ) -#define RENDER_PRIMITIVE intel->render_primitive -#define TAG(x) x -#define IND INTEL_FALLBACK_BIT -#include "tnl_dd/t_dd_unfilled.h" -#undef IND - -/*********************************************************************** - * Generate GL render functions * - ***********************************************************************/ - -#define IND (0) -#define TAG(x) x -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT) -#define TAG(x) x##_offset -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT) -#define TAG(x) x##_twoside -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT) -#define TAG(x) x##_twoside_offset -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_UNFILLED_BIT) -#define TAG(x) x##_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) -#define TAG(x) x##_offset_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT) -#define TAG(x) x##_twoside_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) -#define TAG(x) x##_twoside_offset_unfilled -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_FALLBACK_BIT) -#define TAG(x) x##_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_offset_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_offset_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_offset_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - -#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \ - INTEL_FALLBACK_BIT) -#define TAG(x) x##_twoside_offset_unfilled_fallback -#include "tnl_dd/t_dd_tritmp.h" - - -static void -init_rast_tab(void) -{ - init(); - init_offset(); - init_twoside(); - init_twoside_offset(); - init_unfilled(); - init_offset_unfilled(); - init_twoside_unfilled(); - init_twoside_offset_unfilled(); - init_fallback(); - init_offset_fallback(); - init_twoside_fallback(); - init_twoside_offset_fallback(); - init_unfilled_fallback(); - init_offset_unfilled_fallback(); - init_twoside_unfilled_fallback(); - init_twoside_offset_unfilled_fallback(); -} - - -/*********************************************************************** - * Rasterization fallback helpers * - ***********************************************************************/ - - -/* This code is hit only when a mix of accelerated and unaccelerated - * primitives are being drawn, and only for the unaccelerated - * primitives. - */ -static void -intel_fallback_tri(struct intel_context *intel, - intelVertex * v0, intelVertex * v1, intelVertex * v2) -{ - GLcontext *ctx = &intel->ctx; - SWvertex v[3]; - - if (0) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - INTEL_FIREVERTICES(intel); - - _swsetup_Translate(ctx, v0, &v[0]); - _swsetup_Translate(ctx, v1, &v[1]); - _swsetup_Translate(ctx, v2, &v[2]); - intelSpanRenderStart(ctx); - _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); - intelSpanRenderFinish(ctx); -} - - -static void -intel_fallback_line(struct intel_context *intel, - intelVertex * v0, intelVertex * v1) -{ - GLcontext *ctx = &intel->ctx; - SWvertex v[2]; - - if (0) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - INTEL_FIREVERTICES(intel); - - _swsetup_Translate(ctx, v0, &v[0]); - _swsetup_Translate(ctx, v1, &v[1]); - intelSpanRenderStart(ctx); - _swrast_Line(ctx, &v[0], &v[1]); - intelSpanRenderFinish(ctx); -} - -static void -intel_fallback_point(struct intel_context *intel, - intelVertex * v0) -{ - GLcontext *ctx = &intel->ctx; - SWvertex v[1]; - - if (0) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - INTEL_FIREVERTICES(intel); - - _swsetup_Translate(ctx, v0, &v[0]); - intelSpanRenderStart(ctx); - _swrast_Point(ctx, &v[0]); - intelSpanRenderFinish(ctx); -} - - -/**********************************************************************/ -/* Render unclipped begin/end objects */ -/**********************************************************************/ - -#define IND 0 -#define V(x) (intelVertex *)(vertptr + ((x)*vertsize*sizeof(GLuint))) -#define RENDER_POINTS( start, count ) \ - for ( ; start < count ; start++) POINT( V(ELT(start)) ); -#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) -#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) -#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) -#define INIT(x) intelRenderPrimitive( ctx, x ) -#undef LOCAL_VARS -#define LOCAL_VARS \ - struct intel_context *intel = intel_context(ctx); \ - GLubyte *vertptr = (GLubyte *)intel->verts; \ - const GLuint vertsize = intel->vertex_size; \ - const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ - (void) elt; -#define RESET_STIPPLE -#define RESET_OCCLUSION -#define PRESERVE_VB_DEFS -#define ELT(x) x -#define TAG(x) intel_##x##_verts -#include "tnl/t_vb_rendertmp.h" -#undef ELT -#undef TAG -#define TAG(x) intel_##x##_elts -#define ELT(x) elt[x] -#include "tnl/t_vb_rendertmp.h" - -/**********************************************************************/ -/* Render clipped primitives */ -/**********************************************************************/ - - - -static void -intelRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) -{ - struct intel_context *intel = intel_context(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLuint prim = intel->render_primitive; - - /* Render the new vertices as an unclipped polygon. - */ - { - GLuint *tmp = VB->Elts; - VB->Elts = (GLuint *) elts; - tnl->Driver.Render.PrimTabElts[GL_POLYGON] (ctx, 0, n, - PRIM_BEGIN | PRIM_END); - VB->Elts = tmp; - } - - /* Restore the render primitive - */ - if (prim != GL_POLYGON) - tnl->Driver.Render.PrimitiveNotify(ctx, prim); -} - -static void -intelRenderClippedLine(GLcontext * ctx, GLuint ii, GLuint jj) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - - tnl->Driver.Render.Line(ctx, ii, jj); -} - -static void -intelFastRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) -{ - struct intel_context *intel = intel_context(ctx); - const GLuint vertsize = intel->vertex_size; - GLuint *vb = intelExtendInlinePrimitive(intel, (n - 2) * 3 * vertsize); - GLubyte *vertptr = (GLubyte *) intel->verts; - const GLuint *start = (const GLuint *) V(elts[0]); - int i, j; - - for (i = 2; i < n; i++) { - COPY_DWORDS(j, vb, vertsize, V(elts[i - 1])); - COPY_DWORDS(j, vb, vertsize, V(elts[i])); - COPY_DWORDS(j, vb, vertsize, start); - } -} - -/**********************************************************************/ -/* Choose render functions */ -/**********************************************************************/ - - - - -#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN | DD_POINT_SMOOTH | DD_TRI_SMOOTH) -#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED) - -void -intelChooseRenderState(GLcontext * ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct intel_context *intel = intel_context(ctx); - GLuint flags = ctx->_TriangleCaps; - const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; - GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS)); - GLuint index = 0; - - if (INTEL_DEBUG & DEBUG_STATE) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - if ((flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) || have_wpos) { - - if (flags & ANY_RASTER_FLAGS) { - if (flags & DD_TRI_LIGHT_TWOSIDE) - index |= INTEL_TWOSIDE_BIT; - if (flags & DD_TRI_OFFSET) - index |= INTEL_OFFSET_BIT; - if (flags & DD_TRI_UNFILLED) - index |= INTEL_UNFILLED_BIT; - } - - if (have_wpos) { - intel->draw_point = intel_wpos_point; - intel->draw_line = intel_wpos_line; - intel->draw_tri = intel_wpos_triangle; - - /* Make sure these get called: - */ - index |= INTEL_FALLBACK_BIT; - } - else { - intel->draw_point = intel_draw_point; - intel->draw_line = intel_draw_line; - intel->draw_tri = intel_draw_triangle; - } - - /* Hook in fallbacks for specific primitives. - */ - if (flags & ANY_FALLBACK_FLAGS) { - if (flags & DD_LINE_STIPPLE) - intel->draw_line = intel_fallback_line; - - if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) - intel->draw_tri = intel_fallback_tri; - - if (flags & DD_TRI_SMOOTH) { - if (intel->strict_conformance) - intel->draw_tri = intel_fallback_tri; - } - - if (flags & DD_POINT_ATTEN) { - if (0) - intel->draw_point = intel_atten_point; - else - intel->draw_point = intel_fallback_point; - } - - if (flags & DD_POINT_SMOOTH) { - if (intel->strict_conformance) - intel->draw_point = intel_fallback_point; - } - - index |= INTEL_FALLBACK_BIT; - } - } - - if (intel->RenderIndex != index) { - intel->RenderIndex = index; - - tnl->Driver.Render.Points = rast_tab[index].points; - tnl->Driver.Render.Line = rast_tab[index].line; - tnl->Driver.Render.Triangle = rast_tab[index].triangle; - tnl->Driver.Render.Quad = rast_tab[index].quad; - - if (index == 0) { - tnl->Driver.Render.PrimTabVerts = intel_render_tab_verts; - tnl->Driver.Render.PrimTabElts = intel_render_tab_elts; - tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ - tnl->Driver.Render.ClippedPolygon = intelFastRenderClippedPoly; - } - else { - tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; - tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; - tnl->Driver.Render.ClippedLine = intelRenderClippedLine; - tnl->Driver.Render.ClippedPolygon = intelRenderClippedPoly; - } - } -} - -static const GLenum reduced_prim[GL_POLYGON + 1] = { - GL_POINTS, - GL_LINES, - GL_LINES, - GL_LINES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES -}; - - -/**********************************************************************/ -/* High level hooks for t_vb_render.c */ -/**********************************************************************/ - - - - -static void -intelRunPipeline(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - - _mesa_lock_context_textures(ctx); - - if (ctx->NewState) - _mesa_update_state_locked(ctx); - - if (intel->NewGLState) { - if (intel->NewGLState & _NEW_TEXTURE) { - intel->vtbl.update_texture_state(intel); - } - - if (!intel->Fallback) { - if (intel->NewGLState & _INTEL_NEW_RENDERSTATE) - intelChooseRenderState(ctx); - } - - intel->NewGLState = 0; - } - - _tnl_run_pipeline(ctx); - - _mesa_unlock_context_textures(ctx); -} - -static void -intelRenderStart(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - - intel->vtbl.render_start(intel_context(ctx)); - intel->vtbl.emit_state(intel); -} - -static void -intelRenderFinish(GLcontext * ctx) -{ - struct intel_context *intel = intel_context(ctx); - - if (intel->RenderIndex & INTEL_FALLBACK_BIT) - _swrast_flush(ctx); - - INTEL_FIREVERTICES(intel); -} - - - - - /* System to flush dma and emit state changes based on the rasterized - * primitive. - */ -static void -intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim) -{ - struct intel_context *intel = intel_context(ctx); - - if (0) - fprintf(stderr, "%s %s %x\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(rprim), hwprim); - - intel->vtbl.reduced_primitive_state(intel, rprim); - - /* Start a new primitive. Arrange to have it flushed later on. - */ - if (hwprim != intel->prim.primitive) { - INTEL_FIREVERTICES(intel); - - intelStartInlinePrimitive(intel, hwprim, INTEL_BATCH_CLIPRECTS); - } -} - - - /* - */ -static void -intelRenderPrimitive(GLcontext * ctx, GLenum prim) -{ - struct intel_context *intel = intel_context(ctx); - - if (0) - fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); - - /* Let some clipping routines know which primitive they're dealing - * with. - */ - intel->render_primitive = prim; - - /* Shortcircuit this when called from t_dd_rendertmp.h for unfilled - * triangles. The rasterized primitive will always be reset by - * lower level functions in that case, potentially pingponging the - * state: - */ - if (reduced_prim[prim] == GL_TRIANGLES && - (ctx->_TriangleCaps & DD_TRI_UNFILLED)) - return; - - /* Set some primitive-dependent state and Start? a new primitive. - */ - intelRasterPrimitive(ctx, reduced_prim[prim], hw_prim[prim]); -} - - - /**********************************************************************/ - /* Transition to/from hardware rasterization. */ - /**********************************************************************/ - -static char *fallbackStrings[] = { - [0] = "Draw buffer", - [1] = "Read buffer", - [2] = "Depth buffer", - [3] = "Stencil buffer", - [4] = "User disable", - [5] = "Render mode", - - [12] = "Texture", - [13] = "Color mask", - [14] = "Stencil", - [15] = "Stipple", - [16] = "Program", - [17] = "Logic op", - [18] = "Smooth polygon", - [19] = "Smooth point", -}; - - -static char * -getFallbackString(GLuint bit) -{ - int i = 0; - while (bit > 1) { - i++; - bit >>= 1; - } - return fallbackStrings[i]; -} - - - -void -intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode) -{ - GLcontext *ctx = &intel->ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint oldfallback = intel->Fallback; - - if (mode) { - intel->Fallback |= bit; - if (oldfallback == 0) { - intelFlush(ctx); - if (INTEL_DEBUG & DEBUG_FALLBACKS) - fprintf(stderr, "ENTER FALLBACK %x: %s\n", - bit, getFallbackString(bit)); - _swsetup_Wakeup(ctx); - intel->RenderIndex = ~0; - } - } - else { - intel->Fallback &= ~bit; - if (oldfallback == bit) { - _swrast_flush(ctx); - if (INTEL_DEBUG & DEBUG_FALLBACKS) - fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString(bit)); - tnl->Driver.Render.Start = intelRenderStart; - tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; - tnl->Driver.Render.Finish = intelRenderFinish; - tnl->Driver.Render.BuildVertices = _tnl_build_vertices; - tnl->Driver.Render.CopyPV = _tnl_copy_pv; - tnl->Driver.Render.Interp = _tnl_interp; - - _tnl_invalidate_vertex_state(ctx, ~0); - _tnl_invalidate_vertices(ctx, ~0); - _tnl_install_attrs(ctx, - intel->vertex_attrs, - intel->vertex_attr_count, - intel->ViewportMatrix.m, 0); - - intel->NewGLState |= _INTEL_NEW_RENDERSTATE; - } - } -} - -union fi -{ - GLfloat f; - GLint i; -}; - - -/**********************************************************************/ -/* Used only with the metaops callbacks. */ -/**********************************************************************/ -void -intel_meta_draw_poly(struct intel_context *intel, - GLuint n, - GLfloat xy[][2], - GLfloat z, GLuint color, GLfloat tex[][2]) -{ - union fi *vb; - GLint i; - - /* All 3d primitives should be emitted with INTEL_BATCH_CLIPRECTS, - * otherwise the drawing origin (DR4) might not be set correctly. - */ - intelStartInlinePrimitive(intel, PRIM3D_TRIFAN, INTEL_BATCH_CLIPRECTS); - vb = (union fi *) intelExtendInlinePrimitive(intel, n * 6); - - for (i = 0; i < n; i++) { - vb[0].f = xy[i][0]; - vb[1].f = xy[i][1]; - vb[2].f = z; - vb[3].i = color; - vb[4].f = tex[i][0]; - vb[5].f = tex[i][1]; - vb += 6; - } - - INTEL_FIREVERTICES(intel); -} - -void -intel_meta_draw_quad(struct intel_context *intel, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLfloat z, - GLuint color, - GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1) -{ - GLfloat xy[4][2]; - GLfloat tex[4][2]; - - xy[0][0] = x0; - xy[0][1] = y0; - xy[1][0] = x1; - xy[1][1] = y0; - xy[2][0] = x1; - xy[2][1] = y1; - xy[3][0] = x0; - xy[3][1] = y1; - - tex[0][0] = s0; - tex[0][1] = t0; - tex[1][0] = s1; - tex[1][1] = t0; - tex[2][0] = s1; - tex[2][1] = t1; - tex[3][0] = s0; - tex[3][1] = t1; - - intel_meta_draw_poly(intel, 4, xy, z, color, tex); -} - - - -/**********************************************************************/ -/* Initialization. */ -/**********************************************************************/ - - -void -intelInitTriFuncs(GLcontext * ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - static int firsttime = 1; - - if (firsttime) { - init_rast_tab(); - firsttime = 0; - } - - tnl->Driver.RunPipeline = intelRunPipeline; - tnl->Driver.Render.Start = intelRenderStart; - tnl->Driver.Render.Finish = intelRenderFinish; - tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; - tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; - tnl->Driver.Render.BuildVertices = _tnl_build_vertices; - tnl->Driver.Render.CopyPV = _tnl_copy_pv; - tnl->Driver.Render.Interp = _tnl_interp; -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.h b/src/mesa/drivers/dri/i915tex/intel_tris.h deleted file mode 100644 index b7bae8cd3b..0000000000 --- a/src/mesa/drivers/dri/i915tex/intel_tris.h +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef INTELTRIS_INC -#define INTELTRIS_INC - -#include "mtypes.h" - - - -#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ - _DD_NEW_TRI_UNFILLED | \ - _DD_NEW_TRI_LIGHT_TWOSIDE | \ - _DD_NEW_TRI_OFFSET | \ - _DD_NEW_TRI_STIPPLE | \ - _NEW_PROGRAM | \ - _NEW_POLYGONSTIPPLE) - -extern void intelInitTriFuncs(GLcontext * ctx); - -extern void intelChooseRenderState(GLcontext * ctx); - -extern void intelStartInlinePrimitive(struct intel_context *intel, - GLuint prim, GLuint flags); -extern void intelWrapInlinePrimitive(struct intel_context *intel); - -GLuint *intelExtendInlinePrimitive(struct intel_context *intel, - GLuint dwords); - - -void intel_meta_draw_quad(struct intel_context *intel, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLfloat z, - GLuint color, - GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1); - -void intel_meta_draw_poly(struct intel_context *intel, - GLuint n, - GLfloat xy[][2], - GLfloat z, GLuint color, GLfloat tex[][2]); - - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h deleted file mode 100644 index a877f3c2f4..0000000000 --- a/src/mesa/drivers/dri/i915tex/server/i830_common.h +++ /dev/null @@ -1,236 +0,0 @@ -/************************************************************************** - -Copyright 2001 VA Linux Systems Inc., Fremont, California. -Copyright 2002 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 -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 -ATI, VA LINUX SYSTEMS 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. - -**************************************************************************/ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ - -#ifndef _I830_COMMON_H_ -#define _I830_COMMON_H_ - - -#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ -#define I830_LOG_MIN_TEX_REGION_SIZE 14 - - -/* Driver specific DRM command indices - * NOTE: these are not OS specific, but they are driver specific - */ -#define DRM_I830_INIT 0x00 -#define DRM_I830_FLUSH 0x01 -#define DRM_I830_FLIP 0x02 -#define DRM_I830_BATCHBUFFER 0x03 -#define DRM_I830_IRQ_EMIT 0x04 -#define DRM_I830_IRQ_WAIT 0x05 -#define DRM_I830_GETPARAM 0x06 -#define DRM_I830_SETPARAM 0x07 -#define DRM_I830_ALLOC 0x08 -#define DRM_I830_FREE 0x09 -#define DRM_I830_INIT_HEAP 0x0a -#define DRM_I830_CMDBUFFER 0x0b -#define DRM_I830_DESTROY_HEAP 0x0c -#define DRM_I830_SET_VBLANK_PIPE 0x0d -#define DRM_I830_GET_VBLANK_PIPE 0x0e - -typedef struct { - enum { - I830_INIT_DMA = 0x01, - I830_CLEANUP_DMA = 0x02, - I830_RESUME_DMA = 0x03 - } func; - unsigned int mmio_offset; - int sarea_priv_offset; - unsigned int ring_start; - unsigned int ring_end; - unsigned int ring_size; - unsigned int front_offset; - unsigned int back_offset; - unsigned int depth_offset; - unsigned int w; - unsigned int h; - unsigned int pitch; - unsigned int pitch_bits; - unsigned int back_pitch; - unsigned int depth_pitch; - unsigned int cpp; - unsigned int chipset; -} drmI830Init; - -typedef struct { - drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; - int last_upload; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - int last_dispatch; /* age of the most recently dispatched buffer */ - int ctxOwner; /* last context to upload state */ - /** Last context that used the buffer manager. */ - int texAge; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - int width, height; /* screen size in pixels */ - - drm_handle_t front_handle; - int front_offset; - int front_size; - - drm_handle_t back_handle; - int back_offset; - int back_size; - - drm_handle_t depth_handle; - int depth_offset; - int depth_size; - - drm_handle_t tex_handle; - int tex_offset; - int tex_size; - int log_tex_granularity; - int pitch; - int rotation; /* 0, 90, 180 or 270 */ - int rotated_offset; - int rotated_size; - int rotated_pitch; - int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; - - int planeA_x; - int planeA_y; - int planeA_w; - int planeA_h; - int planeB_x; - int planeB_y; - int planeB_w; - int planeB_h; - - /* Triple buffering */ - drm_handle_t third_handle; - int third_offset; - int third_size; - unsigned int third_tiled; - - /* buffer object handles for the static buffers. May change - * over the lifetime of the client, though it doesn't in our current - * implementation. - */ - unsigned int front_bo_handle; - unsigned int back_bo_handle; - unsigned int third_bo_handle; - unsigned int depth_bo_handle; -} drmI830Sarea; - -/* Flags for perf_boxes - */ -#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ -#define I830_BOX_FLIP 0x2 /* populated by kernel */ -#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ -#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ -#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ - - -typedef struct { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830BatchBuffer; - -typedef struct { - char *buf; /* agp offset */ - int sz; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830CmdBuffer; - -typedef struct { - int *irq_seq; -} drmI830IrqEmit; - -typedef struct { - int irq_seq; -} drmI830IrqWait; - -typedef struct { - int param; - int *value; -} drmI830GetParam; - -#define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 - -typedef struct { - int param; - int value; -} drmI830SetParam; - -#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 -#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 -#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 - - -/* A memory manager for regions of shared memory: - */ -#define I830_MEM_REGION_AGP 1 - -typedef struct { - int region; - int alignment; - int size; - int *region_offset; /* offset from start of fb or agp */ -} drmI830MemAlloc; - -typedef struct { - int region; - int region_offset; -} drmI830MemFree; - -typedef struct { - int region; - int size; - int start; -} drmI830MemInitHeap; - -typedef struct { - int region; -} drmI830MemDestroyHeap; - -#define DRM_I830_VBLANK_PIPE_A 1 -#define DRM_I830_VBLANK_PIPE_B 2 - -typedef struct { - int pipe; -} drmI830VBlankPipe; - -#endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i915tex/server/i830_dri.h b/src/mesa/drivers/dri/i915tex/server/i830_dri.h deleted file mode 100644 index c2a3af8cbf..0000000000 --- a/src/mesa/drivers/dri/i915tex/server/i830_dri.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ - -#ifndef _I830_DRI_H -#define _I830_DRI_H - -#include "xf86drm.h" -#include "i830_common.h" - -#define I830_MAX_DRAWABLES 256 - -#define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 7 -#define I830_PATCHLEVEL 2 - -#define I830_REG_SIZE 0x80000 - -typedef struct _I830DRIRec { - drm_handle_t regs; - drmSize regsSize; - - drmSize unused1; /* backbufferSize */ - drm_handle_t unused2; /* backbuffer */ - - drmSize unused3; /* depthbufferSize */ - drm_handle_t unused4; /* depthbuffer */ - - drmSize unused5; /* rotatedSize */ - drm_handle_t unused6; /* rotatedbuffer */ - - drm_handle_t unused7; /* textures */ - int unused8; /* textureSize */ - - drm_handle_t unused9; /* agp_buffers */ - drmSize unused10; /* agp_buf_size */ - - int deviceID; - int width; - int height; - int mem; - int cpp; - int bitsPerPixel; - - int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - - int unused12; /* logTextureGranularity */ - int unused13; /* textureOffset */ - - int irq; - int sarea_priv_offset; -} I830DRIRec, *I830DRIPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830ConfigPrivRec, *I830ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830DRIContextRec, *I830DRIContextPtr; - - -#endif diff --git a/src/mesa/drivers/dri/i915tex/server/intel.h b/src/mesa/drivers/dri/i915tex/server/intel.h deleted file mode 100644 index 6ea72499c1..0000000000 --- a/src/mesa/drivers/dri/i915tex/server/intel.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef _INTEL_H_ -#define _INTEL_H_ - -#include "xf86drm.h" /* drm_handle_t, etc */ - -/* Intel */ -#ifndef PCI_CHIP_I810 -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 -#define PCI_CHIP_I810_BRIDGE 0x7120 -#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 -#define PCI_CHIP_I810_E_BRIDGE 0x7124 -#define PCI_CHIP_I815_BRIDGE 0x1130 -#endif - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 - -#ifndef PCI_CHIP_I855_GM -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I855_GM_BRIDGE 0x3580 -#endif - -#ifndef PCI_CHIP_I865_G -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I865_G_BRIDGE 0x2570 -#endif - -#ifndef PCI_CHIP_I915_G -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I915_GM -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I915_GM_BRIDGE 0x2590 -#endif - -#ifndef PCI_CHIP_E7221_G -#define PCI_CHIP_E7221_G 0x258A -/* Same as I915_G_BRIDGE */ -#define PCI_CHIP_E7221_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I945_G -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_G_BRIDGE 0x2770 -#endif - -#ifndef PCI_CHIP_I945_GM -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 -#endif - -#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ - pI810->Chipset == PCI_CHIP_I810_DC100 || \ - pI810->Chipset == PCI_CHIP_I810_E) -#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) -#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) -#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) -#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) -#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) -#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) -#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) - -#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) -#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) -#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) -#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) - -#define I830_GMCH_CTRL 0x52 - -#define I830_GMCH_MEM_MASK 0x1 -#define I830_GMCH_MEM_64M 0x1 -#define I830_GMCH_MEM_128M 0 - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_DISABLED 0x00 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK (0x7 << 4) -#define I855_GMCH_GMS_DISABLED 0x00 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -typedef unsigned char Bool; -#define TRUE 1 -#define FALSE 0 - -#define PIPE_NONE 0<<0 -#define PIPE_CRT 1<<0 -#define PIPE_TV 1<<1 -#define PIPE_DFP 1<<2 -#define PIPE_LFP 1<<3 -#define PIPE_CRT2 1<<4 -#define PIPE_TV2 1<<5 -#define PIPE_DFP2 1<<6 -#define PIPE_LFP2 1<<7 - -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - drm_handle_t Key; - unsigned long Pitch; // add pitch - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; - -typedef struct { - int tail_mask; - I830MemRange mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -typedef struct _I830Rec { - unsigned char *MMIOBase; - unsigned char *FbBase; - int cpp; - uint32_t aper_size; - unsigned int bios_version; - - /* These are set in PreInit and never changed. */ - long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - long BIOSMemorySize; /* min stolen pool size */ - int BIOSMemSizeLoc; - - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; - - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; - - I830RingBuffer *LpRing; - - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; - int TexGranularity; - I830MemRange ContextMem; - int drmMinor; - Bool have3DWindows; - - Bool NeedRingBufferLow; - Bool allowPageFlip; - Bool disableTiling; - - int Chipset; - unsigned long LinearAddr; - unsigned long MMIOAddr; - - drmSize registerSize; /**< \brief MMIO register map size */ - drm_handle_t registerHandle; /**< \brief MMIO register map handle */ - // IOADDRESS ioBase; - int irq; /**< \brief IRQ number */ - int GttBound; - - drm_handle_t ring_map; - unsigned int Fence[8]; - -} I830Rec; - -/* - * 12288 is set as the maximum, chosen because it is enough for - * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. - */ -#define I830_MAXIMUM_VBIOS_MEM 12288 -#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) -#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) - -/* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -#define KB(x) ((x) * 1024) -#define MB(x) ((x) * KB(1024)) - -#define GTT_PAGE_SIZE KB(4) -#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) -#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) -#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) -#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(128) - - -/* Ring buffer registers, p277, overview p19 - */ -#define LP_RING 0x2030 -#define HP_RING 0x2040 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define I830_TAIL_MASK 0x001FFFF8 - -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define I830_HEAD_MASK 0x001FFFFC - -#define RING_START 0x08 -#define START_ADDR 0x03FFFFF8 -#define I830_RING_START_MASK 0xFFFFF000 - -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define I830_RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - - -/* Fence/Tiling ranges [0..7] - */ -#define FENCE 0x2000 -#define FENCE_NR 8 - -#define I915G_FENCE_START_MASK 0x0ff00000 - -#define I830_FENCE_START_MASK 0x07f80000 - -#define FENCE_START_MASK 0x03F80000 -#define FENCE_X_MAJOR 0x00000000 -#define FENCE_Y_MAJOR 0x00001000 -#define FENCE_SIZE_MASK 0x00000700 -#define FENCE_SIZE_512K 0x00000000 -#define FENCE_SIZE_1M 0x00000100 -#define FENCE_SIZE_2M 0x00000200 -#define FENCE_SIZE_4M 0x00000300 -#define FENCE_SIZE_8M 0x00000400 -#define FENCE_SIZE_16M 0x00000500 -#define FENCE_SIZE_32M 0x00000600 -#define FENCE_SIZE_64M 0x00000700 -#define I915G_FENCE_SIZE_1M 0x00000000 -#define I915G_FENCE_SIZE_2M 0x00000100 -#define I915G_FENCE_SIZE_4M 0x00000200 -#define I915G_FENCE_SIZE_8M 0x00000300 -#define I915G_FENCE_SIZE_16M 0x00000400 -#define I915G_FENCE_SIZE_32M 0x00000500 -#define I915G_FENCE_SIZE_64M 0x00000600 -#define I915G_FENCE_SIZE_128M 0x00000700 -#define FENCE_PITCH_1 0x00000000 -#define FENCE_PITCH_2 0x00000010 -#define FENCE_PITCH_4 0x00000020 -#define FENCE_PITCH_8 0x00000030 -#define FENCE_PITCH_16 0x00000040 -#define FENCE_PITCH_32 0x00000050 -#define FENCE_PITCH_64 0x00000060 -#define FENCE_VALID 0x00000001 - -#include - -# define MMIO_IN8(base, offset) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - read_MMIO_LE32(base, offset) -# define MMIO_OUT8(base, offset, val) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) - - - /* Memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(MMIO, addr) -#define INREG(addr) MMIO_IN32(MMIO, addr) -#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) -#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) - -#define DSPABASE 0x70184 - -#endif diff --git a/src/mesa/drivers/dri/i915tex/server/intel_dri.c b/src/mesa/drivers/dri/i915tex/server/intel_dri.c deleted file mode 100644 index e49c4214ad..0000000000 --- a/src/mesa/drivers/dri/i915tex/server/intel_dri.c +++ /dev/null @@ -1,1306 +0,0 @@ -/** - * \file server/intel_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) - - 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 THE COPYRIGHT HOLDERS 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. -*/ - -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "intel.h" -#include "i830_dri.h" - -#include "memops.h" -#include "pciaccess.h" - -static size_t drm_page_size; -static int nextTile = 0; -#define xf86DrvMsg(...) do {} while(0) - -static const int pitches[] = { - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 -}; - -static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); - -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - -static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - unsigned char *MMIO = ctx->MMIOAddress; - - for (i = 0; i < 8; i++) { - OUTREG(FENCE + i * 4, pI830->Fence[i]); - // if (I810_DEBUG & DEBUG_VERBOSE_VGA) - fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); - } -} - -/* Tiled memory is good... really, really good... - * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. - */ -static void -SetFence(const DRIDriverContext *ctx, I830Rec *pI830, - int nr, unsigned int start, unsigned int pitch, - unsigned int size) -{ - unsigned int val; - unsigned int fence_mask = 0; - unsigned int fence_pitch; - - if (nr < 0 || nr > 7) { - fprintf(stderr, - "SetFence: fence %d out of range\n",nr); - return; - } - - pI830->Fence[nr] = 0; - - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (start & fence_mask) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - fprintf(stderr, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } - - if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - pI830->Fence[nr] = val; -} - -static Bool -MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) -{ - int pitch, ntiles, i; - - pitch = pMem->Pitch * ctx->cpp; - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - - /* Clear out */ - for (i = 0; i < 8; i++) - pI830->Fence[i] = 0; - - nextTile = 0; - - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { - fprintf(stderr, - "Activating tiled memory for the back buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { - fprintf(stderr, - "Activating tiled memory for the depth buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the depth buffer.\n"); - } - } - - return; -} - -static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - struct pci_device host_bridge, ig_dev; - uint32_t gmch_ctrl; - int memsize = 0; - int range; - uint32_t aper_size; - uint32_t membase2 = 0; - - memset(&host_bridge, 0, sizeof(host_bridge)); - memset(&ig_dev, 0, sizeof(ig_dev)); - - ig_dev.dev = 2; - - pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); - - if (IS_I830(pI830) || IS_845G(pI830)) { - if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - aper_size = 0x80000000; - } else { - aper_size = 0x40000000; - } - } else { - if (IS_I9XX(pI830)) { - int ret; - ret = pci_device_cfg_read_u32(&ig_dev, &membase2, 0x18); - if (membase2 & 0x08000000) - aper_size = 0x8000000; - else - aper_size = 0x10000000; - - fprintf(stderr,"aper size is %08X %08x %d\n", aper_size, membase2, ret); - } else - aper_size = 0x8000000; - } - - pI830->aper_size = aper_size; - - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB */ - range = (ctx->shared.fbSize / (1024*1024)) + 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - if (memsize > 0) { - fprintf(stderr, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - fprintf(stderr, - "no video memory detected.\n"); - } - return memsize; -} - -static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) -{ - unsigned long mode = 0x4; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - return 1; -} - -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) -{ - long needed, start, end; - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - start = ROUND_TO(pool->Free.Start, alignment); - end = ROUND_TO(start + size, alignment); - needed = end - pool->Free.Start; - } - if (needed > pool->Free.Size) { - return 0; - } - - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; -} - -static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) -{ - unsigned long start, end; - unsigned long newApStart, newApEnd; - int ret; - if (!result || !size) - return 0; - - if (!alignment) - alignment = 4; - - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - end = ROUND_TO(start + size, alignment); - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - - ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); - - if (ret) - { - fprintf(stderr,"drmAgpAlloc failed %d\n", ret); - return 0; - } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - // pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; -} - -unsigned long -I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, long size, - unsigned long alignment, int flags) -{ - unsigned long ret; - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - if (pool->Free.Size < size) { - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - else { - ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); - if (ret == 0) - ret = AllocFromAGP(ctx, pI830, size, alignment, result); - } - return ret; -} - -static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); -} - -/* simple memory allocation routines needed */ -/* put ring buffer in low memory */ -/* need to allocate front, back, depth buffers aligned correctly, - allocate ring buffer, -*/ - -/* */ -static Bool -I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long size, ret; - unsigned long lines, lineSize, align; - - /* allocate ring buffer */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - size = PRIMARY_RINGBUFFER_SIZE; - - ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); - - if (ret != size) - { - fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); - return FALSE; - } - - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - - - /* allocate front buffer */ - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; - - align = KB(512); - - lineSize = ctx->shared.virtualWidth * ctx->cpp; - lines = (ctx->shared.virtualHeight + 15) / 16 * 16; - size = lineSize * lines; - size = ROUND_TO_PAGE(size); - - align = GetBestTileAlignment(size); - - ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate front buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate back buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - - ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate context buffer %ld\n", ret); - return FALSE; - } - -#if 0 - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - size = 32768 * 1024; - ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); - if (ret < size) - { - fprintf(stderr,"unable to allocate texture memory %ld\n", ret); - return FALSE; - } -#endif - - return TRUE; -} - -static Bool -I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - if (!BindAgpRange(ctx, &pI830->LpRing->mem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->FrontBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->BackBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->DepthBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->ContextMem)) - return FALSE; -#if 0 - if (!BindAgpRange(ctx, &pI830->TexMem)) - return FALSE; -#endif - return TRUE; -} - -static void SetupDRIMM(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long aperEnd = ROUND_DOWN_TO(pI830->aper_size, GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - unsigned long aperStart = ROUND_TO(pI830->aper_size - KB(32768), GTT_PAGE_SIZE) / GTT_PAGE_SIZE; - - fprintf(stderr, "aper size is %08X\n", ctx->shared.fbSize); - if (drmMMInit(ctx->drmFD, aperStart, aperEnd - aperStart, DRM_BO_MEM_TT)) { - fprintf(stderr, - "DRM MM Initialization Failed\n"); - } else { - fprintf(stderr, - "DRM MM Initialized at offset 0x%lx length %d page\n", aperStart, aperEnd-aperStart); - } - -} - -static Bool -I830CleanupDma(const DRIDriverContext *ctx) -{ - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_CLEANUP_DMA; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, "I830 Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) -{ - I830RingBuffer *ring = pI830->LpRing; - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_INIT_DMA; - - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; - - info.mmio_offset = (unsigned int)ctx->MMIOStart; - - info.sarea_priv_offset = sizeof(drm_sarea_t); - - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; - info.w = ctx->shared.virtualWidth; - info.h = ctx->shared.virtualHeight; - info.pitch = ctx->shared.virtualWidth; - info.back_pitch = pI830->BackBuffer.Pitch; - info.depth_pitch = pI830->DepthBuffer.Pitch; - info.cpp = ctx->cpp; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, - "I830 Dma Initialization Failed\n"); - return FALSE; - } - - return TRUE; -} - -static int I830CheckDRMVersion( const DRIDriverContext *ctx, - I830Rec *pI830 ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I830DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i915.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - pI830->drmMinor = version->version_minor; - drmFreeVersion(version); - } - return 1; -} - -static void -I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned int itemp; - unsigned char *MMIO = ctx->MMIOAddress; - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - - pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); - pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); - if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; - - SetFenceRegs(ctx, pI830); - - /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky - hacky hacky */ - OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); - -} - -static Bool -I830SetParam(const DRIDriverContext *ctx, int param, int value) -{ - drmI830SetParam sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { - fprintf(stderr, "I830 SetParam Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - fprintf(stderr, - "[drm] Mapping front buffer\n"); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_FRAME_BUFFER, /*DRM_AGP,*/ - 0, - &sarea->front_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - return FALSE; - } - ctx->shared.hFrameBuffer = sarea->front_handle; - ctx->shared.fbSize = sarea->front_size; - fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", - sarea->front_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->back_offset), - sarea->back_size, DRM_AGP, 0, - &sarea->back_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", - sarea->back_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->depth_offset, - sarea->depth_size, DRM_AGP, 0, - &sarea->depth_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", - sarea->depth_handle); - -#if 0 - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->tex_offset, - sarea->tex_size, DRM_AGP, 0, - &sarea->tex_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] textures = 0x%08x\n", - sarea->tex_handle); -#endif - return TRUE; -} - - -static void -I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ -#if 1 - if (sarea->front_handle) { - drmRmMap(ctx->drmFD, sarea->front_handle); - sarea->front_handle = 0; - } -#endif - if (sarea->back_handle) { - drmRmMap(ctx->drmFD, sarea->back_handle); - sarea->back_handle = 0; - } - if (sarea->depth_handle) { - drmRmMap(ctx->drmFD, sarea->depth_handle); - sarea->depth_handle = 0; - } - if (sarea->tex_handle) { - drmRmMap(ctx->drmFD, sarea->tex_handle); - sarea->tex_handle = 0; - } -} - -static Bool -I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)pI830->LpRing->mem.Start, - pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { - fprintf(stderr, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); - - if (I830InitDma(ctx, pI830) == FALSE) { - return FALSE; - } - - /* init to zero to be safe */ - - I830DRIMapScreenRegions(ctx, pI830, sarea); - SetupDRIMM(ctx, pI830); - - if (ctx->pciDevice != PCI_CHIP_845_G && - ctx->pciDevice != PCI_CHIP_I830_M) { - I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); - } - - /* Okay now initialize the dma engine */ - { - pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { - fprintf(stderr, - "[drm] failure adding irq handler\n"); - pI830->irq = 0; - return FALSE; - } - else - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pI830->irq); - } - - fprintf(stderr, "[dri] visual configs initialized\n"); - - return TRUE; -} - -static Bool -I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* need to drmMap front and back buffers and zero them */ - drmAddress map_addr; - int ret; - - ret = drmMap(ctx->drmFD, - sarea->front_handle, - sarea->front_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map front buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->front_size); - drmUnmap(map_addr, sarea->front_size); - - - ret = drmMap(ctx->drmFD, - sarea->back_handle, - sarea->back_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map back buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->back_size); - drmUnmap(map_addr, sarea->back_size); - - return TRUE; -} - -static Bool -I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) - -{ - I830DRIPtr pI830DRI; - drmI830Sarea *pSAREAPriv; - int err; - - drm_page_size = getpagesize(); - - pI830->registerSize = ctx->MMIOSize; - /* This is a hack for now. We have to have more than a 4k page here - * because of the size of the state. However, the state should be - * in a per-context mapping. This will be added in the Mesa 3.5 port - * of the I830 driver. - */ - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i915", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - - } - - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pI830->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", pI830->registerHandle); - - - if (!I830CheckDRMVersion(ctx, pI830)) { - return FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the SAREA private data structure */ - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = KB(40000); - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->StolenPool.Total.Size; - - if (!AgpInit(ctx, pI830)) - return FALSE; - - if (I830AllocateMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - if (I830BindMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - pSAREAPriv->rotated_offset = -1; - pSAREAPriv->rotated_size = 0; - pSAREAPriv->rotated_pitch = ctx->shared.virtualWidth; - - pSAREAPriv->front_offset = pI830->FrontBuffer.Start; - pSAREAPriv->front_size = pI830->FrontBuffer.Size; - pSAREAPriv->width = ctx->shared.virtualWidth; - pSAREAPriv->height = ctx->shared.virtualHeight; - pSAREAPriv->pitch = ctx->shared.virtualWidth; - pSAREAPriv->virtualX = ctx->shared.virtualWidth; - pSAREAPriv->virtualY = ctx->shared.virtualHeight; - pSAREAPriv->back_offset = pI830->BackBuffer.Start; - pSAREAPriv->back_size = pI830->BackBuffer.Size; - pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; - pSAREAPriv->depth_size = pI830->DepthBuffer.Size; -#if 0 - pSAREAPriv->tex_offset = pI830->TexMem.Start; - pSAREAPriv->tex_size = pI830->TexMem.Size; -#endif - pSAREAPriv->log_tex_granularity = pI830->TexGranularity; - - ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); - ctx->driverClientMsgSize = sizeof(I830DRIRec); - pI830DRI = (I830DRIPtr)ctx->driverClientMsg; - pI830DRI->deviceID = pI830->Chipset; - pI830DRI->regsSize = I830_REG_SIZE; - pI830DRI->width = ctx->shared.virtualWidth; - pI830DRI->height = ctx->shared.virtualHeight; - pI830DRI->mem = ctx->shared.fbSize; - pI830DRI->cpp = ctx->cpp; - - pI830DRI->bitsPerPixel = ctx->bpp; - pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); - if (err == FALSE) - return FALSE; - - I830SetupMemoryTiling(ctx, pI830); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - I830ClearScreen(ctx, pI830, pSAREAPriv); - - I830SetRingRegs(ctx, pI830); - - return TRUE; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int i830ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i830PostValidateMode( const DRIDriverContext *ctx ) -{ - I830Rec *pI830 = ctx->driverPrivate; - - I830SetRingRegs(ctx, pI830); - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i830InitFBDev( DRIDriverContext *ctx ) -{ - I830Rec *pI830 = calloc(1, sizeof(I830Rec)); - int i; - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = ctx->shared.virtualWidth; - } - - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= ctx->shared.virtualWidth) { - ctx->shared.virtualWidth = pitches[i]; - break; - } - } - - ctx->driverPrivate = (void *)pI830; - - pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); - pI830->Chipset = ctx->chipset; - pI830->LinearAddr = ctx->FBStart; - - if (!I830ScreenInit( ctx, pI830 )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i830HaltFBDev( DRIDriverContext *ctx ) -{ - drmI830Sarea *pSAREAPriv; - I830Rec *pI830 = ctx->driverPrivate; - - if (pI830->irq) { - drmCtlUninstHandler(ctx->drmFD); - pI830->irq = 0; } - - I830CleanupDma(ctx); - - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - - I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i830ValidateMode, - i830PostValidateMode, - i830InitFBDev, - i830HaltFBDev, - NULL,//I830EngineShutdown, - NULL, //I830EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; -- cgit v1.2.3 From c8cb87d35686c155143ed3e511e1ea674d8371a3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 24 Sep 2007 13:36:56 -0700 Subject: Remove leftover code for i915_texprog.c noticed in crossbar review. --- src/mesa/drivers/dri/i915/i915_context.h | 15 --------------- src/mesa/drivers/dri/i915/i915_program.c | 6 ------ src/mesa/drivers/dri/i915/intel_context.c | 4 ---- 3 files changed, 25 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index 0be2b3cc8b..1070de1a54 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -173,21 +173,6 @@ struct i915_fragment_program const GLfloat *values; /* Pointer to tracked values */ } param[I915_MAX_CONSTANT]; GLuint nr_params; - - - /* Helpers for i915_texprog.c: - */ - GLuint src_texture; /* Reg containing sampled texture color, - * else UREG_BAD. - */ - - GLuint src_previous; /* Reg containing color from previous - * stage. May need to be decl'd. - */ - - GLuint last_tex_stage; /* Number of last enabled texture unit */ - - struct vertex_buffer *VB; }; diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c index ed45e4f806..c6c6434023 100644 --- a/src/mesa/drivers/dri/i915/i915_program.c +++ b/src/mesa/drivers/dri/i915/i915_program.c @@ -391,7 +391,6 @@ void i915_init_program(struct i915_context *i915, struct i915_fragment_program *p) { GLcontext *ctx = &i915->intel.ctx; - TNLcontext *tnl = TNL_CONTEXT(ctx); p->translated = 0; p->params_uptodate = 0; @@ -417,11 +416,6 @@ i915_init_program(struct i915_context *i915, struct i915_fragment_program *p) p->depth_written = 0; p->nr_params = 0; - p->src_texture = UREG_BAD; - p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE); - p->last_tex_stage = 0; - p->VB = &tnl->vb; - *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; } diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 16fbe38e64..041a155fe7 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -159,10 +159,6 @@ intelGetString(GLcontext * ctx, GLenum name) /** * Extension strings exported by the intel driver. - * - * \note - * It appears that ARB_texture_env_crossbar has "disappeared" compared to the - * old i830-specific driver. */ const struct dri_extension card_extensions[] = { {"GL_ARB_multisample", GL_ARB_multisample_functions}, -- cgit v1.2.3 From 919709af6ba19eb30d293a161d89a0b8fccb9ec7 Mon Sep 17 00:00:00 2001 From: Roland Bär Date: Mon, 24 Sep 2007 13:47:26 -0700 Subject: [i965] Bug #11812: Fix fwrite return value checks in AUB file code. --- src/mesa/drivers/dri/i965/brw_aub.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_aub.c b/src/mesa/drivers/dri/i965/brw_aub.c index f851a5b795..c549f7a4f6 100644 --- a/src/mesa/drivers/dri/i965/brw_aub.c +++ b/src/mesa/drivers/dri/i965/brw_aub.c @@ -80,7 +80,7 @@ static void init_aubfile( FILE *aub_file ) fh.hour = (nr>>16) & 0xff; fh.comment_length = 0x0; - if (fwrite(&fh, sizeof(fh), 1, aub_file) < 0) + if (fwrite(&fh, sizeof(fh), 1, aub_file) < 1) FAIL; /* Setup the GTT starting at main memory address zero (!): @@ -96,12 +96,12 @@ static void init_aubfile( FILE *aub_file ) bh.address = PGETBL_CTL; bh.length = 0x4; - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) FAIL; data = 0x0 | PGETBL_ENABLED; - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + if (fwrite(&data, sizeof(data), 1, aub_file) < 1) FAIL; } @@ -128,7 +128,7 @@ static void init_aub_gtt( struct brw_context *brw, bh.address = start_offset / 4096 * 4; bh.length = size / 4096 * 4; - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 0) + if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) FAIL; for (i = 0; i < size / 4096; i++) { @@ -136,7 +136,7 @@ static void init_aub_gtt( struct brw_context *brw, brw->next_free_page += 4096; - if (fwrite(&data, sizeof(data), 1, aub_file) < 0) + if (fwrite(&data, sizeof(data), 1, aub_file) < 1) FAIL; } @@ -149,10 +149,10 @@ static void write_block_header( FILE *aub_file, { sz = (sz + 3) & ~3; - if (fwrite(bh, sizeof(*bh), 1, aub_file) < 0) + if (fwrite(bh, sizeof(*bh), 1, aub_file) < 1) FAIL; - if (fwrite(data, sz, 1, aub_file) < 0) + if (fwrite(data, sz, 1, aub_file) < 1) FAIL; fflush(aub_file); @@ -162,7 +162,7 @@ static void write_block_header( FILE *aub_file, static void write_dump_bmp( FILE *aub_file, struct aub_dump_bmp *db ) { - if (fwrite(db, sizeof(*db), 1, aub_file) < 0) + if (fwrite(db, sizeof(*db), 1, aub_file) < 1) FAIL; fflush(aub_file); -- cgit v1.2.3 From f388d62b39e9273dd8aac425da54015af91192d8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 25 Sep 2007 16:22:00 +1000 Subject: drm: update bufmgr code to reflect changes in drm interface --- src/mesa/drivers/dri/common/dri_bufmgr_ttm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c index bda8e34190..235398eb87 100644 --- a/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c +++ b/src/mesa/drivers/dri/common/dri_bufmgr_ttm.c @@ -305,7 +305,7 @@ dri_ttm_validate(dri_bo *buf, unsigned int flags) mask = DRM_BO_MASK_MEM; mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE); - err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, mask, 0); + err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, 0, flags, mask, 0); if (err == 0) { /* XXX: add to fence list for sanity checking */ @@ -343,7 +343,7 @@ dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name, fence_ttm->refcount = 1; fence_ttm->name = name; fence_ttm->fence.bufmgr = bufmgr; - ret = drmFenceBuffers(bufmgr_ttm->fd, type, &fence_ttm->drm_fence); + ret = drmFenceBuffers(bufmgr_ttm->fd, type, 0, &fence_ttm->drm_fence); if (ret) { fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret)); free(fence_ttm); -- cgit v1.2.3 From 395b3bf6f95b35a84a74d4baf7e04bc67cf3771c Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 26 Sep 2007 10:00:41 +0800 Subject: fix a bug in 965 ARB_occlusion_query, fd.o bug #12132 --- src/mesa/drivers/dri/i965/intel_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 4a95087d78..f3ec2b2eee 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -271,7 +271,7 @@ intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) }; intel->stats_wm++; intelFinish(&intel->ctx); - drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); } static void @@ -285,7 +285,7 @@ intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) .data = &tmp }; intelFinish(&intel->ctx); - drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); q->Result = tmp - q->Result; q->Ready = GL_TRUE; intel->stats_wm--; -- cgit v1.2.3 From 175db68db59c6b917306adff98442d590df9af06 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 26 Sep 2007 16:42:50 +0800 Subject: i965: The cube map texture coordinates must be devided by the component with the largest absolute value before they are delivered. fix bug #12421 --- src/mesa/drivers/dri/i965/brw_wm_fp.c | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 62bb081206..67154c1b13 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -525,7 +525,57 @@ static void precalc_tex( struct brw_wm_compile *c, struct prog_src_register coord; struct prog_dst_register tmpcoord; - if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { + if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) { + struct prog_instruction *out; + struct prog_dst_register tmp0 = get_temp(c); + struct prog_src_register tmp0src = src_reg_from_dst(tmp0); + struct prog_dst_register tmp1 = get_temp(c); + struct prog_src_register tmp1src = src_reg_from_dst(tmp1); + struct prog_src_register src0 = inst->SrcReg[0]; + + tmpcoord = get_temp(c); + coord = src_reg_from_dst(tmpcoord); + + out = emit_op(c, OPCODE_MOV, + tmpcoord, + 0, 0, 0, + src0, + src_undef(), + src_undef()); + out->SrcReg[0].NegateBase = 0; + out->SrcReg[0].Abs = 1; + + emit_op(c, OPCODE_MAX, + tmp0, + 0, 0, 0, + src_swizzle1(coord, X), + src_swizzle1(coord, Y), + src_undef()); + + emit_op(c, OPCODE_MAX, + tmp1, + 0, 0, 0, + tmp0src, + src_swizzle1(coord, Z), + src_undef()); + + emit_op(c, OPCODE_RCP, + tmp0, + 0, 0, 0, + tmp1src, + src_undef(), + src_undef()); + + emit_op(c, OPCODE_MUL, + tmpcoord, + 0, 0, 0, + src0, + tmp0src, + src_undef()); + + release_temp(c, tmp0); + release_temp(c, tmp1); + } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { struct prog_src_register scale = search_or_add_param5( c, STATE_INTERNAL, -- cgit v1.2.3 From 67f6449743d006084df85693085eca79a966ad17 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 27 Sep 2007 11:15:42 +1000 Subject: i915/i965 merge serer directories along lines for radeon/r200 --- src/mesa/drivers/dri/i915/server/i830_common.h | 20 + src/mesa/drivers/dri/i965/Makefile | 14 +- src/mesa/drivers/dri/i965/server/i830_common.h | 222 ---- src/mesa/drivers/dri/i965/server/i830_dri.h | 63 -- src/mesa/drivers/dri/i965/server/intel.h | 328 ------ src/mesa/drivers/dri/i965/server/intel_dri.c | 1282 ------------------------ 6 files changed, 33 insertions(+), 1896 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/server/i830_common.h delete mode 100644 src/mesa/drivers/dri/i965/server/i830_dri.h delete mode 100644 src/mesa/drivers/dri/i965/server/intel.h delete mode 100644 src/mesa/drivers/dri/i965/server/intel_dri.c (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/i915/server/i830_common.h index a877f3c2f4..f1fd3939ab 100644 --- a/src/mesa/drivers/dri/i915/server/i830_common.h +++ b/src/mesa/drivers/dri/i915/server/i830_common.h @@ -54,6 +54,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_DESTROY_HEAP 0x0c #define DRM_I830_SET_VBLANK_PIPE 0x0d #define DRM_I830_GET_VBLANK_PIPE 0x0e +#define DRM_I830_MMIO 0x10 typedef struct { enum { @@ -233,4 +234,23 @@ typedef struct { int pipe; } drmI830VBlankPipe; +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; + #endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 9e4ff112dc..15a6752e0f 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -77,6 +77,12 @@ DRIVER_SOURCES = \ brw_wm_state.c \ brw_wm_surface_state.c +SYMLINKS = \ + server/i830_dri.h \ + server/i830_common.h \ + server/intel_dri.c \ + server/intel.h + C_SOURCES = \ $(COMMON_SOURCES) \ $(MINIGLX_SOURCES) \ @@ -90,4 +96,10 @@ include ../Makefile.template intel_tex_layout.o: ../intel/intel_tex_layout.c -symlinks: +server: + mkdir -p server + +$(SYMLINKS): server + @[ -e $@ ] || ln -sf ../../i915/$@ server/ + +symlinks: $(SYMLINKS) diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h deleted file mode 100644 index f320378c2a..0000000000 --- a/src/mesa/drivers/dri/i965/server/i830_common.h +++ /dev/null @@ -1,222 +0,0 @@ -/************************************************************************** - -Copyright 2001 VA Linux Systems Inc., Fremont, California. -Copyright 2002 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 -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 -ATI, VA LINUX SYSTEMS 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. - -**************************************************************************/ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ - -#ifndef _I830_COMMON_H_ -#define _I830_COMMON_H_ - - -#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ -#define I830_LOG_MIN_TEX_REGION_SIZE 14 - - -/* Driver specific DRM command indices - * NOTE: these are not OS specific, but they are driver specific - */ -#define DRM_I830_INIT 0x00 -#define DRM_I830_FLUSH 0x01 -#define DRM_I830_FLIP 0x02 -#define DRM_I830_BATCHBUFFER 0x03 -#define DRM_I830_IRQ_EMIT 0x04 -#define DRM_I830_IRQ_WAIT 0x05 -#define DRM_I830_GETPARAM 0x06 -#define DRM_I830_SETPARAM 0x07 -#define DRM_I830_ALLOC 0x08 -#define DRM_I830_FREE 0x09 -#define DRM_I830_INIT_HEAP 0x0a -#define DRM_I830_CMDBUFFER 0x0b -#define DRM_I830_DESTROY_HEAP 0x0c -#define DRM_I830_MMIO 0x10 - -typedef struct { - enum { - I830_INIT_DMA = 0x01, - I830_CLEANUP_DMA = 0x02, - I830_RESUME_DMA = 0x03 - } func; - unsigned int mmio_offset; - int sarea_priv_offset; - unsigned int ring_start; - unsigned int ring_end; - unsigned int ring_size; - unsigned int front_offset; - unsigned int back_offset; - unsigned int depth_offset; - unsigned int w; - unsigned int h; - unsigned int pitch; - unsigned int pitch_bits; - unsigned int back_pitch; - unsigned int depth_pitch; - unsigned int cpp; - unsigned int chipset; -} drmI830Init; - -typedef struct { - drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; - int last_upload; /* last time texture was uploaded */ - int last_enqueue; /* last time a buffer was enqueued */ - volatile int last_dispatch; /* age of the most recently dispatched buffer */ - int ctxOwner; /* last context to upload state */ - int texAge; - int pf_enabled; /* is pageflipping allowed? */ - int pf_active; - int pf_current_page; /* which buffer is being displayed? */ - int perf_boxes; /* performance boxes to be displayed */ - int width, height; /* screen size in pixels */ - - drm_handle_t front_handle; - int front_offset; - int front_size; - - drm_handle_t back_handle; - int back_offset; - int back_size; - - drm_handle_t depth_handle; - int depth_offset; - int depth_size; - - drm_handle_t tex_handle; - int tex_offset; - int tex_size; - int log_tex_granularity; - int pitch; - int rotation; /* 0, 90, 180 or 270 */ - int rotated_offset; - int rotated_size; - int rotated_pitch; - int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; -} drmI830Sarea; - -/* Flags for perf_boxes - */ -#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ -#define I830_BOX_FLIP 0x2 /* populated by kernel */ -#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ -#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ -#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ - - -typedef struct { - int start; /* agp offset */ - int used; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830BatchBuffer; - -typedef struct { - char *buf; /* agp offset */ - int sz; /* nr bytes in use */ - int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ - int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ - int num_cliprects; /* mulitpass with multiple cliprects? */ - drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ -} drmI830CmdBuffer; - -typedef struct { - int *irq_seq; -} drmI830IrqEmit; - -typedef struct { - int irq_seq; -} drmI830IrqWait; - -typedef struct { - int param; - int *value; -} drmI830GetParam; - -#define I830_PARAM_IRQ_ACTIVE 1 -#define I830_PARAM_ALLOW_BATCHBUFFER 2 - -typedef struct { - int param; - int value; -} drmI830SetParam; - -#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 -#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 -#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 - - -/* A memory manager for regions of shared memory: - */ -#define I830_MEM_REGION_AGP 1 - -typedef struct { - int region; - int alignment; - int size; - int *region_offset; /* offset from start of fb or agp */ -} drmI830MemAlloc; - -typedef struct { - int region; - int region_offset; -} drmI830MemFree; - -typedef struct { - int region; - int size; - int start; -} drmI830MemInitHeap; - -typedef struct { - int region; -} drmI830MemDestroyHeap; - -#define MMIO_READ 0 -#define MMIO_WRITE 1 - -#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 -#define MMIO_REGS_IA_VERTICES_COUNT 1 -#define MMIO_REGS_VS_INVOCATION_COUNT 2 -#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 -#define MMIO_REGS_GS_INVOCATION_COUNT 4 -#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 -#define MMIO_REGS_CL_INVOCATION_COUNT 6 -#define MMIO_REGS_PS_INVOCATION_COUNT 7 -#define MMIO_REGS_PS_DEPTH_COUNT 8 - -typedef struct { - unsigned int read_write:1; - unsigned int reg:31; - void __user *data; -} drmI830MMIO; - -#endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i965/server/i830_dri.h b/src/mesa/drivers/dri/i965/server/i830_dri.h deleted file mode 100644 index 22951812ad..0000000000 --- a/src/mesa/drivers/dri/i965/server/i830_dri.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ - -#ifndef _I830_DRI_H -#define _I830_DRI_H - -#include "xf86drm.h" -#include "i830_common.h" - -#define I830_MAX_DRAWABLES 256 - -#define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 3 -#define I830_PATCHLEVEL 0 - -#define I830_REG_SIZE 0x80000 - -typedef struct _I830DRIRec { - drm_handle_t regs; - drmSize regsSize; - - drmSize unused1; /* backbufferSize */ - drm_handle_t unused2; /* backbuffer */ - - drmSize unused3; /* depthbufferSize */ - drm_handle_t unused4; /* depthbuffer */ - - drmSize unused5; /* rotatedSize /*/ - drm_handle_t unused6; /* rotatedbuffer */ - - drm_handle_t unused7; /* textures */ - int unused8; /* textureSize */ - - drm_handle_t unused9; /* agp_buffers */ - drmSize unused10; /* agp_buf_size */ - - int deviceID; - int width; - int height; - int mem; - int cpp; - int bitsPerPixel; - - int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - - int unused12; /* logTextureGranularity */ - int unused13; /* textureOffset */ - - int irq; - int sarea_priv_offset; -} I830DRIRec, *I830DRIPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830ConfigPrivRec, *I830ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830DRIContextRec, *I830DRIContextPtr; - - -#endif diff --git a/src/mesa/drivers/dri/i965/server/intel.h b/src/mesa/drivers/dri/i965/server/intel.h deleted file mode 100644 index d7858a20c8..0000000000 --- a/src/mesa/drivers/dri/i965/server/intel.h +++ /dev/null @@ -1,328 +0,0 @@ -#ifndef _INTEL_H_ -#define _INTEL_H_ - -#include "xf86drm.h" /* drm_handle_t, etc */ - -/* Intel */ -#ifndef PCI_CHIP_I810 -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 -#define PCI_CHIP_I810_BRIDGE 0x7120 -#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 -#define PCI_CHIP_I810_E_BRIDGE 0x7124 -#define PCI_CHIP_I815_BRIDGE 0x1130 -#endif - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 - -#ifndef PCI_CHIP_I855_GM -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I855_GM_BRIDGE 0x3580 -#endif - -#ifndef PCI_CHIP_I865_G -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I865_G_BRIDGE 0x2570 -#endif - -#ifndef PCI_CHIP_I915_G -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I915_GM -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I915_GM_BRIDGE 0x2590 -#endif - -#ifndef PCI_CHIP_E7221_G -#define PCI_CHIP_E7221_G 0x258A -/* Same as I915_G_BRIDGE */ -#define PCI_CHIP_E7221_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I945_G -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_G_BRIDGE 0x2770 -#endif - -#ifndef PCI_CHIP_I945_GM -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 -#endif - -#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ - pI810->Chipset == PCI_CHIP_I810_DC100 || \ - pI810->Chipset == PCI_CHIP_I810_E) -#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) -#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) -#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) -#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) -#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) -#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) -#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) - -#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) -#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) -#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) -#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) - -#define I830_GMCH_CTRL 0x52 - - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_DISABLED 0x00 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK (0x7 << 4) -#define I855_GMCH_GMS_DISABLED 0x00 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -typedef unsigned char Bool; -#define TRUE 1 -#define FALSE 0 - -#define PIPE_NONE 0<<0 -#define PIPE_CRT 1<<0 -#define PIPE_TV 1<<1 -#define PIPE_DFP 1<<2 -#define PIPE_LFP 1<<3 -#define PIPE_CRT2 1<<4 -#define PIPE_TV2 1<<5 -#define PIPE_DFP2 1<<6 -#define PIPE_LFP2 1<<7 - -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - drm_handle_t Key; - unsigned long Pitch; // add pitch - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; - -typedef struct { - int tail_mask; - I830MemRange mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -typedef struct _I830Rec { - unsigned char *MMIOBase; - unsigned char *FbBase; - int cpp; - - unsigned int bios_version; - - /* These are set in PreInit and never changed. */ - long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - long BIOSMemorySize; /* min stolen pool size */ - int BIOSMemSizeLoc; - - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; - - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; - - I830RingBuffer *LpRing; - - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; - int TexGranularity; - I830MemRange ContextMem; - int drmMinor; - Bool have3DWindows; - - Bool NeedRingBufferLow; - Bool allowPageFlip; - Bool disableTiling; - - int Chipset; - unsigned long LinearAddr; - unsigned long MMIOAddr; - - drmSize registerSize; /**< \brief MMIO register map size */ - drm_handle_t registerHandle; /**< \brief MMIO register map handle */ - // IOADDRESS ioBase; - int irq; /**< \brief IRQ number */ - int GttBound; - - drm_handle_t ring_map; - unsigned int Fence[8]; - -} I830Rec; - -/* - * 12288 is set as the maximum, chosen because it is enough for - * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. - */ -#define I830_MAXIMUM_VBIOS_MEM 12288 -#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) -#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) - -/* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -#define KB(x) ((x) * 1024) -#define MB(x) ((x) * KB(1024)) - -#define GTT_PAGE_SIZE KB(4) -#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) -#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) -#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) -#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(128) - - -/* Ring buffer registers, p277, overview p19 - */ -#define LP_RING 0x2030 -#define HP_RING 0x2040 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define I830_TAIL_MASK 0x001FFFF8 - -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define I830_HEAD_MASK 0x001FFFFC - -#define RING_START 0x08 -#define START_ADDR 0x03FFFFF8 -#define I830_RING_START_MASK 0xFFFFF000 - -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define I830_RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - - -/* Fence/Tiling ranges [0..7] - */ -#define FENCE 0x2000 -#define FENCE_NR 8 - -#define I915G_FENCE_START_MASK 0x0ff00000 - -#define I830_FENCE_START_MASK 0x07f80000 - -#define FENCE_START_MASK 0x03F80000 -#define FENCE_X_MAJOR 0x00000000 -#define FENCE_Y_MAJOR 0x00001000 -#define FENCE_SIZE_MASK 0x00000700 -#define FENCE_SIZE_512K 0x00000000 -#define FENCE_SIZE_1M 0x00000100 -#define FENCE_SIZE_2M 0x00000200 -#define FENCE_SIZE_4M 0x00000300 -#define FENCE_SIZE_8M 0x00000400 -#define FENCE_SIZE_16M 0x00000500 -#define FENCE_SIZE_32M 0x00000600 -#define FENCE_SIZE_64M 0x00000700 -#define I915G_FENCE_SIZE_1M 0x00000000 -#define I915G_FENCE_SIZE_2M 0x00000100 -#define I915G_FENCE_SIZE_4M 0x00000200 -#define I915G_FENCE_SIZE_8M 0x00000300 -#define I915G_FENCE_SIZE_16M 0x00000400 -#define I915G_FENCE_SIZE_32M 0x00000500 -#define I915G_FENCE_SIZE_64M 0x00000600 -#define I915G_FENCE_SIZE_128M 0x00000700 -#define FENCE_PITCH_1 0x00000000 -#define FENCE_PITCH_2 0x00000010 -#define FENCE_PITCH_4 0x00000020 -#define FENCE_PITCH_8 0x00000030 -#define FENCE_PITCH_16 0x00000040 -#define FENCE_PITCH_32 0x00000050 -#define FENCE_PITCH_64 0x00000060 -#define FENCE_VALID 0x00000001 - -#include - -# define MMIO_IN8(base, offset) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - read_MMIO_LE32(base, offset) -# define MMIO_OUT8(base, offset, val) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) - - - /* Memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(MMIO, addr) -#define INREG(addr) MMIO_IN32(MMIO, addr) -#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) -#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) - -#define DSPABASE 0x70184 - -#endif diff --git a/src/mesa/drivers/dri/i965/server/intel_dri.c b/src/mesa/drivers/dri/i965/server/intel_dri.c deleted file mode 100644 index 169fdbece3..0000000000 --- a/src/mesa/drivers/dri/i965/server/intel_dri.c +++ /dev/null @@ -1,1282 +0,0 @@ -/** - * \file server/intel_dri.c - * \brief File to perform the device-specific initialization tasks typically - * done in the X server. - * - * Here they are converted to run in the client (or perhaps a standalone - * process), and to work with the frame buffer device rather than the X - * server infrastructure. - * - * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) - - 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 THE COPYRIGHT HOLDERS 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. -*/ - -#include -#include -#include -#include -#include - -#include "driver.h" -#include "drm.h" - -#include "intel.h" -#include "i830_dri.h" - -#include "memops.h" -#include "pciaccess.h" - -static size_t drm_page_size; -static int nextTile = 0; -#define xf86DrvMsg(...) do {} while(0) - -static const int pitches[] = { - 128 * 8, - 128 * 16, - 128 * 32, - 128 * 64, - 0 -}; - -static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); - -static unsigned long -GetBestTileAlignment(unsigned long size) -{ - unsigned long i; - - for (i = KB(512); i < size; i <<= 1) - ; - - if (i > MB(64)) - i = MB(64); - - return i; -} - -static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - unsigned char *MMIO = ctx->MMIOAddress; - - for (i = 0; i < 8; i++) { - OUTREG(FENCE + i * 4, pI830->Fence[i]); - // if (I810_DEBUG & DEBUG_VERBOSE_VGA) - fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); - } -} - -/* Tiled memory is good... really, really good... - * - * Need to make it less likely that we miss out on this - probably - * need to move the frontbuffer away from the 'guarenteed' alignment - * of the first memory segment, or perhaps allocate a discontigous - * framebuffer to get more alignment 'sweet spots'. - */ -static void -SetFence(const DRIDriverContext *ctx, I830Rec *pI830, - int nr, unsigned int start, unsigned int pitch, - unsigned int size) -{ - unsigned int val; - unsigned int fence_mask = 0; - unsigned int fence_pitch; - - if (nr < 0 || nr > 7) { - fprintf(stderr, - "SetFence: fence %d out of range\n",nr); - return; - } - - pI830->Fence[nr] = 0; - - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (start & fence_mask) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not %s aligned\n", - nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); - return; - } - - if (start % size) { - fprintf(stderr, - "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", - nr, start, size / 1024); - return; - } - - if (pitch & 127) { - fprintf(stderr, - "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", - nr, pitch); - return; - } - - val = (start | FENCE_X_MAJOR | FENCE_VALID); - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); - return; - } - } - - if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - fprintf(stderr, - "SetFence: %d: illegal pitch (%d)\n", nr, pitch); - return; - } - - pI830->Fence[nr] = val; -} - -static Bool -MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) -{ - int pitch, ntiles, i; - - pitch = pMem->Pitch * ctx->cpp; - /* - * Simply try to break the region up into at most four pieces of size - * equal to the alignment. - */ - ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; - if (ntiles >= 4) { - return FALSE; - } - - for (i = 0; i < ntiles; i++, nextTile++) { - SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, - pitch, pMem->Alignment); - } - return TRUE; -} - -static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) -{ - int i; - - /* Clear out */ - for (i = 0; i < 8; i++) - pI830->Fence[i] = 0; - - nextTile = 0; - - if (pI830->BackBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { - fprintf(stderr, - "Activating tiled memory for the back buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the back buffer.\n"); - pI830->allowPageFlip = FALSE; - } - } - - if (pI830->DepthBuffer.Alignment >= KB(512)) { - if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { - fprintf(stderr, - "Activating tiled memory for the depth buffer.\n"); - } else { - fprintf(stderr, - "MakeTiles failed for the depth buffer.\n"); - } - } - - return; -} - -static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - struct pci_device host_bridge; - uint32_t gmch_ctrl; - int memsize = 0; - int range; - - memset(&host_bridge, 0, sizeof(host_bridge)); - - pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); - - /* We need to reduce the stolen size, by the GTT and the popup. - * The GTT varying according the the FbMapSize and the popup is 4KB */ - range = (ctx->shared.fbSize / (1024*1024)) + 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - if (memsize > 0) { - fprintf(stderr, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - fprintf(stderr, - "no video memory detected.\n"); - } - return memsize; -} - -static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) -{ - unsigned long mode = 0x4; - - if (drmAgpAcquire(ctx->drmFD) < 0) { - fprintf(stderr, "[gart] AGP not available\n"); - return 0; - } - - if (drmAgpEnable(ctx->drmFD, mode) < 0) { - fprintf(stderr, "[gart] AGP not enabled\n"); - drmAgpRelease(ctx->drmFD); - return 0; - } - else - fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); - - return 1; -} - -/* - * Allocate memory from the given pool. Grow the pool if needed and if - * possible. - */ -static unsigned long -AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, - I830MemRange *result, I830MemPool *pool, - long size, unsigned long alignment, int flags) -{ - long needed, start, end; - - if (!result || !pool || !size) - return 0; - - /* Calculate how much space is needed. */ - if (alignment <= GTT_PAGE_SIZE) - needed = size; - else { - start = ROUND_TO(pool->Free.Start, alignment); - end = ROUND_TO(start + size, alignment); - needed = end - pool->Free.Start; - } - if (needed > pool->Free.Size) { - return 0; - } - - result->Start = ROUND_TO(pool->Free.Start, alignment); - pool->Free.Start += needed; - result->End = pool->Free.Start; - - pool->Free.Size = pool->Free.End - pool->Free.Start; - result->Size = result->End - result->Start; - result->Pool = pool; - result->Alignment = alignment; - return needed; -} - -static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) -{ - unsigned long start, end; - unsigned long newApStart, newApEnd; - int ret; - if (!result || !size) - return 0; - - if (!alignment) - alignment = 4; - - start = ROUND_TO(pI830->MemoryAperture.Start, alignment); - end = ROUND_TO(start + size, alignment); - newApStart = end; - newApEnd = pI830->MemoryAperture.End; - - ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); - - if (ret) - { - fprintf(stderr,"drmAgpAlloc failed %d\n", ret); - return 0; - } - pI830->allocatedMemory += size; - pI830->MemoryAperture.Start = newApStart; - pI830->MemoryAperture.End = newApEnd; - pI830->MemoryAperture.Size = newApEnd - newApStart; - // pI830->FreeMemory -= size; - result->Start = start; - result->End = start + size; - result->Size = size; - result->Offset = start; - result->Alignment = alignment; - result->Pool = NULL; - - return size; -} - -unsigned long -I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags) -{ - int ret; - - if (!result) - return 0; - - /* Make sure these are initialised. */ - result->Size = 0; - result->Key = -1; - - if (!size) { - return 0; - } - - if (pool->Free.Size < size) - return AllocFromAGP(ctx, pI830, size, alignment, result); - else - { - ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); - - if (ret==0) - return AllocFromAGP(ctx, pI830, size, alignment, result); - return ret; - } -} - -static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) -{ - if (!mem) - return FALSE; - - if (mem->Key == -1) - return TRUE; - - return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); -} - -/* simple memory allocation routines needed */ -/* put ring buffer in low memory */ -/* need to allocate front, back, depth buffers aligned correctly, - allocate ring buffer, -*/ - -/* */ -static Bool -I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned long size, ret; - unsigned long lines, lineSize, align; - - /* allocate ring buffer */ - memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); - pI830->LpRing->mem.Key = -1; - - size = PRIMARY_RINGBUFFER_SIZE; - - ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); - - if (ret != size) - { - fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); - return FALSE; - } - - pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; - - - /* allocate front buffer */ - memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); - pI830->FrontBuffer.Key = -1; - pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; - - align = KB(512); - - lineSize = ctx->shared.virtualWidth * ctx->cpp; - lines = (ctx->shared.virtualHeight + 15) / 16 * 16; - size = lineSize * lines; - size = ROUND_TO_PAGE(size); - - align = GetBestTileAlignment(size); - - ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate front buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); - pI830->BackBuffer.Key = -1; - pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate back buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); - pI830->DepthBuffer.Key = -1; - pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; - - ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); - pI830->ContextMem.Key = -1; - size = KB(32); - - ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); - if (ret < size) - { - fprintf(stderr,"unable to allocate context buffer %ld\n", ret); - return FALSE; - } - - memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); - pI830->TexMem.Key = -1; - - size = 32768 * 1024; - ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); - if (ret < size) - { - fprintf(stderr,"unable to allocate texture memory %ld\n", ret); - return FALSE; - } - - return TRUE; -} - -static Bool -I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) -{ - if (!BindAgpRange(ctx, &pI830->LpRing->mem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->FrontBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->BackBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->DepthBuffer)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->ContextMem)) - return FALSE; - if (!BindAgpRange(ctx, &pI830->TexMem)) - return FALSE; - - return TRUE; -} - -static Bool -I830CleanupDma(const DRIDriverContext *ctx) -{ - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_CLEANUP_DMA; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, "I830 Dma Cleanup Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) -{ - I830RingBuffer *ring = pI830->LpRing; - drmI830Init info; - - memset(&info, 0, sizeof(drmI830Init)); - info.func = I830_INIT_DMA; - - info.ring_start = ring->mem.Start + pI830->LinearAddr; - info.ring_end = ring->mem.End + pI830->LinearAddr; - info.ring_size = ring->mem.Size; - - info.mmio_offset = (unsigned int)ctx->MMIOStart; - - info.sarea_priv_offset = sizeof(drm_sarea_t); - - info.front_offset = pI830->FrontBuffer.Start; - info.back_offset = pI830->BackBuffer.Start; - info.depth_offset = pI830->DepthBuffer.Start; - info.w = ctx->shared.virtualWidth; - info.h = ctx->shared.virtualHeight; - info.pitch = ctx->shared.virtualWidth; - info.back_pitch = pI830->BackBuffer.Pitch; - info.depth_pitch = pI830->DepthBuffer.Pitch; - info.cpp = ctx->cpp; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, - &info, sizeof(drmI830Init))) { - fprintf(stderr, - "I830 Dma Initialization Failed\n"); - return FALSE; - } - - return TRUE; -} - -static int I830CheckDRMVersion( const DRIDriverContext *ctx, - I830Rec *pI830 ) -{ - drmVersionPtr version; - - version = drmGetVersion(ctx->drmFD); - - if (version) { - int req_minor, req_patch; - - req_minor = 4; - req_patch = 0; - - if (version->version_major != 1 || - version->version_minor < req_minor || - (version->version_minor == req_minor && - version->version_patchlevel < req_patch)) { - /* Incompatible drm version */ - fprintf(stderr, - "[dri] I830DRIScreenInit failed because of a version " - "mismatch.\n" - "[dri] i915.o kernel module version is %d.%d.%d " - "but version 1.%d.%d or newer is needed.\n" - "[dri] Disabling DRI.\n", - version->version_major, - version->version_minor, - version->version_patchlevel, - req_minor, - req_patch); - drmFreeVersion(version); - return 0; - } - - pI830->drmMinor = version->version_minor; - drmFreeVersion(version); - } - return 1; -} - -static void -I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) -{ - unsigned int itemp; - unsigned char *MMIO = ctx->MMIOAddress; - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != - pI830->LpRing->mem.Start) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer start (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != - pI830->LpRing->mem.Size - 4096) { - fprintf(stderr, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->LpRing->mem.Size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - - pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); - pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); - if (pI830->LpRing->space < 0) - pI830->LpRing->space += pI830->LpRing->mem.Size; - - SetFenceRegs(ctx, pI830); - - /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky - hacky hacky */ - OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); - -} - -static Bool -I830SetParam(const DRIDriverContext *ctx, int param, int value) -{ - drmI830SetParam sp; - - memset(&sp, 0, sizeof(sp)); - sp.param = param; - sp.value = value; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { - fprintf(stderr, "I830 SetParam Failed\n"); - return FALSE; - } - - return TRUE; -} - -static Bool -I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - fprintf(stderr, - "[drm] Mapping front buffer\n"); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), - sarea->front_size, - DRM_FRAME_BUFFER, /*DRM_AGP,*/ - 0, - &sarea->front_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); - return FALSE; - } - ctx->shared.hFrameBuffer = sarea->front_handle; - ctx->shared.fbSize = sarea->front_size; - fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", - sarea->front_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)(sarea->back_offset), - sarea->back_size, DRM_AGP, 0, - &sarea->back_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", - sarea->back_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->depth_offset, - sarea->depth_size, DRM_AGP, 0, - &sarea->depth_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", - sarea->depth_handle); - - if (drmAddMap(ctx->drmFD, - (drm_handle_t)sarea->tex_offset, - sarea->tex_size, DRM_AGP, 0, - &sarea->tex_handle) < 0) { - fprintf(stderr, - "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] textures = 0x%08x\n", - sarea->tex_handle); - - return TRUE; -} - - -static void -I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ -#if 1 - if (sarea->front_handle) { - drmRmMap(ctx->drmFD, sarea->front_handle); - sarea->front_handle = 0; - } -#endif - if (sarea->back_handle) { - drmRmMap(ctx->drmFD, sarea->back_handle); - sarea->back_handle = 0; - } - if (sarea->depth_handle) { - drmRmMap(ctx->drmFD, sarea->depth_handle); - sarea->depth_handle = 0; - } - if (sarea->tex_handle) { - drmRmMap(ctx->drmFD, sarea->tex_handle); - sarea->tex_handle = 0; - } -} - -static void -I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* Start up the simple memory manager for agp space */ - drmI830MemInitHeap drmHeap; - drmHeap.region = I830_MEM_REGION_AGP; - drmHeap.start = 0; - drmHeap.size = sarea->tex_size; - - if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT_HEAP, - &drmHeap, sizeof(drmHeap))) { - fprintf(stderr, - "[drm] Failed to initialized agp heap manager\n"); - } else { - fprintf(stderr, - "[drm] Initialized kernel agp heap manager, %d\n", - sarea->tex_size); - - I830SetParam(ctx, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY, - sarea->log_tex_granularity); - } -} - -static Bool -I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - if (drmAddMap(ctx->drmFD, - (drm_handle_t)pI830->LpRing->mem.Start, - pI830->LpRing->mem.Size, DRM_AGP, 0, - &pI830->ring_map) < 0) { - fprintf(stderr, - "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); - return FALSE; - } - fprintf(stderr, "[drm] ring buffer = 0x%08x\n", - pI830->ring_map); - - if (I830InitDma(ctx, pI830) == FALSE) { - return FALSE; - } - - /* init to zero to be safe */ - - I830DRIMapScreenRegions(ctx, pI830, sarea); - I830InitTextureHeap(ctx, pI830, sarea); - - if (ctx->pciDevice != PCI_CHIP_845_G && - ctx->pciDevice != PCI_CHIP_I830_M) { - I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); - } - - /* Okay now initialize the dma engine */ - { - pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, - ctx->pciBus, - ctx->pciDevice, - ctx->pciFunc); - - if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { - fprintf(stderr, - "[drm] failure adding irq handler\n"); - pI830->irq = 0; - return FALSE; - } - else - fprintf(stderr, - "[drm] dma control initialized, using IRQ %d\n", - pI830->irq); - } - - fprintf(stderr, "[dri] visual configs initialized\n"); - - return TRUE; -} - -static Bool -I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) -{ - /* need to drmMap front and back buffers and zero them */ - drmAddress map_addr; - int ret; - - ret = drmMap(ctx->drmFD, - sarea->front_handle, - sarea->front_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map front buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->front_size); - drmUnmap(map_addr, sarea->front_size); - - - ret = drmMap(ctx->drmFD, - sarea->back_handle, - sarea->back_size, - &map_addr); - - if (ret) - { - fprintf(stderr, "Unable to map back buffer\n"); - return FALSE; - } - - drimemsetio((char *)map_addr, - 0, - sarea->back_size); - drmUnmap(map_addr, sarea->back_size); - - return TRUE; -} - -static Bool -I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) - -{ - I830DRIPtr pI830DRI; - drmI830Sarea *pSAREAPriv; - int err; - - drm_page_size = getpagesize(); - - pI830->registerSize = ctx->MMIOSize; - /* This is a hack for now. We have to have more than a 4k page here - * because of the size of the state. However, the state should be - * in a per-context mapping. This will be added in the Mesa 3.5 port - * of the I830 driver. - */ - ctx->shared.SAREASize = SAREA_MAX; - - /* Note that drmOpen will try to load the kernel module, if needed. */ - ctx->drmFD = drmOpen("i915", NULL ); - if (ctx->drmFD < 0) { - fprintf(stderr, "[drm] drmOpen failed\n"); - return 0; - } - - if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { - fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", - ctx->drmFD, ctx->pciBusID, strerror(-err)); - return 0; - } - - if (drmAddMap( ctx->drmFD, - 0, - ctx->shared.SAREASize, - DRM_SHM, - DRM_CONTAINS_LOCK, - &ctx->shared.hSAREA) < 0) - { - fprintf(stderr, "[drm] drmAddMap failed\n"); - return 0; - } - - fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", - ctx->shared.SAREASize, ctx->shared.hSAREA); - - if (drmMap( ctx->drmFD, - ctx->shared.hSAREA, - ctx->shared.SAREASize, - (drmAddressPtr)(&ctx->pSAREA)) < 0) - { - fprintf(stderr, "[drm] drmMap failed\n"); - return 0; - - } - - memset(ctx->pSAREA, 0, ctx->shared.SAREASize); - fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", - ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); - - - if (drmAddMap(ctx->drmFD, - ctx->MMIOStart, - ctx->MMIOSize, - DRM_REGISTERS, - DRM_READ_ONLY, - &pI830->registerHandle) < 0) { - fprintf(stderr, "[drm] drmAddMap mmio failed\n"); - return 0; - } - fprintf(stderr, - "[drm] register handle = 0x%08x\n", pI830->registerHandle); - - - if (!I830CheckDRMVersion(ctx, pI830)) { - return FALSE; - } - - /* Create a 'server' context so we can grab the lock for - * initialization ioctls. - */ - if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { - fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); - return 0; - } - - DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); - - /* Initialize the SAREA private data structure */ - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); - - pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); - pI830->StolenMemory.Start = 0; - pI830->StolenMemory.End = pI830->StolenMemory.Size; - - pI830->MemoryAperture.Start = pI830->StolenMemory.End; - pI830->MemoryAperture.End = KB(40000); - pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; - - pI830->StolenPool.Fixed = pI830->StolenMemory; - pI830->StolenPool.Total = pI830->StolenMemory; - pI830->StolenPool.Free = pI830->StolenPool.Total; - pI830->FreeMemory = pI830->StolenPool.Total.Size; - - if (!AgpInit(ctx, pI830)) - return FALSE; - - if (I830AllocateMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - if (I830BindMemory(ctx, pI830) == FALSE) - { - return FALSE; - } - - pSAREAPriv->front_offset = pI830->FrontBuffer.Start; - pSAREAPriv->front_size = pI830->FrontBuffer.Size; - pSAREAPriv->width = ctx->shared.virtualWidth; - pSAREAPriv->height = ctx->shared.virtualHeight; - pSAREAPriv->pitch = ctx->shared.virtualWidth; - pSAREAPriv->virtualX = ctx->shared.virtualWidth; - pSAREAPriv->virtualY = ctx->shared.virtualHeight; - pSAREAPriv->back_offset = pI830->BackBuffer.Start; - pSAREAPriv->back_size = pI830->BackBuffer.Size; - pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; - pSAREAPriv->depth_size = pI830->DepthBuffer.Size; - pSAREAPriv->tex_offset = pI830->TexMem.Start; - pSAREAPriv->tex_size = pI830->TexMem.Size; - pSAREAPriv->log_tex_granularity = pI830->TexGranularity; - - ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); - ctx->driverClientMsgSize = sizeof(I830DRIRec); - pI830DRI = (I830DRIPtr)ctx->driverClientMsg; - pI830DRI->deviceID = pI830->Chipset; - pI830DRI->regsSize = I830_REG_SIZE; - pI830DRI->width = ctx->shared.virtualWidth; - pI830DRI->height = ctx->shared.virtualHeight; - pI830DRI->mem = ctx->shared.fbSize; - pI830DRI->cpp = ctx->cpp; - pI830DRI->backOffset = pI830->BackBuffer.Start; - pI830DRI->backPitch = pI830->BackBuffer.Pitch; - - pI830DRI->depthOffset = pI830->DepthBuffer.Start; - pI830DRI->depthPitch = pI830->DepthBuffer.Pitch; - - pI830DRI->fbOffset = pI830->FrontBuffer.Start; - pI830DRI->fbStride = pI830->FrontBuffer.Pitch; - - pI830DRI->bitsPerPixel = ctx->bpp; - pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); - - err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); - if (err == FALSE) - return FALSE; - - I830SetupMemoryTiling(ctx, pI830); - - /* Quick hack to clear the front & back buffers. Could also use - * the clear ioctl to do this, but would need to setup hw state - * first. - */ - I830ClearScreen(ctx, pI830, pSAREAPriv); - - I830SetRingRegs(ctx, pI830); - - return TRUE; -} - - -/** - * \brief Validate the fbdev mode. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Saves some registers and returns 1. - * - * \sa radeonValidateMode(). - */ -static int i830ValidateMode( const DRIDriverContext *ctx ) -{ - return 1; -} - -/** - * \brief Examine mode returned by fbdev. - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Restores registers that fbdev has clobbered and returns 1. - * - * \sa i810ValidateMode(). - */ -static int i830PostValidateMode( const DRIDriverContext *ctx ) -{ - I830Rec *pI830 = ctx->driverPrivate; - - I830SetRingRegs(ctx, pI830); - return 1; -} - - -/** - * \brief Initialize the framebuffer device mode - * - * \param ctx display handle. - * - * \return one on success, or zero on failure. - * - * Fills in \p info with some default values and some information from \p ctx - * and then calls I810ScreenInit() for the screen initialization. - * - * Before exiting clears the framebuffer memory accessing it directly. - */ -static int i830InitFBDev( DRIDriverContext *ctx ) -{ - I830Rec *pI830 = calloc(1, sizeof(I830Rec)); - int i; - - { - int dummy = ctx->shared.virtualWidth; - - switch (ctx->bpp / 8) { - case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; - case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; - case 3: - case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; - } - - ctx->shared.virtualWidth = dummy; - ctx->shared.Width = ctx->shared.virtualWidth; - } - - - for (i = 0; pitches[i] != 0; i++) { - if (pitches[i] >= ctx->shared.virtualWidth) { - ctx->shared.virtualWidth = pitches[i]; - break; - } - } - - ctx->driverPrivate = (void *)pI830; - - pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); - pI830->Chipset = ctx->chipset; - pI830->LinearAddr = ctx->FBStart; - - if (!I830ScreenInit( ctx, pI830 )) - return 0; - - - return 1; -} - - -/** - * \brief The screen is being closed, so clean up any state and free any - * resources used by the DRI. - * - * \param ctx display handle. - * - * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver - * private data. - */ -static void i830HaltFBDev( DRIDriverContext *ctx ) -{ - drmI830Sarea *pSAREAPriv; - I830Rec *pI830 = ctx->driverPrivate; - - if (pI830->irq) { - drmCtlUninstHandler(ctx->drmFD); - pI830->irq = 0; } - - I830CleanupDma(ctx); - - pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + - sizeof(drm_sarea_t)); - - I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); - drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); - drmClose(ctx->drmFD); - - if (ctx->driverPrivate) { - free(ctx->driverPrivate); - ctx->driverPrivate = 0; - } -} - - -extern void i810NotifyFocus( int ); - -/** - * \brief Exported driver interface for Mini GLX. - * - * \sa DRIDriverRec. - */ -const struct DRIDriverRec __driDriver = { - i830ValidateMode, - i830PostValidateMode, - i830InitFBDev, - i830HaltFBDev, - NULL,//I830EngineShutdown, - NULL, //I830EngineRestore, -#ifndef _EMBEDDED - 0, -#else - i810NotifyFocus, -#endif -}; -- cgit v1.2.3 From aa88d11e7d881f0dd4c02fcefceb4085bdb3cf8a Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 27 Sep 2007 13:49:35 +0800 Subject: fix ppracer and bzflag issue with clip optimization --- src/mesa/drivers/dri/i965/brw_clip_tri.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index 506ab3712d..b7d30bb0c4 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -472,7 +472,6 @@ static void brw_clip_test( struct brw_clip_compile *c ) brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS])); brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS])); brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS])); - brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f)); /* test nearz, xmin, ymin plane */ brw_CMP(p, t1, BRW_CONDITIONAL_LE, negate(v0), get_element(v0, 3)); -- cgit v1.2.3 From 6254be9b7144821e044d3fbade514fa0358db693 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 27 Sep 2007 15:52:01 +0800 Subject: mesa: make sure the gotten value isn't greater than the max depth buffer value on 64bit system. fix bug #12095 --- src/mesa/swrast/s_span.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index bbde0025f4..f1e58bd3d8 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -64,8 +64,11 @@ _swrast_span_default_attribs(GLcontext *ctx, SWspan *span) const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; if (ctx->DrawBuffer->Visual.depthBits <= 16) span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); - else - span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); + else { + GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; + tmpf = MIN2(tmpf, depthMax); + span->z = (GLint)tmpf; + } span->zStep = 0; span->interpMask |= SPAN_Z; } -- cgit v1.2.3 From 3ee6a77e97f7d2996f8fffdbb4787a9589189b39 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Thu, 27 Sep 2007 16:14:57 +0800 Subject: i965: handle all unfilled mode in clip stage. fix bug #12453 --- src/mesa/drivers/dri/i965/brw_clip.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 3bec153075..8287fd9edf 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -212,6 +212,10 @@ static void upload_clip_prog( struct brw_context *brw ) } } + if (brw->attribs.Polygon->BackMode != GL_FILL || + brw->attribs.Polygon->FrontMode != GL_FILL) + key.do_unfilled = 1; + /* Most cases the fixed function units will handle. Cases where * one or more polygon faces are unfilled will require help: */ -- cgit v1.2.3 From 4f9d29cd4e876cd202a7d3e81f6d91fc7f9625a2 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Sep 2007 10:23:32 -0600 Subject: tweak point rast to fix conform failure --- src/mesa/swrast/s_points.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 21316372e8..d54adc8fd1 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -172,9 +172,10 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) } else { /* even size */ - xmin = (GLint) x - iRadius; + /* 0.501 factor allows conformance to pass */ + xmin = (GLint) (x + 0.501) - iRadius; xmax = xmin + iSize - 1; - ymin = (GLint) y - iRadius; + ymin = (GLint) (y + 0.501) - iRadius; ymax = ymin + iSize - 1; } @@ -418,9 +419,10 @@ large_point(GLcontext *ctx, const SWvertex *vert) } else { /* even size */ - xmin = (GLint) x - iRadius; + /* 0.501 factor allows conformance to pass */ + xmin = (GLint) (x + 0.501) - iRadius; xmax = xmin + iSize - 1; - ymin = (GLint) y - iRadius; + ymin = (GLint) (y + 0.501) - iRadius; ymax = ymin + iSize - 1; } -- cgit v1.2.3 From ed6d5ff6f8fdd34aaaa126119dbd8e1e321859d8 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 27 Sep 2007 10:24:17 -0600 Subject: Restore old _TriangleCaps code to fix Blender problem (bug 12164) --- src/mesa/main/enable.c | 13 +++++++++++++ src/mesa/main/light.c | 9 +++++++++ src/mesa/main/lines.c | 5 +++++ src/mesa/main/mtypes.h | 5 ++++- src/mesa/main/points.c | 5 +++++ src/mesa/main/polygon.c | 5 +++++ src/mesa/main/state.c | 38 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 79 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 52dd63f2ce..ba4972b167 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -364,6 +364,10 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_LIGHTING: if (ctx->Light.Enabled == state) return; + if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) + ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; + else + ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Enabled = state; break; @@ -372,12 +376,14 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) return; FLUSH_VERTICES(ctx, _NEW_LINE); ctx->Line.SmoothFlag = state; + ctx->_TriangleCaps ^= DD_LINE_SMOOTH; break; case GL_LINE_STIPPLE: if (ctx->Line.StippleFlag == state) return; FLUSH_VERTICES(ctx, _NEW_LINE); ctx->Line.StippleFlag = state; + ctx->_TriangleCaps ^= DD_LINE_STIPPLE; break; case GL_INDEX_LOGIC_OP: if (ctx->Color.IndexLogicOpEnabled == state) @@ -516,18 +522,21 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.SmoothFlag = state; + ctx->_TriangleCaps ^= DD_POINT_SMOOTH; break; case GL_POLYGON_SMOOTH: if (ctx->Polygon.SmoothFlag == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.SmoothFlag = state; + ctx->_TriangleCaps ^= DD_TRI_SMOOTH; break; case GL_POLYGON_STIPPLE: if (ctx->Polygon.StippleFlag == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.StippleFlag = state; + ctx->_TriangleCaps ^= DD_TRI_STIPPLE; break; case GL_POLYGON_OFFSET_POINT: if (ctx->Polygon.OffsetPoint == state) @@ -877,6 +886,10 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.TestTwoSide = state; + if (state) + ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; + else + ctx->_TriangleCaps &= ~DD_TRI_TWOSTENCIL; break; #if FEATURE_ARB_fragment_program diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 6e057614ba..6dd334e16d 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -53,6 +53,11 @@ _mesa_ShadeModel( GLenum mode ) FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.ShadeModel = mode; + if (mode == GL_FLAT) + ctx->_TriangleCaps |= DD_FLATSHADE; + else + ctx->_TriangleCaps &= ~DD_FLATSHADE; + if (ctx->Driver.ShadeModel) ctx->Driver.ShadeModel( ctx, mode ); } @@ -441,6 +446,10 @@ _mesa_LightModelfv( GLenum pname, const GLfloat *params ) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Model.TwoSide = newbool; + if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) + ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; + else + ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; break; case GL_LIGHT_MODEL_COLOR_CONTROL: if (params[0] == (GLfloat) GL_SINGLE_COLOR) diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c index 0c2dbf915a..81d0d33abb 100644 --- a/src/mesa/main/lines.c +++ b/src/mesa/main/lines.c @@ -56,6 +56,11 @@ _mesa_LineWidth( GLfloat width ) FLUSH_VERTICES(ctx, _NEW_LINE); ctx->Line.Width = width; + if (width != 1.0F) + ctx->_TriangleCaps |= DD_LINE_WIDTH; + else + ctx->_TriangleCaps &= ~DD_LINE_WIDTH; + if (ctx->Driver.LineWidth) ctx->Driver.LineWidth(ctx, width); } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f5a8c970e4..1fbfeb7447 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3040,7 +3040,10 @@ struct __GLcontextRec /** \name Derived state */ /*@{*/ - GLbitfield _TriangleCaps; /**< bitwise-or of DD_* flags */ + /** Bitwise-or of DD_* flags. Note that this bitfield may be used before + * state validation so they need to always be current. + */ + GLbitfield _TriangleCaps; GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */ GLfloat _EyeZDir[3]; GLfloat _ModelViewInvScale; diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index 88e4989405..1458c90ab9 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -123,6 +123,11 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params) ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || ctx->Point.Params[1] != 0.0 || ctx->Point.Params[2] != 0.0); + + if (ctx->Point._Attenuated) + ctx->_TriangleCaps |= DD_POINT_ATTEN; + else + ctx->_TriangleCaps &= ~DD_POINT_ATTEN; } else { _mesa_error(ctx, GL_INVALID_ENUM, diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index fd02e5a652..564250b881 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -167,6 +167,11 @@ _mesa_PolygonMode( GLenum face, GLenum mode ) return; } + if (ctx->Polygon.FrontMode == GL_FILL && ctx->Polygon.BackMode == GL_FILL) + ctx->_TriangleCaps &= ~DD_TRI_UNFILLED; + else + ctx->_TriangleCaps |= DD_TRI_UNFILLED; + if (ctx->Driver.PolygonMode) ctx->Driver.PolygonMode(ctx, face, mode); } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 444f227760..4010020265 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -826,6 +826,16 @@ _mesa_init_exec_table(struct _glapi_table *exec) /*@{*/ +static void +update_separate_specular(GLcontext *ctx) +{ + if (NEED_SECONDARY_COLOR(ctx)) + ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; + else + ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; +} + + /** * Update state dependent on vertex arrays. */ @@ -1050,6 +1060,24 @@ update_color(GLcontext *ctx) } +/* + * Check polygon state and set DD_TRI_CULL_FRONT_BACK and/or DD_TRI_OFFSET + * in ctx->_TriangleCaps if needed. + */ +static void +update_polygon(GLcontext *ctx) +{ + ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); + + if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) + ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; + + if ( ctx->Polygon.OffsetPoint + || ctx->Polygon.OffsetLine + || ctx->Polygon.OffsetFill) + ctx->_TriangleCaps |= DD_TRI_OFFSET; +} + /** * Update the ctx->_TriangleCaps bitfield. @@ -1057,6 +1085,7 @@ update_color(GLcontext *ctx) * This function must be called after other update_*() functions since * there are dependencies on some other derived values. */ +#if 0 static void update_tricaps(GLcontext *ctx, GLbitfield new_state) { @@ -1122,6 +1151,7 @@ update_tricaps(GLcontext *ctx, GLbitfield new_state) if (ctx->Stencil._TestTwoSide) ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; } +#endif /** @@ -1159,6 +1189,9 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) _mesa_update_draw_buffer_bounds( ctx ); + if (new_state & _NEW_POLYGON) + update_polygon( ctx ); + if (new_state & _NEW_LIGHT) _mesa_update_lighting( ctx ); @@ -1168,6 +1201,9 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & _IMAGE_NEW_TRANSFER_STATE) _mesa_update_pixel( ctx, new_state ); + if (new_state & _DD_NEW_SEPARATE_SPECULAR) + update_separate_specular( ctx ); + if (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) update_arrays( ctx ); @@ -1177,9 +1213,11 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & _NEW_COLOR) update_color( ctx ); +#if 0 if (new_state & (_NEW_POINT | _NEW_LINE | _NEW_POLYGON | _NEW_LIGHT | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) update_tricaps( ctx, new_state ); +#endif if (ctx->FragmentProgram._MaintainTexEnvProgram) { if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG)) -- cgit v1.2.3 From 38c30a81844214b030c9c637f9cf97bd2bf19cde Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 26 Sep 2007 13:57:08 -0700 Subject: [965] Remove AUB file support. This code existed to dump logs of hardware access to be replayed in simulation. Since we have real hardware now, it's not really needed. --- src/mesa/drivers/dri/i965/Makefile | 2 - src/mesa/drivers/dri/i965/brw_aub.c | 353 ------------------ src/mesa/drivers/dri/i965/brw_aub.h | 172 --------- src/mesa/drivers/dri/i965/brw_aub_playback.c | 443 ----------------------- src/mesa/drivers/dri/i965/brw_context.c | 11 - src/mesa/drivers/dri/i965/brw_context.h | 3 - src/mesa/drivers/dri/i965/brw_curbe.c | 13 +- src/mesa/drivers/dri/i965/brw_draw.c | 6 - src/mesa/drivers/dri/i965/brw_draw_upload.c | 1 - src/mesa/drivers/dri/i965/brw_program.c | 1 - src/mesa/drivers/dri/i965/brw_state_batch.c | 1 - src/mesa/drivers/dri/i965/brw_state_cache.c | 78 ++-- src/mesa/drivers/dri/i965/brw_state_pool.c | 5 +- src/mesa/drivers/dri/i965/brw_vtbl.c | 3 - src/mesa/drivers/dri/i965/bufmgr.h | 24 -- src/mesa/drivers/dri/i965/bufmgr_fake.c | 100 ----- src/mesa/drivers/dri/i965/intel_batchbuffer.c | 19 - src/mesa/drivers/dri/i965/intel_buffer_objects.c | 7 +- src/mesa/drivers/dri/i965/intel_buffers.c | 6 - src/mesa/drivers/dri/i965/intel_context.c | 7 - src/mesa/drivers/dri/i965/intel_context.h | 17 - src/mesa/drivers/dri/i965/intel_ioctl.c | 4 - src/mesa/drivers/dri/i965/intel_regions.c | 10 +- 23 files changed, 42 insertions(+), 1244 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/brw_aub.c delete mode 100644 src/mesa/drivers/dri/i965/brw_aub.h delete mode 100644 src/mesa/drivers/dri/i965/brw_aub_playback.c (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 15a6752e0f..5748d7ff05 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -22,8 +22,6 @@ DRIVER_SOURCES = \ intel_tex.c \ intel_tex_layout.c \ intel_tex_validate.c \ - brw_aub.c \ - brw_aub_playback.c \ brw_cc.c \ brw_clip.c \ brw_clip_line.c \ diff --git a/src/mesa/drivers/dri/i965/brw_aub.c b/src/mesa/drivers/dri/i965/brw_aub.c deleted file mode 100644 index c549f7a4f6..0000000000 --- a/src/mesa/drivers/dri/i965/brw_aub.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#include "brw_context.h" -#include "brw_aub.h" -#include "intel_regions.h" -#include - -extern char *__progname; - - -/* Registers to control page table - */ -#define PGETBL_CTL 0x2020 -#define PGETBL_ENABLED 0x1 - -#define NR_GTT_ENTRIES 65536 /* 256 mb */ - -#define FAIL \ -do { \ - fprintf(stderr, "failed to write aub data at %s/%d\n", __FUNCTION__, __LINE__); \ - exit(1); \ -} while (0) - - -/* Emit the headers at the top of each aubfile. Initialize the GTT. - */ -static void init_aubfile( FILE *aub_file ) -{ - struct aub_file_header fh; - struct aub_block_header bh; - unsigned int data; - - static int nr; - - nr++; - - /* Emit the aub header: - */ - memset(&fh, 0, sizeof(fh)); - - fh.instruction_type = AUB_FILE_HEADER; - fh.minor = 0x0; - fh.major = 0x7; - memcpy(fh.application, __progname, sizeof(fh.application)); - fh.day = (nr>>24) & 0xff; - fh.month = 0x0; - fh.year = 0x0; - fh.timezone = 0x0; - fh.second = nr & 0xff; - fh.minute = (nr>>8) & 0xff; - fh.hour = (nr>>16) & 0xff; - fh.comment_length = 0x0; - - if (fwrite(&fh, sizeof(fh), 1, aub_file) < 1) - FAIL; - - /* Setup the GTT starting at main memory address zero (!): - */ - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_MMI0_WRITE32; - bh.type = 0x0; - bh.address_space = ADDR_GTT; /* ??? */ - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = PGETBL_CTL; - bh.length = 0x4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) - FAIL; - - data = 0x0 | PGETBL_ENABLED; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 1) - FAIL; -} - - -static void init_aub_gtt( struct brw_context *brw, - GLuint start_offset, - GLuint size ) -{ - FILE *aub_file = brw->intel.aub_file; - struct aub_block_header bh; - unsigned int i; - - assert(start_offset + size < NR_GTT_ENTRIES * 4096); - - - memset(&bh, 0, sizeof(bh)); - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = 0x0; - bh.address_space = ADDR_MAIN; - bh.general_state_type = 0x0; - bh.surface_state_type = 0x0; - bh.address = start_offset / 4096 * 4; - bh.length = size / 4096 * 4; - - if (fwrite(&bh, sizeof(bh), 1, aub_file) < 1) - FAIL; - - for (i = 0; i < size / 4096; i++) { - GLuint data = brw->next_free_page | 1; - - brw->next_free_page += 4096; - - if (fwrite(&data, sizeof(data), 1, aub_file) < 1) - FAIL; - } - -} - -static void write_block_header( FILE *aub_file, - struct aub_block_header *bh, - const GLuint *data, - GLuint sz ) -{ - sz = (sz + 3) & ~3; - - if (fwrite(bh, sizeof(*bh), 1, aub_file) < 1) - FAIL; - - if (fwrite(data, sz, 1, aub_file) < 1) - FAIL; - - fflush(aub_file); -} - - -static void write_dump_bmp( FILE *aub_file, - struct aub_dump_bmp *db ) -{ - if (fwrite(db, sizeof(*db), 1, aub_file) < 1) - FAIL; - - fflush(aub_file); -} - - - -static void brw_aub_gtt_data( struct intel_context *intel, - GLuint offset, - const void *data, - GLuint sz, - GLuint type, - GLuint state_type ) -{ - struct aub_block_header bh; - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_DATA_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - - if (type == DW_GENERAL_STATE) { - bh.general_state_type = state_type; - bh.surface_state_type = 0; - } - else { - bh.general_state_type = 0; - bh.surface_state_type = state_type; - } - - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(intel->aub_file, &bh, data, sz); -} - - - -static void brw_aub_gtt_cmds( struct intel_context *intel, - GLuint offset, - const void *data, - GLuint sz ) -{ - struct brw_context *brw = brw_context(&intel->ctx); - struct aub_block_header bh; - GLuint type = CW_PRIMARY_RING_A; - - - bh.instruction_type = AUB_BLOCK_HEADER; - bh.operation = BH_COMMAND_WRITE; - bh.type = type; - bh.address_space = ADDR_GTT; - bh.pad0 = 0; - bh.general_state_type = 0; - bh.surface_state_type = 0; - bh.pad1 = 0; - bh.address = offset; - bh.length = sz; - - write_block_header(brw->intel.aub_file, &bh, data, sz); -} - -static void brw_aub_dump_bmp( struct intel_context *intel, - GLuint buffer ) -{ - struct brw_context *brw = brw_context(&intel->ctx); - intelScreenPrivate *intelScreen = brw->intel.intelScreen; - struct aub_dump_bmp db; - GLuint format; - - if (intelScreen->cpp == 4) - format = 0x7; - else - format = 0x3; - - - if (buffer == 0) { - db.instruction_type = AUB_DUMP_BMP; - db.xmin = 0; - db.ymin = 0; - db.format = format; - db.bpp = intelScreen->cpp * 8; - db.pitch = intelScreen->front.pitch / intelScreen->cpp; - db.xsize = intelScreen->width; - db.ysize = intelScreen->height; - db.addr = intelScreen->front.offset; - db.unknown = 0x0; /* 4: xmajor tiled, 0: not tiled */ - - write_dump_bmp(brw->intel.aub_file, &db); - } - else { - db.instruction_type = AUB_DUMP_BMP; - db.xmin = 0; - db.ymin = 0; - db.format = format; - db.bpp = intel->back_region->cpp * 8; - db.pitch = intel->back_region->pitch; - db.xsize = intel->back_region->pitch; - db.ysize = intel->back_region->height; - db.addr = intelScreen->back.offset; - db.unknown = intel->back_region->tiled ? 0x4 : 0x0; - - write_dump_bmp(brw->intel.aub_file, &db); - } -} - -/* Attempt to prevent monster aubfiles by closing and reopening when - * the state pools wrap. - */ -static void brw_aub_wrap( struct intel_context *intel ) -{ - struct brw_context *brw = brw_context(&intel->ctx); - if (intel->aub_file) { - brw_aub_destroy(brw); - brw_aub_init(brw); - } - brw->wrap = 1; /* ??? */ -} - - -int brw_aub_init( struct brw_context *brw ) -{ - struct intel_context *intel = &brw->intel; - intelScreenPrivate *intelScreen = intel->intelScreen; - char filename[80]; - int val; - static int i = 0; - - i++; - - if (_mesa_getenv("INTEL_REPLAY")) - return 0; - - if (_mesa_getenv("INTEL_AUBFILE")) { - val = snprintf(filename, sizeof(filename), "%s%d.aub", _mesa_getenv("INTEL_AUBFILE"), i%4); - _mesa_printf("--> Aub file: %s\n", filename); - brw->intel.aub_file = fopen(filename, "w"); - } - else if (_mesa_getenv("INTEL_AUB")) { - val = snprintf(filename, sizeof(filename), "%s.aub", __progname); - if (val < 0 || val > sizeof(filename)) - strcpy(filename, "default.aub"); - - _mesa_printf("--> Aub file: %s\n", filename); - brw->intel.aub_file = fopen(filename, "w"); - } - else { - return 0; - } - - if (!brw->intel.aub_file) { - _mesa_printf("couldn't open aubfile\n"); - exit(1); - } - - brw->intel.vtbl.aub_commands = brw_aub_gtt_cmds; - brw->intel.vtbl.aub_dump_bmp = brw_aub_dump_bmp; - brw->intel.vtbl.aub_gtt_data = brw_aub_gtt_data; - brw->intel.vtbl.aub_wrap = brw_aub_wrap; - - init_aubfile(brw->intel.aub_file); - - /* The GTT is located starting address zero in main memory. Pages - * to populate the gtt start after this point. - */ - brw->next_free_page = (NR_GTT_ENTRIES * 4 + 4095) & ~4095; - - /* More or less correspond with all the agp regions mapped by the - * driver: - */ - init_aub_gtt(brw, 0, 4096*4); /* so new fulsim doesn't crash */ - init_aub_gtt(brw, intelScreen->front.offset, intelScreen->back.size); - init_aub_gtt(brw, intelScreen->back.offset, intelScreen->back.size); - init_aub_gtt(brw, intelScreen->depth.offset, intelScreen->back.size); - init_aub_gtt(brw, intelScreen->tex.offset, intelScreen->tex.size); - - return 0; -} - -void brw_aub_destroy( struct brw_context *brw ) -{ - if (brw->intel.aub_file) { - fclose(brw->intel.aub_file); - brw->intel.aub_file = NULL; - } -} diff --git a/src/mesa/drivers/dri/i965/brw_aub.h b/src/mesa/drivers/dri/i965/brw_aub.h deleted file mode 100644 index 198e36dc3c..0000000000 --- a/src/mesa/drivers/dri/i965/brw_aub.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice (including the - next paragraph) shall be included in all copies or substantial - portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - **********************************************************************/ - /* - * Authors: - * Keith Whitwell - */ - -#ifndef BRW_AUB_H -#define BRW_AUB_H - -struct aub_file_header { - unsigned int instruction_type; - unsigned int pad0:16; - unsigned int minor:8; - unsigned int major:8; - unsigned char application[8*4]; - unsigned int day:8; - unsigned int month:8; - unsigned int year:16; - unsigned int timezone:8; - unsigned int second:8; - unsigned int minute:8; - unsigned int hour:8; - unsigned int comment_length:16; - unsigned int pad1:16; -}; - -struct aub_block_header { - unsigned int instruction_type; - unsigned int operation:8; - unsigned int type:8; - unsigned int address_space:8; - unsigned int pad0:8; - unsigned int general_state_type:8; - unsigned int surface_state_type:8; - unsigned int pad1:16; - unsigned int address; - unsigned int length; -}; - -struct aub_dump_bmp { - unsigned int instruction_type; - unsigned int xmin:16; - unsigned int ymin:16; - unsigned int pitch:16; - unsigned int bpp:8; - unsigned int format:8; - unsigned int xsize:16; - unsigned int ysize:16; - unsigned int addr; - unsigned int unknown; -}; - -enum bh_operation { - BH_COMMENT, - BH_DATA_WRITE, - BH_COMMAND_WRITE, - BH_MMI0_WRITE32, - BH_END_SCENE, - BH_CONFIG_MEMORY_MAP, - BH_MAX_OPERATION -}; - -enum command_write_type { - CW_HWB_RING = 1, - CW_PRIMARY_RING_A, - CW_PRIMARY_RING_B, /* XXX - disagreement with listaub! */ - CW_PRIMARY_RING_C, - CW_MAX_TYPE -}; - -enum data_write_type { - DW_NOTYPE, - DW_BATCH_BUFFER, - DW_BIN_BUFFER, - DW_BIN_POINTER_LIST, - DW_SLOW_STATE_BUFFER, - DW_VERTEX_BUFFER, - DW_2D_MAP, - DW_CUBE_MAP, - DW_INDIRECT_STATE_BUFFER, - DW_VOLUME_MAP, - DW_1D_MAP, - DW_CONSTANT_BUFFER, - DW_CONSTANT_URB_ENTRY, - DW_INDEX_BUFFER, - DW_GENERAL_STATE, - DW_SURFACE_STATE, - DW_MEDIA_OBJECT_INDIRECT_DATA, - DW_MAX_TYPE -}; - -enum data_write_general_state_type { - DWGS_NOTYPE, - DWGS_VERTEX_SHADER_STATE, - DWGS_GEOMETRY_SHADER_STATE , - DWGS_CLIPPER_STATE, - DWGS_STRIPS_FANS_STATE, - DWGS_WINDOWER_IZ_STATE, - DWGS_COLOR_CALC_STATE, - DWGS_CLIPPER_VIEWPORT_STATE, /* was 0x7 */ - DWGS_STRIPS_FANS_VIEWPORT_STATE, - DWGS_COLOR_CALC_VIEWPORT_STATE, /* was 0x9 */ - DWGS_SAMPLER_STATE, - DWGS_KERNEL_INSTRUCTIONS, - DWGS_SCRATCH_SPACE, - DWGS_SAMPLER_DEFAULT_COLOR, - DWGS_INTERFACE_DESCRIPTOR, - DWGS_VLD_STATE, - DWGS_VFE_STATE, - DWGS_MAX_TYPE -}; - -enum data_write_surface_state_type { - DWSS_NOTYPE, - DWSS_BINDING_TABLE_STATE, - DWSS_SURFACE_STATE, - DWSS_MAX_TYPE -}; - -enum memory_map_type { - MM_DEFAULT, - MM_DYNAMIC, - MM_MAX_TYPE -}; - -enum address_space { - ADDR_GTT, - ADDR_LOCAL, - ADDR_MAIN, - ADDR_MAX -}; - - -#define AUB_FILE_HEADER 0xe085000b -#define AUB_BLOCK_HEADER 0xe0c10003 -#define AUB_DUMP_BMP 0xe09e0004 - -struct brw_context; -struct intel_context; - -int brw_aub_init( struct brw_context *brw ); -void brw_aub_destroy( struct brw_context *brw ); - -int brw_playback_aubfile(struct brw_context *brw, - const char *filename); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_aub_playback.c b/src/mesa/drivers/dri/i965/brw_aub_playback.c deleted file mode 100644 index 2433d50c11..0000000000 --- a/src/mesa/drivers/dri/i965/brw_aub_playback.c +++ /dev/null @@ -1,443 +0,0 @@ - -#include -#include -#include -#include -#include -#include - -#include "brw_aub.h" -#include "brw_defines.h" -#include "brw_context.h" -#include "intel_ioctl.h" -#include "bufmgr.h" - -struct aub_state { - struct intel_context *intel; - const char *map; - unsigned int csr; - unsigned int sz; -}; - - -static int gobble( struct aub_state *s, int size ) -{ - if (s->csr + size > s->sz) { - _mesa_printf("EOF in %s\n", __FUNCTION__); - return 1; - } - - s->csr += size; - return 0; -} - -static void flush_and_fence( struct aub_state *s ) -{ - struct intel_context *intel = s->intel; - GLuint buf[2]; - - buf[0] = intel->vtbl.flush_cmd(); - buf[1] = 0; - - intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf)); - - intelWaitIrq( intel, intelEmitIrqLocked( intel )); -} - -static void flush_cmds( struct aub_state *s, - const void *data, - int len ) -{ - DBG("%s %d\n", __FUNCTION__, len); - - if (len & 0x4) { - unsigned int *tmp = malloc(len + 4); - DBG("padding to octword\n"); - memcpy(tmp, data, len); - tmp[len/4] = MI_NOOP; - flush_cmds(s, tmp, len+4); - free(tmp); - return; - } - - /* For ring data, just send off immediately via an ioctl. - * This differs slightly from how the stream was executed - * initially as this would have been a batchbuffer. - */ - intel_cmd_ioctl(s->intel, (void *)data, len); - - if (1) - flush_and_fence(s); -} - -static const char *pstrings[] = { - "none", - "POINTLIST", - "LINELIST", - "LINESTRIP", - "TRILIST", - "TRISTRIP", - "TRIFAN", - "QUADLIST", - "QUADSTRIP", - "LINELIST_ADJ", - "LINESTRIP_ADJ", - "TRILIST_ADJ", - "TRISTRIP_ADJ", - "TRISTRIP_REVERSE", - "POLYGON", - "RECTLIST", - "LINELOOP", - "POINTLIST_BF", - "LINESTRIP_CONT", - "LINESTRIP_BF", - "LINESTRIP_CONT_BF", - "TRIFAN_NOSTIPPLE", -}; - -static void do_3d_prim( struct aub_state *s, - const void *data, - int len ) -{ - struct brw_3d_primitive prim; - const struct brw_3d_primitive *orig = data; - int i; - - assert(len == sizeof(prim)); - memcpy(&prim, data, sizeof(prim)); - -#define START 0 -#define BLOCK (12*28) - - if (orig->verts_per_instance < BLOCK) - flush_cmds(s, &prim, sizeof(prim)); - else { - for (i = START; i + BLOCK < orig->verts_per_instance; i += BLOCK/2) { - prim.start_vert_location = i; - prim.verts_per_instance = BLOCK; - _mesa_printf("%sprim %d/%s verts %d..%d (of %d)\n", - prim.header.indexed ? "INDEXED " : "", - prim.header.topology, pstrings[prim.header.topology%16], - prim.start_vert_location, - prim.start_vert_location + prim.verts_per_instance, - orig->verts_per_instance); - flush_cmds(s, &prim, sizeof(prim)); - } - } -} - - - -static struct { - int cmd; - const char *name; - int has_length; -} cmd_info[] = { - { 0, "NOOP", 0 }, - { 0x5410, "XY_COLOR_BLT_RGB", 1 }, - { 0x5430, "XY_COLOR_BLT_RGBA", 1 }, - { 0x54d0, "XY_SRC_COPY_BLT_RGB", 1 }, - { 0x54f0, "XY_SRC_COPY_BLT_RGBA", 1 }, - { CMD_URB_FENCE, "URB_FENCE", 1 }, - { CMD_CONST_BUFFER_STATE, "CONST_BUFFER_STATE", 1 }, - { CMD_CONST_BUFFER, "CONST_BUFFER", 1 }, - { CMD_STATE_BASE_ADDRESS, "STATE_BASE_ADDRESS", 1 }, - { CMD_STATE_INSN_POINTER, "STATE_INSN_POINTER", 1 }, - { CMD_PIPELINE_SELECT, "PIPELINE_SELECT", 0, }, - { CMD_PIPELINED_STATE_POINTERS, "PIPELINED_STATE_POINTERS", 1 }, - { CMD_BINDING_TABLE_PTRS, "BINDING_TABLE_PTRS", 1 }, - { CMD_VERTEX_BUFFER, "VERTEX_BUFFER", 1 }, - { CMD_VERTEX_ELEMENT, "VERTEX_ELEMENT", 1 }, - { CMD_INDEX_BUFFER, "INDEX_BUFFER", 1 }, - { CMD_VF_STATISTICS, "VF_STATISTICS", 0 }, - { CMD_DRAW_RECT, "DRAW_RECT", 1 }, - { CMD_BLEND_CONSTANT_COLOR, "BLEND_CONSTANT_COLOR", 1 }, - { CMD_CHROMA_KEY, "CHROMA_KEY", 1 }, - { CMD_DEPTH_BUFFER, "DEPTH_BUFFER", 1 }, - { CMD_POLY_STIPPLE_OFFSET, "POLY_STIPPLE_OFFSET", 1 }, - { CMD_POLY_STIPPLE_PATTERN, "POLY_STIPPLE_PATTERN", 1 }, - { CMD_LINE_STIPPLE_PATTERN, "LINE_STIPPLE_PATTERN", 1 }, - { CMD_GLOBAL_DEPTH_OFFSET_CLAMP, "GLOBAL_DEPTH_OFFSET_CLAMP", 1 }, - { CMD_PIPE_CONTROL, "PIPE_CONTROL", 1 }, - { CMD_MI_FLUSH, "MI_FLUSH", 0 }, - { CMD_3D_PRIM, "3D_PRIM", 1 }, -}; - -#define NR_CMDS (sizeof(cmd_info)/sizeof(cmd_info[0])) - - -static int find_command( unsigned int cmd ) -{ - int i; - - for (i = 0; i < NR_CMDS; i++) - if (cmd == cmd_info[i].cmd) - return i; - - return -1; -} - - - -static int parse_commands( struct aub_state *s, - const unsigned int *data, - int len ) -{ - while (len) { - int cmd = data[0] >> 16; - int dwords; - int i; - - i = find_command(cmd); - - if (i < 0) { - _mesa_printf("couldn't find info for cmd %x\n", cmd); - return 1; - } - - if (cmd_info[i].has_length) - dwords = (data[0] & 0xff) + 2; - else - dwords = 1; - - _mesa_printf("%s (%d dwords) 0x%x\n", cmd_info[i].name, dwords, data[0]); - - if (len < dwords * 4) { - _mesa_printf("EOF in %s (%d bytes)\n", __FUNCTION__, len); - return 1; - } - - - if (0 && cmd == CMD_3D_PRIM) - do_3d_prim(s, data, dwords * 4); - else - flush_cmds(s, data, dwords * 4); - - data += dwords; - len -= dwords * 4; - } - - return 0; -} - - - -static void parse_data_write( struct aub_state *s, - const struct aub_block_header *bh, - void *dest, - const unsigned int *data, - int len ) -{ - switch (bh->type) { - case DW_GENERAL_STATE: - switch (bh->general_state_type) { - case DWGS_VERTEX_SHADER_STATE: { - struct brw_vs_unit_state vs; - assert(len == sizeof(vs)); - - _mesa_printf("DWGS_VERTEX_SHADER_STATE\n"); - memcpy(&vs, data, sizeof(vs)); - -/* vs.vs6.vert_cache_disable = 1; */ -/* vs.thread4.max_threads = 4; */ - - memcpy(dest, &vs, sizeof(vs)); - return; - } - case DWGS_CLIPPER_STATE: { - struct brw_clip_unit_state clip; - assert(len == sizeof(clip)); - - _mesa_printf("DWGS_CLIPPER_STATE\n"); - memcpy(&clip, data, sizeof(clip)); - -/* clip.thread4.max_threads = 0; */ -/* clip.clip5.clip_mode = BRW_CLIPMODE_REJECT_ALL; */ - - memcpy(dest, &clip, sizeof(clip)); - return; - } - - case DWGS_NOTYPE: - case DWGS_GEOMETRY_SHADER_STATE: - case DWGS_STRIPS_FANS_STATE: - break; - - case DWGS_WINDOWER_IZ_STATE: { - struct brw_wm_unit_state wm; - assert(len == sizeof(wm)); - - _mesa_printf("DWGS_WINDOWER_IZ_STATE\n"); - memcpy(&wm, data, sizeof(wm)); - -/* wm.wm5.max_threads = 10; */ - - memcpy(dest, &wm, sizeof(wm)); - return; - } - - case DWGS_COLOR_CALC_STATE: - case DWGS_CLIPPER_VIEWPORT_STATE: - case DWGS_STRIPS_FANS_VIEWPORT_STATE: - case DWGS_COLOR_CALC_VIEWPORT_STATE: - case DWGS_SAMPLER_STATE: - case DWGS_KERNEL_INSTRUCTIONS: - case DWGS_SCRATCH_SPACE: - case DWGS_SAMPLER_DEFAULT_COLOR: - case DWGS_INTERFACE_DESCRIPTOR: - case DWGS_VLD_STATE: - case DWGS_VFE_STATE: - default: - break; - } - break; - case DW_SURFACE_STATE: - break; - case DW_1D_MAP: - case DW_2D_MAP: - case DW_CUBE_MAP: - case DW_VOLUME_MAP: - case DW_CONSTANT_BUFFER: - case DW_CONSTANT_URB_ENTRY: - case DW_VERTEX_BUFFER: - case DW_INDEX_BUFFER: - default: - break; - } - - memcpy(dest, data, len); -} - - -/* In order to work, the memory layout has to be the same as the X - * server which created the aubfile. - */ -static int parse_block_header( struct aub_state *s ) -{ - struct aub_block_header *bh = (struct aub_block_header *)(s->map + s->csr); - void *data = (void *)(bh + 1); - unsigned int len = (bh->length + 3) & ~3; - - _mesa_printf("block header at 0x%x\n", s->csr); - - if (s->csr + len + sizeof(*bh) > s->sz) { - _mesa_printf("EOF in data in %s\n", __FUNCTION__); - return 1; - } - - if (bh->address_space == ADDR_GTT) { - - switch (bh->operation) - { - case BH_DATA_WRITE: { - void *dest = bmFindVirtual( s->intel, bh->address, len ); - if (dest == NULL) { - _mesa_printf("Couldn't find virtual address for offset %x\n", bh->address); - return 1; - } - -#if 1 - parse_data_write(s, bh, dest, data, len); -#else - memcpy(dest, data, len); -#endif - break; - } - case BH_COMMAND_WRITE: -#if 0 - intel_cmd_ioctl(s->intel, (void *)data, len); -#else - if (parse_commands(s, data, len) != 0) - _mesa_printf("parse_commands failed\n"); -#endif - break; - default: - break; - } - } - - s->csr += sizeof(*bh) + len; - return 0; -} - - -#define AUB_FILE_HEADER 0xe085000b -#define AUB_BLOCK_HEADER 0xe0c10003 -#define AUB_DUMP_BMP 0xe09e0004 - -int brw_playback_aubfile(struct brw_context *brw, - const char *filename) -{ - struct intel_context *intel = &brw->intel; - struct aub_state state; - struct stat sb; - int fd; - int retval = 0; - - state.intel = intel; - - fd = open(filename, O_RDONLY, 0); - if (fd < 0) { - _mesa_printf("couldn't open aubfile: %s\n", filename); - return 1; - } - - if (fstat(fd, &sb) != 0) { - _mesa_printf("couldn't open %s\n", filename); - return 1; - } - - state.csr = 0; - state.sz = sb.st_size; - state.map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - - if (state.map == NULL) { - _mesa_printf("couldn't mmap %s\n", filename); - return 1; - } - - LOCK_HARDWARE(intel); - { - /* Make sure we don't confuse anything that might happen to be - * going on with the hardware: - */ -/* bmEvictAll(intel); */ -/* intel->vtbl.lost_hardware(intel); */ - - - /* Replay the aubfile item by item: - */ - while (retval == 0 && - state.csr != state.sz) { - unsigned int insn = *(unsigned int *)(state.map + state.csr); - - switch (insn) { - case AUB_FILE_HEADER: - retval = gobble(&state, sizeof(struct aub_file_header)); - break; - - case AUB_BLOCK_HEADER: - retval = parse_block_header(&state); - break; - - case AUB_DUMP_BMP: - retval = gobble(&state, sizeof(struct aub_dump_bmp)); - break; - - default: - _mesa_printf("unknown instruction %x\n", insn); - retval = 1; - break; - } - } - } - UNLOCK_HARDWARE(intel); - return retval; -} - - - - - - - diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 397a9bd3f5..0ccdd8a661 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -31,7 +31,6 @@ #include "brw_context.h" -#include "brw_aub.h" #include "brw_defines.h" #include "brw_draw.h" #include "brw_vs.h" @@ -135,8 +134,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, driInitExtensions( ctx, brw_extensions, GL_FALSE ); - brw_aub_init( brw ); - brw_init_attribs( brw ); brw_init_metaops( brw ); brw_init_state( brw ); @@ -156,14 +153,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, brw_FrameBufferTexInit( brw ); - { - const char *filename = getenv("INTEL_REPLAY"); - if (filename) { - brw_playback_aubfile(brw, filename); - exit(0); - } - } - return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 08fdc54520..aa797b72ce 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -277,9 +277,6 @@ struct brw_cache { GLuint key_size; /* for fixed-size keys */ GLuint aux_size; - GLuint aub_type; - GLuint aub_sub_type; - GLuint last_addr; /* offset of active item */ }; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 5bf0ed536b..d3c88c1dca 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -42,7 +42,6 @@ #include "brw_defines.h" #include "brw_state.h" #include "brw_util.h" -#include "brw_aub.h" /* Partition the CURBE between the various users of constant values: @@ -315,13 +314,11 @@ static void upload_constant_buffer(struct brw_context *brw) /* Copy data to the buffer: */ - bmBufferSubDataAUB(&brw->intel, - pool->buffer, - brw->curbe.gs_offset, - bufsz, - buf, - DW_CONSTANT_BUFFER, - 0); + bmBufferSubData(&brw->intel, + pool->buffer, + brw->curbe.gs_offset, + bufsz, + buf); } /* TODO: only emit the constant_buffer packet when necessary, ie: diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 5ca9b2f549..b23b357988 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -36,7 +36,6 @@ #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" -#include "brw_aub.h" #include "brw_state.h" #include "brw_fallback.h" @@ -468,11 +467,6 @@ void brw_draw_prims( GLcontext *ctx, _swsetup_Wakeup(ctx); _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); } - - if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { - intelFinish( &intel->ctx ); - intel->aub_wrap = 1; - } } diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index dc289ca9ae..fc2e3035af 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -36,7 +36,6 @@ #include "brw_draw.h" #include "brw_defines.h" #include "brw_context.h" -#include "brw_aub.h" #include "brw_state.h" #include "brw_fallback.h" diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index f7b1d31810..8e8fea48e9 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -36,7 +36,6 @@ #include "tnl/tnl.h" #include "brw_context.h" -#include "brw_aub.h" #include "brw_util.h" static void brwBindProgram( GLcontext *ctx, diff --git a/src/mesa/drivers/dri/i965/brw_state_batch.c b/src/mesa/drivers/dri/i965/brw_state_batch.c index 909b0acd12..b78b51328a 100644 --- a/src/mesa/drivers/dri/i965/brw_state_batch.c +++ b/src/mesa/drivers/dri/i965/brw_state_batch.c @@ -32,7 +32,6 @@ #include "brw_state.h" -#include "brw_aub.h" #include "intel_batchbuffer.h" #include "imports.h" diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index 71c6938f9a..98d765ac0e 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -31,7 +31,6 @@ #include "brw_state.h" -#include "brw_aub.h" #include "intel_batchbuffer.h" #include "imports.h" @@ -188,13 +187,11 @@ GLuint brw_upload_cache( struct brw_cache *cache, /* Copy data to the buffer: */ - bmBufferSubDataAUB(&cache->brw->intel, - cache->pool->buffer, - offset, - data_size, - data, - cache->aub_type, - cache->aub_sub_type); + bmBufferSubData(&cache->brw->intel, + cache->pool->buffer, + offset, + data_size, + data); cache->brw->state.dirty.cache |= 1<id; @@ -227,17 +224,17 @@ GLuint brw_cache_data(struct brw_cache *cache, return brw_cache_data_sz(cache, data, cache->key_size); } - - - +enum pool_type { + DW_SURFACE_STATE, + DW_GENERAL_STATE +}; static void brw_init_cache( struct brw_context *brw, const char *name, GLuint id, GLuint key_size, GLuint aux_size, - GLuint aub_type, - GLuint aub_sub_type ) + enum pool_type pool_type) { struct brw_cache *cache = &brw->cache[id]; cache->brw = brw; @@ -254,9 +251,7 @@ static void brw_init_cache( struct brw_context *brw, cache->key_size = key_size; cache->aux_size = aux_size; - cache->aub_type = aub_type; - cache->aub_sub_type = aub_sub_type; - switch (aub_type) { + switch (pool_type) { case DW_GENERAL_STATE: cache->pool = &brw->pool[BRW_GS_POOL]; break; case DW_SURFACE_STATE: cache->pool = &brw->pool[BRW_SS_POOL]; break; default: assert(0); break; @@ -271,136 +266,119 @@ void brw_init_caches( struct brw_context *brw ) BRW_CC_VP, sizeof(struct brw_cc_viewport), 0, - DW_GENERAL_STATE, - DWGS_COLOR_CALC_VIEWPORT_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "CC_UNIT", BRW_CC_UNIT, sizeof(struct brw_cc_unit_state), 0, - DW_GENERAL_STATE, - DWGS_COLOR_CALC_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "WM_PROG", BRW_WM_PROG, sizeof(struct brw_wm_prog_key), sizeof(struct brw_wm_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "SAMPLER_DEFAULT_COLOR", BRW_SAMPLER_DEFAULT_COLOR, sizeof(struct brw_sampler_default_color), 0, - DW_GENERAL_STATE, - DWGS_SAMPLER_DEFAULT_COLOR); + DW_GENERAL_STATE); brw_init_cache(brw, "SAMPLER", BRW_SAMPLER, 0, /* variable key/data size */ 0, - DW_GENERAL_STATE, - DWGS_SAMPLER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "WM_UNIT", BRW_WM_UNIT, sizeof(struct brw_wm_unit_state), 0, - DW_GENERAL_STATE, - DWGS_WINDOWER_IZ_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "SF_PROG", BRW_SF_PROG, sizeof(struct brw_sf_prog_key), sizeof(struct brw_sf_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "SF_VP", BRW_SF_VP, sizeof(struct brw_sf_viewport), 0, - DW_GENERAL_STATE, - DWGS_STRIPS_FANS_VIEWPORT_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "SF_UNIT", BRW_SF_UNIT, sizeof(struct brw_sf_unit_state), 0, - DW_GENERAL_STATE, - DWGS_STRIPS_FANS_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "VS_UNIT", BRW_VS_UNIT, sizeof(struct brw_vs_unit_state), 0, - DW_GENERAL_STATE, - DWGS_VERTEX_SHADER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "VS_PROG", BRW_VS_PROG, sizeof(struct brw_vs_prog_key), sizeof(struct brw_vs_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "CLIP_UNIT", BRW_CLIP_UNIT, sizeof(struct brw_clip_unit_state), 0, - DW_GENERAL_STATE, - DWGS_CLIPPER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "CLIP_PROG", BRW_CLIP_PROG, sizeof(struct brw_clip_prog_key), sizeof(struct brw_clip_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "GS_UNIT", BRW_GS_UNIT, sizeof(struct brw_gs_unit_state), 0, - DW_GENERAL_STATE, - DWGS_GEOMETRY_SHADER_STATE); + DW_GENERAL_STATE); brw_init_cache(brw, "GS_PROG", BRW_GS_PROG, sizeof(struct brw_gs_prog_key), sizeof(struct brw_gs_prog_data), - DW_GENERAL_STATE, - DWGS_KERNEL_INSTRUCTIONS); + DW_GENERAL_STATE); brw_init_cache(brw, "SS_SURFACE", BRW_SS_SURFACE, sizeof(struct brw_surface_state), 0, - DW_SURFACE_STATE, - DWSS_SURFACE_STATE); + DW_SURFACE_STATE); brw_init_cache(brw, "SS_SURF_BIND", BRW_SS_SURF_BIND, sizeof(struct brw_surface_binding_table), 0, - DW_SURFACE_STATE, - DWSS_BINDING_TABLE_STATE); + DW_SURFACE_STATE); } diff --git a/src/mesa/drivers/dri/i965/brw_state_pool.c b/src/mesa/drivers/dri/i965/brw_state_pool.c index b9926f2a5d..708ae857ab 100644 --- a/src/mesa/drivers/dri/i965/brw_state_pool.c +++ b/src/mesa/drivers/dri/i965/brw_state_pool.c @@ -126,10 +126,7 @@ void brw_pool_check_wrap( struct brw_context *brw, struct brw_mem_pool *pool ) { if (pool->offset > (pool->size * 3) / 4) { - if (brw->intel.aub_file) - brw->intel.aub_wrap = 1; - else - brw->state.dirty.brw |= BRW_NEW_CONTEXT; + brw->state.dirty.brw |= BRW_NEW_CONTEXT; } } diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 786f30e641..d8cb168802 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -47,7 +47,6 @@ #include "brw_draw.h" #include "brw_state.h" -#include "brw_aub.h" #include "brw_fallback.h" #include "brw_vs.h" @@ -60,8 +59,6 @@ static void brw_destroy_context( struct intel_context *intel ) GLcontext *ctx = &intel->ctx; struct brw_context *brw = brw_context(&intel->ctx); - brw_aub_destroy(brw); - brw_destroy_metaops(brw); brw_destroy_state(brw); brw_draw_destroy( brw ); diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h index e748c0d6d0..b31c2e6d9b 100644 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -130,24 +130,6 @@ int bmBufferSubData(struct intel_context *, unsigned size, const void *data ); - -int bmBufferDataAUB(struct intel_context *, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags, - unsigned aubtype, - unsigned aubsubtype ); - -int bmBufferSubDataAUB(struct intel_context *, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data, - unsigned aubtype, - unsigned aubsubtype ); - - /* In this version, taking the offset will provoke an upload on * buffers not already resident in AGP: */ @@ -170,12 +152,6 @@ void *bmMapBuffer( struct intel_context *, void bmUnmapBuffer( struct intel_context *, struct buffer *buf ); -void bmUnmapBufferAUB( struct intel_context *, - struct buffer *buf, - unsigned aubtype, - unsigned aubsubtype ); - - /* Pertains to all buffers who's offset has been taken since the last * fence or release. */ diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c index 24ee11edd8..a85121122f 100644 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -85,7 +85,6 @@ struct buffer { unsigned mapped:1; unsigned dirty:1; - unsigned aub_dirty:1; unsigned alignment:13; unsigned flags:16; @@ -906,86 +905,6 @@ int bmBufferSubData(struct intel_context *intel, return retval; } - - -int bmBufferDataAUB(struct intel_context *intel, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags, - unsigned aubtype, - unsigned aubsubtype ) -{ - int retval = bmBufferData(intel, buf, size, data, flags); - - - /* This only works because in this version of the buffer manager we - * allocate all buffers statically in agp space and so can emit the - * uploads to the aub file with the correct offsets as they happen. - */ - if (retval == 0 && data && intel->aub_file) { - - if (buf->block && !buf->dirty) { - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs, - buf->block->virtual, - size, - aubtype, - aubsubtype); - buf->aub_dirty = 0; - } - } - - return retval; -} - - -int bmBufferSubDataAUB(struct intel_context *intel, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data, - unsigned aubtype, - unsigned aubsubtype ) -{ - int retval = bmBufferSubData(intel, buf, offset, size, data); - - - /* This only works because in this version of the buffer manager we - * allocate all buffers statically in agp space and so can emit the - * uploads to the aub file with the correct offsets as they happen. - */ - if (intel->aub_file) { - if (retval == 0 && buf->block && !buf->dirty) - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs + offset, - ((const char *)buf->block->virtual) + offset, - size, - aubtype, - aubsubtype); - } - - return retval; -} - -void bmUnmapBufferAUB( struct intel_context *intel, - struct buffer *buf, - unsigned aubtype, - unsigned aubsubtype ) -{ - bmUnmapBuffer(intel, buf); - - if (intel->aub_file) { - /* Hack - exclude the framebuffer mappings. If you removed - * this, you'd get very big aubfiles, but you *would* be able to - * see fallback rendering. - */ - if (buf->block && !buf->dirty && buf->block->pool == &intel->bm->pool[0]) { - buf->aub_dirty = 1; - } - } -} - unsigned bmBufferOffset(struct intel_context *intel, struct buffer *buf) { @@ -1197,26 +1116,7 @@ int bmValidateBuffers( struct intel_context *intel ) buf->backing_store, buf->size); - if (intel->aub_file) { - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs, - buf->backing_store, - buf->size, - 0, - 0); - } - buf->dirty = 0; - buf->aub_dirty = 0; - } - else if (buf->aub_dirty) { - intel->vtbl.aub_gtt_data(intel, - buf->block->mem->ofs, - buf->block->virtual, - buf->size, - 0, - 0); - buf->aub_dirty = 0; } block->referenced = 0; diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index 64885ed9b4..2aaa10e1c2 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -168,31 +168,12 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch ) goto out; } - - if (intel->aub_file) { - /* Send buffered commands to aubfile as a single packet. - */ - intel_batchbuffer_map(batch); - ((int *)batch->ptr)[-1] = intel->vtbl.flush_cmd(); - intel->vtbl.aub_commands(intel, - offset, /* Fulsim wierdness - don't adjust */ - batch->map + batch->offset, - used); - ((int *)batch->ptr)[-1] = MI_BATCH_BUFFER_END; - intel_batchbuffer_unmap(batch); - } - - /* Fire the batch buffer, which was uploaded above: */ intel_batch_ioctl(batch->intel, offset + batch->offset, used); - if (intel->aub_file && - intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) - intel->vtbl.aub_dump_bmp( intel, 0 ); - /* Reset the buffer: */ out: diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c index 015e433fd7..3349284f5d 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c @@ -103,8 +103,7 @@ static void intel_bufferobj_data( GLcontext *ctx, obj->Size = size; obj->Usage = usage; - bmBufferDataAUB(intel, intel_obj->buffer, size, data, 0, - 0, 0); + bmBufferData(intel, intel_obj->buffer, size, data, 0); } @@ -125,7 +124,7 @@ static void intel_bufferobj_subdata( GLcontext *ctx, struct intel_buffer_object *intel_obj = intel_buffer_object(obj); assert(intel_obj); - bmBufferSubDataAUB(intel, intel_obj->buffer, offset, size, data, 0, 0); + bmBufferSubData(intel, intel_obj->buffer, offset, size, data); } @@ -181,7 +180,7 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx, assert(intel_obj); assert(intel_obj->buffer); assert(obj->Pointer); - bmUnmapBufferAUB(intel, intel_obj->buffer, 0, 0); + bmUnmapBuffer(intel, intel_obj->buffer); obj->Pointer = NULL; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c index d155c039d7..6c8b073502 100644 --- a/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/src/mesa/drivers/dri/i965/intel_buffers.c @@ -450,12 +450,6 @@ void intelSwapBuffers( __DRIdrawablePrivate *dPriv ) } else { intelCopyBuffer( dPriv, NULL ); } - if (intel->aub_file) { - intelFlush(ctx); - intel->vtbl.aub_dump_bmp( intel, 1 ); - - intel->aub_wrap = 1; - } } } else { /* XXX this shouldn't be an error but we can't handle it for now */ diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index f3ec2b2eee..022819d582 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -668,13 +668,6 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; - if (intel->aub_wrap) { - bm_fake_NotifyContendedLockTake( intel ); - intel->vtbl.lost_hardware( intel ); - intel->vtbl.aub_wrap(intel); - intel->aub_wrap = 0; - } - if (bmError(intel)) { bmEvictAll(intel); intel->vtbl.lost_hardware( intel ); diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 053d93a82b..06cfc6946d 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -109,20 +109,6 @@ struct intel_context void (*emit_flush)( struct intel_context *intel, GLuint unused ); - void (*aub_commands)( struct intel_context *intel, - GLuint offset, - const void *buf, - GLuint sz ); - void (*aub_dump_bmp)( struct intel_context *intel, GLuint buffer ); - void (*aub_wrap)( struct intel_context *intel ); - void (*aub_gtt_data)( struct intel_context *intel, - GLuint offset, - const void *src, - GLuint size, - GLuint aubtype, - GLuint aubsubtype); - - void (*reduced_primitive_state)( struct intel_context *intel, GLenum rprim ); GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected ); @@ -176,7 +162,6 @@ struct intel_context GLuint last_swap_fence; GLuint second_last_swap_fence; - GLboolean aub_wrap; GLuint stats_wm; struct intel_batchbuffer *batch; @@ -238,8 +223,6 @@ struct intel_context __DRIscreenPrivate *driScreen; intelScreenPrivate *intelScreen; volatile drmI830Sarea *sarea; - - FILE *aub_file; GLuint lastStamp; diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index 0a8e976f70..e7e736079f 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -115,10 +115,6 @@ void intelWaitIrq( struct intel_context *intel, int seq ) if ( ret ) { fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret ); - if (intel->aub_file) { - intel->vtbl.aub_dump_bmp( intel, intel->ctx.Visual.doubleBufferMode ? 1 : 0 ); - } - exit(1); } } diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index 835ecdd725..b78eba898f 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -64,7 +64,7 @@ void intel_region_unmap(struct intel_context *intel, { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - bmUnmapBufferAUB(intel, region->buffer, 0, 0); + bmUnmapBuffer(intel, region->buffer); region->map = NULL; } } @@ -217,10 +217,10 @@ GLboolean intel_region_data(struct intel_context *intel, srcx == 0 && srcy == 0) { - return (bmBufferDataAUB(intel, - dst->buffer, - dst->cpp * width * dst->height, - src, 0, 0, 0) == 0); + return (bmBufferData(intel, + dst->buffer, + dst->cpp * width * dst->height, + src, 0) == 0); } else { GLubyte *map = intel_region_map(intel, dst); -- cgit v1.2.3 From b2f1aa2389473ed09170713301b042661d70a48e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Sep 2007 10:16:04 -0700 Subject: WIP 965 conversion to dri_bufmgr. --- src/mesa/drivers/dri/i915/Makefile | 1 + src/mesa/drivers/dri/i915/intel_batchbuffer.c | 331 ------ src/mesa/drivers/dri/i915/intel_batchbuffer.h | 122 -- src/mesa/drivers/dri/i965/Makefile | 2 +- src/mesa/drivers/dri/i965/brw_context.h | 4 +- src/mesa/drivers/dri/i965/brw_draw_upload.c | 6 +- src/mesa/drivers/dri/i965/brw_state_pool.c | 2 +- src/mesa/drivers/dri/i965/brw_state_upload.c | 2 +- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- src/mesa/drivers/dri/i965/bufmgr.h | 191 --- src/mesa/drivers/dri/i965/bufmgr_fake.c | 1360 ---------------------- src/mesa/drivers/dri/i965/intel_batchbuffer.c | 13 +- src/mesa/drivers/dri/i965/intel_batchbuffer.h | 4 +- src/mesa/drivers/dri/i965/intel_blit.c | 16 +- src/mesa/drivers/dri/i965/intel_blit.h | 10 +- src/mesa/drivers/dri/i965/intel_buffer_objects.c | 4 +- src/mesa/drivers/dri/i965/intel_buffer_objects.h | 4 +- src/mesa/drivers/dri/i965/intel_context.c | 25 +- src/mesa/drivers/dri/i965/intel_ioctl.c | 2 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/i965/intel_regions.c | 12 +- src/mesa/drivers/dri/i965/intel_regions.h | 4 +- src/mesa/drivers/dri/i965/intel_screen.c | 59 +- src/mesa/drivers/dri/i965/intel_screen.h | 7 + src/mesa/drivers/dri/i965/intel_tex_layout.c | 103 +- src/mesa/drivers/dri/i965/intel_tex_validate.c | 2 +- src/mesa/drivers/dri/intel/intel_batchbuffer.c | 331 ++++++ src/mesa/drivers/dri/intel/intel_batchbuffer.h | 122 ++ 28 files changed, 673 insertions(+), 2070 deletions(-) delete mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.c delete mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.h delete mode 100644 src/mesa/drivers/dri/i965/bufmgr.h delete mode 100644 src/mesa/drivers/dri/i965/bufmgr_fake.c mode change 120000 => 100644 src/mesa/drivers/dri/i965/intel_tex_layout.c create mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.c create mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.h (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index d3d0bd570c..0e2cdcb240 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -66,6 +66,7 @@ DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ include ../Makefile.template +intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c symlinks: diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c deleted file mode 100644 index 8ee48b5a68..0000000000 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_decode.h" -#include "i915_debug.h" - -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - - if (batch->buf != NULL) { - dri_bo_unreference(batch->buf); - batch->buf = NULL; - } - - batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", - intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT); - dri_bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - batch->size = intel->intelScreen->maxBatchSize; - batch->ptr = batch->map; -} - -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - batch->last_fence = NULL; - intel_batchbuffer_reset(batch); - - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - dri_fence_wait(batch->last_fence); - dri_fence_unreference(batch->last_fence); - batch->last_fence = NULL; - } - if (batch->map) { - dri_bo_unmap(batch->buf); - batch->map = NULL; - } - dri_bo_unreference(batch->buf); - batch->buf = NULL; - free(batch); -} - -static int -relocation_sort(const void *a_in, const void *b_in) { - const struct buffer_reloc *a = a_in, *b = b_in; - - return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; -} - - -/* TODO: Push this whole function into bufmgr. - */ -static void -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - GLuint *ptr; - GLuint i; - struct intel_context *intel = batch->intel; - dri_fence *fo; - GLboolean performed_rendering = GL_FALSE; - - assert(batch->buf->virtual != NULL); - ptr = batch->buf->virtual; - - /* Sort our relocation list in terms of referenced buffer pointer. - * This lets us uniquely validate the buffers with the sum of all the flags, - * while avoiding O(n^2) on number of relocations. - */ - qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), - relocation_sort); - - /* Perform the necessary validations of buffers, and enter the relocations - * in the batchbuffer. - */ - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - - if (r->validate_flags & DRM_BO_FLAG_WRITE) - performed_rendering = GL_TRUE; - - /* If this is the first time we've seen this buffer in the relocation - * list, figure out our flags and validate it. - */ - if (i == 0 || batch->reloc[i - 1].buf != r->buf) { - uint32_t validate_flags; - int j, ret; - - /* Accumulate the flags we need for validating this buffer. */ - validate_flags = r->validate_flags; - for (j = i + 1; j < batch->nr_relocs; j++) { - if (batch->reloc[j].buf != r->buf) - break; - validate_flags |= batch->reloc[j].validate_flags; - } - - /* Validate. If we fail, fence to clear the unfenced list and bail - * out. - */ - ret = dri_bo_validate(r->buf, validate_flags); - if (ret != 0) { - dri_bo_unmap(batch->buf); - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "batchbuffer failure fence", GL_TRUE); - dri_fence_unreference(fo); - goto done; - } - } - ptr[r->offset / 4] = r->buf->offset + r->delta; - dri_bo_unreference(r->buf); - } - - dri_bo_unmap(batch->buf); - batch->map = NULL; - batch->ptr = NULL; - - dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); - - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { - intel_batch_ioctl(batch->intel, - batch->buf->offset, - used, ignore_cliprects, allow_unlock); - } - - /* Associate a fence with the validated buffers, and note that we included - * a flush at the end. - */ - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "Batch fence", GL_TRUE); - - if (performed_rendering) { - dri_fence_unreference(batch->last_fence); - batch->last_fence = fo; - } else { - /* If we didn't validate any buffers for writing by the card, we don't - * need to track the fence for glFinish(). - */ - dri_fence_unreference(fo); - } - - if (intel->numClipRects == 0 && !ignore_cliprects) { - if (allow_unlock) { - /* If we are not doing any actual user-visible rendering, - * do a sched_yield to keep the app from pegging the cpu while - * achieving nothing. - */ - UNLOCK_HARDWARE(intel); - sched_yield(); - LOCK_HARDWARE(intel); - } - intel->vtbl.lost_hardware(intel); - } - -done: - if (INTEL_DEBUG & DEBUG_BATCH) { - dri_bo_map(batch->buf, GL_FALSE); - intel_decode(ptr, used / 4, batch->buf->offset); - dri_bo_unmap(batch->buf); - } -} - - -void -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; - GLboolean was_locked = intel->locked; - - if (used == 0) - return; - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ - if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - LOCK_HARDWARE(intel); - - do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - intel_batchbuffer_flush(batch); - if (batch->last_fence != NULL) - dri_fence_wait(batch->last_fence); -} - - -/* This is the only way buffers get added to the validate list. - */ -GLboolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint delta) -{ - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - - assert(batch->nr_relocs <= MAX_RELOCS); - - dri_bo_reference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - r->validate_flags = flags; - - batch->ptr += 4; - return GL_TRUE; -} - - - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - __memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; -} diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h deleted file mode 100644 index 850a91e1c9..0000000000 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "mtypes.h" -#include "dri_bufmgr.h" - -struct intel_context; - -#define BATCH_SZ 16384 -#define BATCH_RESERVED 16 - -#define MAX_RELOCS 4096 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct buffer_reloc -{ - dri_bo *buf; - GLuint offset; - GLuint delta; /* not needed? */ - GLuint validate_flags; -}; - -struct intel_batchbuffer -{ - struct intel_context *intel; - - dri_bo *buf; - dri_fence *last_fence; - GLuint flags; - - drmBOList list; - GLuint list_count; - GLubyte *map; - GLubyte *ptr; - - struct buffer_reloc reloc[MAX_RELOCS]; - GLuint nr_relocs; - GLuint size; -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -void intel_batchbuffer_flush(struct intel_batchbuffer *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint offset); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... - */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; -} - -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - assert(sz < batch->size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) - intel_batchbuffer_flush(batch); - - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: - */ -#define BATCH_LOCALS - -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) - -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) - -#define OUT_RELOC(buf, flags, delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ -} while (0) - -#define ADVANCE_BATCH() do { } while(0) - - -#endif diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 5748d7ff05..07256ce1e5 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -5,7 +5,6 @@ include $(TOP)/configs/current LIBNAME = i965_dri.so DRIVER_SOURCES = \ - bufmgr_fake.c \ intel_batchbuffer.c \ intel_blit.c \ intel_buffer_objects.c \ @@ -92,6 +91,7 @@ DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c server: diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index aa797b72ce..279baf8c83 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -242,7 +242,7 @@ struct brw_surface_binding_table { struct brw_cache; struct brw_mem_pool { - struct buffer *buffer; + dri_bo *buffer; GLuint size; GLuint offset; /* offset of first free byte */ @@ -605,7 +605,7 @@ struct brw_context GLuint nr_surfaces; GLuint max_threads; - struct buffer *scratch_buffer; + dri_bo *scratch_buffer; GLuint scratch_buffer_size; GLuint sampler_count; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index fc2e3035af..5f6f0ef5a6 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -58,7 +58,7 @@ struct brw_array_state { GLuint dword; } vb0; - struct buffer *buffer; + dri_bo *buffer; GLuint offset; GLuint max_index; @@ -68,7 +68,7 @@ struct brw_array_state { }; -static struct buffer *array_buffer( const struct gl_client_array *array ) +static dri_bo *array_buffer( const struct gl_client_array *array ) { return intel_bufferobj_buffer(intel_buffer_object(array->BufferObj)); } @@ -620,7 +620,7 @@ void brw_upload_indices( struct brw_context *brw, */ { struct brw_indexbuffer ib; - struct buffer *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); + dri_bo *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); memset(&ib, 0, sizeof(ib)); diff --git a/src/mesa/drivers/dri/i965/brw_state_pool.c b/src/mesa/drivers/dri/i965/brw_state_pool.c index 708ae857ab..9677c73583 100644 --- a/src/mesa/drivers/dri/i965/brw_state_pool.c +++ b/src/mesa/drivers/dri/i965/brw_state_pool.c @@ -34,7 +34,7 @@ #include "imports.h" #include "intel_ioctl.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" GLboolean brw_pool_alloc( struct brw_mem_pool *pool, GLuint size, diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 92c07c2962..d5e575ef66 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -33,7 +33,7 @@ #include "brw_context.h" #include "brw_state.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "intel_batchbuffer.h" /* This is used to initialize brw->state.atoms[]. We could use this diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 5b4f2abd0e..b1de66d988 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -34,7 +34,7 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" /*********************************************************************** * WM unit - fragment programs and rasterization diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h deleted file mode 100644 index b31c2e6d9b..0000000000 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ /dev/null @@ -1,191 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef BUFMGR_H -#define BUFMGR_H - -#include "intel_context.h" - - -/* The buffer manager context. Opaque. - */ -struct bufmgr; -struct buffer; - - -struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); - -/* Flags for validate and other calls. If both NO_UPLOAD and NO_EVICT - * are specified, ValidateBuffers is essentially a query. - */ -#define BM_MEM_LOCAL 0x1 -#define BM_MEM_AGP 0x2 -#define BM_MEM_VRAM 0x4 /* not yet used */ -#define BM_WRITE 0x8 /* not yet used */ -#define BM_READ 0x10 /* not yet used */ -#define BM_NO_UPLOAD 0x20 -#define BM_NO_EVICT 0x40 -#define BM_NO_MOVE 0x80 /* not yet used */ -#define BM_NO_ALLOC 0x100 /* legacy "fixed" buffers only */ -#define BM_CLIENT 0x200 /* for map - pointer will be accessed - * without dri lock */ - -#define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM) - - - - -/* Create a pool of a given memory type, from a certain offset and a - * certain size. - * - * Also passed in is a virtual pointer to the start of the pool. This - * is useful in the faked-out version in i915 so that MapBuffer can - * return a pointer to a buffer residing in AGP space. - * - * Flags passed into a pool are inherited by all buffers allocated in - * that pool. So pools representing the static front,back,depth - * buffer allocations should have MEM_AGP|NO_UPLOAD|NO_EVICT|NO_MOVE to match - * the behaviour of the legacy allocations. - * - * Returns -1 for failure, pool number for success. - */ -int bmInitPool( struct intel_context *, - unsigned long low_offset, - void *low_virtual, - unsigned long size, - unsigned flags); - - -/* Stick closely to ARB_vbo semantics - they're well defined and - * understood, and drivers can just pass the calls through without too - * much thunking. - */ -void bmGenBuffers(struct intel_context *, const char *, unsigned n, struct buffer **buffers, - int align ); -void bmDeleteBuffers(struct intel_context *, unsigned n, struct buffer **buffers); - - -/* Hook to inform faked buffer manager about fixed-position - * front,depth,back buffers. These may move to a fully memory-managed - * scheme, or they may continue to be managed as is. - */ -struct buffer *bmGenBufferStatic(struct intel_context *, - unsigned pool); - -/* On evict, buffer manager will call invalidate_cb() to note that the - * buffer needs to be reloaded. - * - * Buffer is uploaded by calling bmMapBuffer() and copying data into - * the returned pointer. - * - * This is basically a big hack to get some more performance by - * turning off backing store for buffers where we either have it - * already (textures) or don't need it (batch buffers, temporary - * vbo's). - */ -void bmBufferSetInvalidateCB(struct intel_context *, - struct buffer *buf, - void (*invalidate_cb)( struct intel_context *, void *ptr ), - void *ptr, - GLboolean dont_fence_subdata); - - -/* The driver has more intimate knowledge of the hardare than a GL - * client would, so flags here is more proscriptive than the usage - * values in the ARB_vbo interface: - */ -int bmBufferData(struct intel_context *, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags ); - -int bmBufferSubData(struct intel_context *, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data ); - -/* In this version, taking the offset will provoke an upload on - * buffers not already resident in AGP: - */ -unsigned bmBufferOffset(struct intel_context *, - struct buffer *buf); - - -/* Extract data from the buffer: - */ -void bmBufferGetSubData(struct intel_context *, - struct buffer *buf, - unsigned offset, - unsigned size, - void *data ); - -void *bmMapBuffer( struct intel_context *, - struct buffer *buf, - unsigned access ); - -void bmUnmapBuffer( struct intel_context *, - struct buffer *buf ); - -/* Pertains to all buffers who's offset has been taken since the last - * fence or release. - */ -int bmValidateBuffers( struct intel_context * ); -void bmReleaseBuffers( struct intel_context * ); - -GLuint bmCtxId( struct intel_context *intel ); - - -GLboolean bmError( struct intel_context * ); -void bmEvictAll( struct intel_context * ); - -void *bmFindVirtual( struct intel_context *intel, - unsigned int offset, - size_t sz ); - -/* This functionality is used by the buffer manager, not really sure - * if we need to be exposing it in this way, probably libdrm will - * offer equivalent calls. - * - * For now they can stay, but will likely change/move before final: - */ -unsigned bmSetFence( struct intel_context * ); -unsigned bmSetFenceLock( struct intel_context * ); -unsigned bmLockAndFence( struct intel_context *intel ); -int bmTestFence( struct intel_context *, unsigned fence ); -void bmFinishFence( struct intel_context *, unsigned fence ); -void bmFinishFenceLock( struct intel_context *, unsigned fence ); - -void bm_fake_NotifyContendedLockTake( struct intel_context * ); - -extern int INTEL_DEBUG; -#define DEBUG_BUFMGR 0x10000000 - -#define DBG(...) do { if (INTEL_DEBUG & DEBUG_BUFMGR) _mesa_printf(__VA_ARGS__); } while(0) - -#endif diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c deleted file mode 100644 index a85121122f..0000000000 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ /dev/null @@ -1,1360 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* Originally a fake version of the buffer manager so that we can - * prototype the changes in a driver fairly quickly, has been fleshed - * out to a fully functional interim solution. - * - * Basically wraps the old style memory management in the new - * programming interface, but is more expressive and avoids many of - * the bugs in the old texture manager. - */ -#include "bufmgr.h" - -#include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" - -#include "simple_list.h" -#include "mm.h" -#include "imports.h" - -#define BM_POOL_MAX 8 - -/* Internal flags: - */ -#define BM_NO_BACKING_STORE 0x2000 -#define BM_NO_FENCE_SUBDATA 0x4000 - - -static int check_fenced( struct intel_context *intel ); - -static int nr_attach = 0; - -/* Wrapper around mm.c's mem_block, which understands that you must - * wait for fences to expire before memory can be freed. This is - * specific to our use of memcpy for uploads - an upload that was - * processed through the command queue wouldn't need to care about - * fences. - */ -struct block { - struct block *next, *prev; - struct pool *pool; /* BM_MEM_AGP */ - struct mem_block *mem; /* BM_MEM_AGP */ - - unsigned referenced:1; - unsigned on_hardware:1; - unsigned fenced:1; - - - unsigned fence; /* BM_MEM_AGP, Split to read_fence, write_fence */ - - struct buffer *buf; - void *virtual; -}; - - -struct buffer { - unsigned id; /* debug only */ - const char *name; - unsigned size; - - unsigned mapped:1; - unsigned dirty:1; - unsigned alignment:13; - unsigned flags:16; - - struct block *block; - void *backing_store; - void (*invalidate_cb)( struct intel_context *, void * ); - void *invalidate_ptr; -}; - -struct pool { - unsigned size; - unsigned low_offset; - struct buffer *static_buffer; - unsigned flags; - struct mem_block *heap; - void *virtual; - struct block lru; /* only allocated, non-fence-pending blocks here */ -}; - -struct bufmgr { - _glthread_Mutex mutex; /**< for thread safety */ - struct pool pool[BM_POOL_MAX]; - unsigned nr_pools; - - unsigned buf_nr; /* for generating ids */ - - struct block referenced; /* after bmBufferOffset */ - struct block on_hardware; /* after bmValidateBuffers */ - struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ - /* then to pool->lru or free() */ - - unsigned ctxId; - unsigned last_fence; - unsigned free_on_hardware; - - unsigned fail:1; - unsigned need_fence:1; -}; - -#define MAXFENCE 0x7fffffff - -static GLboolean FENCE_LTE( unsigned a, unsigned b ) -{ - if (a == b) - return GL_TRUE; - - if (a < b && b - a < (1<<24)) - return GL_TRUE; - - if (a > b && MAXFENCE - a + b < (1<<24)) - return GL_TRUE; - - return GL_FALSE; -} - -int bmTestFence( struct intel_context *intel, unsigned fence ) -{ - /* Slight problem with wrap-around: - */ - return fence == 0 || FENCE_LTE(fence, intel->sarea->last_dispatch); -} - -#define LOCK(bm) \ - int dolock = nr_attach > 1; \ - if (dolock) _glthread_LOCK_MUTEX(bm->mutex) - -#define UNLOCK(bm) \ - if (dolock) _glthread_UNLOCK_MUTEX(bm->mutex) - - - -static GLboolean alloc_from_pool( struct intel_context *intel, - unsigned pool_nr, - struct buffer *buf ) -{ - struct bufmgr *bm = intel->bm; - struct pool *pool = &bm->pool[pool_nr]; - struct block *block = (struct block *)calloc(sizeof *block, 1); - GLuint sz, align = (1<alignment); - - if (!block) - return GL_FALSE; - - sz = (buf->size + align-1) & ~(align-1); - - block->mem = mmAllocMem(pool->heap, - sz, - buf->alignment, 0); - if (!block->mem) { - free(block); - return GL_FALSE; - } - - make_empty_list(block); - - /* Insert at head or at tail??? - */ - insert_at_tail(&pool->lru, block); - - block->pool = pool; - block->virtual = pool->virtual + block->mem->ofs; - block->buf = buf; - - buf->block = block; - - return GL_TRUE; -} - - - - - - - - -/* Release the card storage associated with buf: - */ -static void free_block( struct intel_context *intel, struct block *block ) -{ - DBG("free block %p\n", block); - - if (!block) - return; - - check_fenced(intel); - - if (block->referenced) { - _mesa_printf("tried to free block on referenced list\n"); - assert(0); - } - else if (block->on_hardware) { - block->buf = NULL; - intel->bm->free_on_hardware += block->mem->size; - } - else if (block->fenced) { - block->buf = NULL; - } - else { - DBG(" - free immediately\n"); - remove_from_list(block); - - mmFreeMem(block->mem); - free(block); - } -} - - -static void alloc_backing_store( struct intel_context *intel, struct buffer *buf ) -{ - assert(!buf->backing_store); - assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); - - buf->backing_store = ALIGN_MALLOC(buf->size, 64); -} - -static void free_backing_store( struct intel_context *intel, struct buffer *buf ) -{ - assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); - - if (buf->backing_store) { - ALIGN_FREE(buf->backing_store); - buf->backing_store = NULL; - } -} - - - - - - -static void set_dirty( struct intel_context *intel, - struct buffer *buf ) -{ - if (buf->flags & BM_NO_BACKING_STORE) - buf->invalidate_cb(intel, buf->invalidate_ptr); - - assert(!(buf->flags & BM_NO_EVICT)); - - DBG("set_dirty - buf %d\n", buf->id); - buf->dirty = 1; -} - - -static int evict_lru( struct intel_context *intel, GLuint max_fence, GLuint *pool ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - int i; - - DBG("%s\n", __FUNCTION__); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s(block, tmp, &bm->pool[i].lru) { - - if (block->buf && - (block->buf->flags & BM_NO_FENCE_SUBDATA)) - continue; - - if (block->fence && max_fence && - !FENCE_LTE(block->fence, max_fence)) - return 0; - - set_dirty(intel, block->buf); - block->buf->block = NULL; - - free_block(intel, block); - *pool = i; - return 1; - } - } - } - - - return 0; -} - - -#define foreach_s_rev(ptr, t, list) \ - for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev) - -static int evict_mru( struct intel_context *intel, GLuint *pool ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - int i; - - DBG("%s\n", __FUNCTION__); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s_rev(block, tmp, &bm->pool[i].lru) { - - if (block->buf && - (block->buf->flags & BM_NO_FENCE_SUBDATA)) - continue; - - set_dirty(intel, block->buf); - block->buf->block = NULL; - - free_block(intel, block); - *pool = i; - return 1; - } - } - } - - - return 0; -} - - -static int check_fenced( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - int ret = 0; - - foreach_s(block, tmp, &bm->fenced ) { - assert(block->fenced); - - if (bmTestFence(intel, block->fence)) { - - block->fenced = 0; - - if (!block->buf) { - DBG("delayed free: offset %x sz %x\n", block->mem->ofs, block->mem->size); - remove_from_list(block); - mmFreeMem(block->mem); - free(block); - } - else { - DBG("return to lru: offset %x sz %x\n", block->mem->ofs, block->mem->size); - move_to_tail(&block->pool->lru, block); - } - - ret = 1; - } - else { - /* Blocks are ordered by fence, so if one fails, all from - * here will fail also: - */ - break; - } - } - - /* Also check the referenced list: - */ - foreach_s(block, tmp, &bm->referenced ) { - if (block->fenced && - bmTestFence(intel, block->fence)) { - block->fenced = 0; - } - } - - - DBG("%s: %d\n", __FUNCTION__, ret); - return ret; -} - - - -static void fence_blocks( struct intel_context *intel, - unsigned fence ) -{ - struct bufmgr *bm = intel->bm; - struct block *block, *tmp; - - foreach_s (block, tmp, &bm->on_hardware) { - DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, - block->mem->size, block->buf, fence); - block->fence = fence; - - block->on_hardware = 0; - block->fenced = 1; - - /* Move to tail of pending list here - */ - move_to_tail(&bm->fenced, block); - } - - /* Also check the referenced list: - */ - foreach_s (block, tmp, &bm->referenced) { - if (block->on_hardware) { - DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, - block->mem->size, block->buf, fence); - - block->fence = fence; - block->on_hardware = 0; - block->fenced = 1; - } - } - - - bm->last_fence = fence; - assert(is_empty_list(&bm->on_hardware)); -} - - - - -static GLboolean alloc_block( struct intel_context *intel, - struct buffer *buf ) -{ - struct bufmgr *bm = intel->bm; - int i; - - assert(intel->locked); - - DBG("%s 0x%x bytes (%s)\n", __FUNCTION__, buf->size, buf->name); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_ALLOC) && - alloc_from_pool(intel, i, buf)) { - - DBG("%s --> 0x%x (sz %x)\n", __FUNCTION__, - buf->block->mem->ofs, buf->block->mem->size); - - return GL_TRUE; - } - } - - DBG("%s --> fail\n", __FUNCTION__); - return GL_FALSE; -} - - -static GLboolean evict_and_alloc_block( struct intel_context *intel, - struct buffer *buf ) -{ - GLuint pool; - struct bufmgr *bm = intel->bm; - - assert(buf->block == NULL); - - /* Put a cap on the amount of free memory we'll allow to accumulate - * before emitting a fence. - */ - if (bm->free_on_hardware > 1 * 1024 * 1024) { - DBG("fence for free space: %x\n", bm->free_on_hardware); - bmSetFence(intel); - } - - /* Search for already free memory: - */ - if (alloc_block(intel, buf)) - return GL_TRUE; - - /* Look for memory that may have become free: - */ - if (check_fenced(intel) && - alloc_block(intel, buf)) - return GL_TRUE; - - /* Look for memory blocks not used for >1 frame: - */ - while (evict_lru(intel, intel->second_last_swap_fence, &pool)) - if (alloc_from_pool(intel, pool, buf)) - return GL_TRUE; - - /* If we're not thrashing, allow lru eviction to dig deeper into - * recently used textures. We'll probably be thrashing soon: - */ - if (!intel->thrashing) { - while (evict_lru(intel, 0, &pool)) - if (alloc_from_pool(intel, pool, buf)) - return GL_TRUE; - } - - /* Keep thrashing counter alive? - */ - if (intel->thrashing) - intel->thrashing = 20; - - /* Wait on any already pending fences - here we are waiting for any - * freed memory that has been submitted to hardware and fenced to - * become available: - */ - while (!is_empty_list(&bm->fenced)) { - GLuint fence = bm->fenced.next->fence; - bmFinishFence(intel, fence); - - if (alloc_block(intel, buf)) - return GL_TRUE; - } - - - /* - */ - if (!is_empty_list(&bm->on_hardware)) { - bmSetFence(intel); - - while (!is_empty_list(&bm->fenced)) { - GLuint fence = bm->fenced.next->fence; - bmFinishFence(intel, fence); - } - - if (!intel->thrashing) { - DBG("thrashing\n"); - } - intel->thrashing = 20; - - if (alloc_block(intel, buf)) - return GL_TRUE; - } - - while (evict_mru(intel, &pool)) - if (alloc_from_pool(intel, pool, buf)) - return GL_TRUE; - - DBG("%s 0x%x bytes failed\n", __FUNCTION__, buf->size); - - assert(is_empty_list(&bm->on_hardware)); - assert(is_empty_list(&bm->fenced)); - - return GL_FALSE; -} - - - - - - - - - - -/*********************************************************************** - * Public functions - */ - - -/* The initialization functions are skewed in the fake implementation. - * This call would be to attach to an existing manager, rather than to - * create a local one. - */ -struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ) -{ - _glthread_DECLARE_STATIC_MUTEX(initMutex); - static struct bufmgr bm; - - /* This function needs a mutex of its own... - */ - _glthread_LOCK_MUTEX(initMutex); - - if (nr_attach == 0) { - _glthread_INIT_MUTEX(bm.mutex); - - make_empty_list(&bm.referenced); - make_empty_list(&bm.fenced); - make_empty_list(&bm.on_hardware); - - /* The context id of any of the share group. This won't be used - * in communication with the kernel, so it doesn't matter if - * this context is eventually deleted. - */ - bm.ctxId = intel->hHWContext; - } - - nr_attach++; - - _glthread_UNLOCK_MUTEX(initMutex); - - return &bm; -} - - - -/* The virtual pointer would go away in a true implementation. - */ -int bmInitPool( struct intel_context *intel, - unsigned long low_offset, - void *low_virtual, - unsigned long size, - unsigned flags) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - LOCK(bm); - { - GLuint i; - - for (i = 0; i < bm->nr_pools; i++) { - if (bm->pool[i].low_offset == low_offset && - bm->pool[i].size == size) { - retval = i; - goto out; - } - } - - - if (bm->nr_pools >= BM_POOL_MAX) - retval = -1; - else { - i = bm->nr_pools++; - - DBG("bmInitPool %d low_offset %x sz %x\n", - i, low_offset, size); - - bm->pool[i].low_offset = low_offset; - bm->pool[i].size = size; - bm->pool[i].heap = mmInit( low_offset, size ); - bm->pool[i].virtual = low_virtual - low_offset; - bm->pool[i].flags = flags; - - make_empty_list(&bm->pool[i].lru); - - retval = i; - } - } - out: - UNLOCK(bm); - return retval; -} - -static struct buffer *do_GenBuffer(struct intel_context *intel, const char *name, int align) -{ - struct bufmgr *bm = intel->bm; - struct buffer *buf = calloc(sizeof(*buf), 1); - - buf->id = ++bm->buf_nr; - buf->name = name; - buf->alignment = align; - buf->flags = BM_MEM_AGP|BM_MEM_VRAM|BM_MEM_LOCAL; - - return buf; -} - - -void *bmFindVirtual( struct intel_context *intel, - unsigned int offset, - size_t sz ) -{ - struct bufmgr *bm = intel->bm; - int i; - - for (i = 0; i < bm->nr_pools; i++) - if (offset >= bm->pool[i].low_offset && - offset + sz <= bm->pool[i].low_offset + bm->pool[i].size) - return bm->pool[i].virtual + offset; - - return NULL; -} - - -void bmGenBuffers(struct intel_context *intel, - const char *name, unsigned n, - struct buffer **buffers, - int align ) -{ - struct bufmgr *bm = intel->bm; - LOCK(bm); - { - int i; - - for (i = 0; i < n; i++) - buffers[i] = do_GenBuffer(intel, name, align); - } - UNLOCK(bm); -} - - -void bmDeleteBuffers(struct intel_context *intel, unsigned n, struct buffer **buffers) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - unsigned i; - - for (i = 0; i < n; i++) { - struct buffer *buf = buffers[i]; - - if (buf && buf->block) - free_block(intel, buf->block); - - if (buf) - free(buf); - } - } - UNLOCK(bm); -} - - - - -/* Hook to inform faked buffer manager about fixed-position - * front,depth,back buffers. These may move to a fully memory-managed - * scheme, or they may continue to be managed as is. It will probably - * be useful to pass a fixed offset here one day. - */ -struct buffer *bmGenBufferStatic(struct intel_context *intel, - unsigned pool ) -{ - struct bufmgr *bm = intel->bm; - struct buffer *buf; - LOCK(bm); - { - assert(bm->pool[pool].flags & BM_NO_EVICT); - assert(bm->pool[pool].flags & BM_NO_MOVE); - - if (bm->pool[pool].static_buffer) - buf = bm->pool[pool].static_buffer; - else { - buf = do_GenBuffer(intel, "static", 12); - - bm->pool[pool].static_buffer = buf; - assert(!buf->block); - - buf->size = bm->pool[pool].size; - buf->flags = bm->pool[pool].flags; - buf->alignment = 12; - - if (!alloc_from_pool(intel, pool, buf)) - assert(0); - } - } - UNLOCK(bm); - return buf; -} - - -static void wait_quiescent(struct intel_context *intel, - struct block *block) -{ - if (block->on_hardware) { - assert(intel->bm->need_fence); - bmSetFence(intel); - assert(!block->on_hardware); - } - - - if (block->fenced) { - bmFinishFence(intel, block->fence); - } - - assert(!block->on_hardware); - assert(!block->fenced); -} - - - -/* If buffer size changes, free and reallocate. Otherwise update in - * place. - */ -int bmBufferData(struct intel_context *intel, - struct buffer *buf, - unsigned size, - const void *data, - unsigned flags ) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - LOCK(bm); - { - DBG("bmBufferData %d sz 0x%x data: %p\n", buf->id, size, data); - - assert(!buf->mapped); - - if (buf->block) { - struct block *block = buf->block; - - /* Optimistic check to see if we can reuse the block -- not - * required for correctness: - */ - if (block->fenced) - check_fenced(intel); - - if (block->on_hardware || - block->fenced || - (buf->size && buf->size != size) || - (data == NULL)) { - - assert(!block->referenced); - - free_block(intel, block); - buf->block = NULL; - buf->dirty = 1; - } - } - - buf->size = size; - if (buf->block) { - assert (buf->block->mem->size >= size); - } - - if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { - - assert(intel->locked || data == NULL); - - if (data != NULL) { - if (!buf->block && !evict_and_alloc_block(intel, buf)) { - bm->fail = 1; - retval = -1; - goto out; - } - - wait_quiescent(intel, buf->block); - - DBG("bmBufferData %d offset 0x%x sz 0x%x\n", - buf->id, buf->block->mem->ofs, size); - - assert(buf->block->virtual == buf->block->pool->virtual + buf->block->mem->ofs); - - do_memcpy(buf->block->virtual, data, size); - } - buf->dirty = 0; - } - else { - DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); - set_dirty(intel, buf); - free_backing_store(intel, buf); - - if (data != NULL) { - alloc_backing_store(intel, buf); - do_memcpy(buf->backing_store, data, size); - } - } - } - out: - UNLOCK(bm); - return retval; -} - - -/* Update the buffer in place, in whatever space it is currently resident: - */ -int bmBufferSubData(struct intel_context *intel, - struct buffer *buf, - unsigned offset, - unsigned size, - const void *data ) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - if (size == 0) - return 0; - - LOCK(bm); - { - DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); - - assert(offset+size <= buf->size); - - if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { - - assert(intel->locked); - - if (!buf->block && !evict_and_alloc_block(intel, buf)) { - bm->fail = 1; - retval = -1; - goto out; - } - - if (!(buf->flags & BM_NO_FENCE_SUBDATA)) - wait_quiescent(intel, buf->block); - - buf->dirty = 0; - - do_memcpy(buf->block->virtual + offset, data, size); - } - else { - DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); - set_dirty(intel, buf); - - if (buf->backing_store == NULL) - alloc_backing_store(intel, buf); - - do_memcpy(buf->backing_store + offset, data, size); - } - } - out: - UNLOCK(bm); - return retval; -} - -unsigned bmBufferOffset(struct intel_context *intel, - struct buffer *buf) -{ - struct bufmgr *bm = intel->bm; - unsigned retval = 0; - - LOCK(bm); - { - assert(intel->locked); - - if (!buf->block && - !evict_and_alloc_block(intel, buf)) { - bm->fail = 1; - retval = ~0; - } - else { - assert(buf->block); - assert(buf->block->buf == buf); - - DBG("Add buf %d (block %p, dirty %d) to referenced list\n", buf->id, buf->block, - buf->dirty); - - move_to_tail(&bm->referenced, buf->block); - buf->block->referenced = 1; - - retval = buf->block->mem->ofs; - } - } - UNLOCK(bm); - - return retval; -} - - - -/* Extract data from the buffer: - */ -void bmBufferGetSubData(struct intel_context *intel, - struct buffer *buf, - unsigned offset, - unsigned size, - void *data ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); - - if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { - if (buf->block && size) { - wait_quiescent(intel, buf->block); - do_memcpy(data, buf->block->virtual + offset, size); - } - } - else { - if (buf->backing_store && size) { - do_memcpy(data, buf->backing_store + offset, size); - } - } - } - UNLOCK(bm); -} - - -/* Return a pointer to whatever space the buffer is currently resident in: - */ -void *bmMapBuffer( struct intel_context *intel, - struct buffer *buf, - unsigned flags ) -{ - struct bufmgr *bm = intel->bm; - void *retval = NULL; - - LOCK(bm); - { - DBG("bmMapBuffer %d\n", buf->id); - - if (buf->mapped) { - _mesa_printf("%s: already mapped\n", __FUNCTION__); - retval = NULL; - } - else if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { - - assert(intel->locked); - - if (!buf->block && !evict_and_alloc_block(intel, buf)) { - DBG("%s: alloc failed\n", __FUNCTION__); - bm->fail = 1; - retval = NULL; - } - else { - assert(buf->block); - buf->dirty = 0; - - if (!(buf->flags & BM_NO_FENCE_SUBDATA)) - wait_quiescent(intel, buf->block); - - buf->mapped = 1; - retval = buf->block->virtual; - } - } - else { - DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); - set_dirty(intel, buf); - - if (buf->backing_store == 0) - alloc_backing_store(intel, buf); - - buf->mapped = 1; - retval = buf->backing_store; - } - } - UNLOCK(bm); - return retval; -} - -void bmUnmapBuffer( struct intel_context *intel, struct buffer *buf ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - DBG("bmUnmapBuffer %d\n", buf->id); - buf->mapped = 0; - } - UNLOCK(bm); -} - - - - -/* This is the big hack that turns on BM_NO_BACKING_STORE. Basically - * says that an external party will maintain the backing store, eg - * Mesa's local copy of texture data. - */ -void bmBufferSetInvalidateCB(struct intel_context *intel, - struct buffer *buf, - void (*invalidate_cb)( struct intel_context *, void *ptr ), - void *ptr, - GLboolean dont_fence_subdata) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - if (buf->backing_store) - free_backing_store(intel, buf); - - buf->flags |= BM_NO_BACKING_STORE; - - if (dont_fence_subdata) - buf->flags |= BM_NO_FENCE_SUBDATA; - - DBG("bmBufferSetInvalidateCB set buf %d dirty\n", buf->id); - buf->dirty = 1; - buf->invalidate_cb = invalidate_cb; - buf->invalidate_ptr = ptr; - - /* Note that it is invalid right from the start. Also note - * invalidate_cb is called with the bufmgr locked, so cannot - * itself make bufmgr calls. - */ - invalidate_cb( intel, ptr ); - } - UNLOCK(bm); -} - - - - - - - -/* This is only protected against thread interactions by the DRI lock - * and the policy of ensuring that all dma is flushed prior to - * releasing that lock. Otherwise you might have two threads building - * up a list of buffers to validate at once. - */ -int bmValidateBuffers( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - int retval = 0; - - LOCK(bm); - { - DBG("%s fail %d\n", __FUNCTION__, bm->fail); - assert(intel->locked); - - if (!bm->fail) { - struct block *block, *tmp; - - foreach_s(block, tmp, &bm->referenced) { - struct buffer *buf = block->buf; - - DBG("Validate buf %d / block %p / dirty %d\n", buf->id, block, buf->dirty); - - /* Upload the buffer contents if necessary: - */ - if (buf->dirty) { - DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", buf->id, - buf->name, buf->size, block->mem->ofs); - - assert(!(buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT))); - - wait_quiescent(intel, buf->block); - - do_memcpy(buf->block->virtual, - buf->backing_store, - buf->size); - - buf->dirty = 0; - } - - block->referenced = 0; - block->on_hardware = 1; - move_to_tail(&bm->on_hardware, block); - } - - bm->need_fence = 1; - } - - retval = bm->fail ? -1 : 0; - } - UNLOCK(bm); - - - if (retval != 0) - DBG("%s failed\n", __FUNCTION__); - - return retval; -} - - - - -void bmReleaseBuffers( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - struct block *block, *tmp; - - foreach_s (block, tmp, &bm->referenced) { - - DBG("remove block %p from referenced list\n", block); - - if (block->on_hardware) { - /* Return to the on-hardware list. - */ - move_to_tail(&bm->on_hardware, block); - } - else if (block->fenced) { - struct block *s; - - /* Hmm - have to scan the fenced list to insert the - * buffers in order. This is O(nm), but rare and the - * numbers are low. - */ - foreach (s, &bm->fenced) { - if (FENCE_LTE(block->fence, s->fence)) - break; - } - - move_to_tail(s, block); - } - else { - /* Return to the lru list: - */ - move_to_tail(&block->pool->lru, block); - } - - block->referenced = 0; - } - } - UNLOCK(bm); -} - - -/* This functionality is used by the buffer manager, not really sure - * if we need to be exposing it in this way, probably libdrm will - * offer equivalent calls. - * - * For now they can stay, but will likely change/move before final: - */ -unsigned bmSetFence( struct intel_context *intel ) -{ - assert(intel->locked); - - /* Emit MI_FLUSH here: - */ - if (intel->bm->need_fence) { - - /* Emit a flush without using a batchbuffer. Can't rely on the - * batchbuffer at this level really. Would really prefer that - * the IRQ ioctly emitted the flush at the same time. - */ - GLuint dword[2]; - dword[0] = intel->vtbl.flush_cmd(); - dword[1] = 0; - intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword)); - - intel->bm->last_fence = intelEmitIrqLocked( intel ); - - fence_blocks(intel, intel->bm->last_fence); - - intel->vtbl.note_fence(intel, intel->bm->last_fence); - intel->bm->need_fence = 0; - - if (intel->thrashing) { - intel->thrashing--; - if (!intel->thrashing) - DBG("not thrashing\n"); - } - - intel->bm->free_on_hardware = 0; - } - - return intel->bm->last_fence; -} - -unsigned bmSetFenceLock( struct intel_context *intel ) -{ - unsigned last; - LOCK(intel->bm); - last = bmSetFence(intel); - UNLOCK(intel->bm); - return last; -} -unsigned bmLockAndFence( struct intel_context *intel ) -{ - if (intel->bm->need_fence) { - LOCK_HARDWARE(intel); - LOCK(intel->bm); - bmSetFence(intel); - UNLOCK(intel->bm); - UNLOCK_HARDWARE(intel); - } - - return intel->bm->last_fence; -} - - -void bmFinishFence( struct intel_context *intel, unsigned fence ) -{ - if (!bmTestFence(intel, fence)) { - DBG("...wait on fence %d\n", fence); - intelWaitIrq( intel, fence ); - } - assert(bmTestFence(intel, fence)); - check_fenced(intel); -} - -void bmFinishFenceLock( struct intel_context *intel, unsigned fence ) -{ - LOCK(intel->bm); - bmFinishFence(intel, fence); - UNLOCK(intel->bm); -} - - -/* Specifically ignore texture memory sharing. - * -- just evict everything - * -- and wait for idle - */ -void bm_fake_NotifyContendedLockTake( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - struct block *block, *tmp; - GLuint i; - - assert(is_empty_list(&bm->referenced)); - - bm->need_fence = 1; - bm->fail = 0; - bmFinishFence(intel, bmSetFence(intel)); - - assert(is_empty_list(&bm->fenced)); - assert(is_empty_list(&bm->on_hardware)); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s(block, tmp, &bm->pool[i].lru) { - assert(bmTestFence(intel, block->fence)); - set_dirty(intel, block->buf); - } - } - } - } - UNLOCK(bm); -} - - - -void bmEvictAll( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - - LOCK(bm); - { - struct block *block, *tmp; - GLuint i; - - DBG("%s\n", __FUNCTION__); - - assert(is_empty_list(&bm->referenced)); - - bm->need_fence = 1; - bm->fail = 0; - bmFinishFence(intel, bmSetFence(intel)); - - assert(is_empty_list(&bm->fenced)); - assert(is_empty_list(&bm->on_hardware)); - - for (i = 0; i < bm->nr_pools; i++) { - if (!(bm->pool[i].flags & BM_NO_EVICT)) { - foreach_s(block, tmp, &bm->pool[i].lru) { - assert(bmTestFence(intel, block->fence)); - set_dirty(intel, block->buf); - block->buf->block = NULL; - - free_block(intel, block); - } - } - } - } - UNLOCK(bm); -} - - -GLboolean bmError( struct intel_context *intel ) -{ - struct bufmgr *bm = intel->bm; - GLboolean retval; - - LOCK(bm); - { - retval = bm->fail; - } - UNLOCK(bm); - - return retval; -} - - -GLuint bmCtxId( struct intel_context *intel ) -{ - return intel->bm->ctxId; -} diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index 2aaa10e1c2..e4557a3847 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -28,13 +28,24 @@ #include "imports.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" static void intel_batchbuffer_reset( struct intel_batchbuffer *batch ) { assert(batch->map == NULL); + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } + + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->offset = (unsigned long)batch->ptr; batch->offset = (batch->offset + 63) & ~63; batch->ptr = (unsigned char *) batch->offset; diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h index 25e0a65e99..a824966d2e 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h @@ -29,7 +29,7 @@ #define INTEL_BATCHBUFFER_H #include "mtypes.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" struct intel_context; @@ -43,7 +43,7 @@ struct intel_context; struct intel_batchbuffer { struct intel_context *intel; - struct buffer *buffer; + dri_bo *buffer; GLuint flags; unsigned long offset; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index f88cbb2328..4502c551a7 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -41,7 +41,7 @@ #include "intel_regions.h" #include "intel_structs.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" @@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intelFlush( &intel->ctx ); - bmFinishFenceLock(intel, intel->last_swap_fence); + dri_fence_wait(intel, intel->last_swap_fence); /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets * should work regardless. @@ -154,8 +154,10 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, } intel_batchbuffer_flush( intel->batch ); + + dri_fence_unreference(intel->second_last_swap_fence); intel->second_last_swap_fence = intel->last_swap_fence; - intel->last_swap_fence = bmSetFenceLock( intel ); + intel->last_swap_fence = dri_fence_reference(intel->bmbmSetFenceLock( intel ); UNLOCK_HARDWARE( intel ); if (!rect) @@ -178,7 +180,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -250,11 +252,11 @@ static GLuint translate_raster_op(GLenum logicop) void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct buffer *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort src_x, GLshort src_y, @@ -528,7 +530,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index e361545c8f..45dd33db66 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_ioctl.h" -struct buffer; +dri_bo; extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, const drm_clip_rect_t *rect ); @@ -40,11 +40,11 @@ extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask); extern void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - struct buffer *src_buffer, + dri_bo *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort srcx, GLshort srcy, @@ -55,7 +55,7 @@ extern void intelEmitCopyBlit( struct intel_context *intel, extern void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -68,7 +68,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - struct buffer *dst_buffer, + dri_bo *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort dst_x, GLshort dst_y, diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c index 3349284f5d..32c458987d 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c @@ -32,7 +32,7 @@ #include "intel_context.h" #include "intel_buffer_objects.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" /** @@ -185,7 +185,7 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx, return GL_TRUE; } -struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) +dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) { assert(intel_obj->Base.Name); assert(intel_obj->buffer); diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.h b/src/mesa/drivers/dri/i965/intel_buffer_objects.h index 4b38803e57..a80f448716 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.h @@ -39,13 +39,13 @@ struct gl_buffer_object; */ struct intel_buffer_object { struct gl_buffer_object Base; - struct buffer *buffer; /* the low-level buffer manager's buffer handle */ + dri_bo *buffer; /* the low-level buffer manager's buffer handle */ }; /* Get the bm buffer associated with a GL bufferobject: */ -struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); +dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); /* Hook the bufferobject implementation into mesa: */ diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 022819d582..37c9fa3ec3 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -58,7 +58,7 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "utils.h" #include "vblank.h" @@ -635,10 +635,10 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags ) /* As above, but don't evict the texture data on transitions * between contexts which all share a local buffer manager. */ - if (sarea->texAge != my_bufmgr) { + if (sarea->texAge != intel->hHWContext) { DBG("Lost Textures: sarea->texAge %x my_bufmgr %x\n", sarea->ctxOwner, my_bufmgr); - sarea->texAge = my_bufmgr; - bm_fake_NotifyContendedLockTake( intel ); + sarea->texAge = intel->hHWContext; + dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); } /* Drawable changed? @@ -668,11 +668,6 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; - if (bmError(intel)) { - bmEvictAll(intel); - intel->vtbl.lost_hardware( intel ); - } - /* Make sure nothing has been emitted prior to getting the lock: */ assert(intel->batch->map == 0); @@ -680,16 +675,8 @@ void LOCK_HARDWARE( struct intel_context *intel ) /* XXX: postpone, may not be needed: */ if (!intel_batchbuffer_map(intel->batch)) { - bmEvictAll(intel); - intel->vtbl.lost_hardware( intel ); - - /* This could only fail if the batchbuffer was greater in size - * than the available texture memory: - */ - if (!intel_batchbuffer_map(intel->batch)) { - _mesa_printf("double failure to map batchbuffer\n"); - assert(0); - } + _mesa_printf("failure to map batchbuffer\n"); + assert(0); } } diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index e7e736079f..88d5983027 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -41,7 +41,7 @@ #include "intel_blit.h" #include "intel_regions.h" #include "drm.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" static int intelWaitIdleLocked( struct intel_context *intel ) { diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 0fb33e27f4..8db61267b5 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -28,7 +28,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "enums.h" #include "imports.h" diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index b78eba898f..9bf858cacb 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -42,7 +42,7 @@ #include "intel_context.h" #include "intel_regions.h" #include "intel_blit.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" #include "imports.h" /* XXX: Thread safety? @@ -51,7 +51,7 @@ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *regi { DBG("%s\n", __FUNCTION__); if (!region->map_refcount++) { - region->map = bmMapBuffer(intel, region->buffer, 0); + region->map = dri_bo_map(region->buffer, GL_TRUE); if (!region->map) region->map_refcount--; } @@ -64,7 +64,7 @@ void intel_region_unmap(struct intel_context *intel, { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - bmUnmapBuffer(intel, region->buffer); + dri_bo_unmap(region->buffer); region->map = NULL; } } @@ -84,8 +84,8 @@ struct intel_region *intel_region_alloc( struct intel_context *intel, region->height = height; /* needed? */ region->refcount = 1; - bmGenBuffers(intel, "tex", 1, ®ion->buffer, 6); - bmBufferData(intel, region->buffer, pitch * cpp * height, NULL, 0); + region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", + pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); return region; } @@ -108,7 +108,7 @@ void intel_region_release( struct intel_context *intel, if (--(*region)->refcount == 0) { assert((*region)->map_refcount == 0); - bmDeleteBuffers(intel, 1, &(*region)->buffer); + dri_bo_unreference((*region)->buffer); free(*region); } *region = NULL; diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index d2235f1275..8505d7eedc 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -29,7 +29,7 @@ #define INTEL_REGIONS_H #include "mtypes.h" -#include "bufmgr.h" /* for DBG! */ +#include "dri_bufmgr.h" /* for DBG! */ struct intel_context; /* A layer on top of the bufmgr buffers that adds a few useful things: @@ -40,7 +40,7 @@ struct intel_context; * - Blitter commands for copying 2D regions between buffers. */ struct intel_region { - struct buffer *buffer; + dri_bo *buffer; GLuint refcount; GLuint cpp; GLuint pitch; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 5dac50df32..06bf9214f0 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -109,12 +109,18 @@ intelMapScreenRegions(__DRIscreenPrivate *sPriv) return GL_FALSE; } - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *)&intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; + if (intelScreen->tex.size != 0) { + intelScreen->ttm = GL_FALSE; + + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *)&intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + } else { + intelScreen->ttm = GL_TRUE; } if (0) @@ -163,6 +169,32 @@ intelUnmapScreenRegions(intelScreenPrivate *intelScreen) } } +/** Driver-specific fence emit implementation for the fake memory manager. */ +static unsigned int +intel_fence_emit(void *private) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + unsigned int fence; + + /* XXX: Need to emit a flush, if we haven't already (at least with the + * current batchbuffer implementation, we have). + */ + + fence = intelEmitIrqLocked(intelScreen); + + return fence; +} + +/** Driver-specific fence wait implementation for the fake memory manager. */ +static int +intel_fence_wait(void *private, unsigned int cookie) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; + + intelWaitIrq(intelScreen, cookie); + + return 0; +} static void intelPrintDRIInfo(intelScreenPrivate *intelScreen, @@ -359,7 +391,19 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" ); } - + + assert(!intelScreen->ttm); + intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, + intelScreen->tex.map, + intelScreen->tex.size, + intel_fence_emit, + intel_fence_wait, + intelScreen); + if (intelScreen->bufmgr == FALSE) { + fprintf(stderr, "Couldn't initialize buffer manager\n"); + return GL_FALSE; + } + return GL_TRUE; } @@ -369,6 +413,7 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv) intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; intelUnmapScreenRegions(intelScreen); + dri_bufmgr_destroy(intelScreen->bufmgr); FREE(intelScreen); sPriv->private = NULL; } diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index bf9a716082..bb004822c4 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -80,6 +80,13 @@ typedef struct * Configuration cache with default values for all contexts */ driOptionCache optionCache; + + /** + * This value indicates that the kernel memory manager is being used + * instead of the fake client-side memory manager. + */ + GLboolean ttm; + dri_bufmgr *bufmgr; } intelScreenPrivate; diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c deleted file mode 120000 index fe61b44194..0000000000 --- a/src/mesa/drivers/dri/i965/intel_tex_layout.c +++ /dev/null @@ -1 +0,0 @@ -../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c new file mode 100644 index 0000000000..fcb5cc3906 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_tex_layout.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" +#include "macros.h" + + +static int align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + +void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) +{ + GLint align_h = 2, align_w = 4; + GLuint level; + GLuint x = 0; + GLuint y = 0; + GLuint width = mt->width0; + GLuint height = mt->height0; + + mt->pitch = mt->width0; + + /* May need to adjust pitch to accomodate the placement of + * the 2nd mipmap. This occurs when the alignment + * constraints of mipmap placement push the right edge of the + * 2nd mipmap out past the width of its parent. + */ + if (mt->first_level != mt->last_level) { + GLuint mip1_width = align(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + + if (mip1_width > mt->width0) + mt->pitch = mip1_width; + } + + /* Pitch must be a whole number of dwords, even though we + * express it in texels. + */ + mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; + mt->total_height = 0; + + for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { + GLuint img_height; + + intel_miptree_set_level_info(mt, level, 1, x, y, width, + height, 1); + + if (mt->compressed) + img_height = MAX2(1, height/4); + else + img_height = align(height, align_h); + + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + mt->total_height = MAX2(mt->total_height, y + img_height); + + /* Layout_below: step right after second mipmap. + */ + if (level == mt->first_level + 1) { + x += align(width, align_w); + } + else { + y += img_height; + } + + width = minify(width); + height = minify(height); + } +} diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index 8c05e7cdab..0cfb32f76d 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" -#include "bufmgr.h" +#include "dri_bufmgr.h" /** * Compute which mipmap levels that really need to be sent to the hardware. diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c new file mode 100644 index 0000000000..8ee48b5a68 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -0,0 +1,331 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_decode.h" +#include "i915_debug.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } + + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->size = intel->intelScreen->maxBatchSize; + batch->ptr = batch->map; +} + +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->last_fence = NULL; + intel_batchbuffer_reset(batch); + + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + dri_fence_wait(batch->last_fence); + dri_fence_unreference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + dri_bo_unmap(batch->buf); + batch->map = NULL; + } + dri_bo_unreference(batch->buf); + batch->buf = NULL; + free(batch); +} + +static int +relocation_sort(const void *a_in, const void *b_in) { + const struct buffer_reloc *a = a_in, *b = b_in; + + return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; +} + + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + GLuint *ptr; + GLuint i; + struct intel_context *intel = batch->intel; + dri_fence *fo; + GLboolean performed_rendering = GL_FALSE; + + assert(batch->buf->virtual != NULL); + ptr = batch->buf->virtual; + + /* Sort our relocation list in terms of referenced buffer pointer. + * This lets us uniquely validate the buffers with the sum of all the flags, + * while avoiding O(n^2) on number of relocations. + */ + qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), + relocation_sort); + + /* Perform the necessary validations of buffers, and enter the relocations + * in the batchbuffer. + */ + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + if (r->validate_flags & DRM_BO_FLAG_WRITE) + performed_rendering = GL_TRUE; + + /* If this is the first time we've seen this buffer in the relocation + * list, figure out our flags and validate it. + */ + if (i == 0 || batch->reloc[i - 1].buf != r->buf) { + uint32_t validate_flags; + int j, ret; + + /* Accumulate the flags we need for validating this buffer. */ + validate_flags = r->validate_flags; + for (j = i + 1; j < batch->nr_relocs; j++) { + if (batch->reloc[j].buf != r->buf) + break; + validate_flags |= batch->reloc[j].validate_flags; + } + + /* Validate. If we fail, fence to clear the unfenced list and bail + * out. + */ + ret = dri_bo_validate(r->buf, validate_flags); + if (ret != 0) { + dri_bo_unmap(batch->buf); + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "batchbuffer failure fence", GL_TRUE); + dri_fence_unreference(fo); + goto done; + } + } + ptr[r->offset / 4] = r->buf->offset + r->delta; + dri_bo_unreference(r->buf); + } + + dri_bo_unmap(batch->buf); + batch->map = NULL; + batch->ptr = NULL; + + dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { + intel_batch_ioctl(batch->intel, + batch->buf->offset, + used, ignore_cliprects, allow_unlock); + } + + /* Associate a fence with the validated buffers, and note that we included + * a flush at the end. + */ + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "Batch fence", GL_TRUE); + + if (performed_rendering) { + dri_fence_unreference(batch->last_fence); + batch->last_fence = fo; + } else { + /* If we didn't validate any buffers for writing by the card, we don't + * need to track the fence for glFinish(). + */ + dri_fence_unreference(fo); + } + + if (intel->numClipRects == 0 && !ignore_cliprects) { + if (allow_unlock) { + /* If we are not doing any actual user-visible rendering, + * do a sched_yield to keep the app from pegging the cpu while + * achieving nothing. + */ + UNLOCK_HARDWARE(intel); + sched_yield(); + LOCK_HARDWARE(intel); + } + intel->vtbl.lost_hardware(intel); + } + +done: + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + intel_decode(ptr, used / 4, batch->buf->offset); + dri_bo_unmap(batch->buf); + } +} + + +void +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; + + if (used == 0) + return; + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + LOCK_HARDWARE(intel); + + do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + + if (!was_locked) + UNLOCK_HARDWARE(intel); + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + intel_batchbuffer_flush(batch); + if (batch->last_fence != NULL) + dri_fence_wait(batch->last_fence); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint delta) +{ + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + + assert(batch->nr_relocs <= MAX_RELOCS); + + dri_bo_reference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->validate_flags = flags; + + batch->ptr += 4; + return GL_TRUE; +} + + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h new file mode 100644 index 0000000000..850a91e1c9 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h @@ -0,0 +1,122 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 4096 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + dri_bo *buf; + GLuint offset; + GLuint delta; /* not needed? */ + GLuint validate_flags; +}; + +struct intel_batchbuffer +{ + struct intel_context *intel; + + dri_bo *buf; + dri_fence *last_fence; + GLuint flags; + + drmBOList list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; + GLuint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +void intel_batchbuffer_flush(struct intel_batchbuffer *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf, flags, delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif -- cgit v1.2.3 From e886ae4c58bc98897d6901e3f30deea008bc7f8a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Sep 2007 15:11:39 -0700 Subject: Revert "WIP 965 conversion to dri_bufmgr." This reverts commit b2f1aa2389473ed09170713301b042661d70a48e. Somehow I ended up with my branch's save-this-while-I-work-on-master commit actually on master. --- src/mesa/drivers/dri/i915/Makefile | 1 - src/mesa/drivers/dri/i915/intel_batchbuffer.c | 331 ++++++ src/mesa/drivers/dri/i915/intel_batchbuffer.h | 122 ++ src/mesa/drivers/dri/i965/Makefile | 2 +- src/mesa/drivers/dri/i965/brw_context.h | 4 +- src/mesa/drivers/dri/i965/brw_draw_upload.c | 6 +- src/mesa/drivers/dri/i965/brw_state_pool.c | 2 +- src/mesa/drivers/dri/i965/brw_state_upload.c | 2 +- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- src/mesa/drivers/dri/i965/bufmgr.h | 191 +++ src/mesa/drivers/dri/i965/bufmgr_fake.c | 1360 ++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_batchbuffer.c | 13 +- src/mesa/drivers/dri/i965/intel_batchbuffer.h | 4 +- src/mesa/drivers/dri/i965/intel_blit.c | 16 +- src/mesa/drivers/dri/i965/intel_blit.h | 10 +- src/mesa/drivers/dri/i965/intel_buffer_objects.c | 4 +- src/mesa/drivers/dri/i965/intel_buffer_objects.h | 4 +- src/mesa/drivers/dri/i965/intel_context.c | 25 +- src/mesa/drivers/dri/i965/intel_ioctl.c | 2 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/i965/intel_regions.c | 12 +- src/mesa/drivers/dri/i965/intel_regions.h | 4 +- src/mesa/drivers/dri/i965/intel_screen.c | 59 +- src/mesa/drivers/dri/i965/intel_screen.h | 7 - src/mesa/drivers/dri/i965/intel_tex_layout.c | 103 +- src/mesa/drivers/dri/i965/intel_tex_validate.c | 2 +- src/mesa/drivers/dri/intel/intel_batchbuffer.c | 331 ------ src/mesa/drivers/dri/intel/intel_batchbuffer.h | 122 -- 28 files changed, 2070 insertions(+), 673 deletions(-) create mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.c create mode 100644 src/mesa/drivers/dri/i915/intel_batchbuffer.h create mode 100644 src/mesa/drivers/dri/i965/bufmgr.h create mode 100644 src/mesa/drivers/dri/i965/bufmgr_fake.c mode change 100644 => 120000 src/mesa/drivers/dri/i965/intel_tex_layout.c delete mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.c delete mode 100644 src/mesa/drivers/dri/intel/intel_batchbuffer.h (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index 0e2cdcb240..d3d0bd570c 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -66,7 +66,6 @@ DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ include ../Makefile.template -intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c symlinks: diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c new file mode 100644 index 0000000000..8ee48b5a68 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -0,0 +1,331 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_decode.h" +#include "i915_debug.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + + if (batch->buf != NULL) { + dri_bo_unreference(batch->buf); + batch->buf = NULL; + } + + batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", + intel->intelScreen->maxBatchSize, 4096, + DRM_BO_FLAG_MEM_TT); + dri_bo_map(batch->buf, GL_TRUE); + batch->map = batch->buf->virtual; + batch->size = intel->intelScreen->maxBatchSize; + batch->ptr = batch->map; +} + +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->last_fence = NULL; + intel_batchbuffer_reset(batch); + + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + dri_fence_wait(batch->last_fence); + dri_fence_unreference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + dri_bo_unmap(batch->buf); + batch->map = NULL; + } + dri_bo_unreference(batch->buf); + batch->buf = NULL; + free(batch); +} + +static int +relocation_sort(const void *a_in, const void *b_in) { + const struct buffer_reloc *a = a_in, *b = b_in; + + return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; +} + + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + GLuint *ptr; + GLuint i; + struct intel_context *intel = batch->intel; + dri_fence *fo; + GLboolean performed_rendering = GL_FALSE; + + assert(batch->buf->virtual != NULL); + ptr = batch->buf->virtual; + + /* Sort our relocation list in terms of referenced buffer pointer. + * This lets us uniquely validate the buffers with the sum of all the flags, + * while avoiding O(n^2) on number of relocations. + */ + qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), + relocation_sort); + + /* Perform the necessary validations of buffers, and enter the relocations + * in the batchbuffer. + */ + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + if (r->validate_flags & DRM_BO_FLAG_WRITE) + performed_rendering = GL_TRUE; + + /* If this is the first time we've seen this buffer in the relocation + * list, figure out our flags and validate it. + */ + if (i == 0 || batch->reloc[i - 1].buf != r->buf) { + uint32_t validate_flags; + int j, ret; + + /* Accumulate the flags we need for validating this buffer. */ + validate_flags = r->validate_flags; + for (j = i + 1; j < batch->nr_relocs; j++) { + if (batch->reloc[j].buf != r->buf) + break; + validate_flags |= batch->reloc[j].validate_flags; + } + + /* Validate. If we fail, fence to clear the unfenced list and bail + * out. + */ + ret = dri_bo_validate(r->buf, validate_flags); + if (ret != 0) { + dri_bo_unmap(batch->buf); + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "batchbuffer failure fence", GL_TRUE); + dri_fence_unreference(fo); + goto done; + } + } + ptr[r->offset / 4] = r->buf->offset + r->delta; + dri_bo_unreference(r->buf); + } + + dri_bo_unmap(batch->buf); + batch->map = NULL; + batch->ptr = NULL; + + dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { + intel_batch_ioctl(batch->intel, + batch->buf->offset, + used, ignore_cliprects, allow_unlock); + } + + /* Associate a fence with the validated buffers, and note that we included + * a flush at the end. + */ + fo = dri_fence_validated(intel->intelScreen->bufmgr, + "Batch fence", GL_TRUE); + + if (performed_rendering) { + dri_fence_unreference(batch->last_fence); + batch->last_fence = fo; + } else { + /* If we didn't validate any buffers for writing by the card, we don't + * need to track the fence for glFinish(). + */ + dri_fence_unreference(fo); + } + + if (intel->numClipRects == 0 && !ignore_cliprects) { + if (allow_unlock) { + /* If we are not doing any actual user-visible rendering, + * do a sched_yield to keep the app from pegging the cpu while + * achieving nothing. + */ + UNLOCK_HARDWARE(intel); + sched_yield(); + LOCK_HARDWARE(intel); + } + intel->vtbl.lost_hardware(intel); + } + +done: + if (INTEL_DEBUG & DEBUG_BATCH) { + dri_bo_map(batch->buf, GL_FALSE); + intel_decode(ptr, used / 4, batch->buf->offset); + dri_bo_unmap(batch->buf); + } +} + + +void +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; + + if (used == 0) + return; + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!was_locked) + LOCK_HARDWARE(intel); + + do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + + if (!was_locked) + UNLOCK_HARDWARE(intel); + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + intel_batchbuffer_flush(batch); + if (batch->last_fence != NULL) + dri_fence_wait(batch->last_fence); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint delta) +{ + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + + assert(batch->nr_relocs <= MAX_RELOCS); + + dri_bo_reference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->validate_flags = flags; + + batch->ptr += 4; + return GL_TRUE; +} + + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h new file mode 100644 index 0000000000..850a91e1c9 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h @@ -0,0 +1,122 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 4096 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + dri_bo *buf; + GLuint offset; + GLuint delta; /* not needed? */ + GLuint validate_flags; +}; + +struct intel_batchbuffer +{ + struct intel_context *intel; + + dri_bo *buf; + dri_fence *last_fence; + GLuint flags; + + drmBOList list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; + GLuint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +void intel_batchbuffer_flush(struct intel_batchbuffer *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + dri_bo *buffer, + GLuint flags, GLuint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf, flags, delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 07256ce1e5..5748d7ff05 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -5,6 +5,7 @@ include $(TOP)/configs/current LIBNAME = i965_dri.so DRIVER_SOURCES = \ + bufmgr_fake.c \ intel_batchbuffer.c \ intel_blit.c \ intel_buffer_objects.c \ @@ -91,7 +92,6 @@ DRIVER_DEFINES = -I../intel include ../Makefile.template -intel_batchbuffer.o: ../intel/intel_batchbuffer.o intel_tex_layout.o: ../intel/intel_tex_layout.c server: diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 279baf8c83..aa797b72ce 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -242,7 +242,7 @@ struct brw_surface_binding_table { struct brw_cache; struct brw_mem_pool { - dri_bo *buffer; + struct buffer *buffer; GLuint size; GLuint offset; /* offset of first free byte */ @@ -605,7 +605,7 @@ struct brw_context GLuint nr_surfaces; GLuint max_threads; - dri_bo *scratch_buffer; + struct buffer *scratch_buffer; GLuint scratch_buffer_size; GLuint sampler_count; diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 5f6f0ef5a6..fc2e3035af 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -58,7 +58,7 @@ struct brw_array_state { GLuint dword; } vb0; - dri_bo *buffer; + struct buffer *buffer; GLuint offset; GLuint max_index; @@ -68,7 +68,7 @@ struct brw_array_state { }; -static dri_bo *array_buffer( const struct gl_client_array *array ) +static struct buffer *array_buffer( const struct gl_client_array *array ) { return intel_bufferobj_buffer(intel_buffer_object(array->BufferObj)); } @@ -620,7 +620,7 @@ void brw_upload_indices( struct brw_context *brw, */ { struct brw_indexbuffer ib; - dri_bo *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); + struct buffer *buffer = intel_bufferobj_buffer(intel_buffer_object(bufferobj)); memset(&ib, 0, sizeof(ib)); diff --git a/src/mesa/drivers/dri/i965/brw_state_pool.c b/src/mesa/drivers/dri/i965/brw_state_pool.c index 9677c73583..708ae857ab 100644 --- a/src/mesa/drivers/dri/i965/brw_state_pool.c +++ b/src/mesa/drivers/dri/i965/brw_state_pool.c @@ -34,7 +34,7 @@ #include "imports.h" #include "intel_ioctl.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" GLboolean brw_pool_alloc( struct brw_mem_pool *pool, GLuint size, diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index d5e575ef66..92c07c2962 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -33,7 +33,7 @@ #include "brw_context.h" #include "brw_state.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "intel_batchbuffer.h" /* This is used to initialize brw->state.atoms[]. We could use this diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index b1de66d988..5b4f2abd0e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -34,7 +34,7 @@ #include "brw_context.h" #include "brw_state.h" #include "brw_defines.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" /*********************************************************************** * WM unit - fragment programs and rasterization diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h new file mode 100644 index 0000000000..b31c2e6d9b --- /dev/null +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -0,0 +1,191 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef BUFMGR_H +#define BUFMGR_H + +#include "intel_context.h" + + +/* The buffer manager context. Opaque. + */ +struct bufmgr; +struct buffer; + + +struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); + +/* Flags for validate and other calls. If both NO_UPLOAD and NO_EVICT + * are specified, ValidateBuffers is essentially a query. + */ +#define BM_MEM_LOCAL 0x1 +#define BM_MEM_AGP 0x2 +#define BM_MEM_VRAM 0x4 /* not yet used */ +#define BM_WRITE 0x8 /* not yet used */ +#define BM_READ 0x10 /* not yet used */ +#define BM_NO_UPLOAD 0x20 +#define BM_NO_EVICT 0x40 +#define BM_NO_MOVE 0x80 /* not yet used */ +#define BM_NO_ALLOC 0x100 /* legacy "fixed" buffers only */ +#define BM_CLIENT 0x200 /* for map - pointer will be accessed + * without dri lock */ + +#define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM) + + + + +/* Create a pool of a given memory type, from a certain offset and a + * certain size. + * + * Also passed in is a virtual pointer to the start of the pool. This + * is useful in the faked-out version in i915 so that MapBuffer can + * return a pointer to a buffer residing in AGP space. + * + * Flags passed into a pool are inherited by all buffers allocated in + * that pool. So pools representing the static front,back,depth + * buffer allocations should have MEM_AGP|NO_UPLOAD|NO_EVICT|NO_MOVE to match + * the behaviour of the legacy allocations. + * + * Returns -1 for failure, pool number for success. + */ +int bmInitPool( struct intel_context *, + unsigned long low_offset, + void *low_virtual, + unsigned long size, + unsigned flags); + + +/* Stick closely to ARB_vbo semantics - they're well defined and + * understood, and drivers can just pass the calls through without too + * much thunking. + */ +void bmGenBuffers(struct intel_context *, const char *, unsigned n, struct buffer **buffers, + int align ); +void bmDeleteBuffers(struct intel_context *, unsigned n, struct buffer **buffers); + + +/* Hook to inform faked buffer manager about fixed-position + * front,depth,back buffers. These may move to a fully memory-managed + * scheme, or they may continue to be managed as is. + */ +struct buffer *bmGenBufferStatic(struct intel_context *, + unsigned pool); + +/* On evict, buffer manager will call invalidate_cb() to note that the + * buffer needs to be reloaded. + * + * Buffer is uploaded by calling bmMapBuffer() and copying data into + * the returned pointer. + * + * This is basically a big hack to get some more performance by + * turning off backing store for buffers where we either have it + * already (textures) or don't need it (batch buffers, temporary + * vbo's). + */ +void bmBufferSetInvalidateCB(struct intel_context *, + struct buffer *buf, + void (*invalidate_cb)( struct intel_context *, void *ptr ), + void *ptr, + GLboolean dont_fence_subdata); + + +/* The driver has more intimate knowledge of the hardare than a GL + * client would, so flags here is more proscriptive than the usage + * values in the ARB_vbo interface: + */ +int bmBufferData(struct intel_context *, + struct buffer *buf, + unsigned size, + const void *data, + unsigned flags ); + +int bmBufferSubData(struct intel_context *, + struct buffer *buf, + unsigned offset, + unsigned size, + const void *data ); + +/* In this version, taking the offset will provoke an upload on + * buffers not already resident in AGP: + */ +unsigned bmBufferOffset(struct intel_context *, + struct buffer *buf); + + +/* Extract data from the buffer: + */ +void bmBufferGetSubData(struct intel_context *, + struct buffer *buf, + unsigned offset, + unsigned size, + void *data ); + +void *bmMapBuffer( struct intel_context *, + struct buffer *buf, + unsigned access ); + +void bmUnmapBuffer( struct intel_context *, + struct buffer *buf ); + +/* Pertains to all buffers who's offset has been taken since the last + * fence or release. + */ +int bmValidateBuffers( struct intel_context * ); +void bmReleaseBuffers( struct intel_context * ); + +GLuint bmCtxId( struct intel_context *intel ); + + +GLboolean bmError( struct intel_context * ); +void bmEvictAll( struct intel_context * ); + +void *bmFindVirtual( struct intel_context *intel, + unsigned int offset, + size_t sz ); + +/* This functionality is used by the buffer manager, not really sure + * if we need to be exposing it in this way, probably libdrm will + * offer equivalent calls. + * + * For now they can stay, but will likely change/move before final: + */ +unsigned bmSetFence( struct intel_context * ); +unsigned bmSetFenceLock( struct intel_context * ); +unsigned bmLockAndFence( struct intel_context *intel ); +int bmTestFence( struct intel_context *, unsigned fence ); +void bmFinishFence( struct intel_context *, unsigned fence ); +void bmFinishFenceLock( struct intel_context *, unsigned fence ); + +void bm_fake_NotifyContendedLockTake( struct intel_context * ); + +extern int INTEL_DEBUG; +#define DEBUG_BUFMGR 0x10000000 + +#define DBG(...) do { if (INTEL_DEBUG & DEBUG_BUFMGR) _mesa_printf(__VA_ARGS__); } while(0) + +#endif diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c new file mode 100644 index 0000000000..a85121122f --- /dev/null +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -0,0 +1,1360 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/* Originally a fake version of the buffer manager so that we can + * prototype the changes in a driver fairly quickly, has been fleshed + * out to a fully functional interim solution. + * + * Basically wraps the old style memory management in the new + * programming interface, but is more expressive and avoids many of + * the bugs in the old texture manager. + */ +#include "bufmgr.h" + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" + +#include "simple_list.h" +#include "mm.h" +#include "imports.h" + +#define BM_POOL_MAX 8 + +/* Internal flags: + */ +#define BM_NO_BACKING_STORE 0x2000 +#define BM_NO_FENCE_SUBDATA 0x4000 + + +static int check_fenced( struct intel_context *intel ); + +static int nr_attach = 0; + +/* Wrapper around mm.c's mem_block, which understands that you must + * wait for fences to expire before memory can be freed. This is + * specific to our use of memcpy for uploads - an upload that was + * processed through the command queue wouldn't need to care about + * fences. + */ +struct block { + struct block *next, *prev; + struct pool *pool; /* BM_MEM_AGP */ + struct mem_block *mem; /* BM_MEM_AGP */ + + unsigned referenced:1; + unsigned on_hardware:1; + unsigned fenced:1; + + + unsigned fence; /* BM_MEM_AGP, Split to read_fence, write_fence */ + + struct buffer *buf; + void *virtual; +}; + + +struct buffer { + unsigned id; /* debug only */ + const char *name; + unsigned size; + + unsigned mapped:1; + unsigned dirty:1; + unsigned alignment:13; + unsigned flags:16; + + struct block *block; + void *backing_store; + void (*invalidate_cb)( struct intel_context *, void * ); + void *invalidate_ptr; +}; + +struct pool { + unsigned size; + unsigned low_offset; + struct buffer *static_buffer; + unsigned flags; + struct mem_block *heap; + void *virtual; + struct block lru; /* only allocated, non-fence-pending blocks here */ +}; + +struct bufmgr { + _glthread_Mutex mutex; /**< for thread safety */ + struct pool pool[BM_POOL_MAX]; + unsigned nr_pools; + + unsigned buf_nr; /* for generating ids */ + + struct block referenced; /* after bmBufferOffset */ + struct block on_hardware; /* after bmValidateBuffers */ + struct block fenced; /* after bmFenceBuffers (mi_flush, emit irq, write dword) */ + /* then to pool->lru or free() */ + + unsigned ctxId; + unsigned last_fence; + unsigned free_on_hardware; + + unsigned fail:1; + unsigned need_fence:1; +}; + +#define MAXFENCE 0x7fffffff + +static GLboolean FENCE_LTE( unsigned a, unsigned b ) +{ + if (a == b) + return GL_TRUE; + + if (a < b && b - a < (1<<24)) + return GL_TRUE; + + if (a > b && MAXFENCE - a + b < (1<<24)) + return GL_TRUE; + + return GL_FALSE; +} + +int bmTestFence( struct intel_context *intel, unsigned fence ) +{ + /* Slight problem with wrap-around: + */ + return fence == 0 || FENCE_LTE(fence, intel->sarea->last_dispatch); +} + +#define LOCK(bm) \ + int dolock = nr_attach > 1; \ + if (dolock) _glthread_LOCK_MUTEX(bm->mutex) + +#define UNLOCK(bm) \ + if (dolock) _glthread_UNLOCK_MUTEX(bm->mutex) + + + +static GLboolean alloc_from_pool( struct intel_context *intel, + unsigned pool_nr, + struct buffer *buf ) +{ + struct bufmgr *bm = intel->bm; + struct pool *pool = &bm->pool[pool_nr]; + struct block *block = (struct block *)calloc(sizeof *block, 1); + GLuint sz, align = (1<alignment); + + if (!block) + return GL_FALSE; + + sz = (buf->size + align-1) & ~(align-1); + + block->mem = mmAllocMem(pool->heap, + sz, + buf->alignment, 0); + if (!block->mem) { + free(block); + return GL_FALSE; + } + + make_empty_list(block); + + /* Insert at head or at tail??? + */ + insert_at_tail(&pool->lru, block); + + block->pool = pool; + block->virtual = pool->virtual + block->mem->ofs; + block->buf = buf; + + buf->block = block; + + return GL_TRUE; +} + + + + + + + + +/* Release the card storage associated with buf: + */ +static void free_block( struct intel_context *intel, struct block *block ) +{ + DBG("free block %p\n", block); + + if (!block) + return; + + check_fenced(intel); + + if (block->referenced) { + _mesa_printf("tried to free block on referenced list\n"); + assert(0); + } + else if (block->on_hardware) { + block->buf = NULL; + intel->bm->free_on_hardware += block->mem->size; + } + else if (block->fenced) { + block->buf = NULL; + } + else { + DBG(" - free immediately\n"); + remove_from_list(block); + + mmFreeMem(block->mem); + free(block); + } +} + + +static void alloc_backing_store( struct intel_context *intel, struct buffer *buf ) +{ + assert(!buf->backing_store); + assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); + + buf->backing_store = ALIGN_MALLOC(buf->size, 64); +} + +static void free_backing_store( struct intel_context *intel, struct buffer *buf ) +{ + assert(!(buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE))); + + if (buf->backing_store) { + ALIGN_FREE(buf->backing_store); + buf->backing_store = NULL; + } +} + + + + + + +static void set_dirty( struct intel_context *intel, + struct buffer *buf ) +{ + if (buf->flags & BM_NO_BACKING_STORE) + buf->invalidate_cb(intel, buf->invalidate_ptr); + + assert(!(buf->flags & BM_NO_EVICT)); + + DBG("set_dirty - buf %d\n", buf->id); + buf->dirty = 1; +} + + +static int evict_lru( struct intel_context *intel, GLuint max_fence, GLuint *pool ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + int i; + + DBG("%s\n", __FUNCTION__); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s(block, tmp, &bm->pool[i].lru) { + + if (block->buf && + (block->buf->flags & BM_NO_FENCE_SUBDATA)) + continue; + + if (block->fence && max_fence && + !FENCE_LTE(block->fence, max_fence)) + return 0; + + set_dirty(intel, block->buf); + block->buf->block = NULL; + + free_block(intel, block); + *pool = i; + return 1; + } + } + } + + + return 0; +} + + +#define foreach_s_rev(ptr, t, list) \ + for(ptr=(list)->prev,t=(ptr)->prev; list != ptr; ptr=t, t=(t)->prev) + +static int evict_mru( struct intel_context *intel, GLuint *pool ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + int i; + + DBG("%s\n", __FUNCTION__); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s_rev(block, tmp, &bm->pool[i].lru) { + + if (block->buf && + (block->buf->flags & BM_NO_FENCE_SUBDATA)) + continue; + + set_dirty(intel, block->buf); + block->buf->block = NULL; + + free_block(intel, block); + *pool = i; + return 1; + } + } + } + + + return 0; +} + + +static int check_fenced( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + int ret = 0; + + foreach_s(block, tmp, &bm->fenced ) { + assert(block->fenced); + + if (bmTestFence(intel, block->fence)) { + + block->fenced = 0; + + if (!block->buf) { + DBG("delayed free: offset %x sz %x\n", block->mem->ofs, block->mem->size); + remove_from_list(block); + mmFreeMem(block->mem); + free(block); + } + else { + DBG("return to lru: offset %x sz %x\n", block->mem->ofs, block->mem->size); + move_to_tail(&block->pool->lru, block); + } + + ret = 1; + } + else { + /* Blocks are ordered by fence, so if one fails, all from + * here will fail also: + */ + break; + } + } + + /* Also check the referenced list: + */ + foreach_s(block, tmp, &bm->referenced ) { + if (block->fenced && + bmTestFence(intel, block->fence)) { + block->fenced = 0; + } + } + + + DBG("%s: %d\n", __FUNCTION__, ret); + return ret; +} + + + +static void fence_blocks( struct intel_context *intel, + unsigned fence ) +{ + struct bufmgr *bm = intel->bm; + struct block *block, *tmp; + + foreach_s (block, tmp, &bm->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->buf, fence); + block->fence = fence; + + block->on_hardware = 0; + block->fenced = 1; + + /* Move to tail of pending list here + */ + move_to_tail(&bm->fenced, block); + } + + /* Also check the referenced list: + */ + foreach_s (block, tmp, &bm->referenced) { + if (block->on_hardware) { + DBG("Fence block %p (sz 0x%x buf %p) with fence %d\n", block, + block->mem->size, block->buf, fence); + + block->fence = fence; + block->on_hardware = 0; + block->fenced = 1; + } + } + + + bm->last_fence = fence; + assert(is_empty_list(&bm->on_hardware)); +} + + + + +static GLboolean alloc_block( struct intel_context *intel, + struct buffer *buf ) +{ + struct bufmgr *bm = intel->bm; + int i; + + assert(intel->locked); + + DBG("%s 0x%x bytes (%s)\n", __FUNCTION__, buf->size, buf->name); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_ALLOC) && + alloc_from_pool(intel, i, buf)) { + + DBG("%s --> 0x%x (sz %x)\n", __FUNCTION__, + buf->block->mem->ofs, buf->block->mem->size); + + return GL_TRUE; + } + } + + DBG("%s --> fail\n", __FUNCTION__); + return GL_FALSE; +} + + +static GLboolean evict_and_alloc_block( struct intel_context *intel, + struct buffer *buf ) +{ + GLuint pool; + struct bufmgr *bm = intel->bm; + + assert(buf->block == NULL); + + /* Put a cap on the amount of free memory we'll allow to accumulate + * before emitting a fence. + */ + if (bm->free_on_hardware > 1 * 1024 * 1024) { + DBG("fence for free space: %x\n", bm->free_on_hardware); + bmSetFence(intel); + } + + /* Search for already free memory: + */ + if (alloc_block(intel, buf)) + return GL_TRUE; + + /* Look for memory that may have become free: + */ + if (check_fenced(intel) && + alloc_block(intel, buf)) + return GL_TRUE; + + /* Look for memory blocks not used for >1 frame: + */ + while (evict_lru(intel, intel->second_last_swap_fence, &pool)) + if (alloc_from_pool(intel, pool, buf)) + return GL_TRUE; + + /* If we're not thrashing, allow lru eviction to dig deeper into + * recently used textures. We'll probably be thrashing soon: + */ + if (!intel->thrashing) { + while (evict_lru(intel, 0, &pool)) + if (alloc_from_pool(intel, pool, buf)) + return GL_TRUE; + } + + /* Keep thrashing counter alive? + */ + if (intel->thrashing) + intel->thrashing = 20; + + /* Wait on any already pending fences - here we are waiting for any + * freed memory that has been submitted to hardware and fenced to + * become available: + */ + while (!is_empty_list(&bm->fenced)) { + GLuint fence = bm->fenced.next->fence; + bmFinishFence(intel, fence); + + if (alloc_block(intel, buf)) + return GL_TRUE; + } + + + /* + */ + if (!is_empty_list(&bm->on_hardware)) { + bmSetFence(intel); + + while (!is_empty_list(&bm->fenced)) { + GLuint fence = bm->fenced.next->fence; + bmFinishFence(intel, fence); + } + + if (!intel->thrashing) { + DBG("thrashing\n"); + } + intel->thrashing = 20; + + if (alloc_block(intel, buf)) + return GL_TRUE; + } + + while (evict_mru(intel, &pool)) + if (alloc_from_pool(intel, pool, buf)) + return GL_TRUE; + + DBG("%s 0x%x bytes failed\n", __FUNCTION__, buf->size); + + assert(is_empty_list(&bm->on_hardware)); + assert(is_empty_list(&bm->fenced)); + + return GL_FALSE; +} + + + + + + + + + + +/*********************************************************************** + * Public functions + */ + + +/* The initialization functions are skewed in the fake implementation. + * This call would be to attach to an existing manager, rather than to + * create a local one. + */ +struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ) +{ + _glthread_DECLARE_STATIC_MUTEX(initMutex); + static struct bufmgr bm; + + /* This function needs a mutex of its own... + */ + _glthread_LOCK_MUTEX(initMutex); + + if (nr_attach == 0) { + _glthread_INIT_MUTEX(bm.mutex); + + make_empty_list(&bm.referenced); + make_empty_list(&bm.fenced); + make_empty_list(&bm.on_hardware); + + /* The context id of any of the share group. This won't be used + * in communication with the kernel, so it doesn't matter if + * this context is eventually deleted. + */ + bm.ctxId = intel->hHWContext; + } + + nr_attach++; + + _glthread_UNLOCK_MUTEX(initMutex); + + return &bm; +} + + + +/* The virtual pointer would go away in a true implementation. + */ +int bmInitPool( struct intel_context *intel, + unsigned long low_offset, + void *low_virtual, + unsigned long size, + unsigned flags) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + LOCK(bm); + { + GLuint i; + + for (i = 0; i < bm->nr_pools; i++) { + if (bm->pool[i].low_offset == low_offset && + bm->pool[i].size == size) { + retval = i; + goto out; + } + } + + + if (bm->nr_pools >= BM_POOL_MAX) + retval = -1; + else { + i = bm->nr_pools++; + + DBG("bmInitPool %d low_offset %x sz %x\n", + i, low_offset, size); + + bm->pool[i].low_offset = low_offset; + bm->pool[i].size = size; + bm->pool[i].heap = mmInit( low_offset, size ); + bm->pool[i].virtual = low_virtual - low_offset; + bm->pool[i].flags = flags; + + make_empty_list(&bm->pool[i].lru); + + retval = i; + } + } + out: + UNLOCK(bm); + return retval; +} + +static struct buffer *do_GenBuffer(struct intel_context *intel, const char *name, int align) +{ + struct bufmgr *bm = intel->bm; + struct buffer *buf = calloc(sizeof(*buf), 1); + + buf->id = ++bm->buf_nr; + buf->name = name; + buf->alignment = align; + buf->flags = BM_MEM_AGP|BM_MEM_VRAM|BM_MEM_LOCAL; + + return buf; +} + + +void *bmFindVirtual( struct intel_context *intel, + unsigned int offset, + size_t sz ) +{ + struct bufmgr *bm = intel->bm; + int i; + + for (i = 0; i < bm->nr_pools; i++) + if (offset >= bm->pool[i].low_offset && + offset + sz <= bm->pool[i].low_offset + bm->pool[i].size) + return bm->pool[i].virtual + offset; + + return NULL; +} + + +void bmGenBuffers(struct intel_context *intel, + const char *name, unsigned n, + struct buffer **buffers, + int align ) +{ + struct bufmgr *bm = intel->bm; + LOCK(bm); + { + int i; + + for (i = 0; i < n; i++) + buffers[i] = do_GenBuffer(intel, name, align); + } + UNLOCK(bm); +} + + +void bmDeleteBuffers(struct intel_context *intel, unsigned n, struct buffer **buffers) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + unsigned i; + + for (i = 0; i < n; i++) { + struct buffer *buf = buffers[i]; + + if (buf && buf->block) + free_block(intel, buf->block); + + if (buf) + free(buf); + } + } + UNLOCK(bm); +} + + + + +/* Hook to inform faked buffer manager about fixed-position + * front,depth,back buffers. These may move to a fully memory-managed + * scheme, or they may continue to be managed as is. It will probably + * be useful to pass a fixed offset here one day. + */ +struct buffer *bmGenBufferStatic(struct intel_context *intel, + unsigned pool ) +{ + struct bufmgr *bm = intel->bm; + struct buffer *buf; + LOCK(bm); + { + assert(bm->pool[pool].flags & BM_NO_EVICT); + assert(bm->pool[pool].flags & BM_NO_MOVE); + + if (bm->pool[pool].static_buffer) + buf = bm->pool[pool].static_buffer; + else { + buf = do_GenBuffer(intel, "static", 12); + + bm->pool[pool].static_buffer = buf; + assert(!buf->block); + + buf->size = bm->pool[pool].size; + buf->flags = bm->pool[pool].flags; + buf->alignment = 12; + + if (!alloc_from_pool(intel, pool, buf)) + assert(0); + } + } + UNLOCK(bm); + return buf; +} + + +static void wait_quiescent(struct intel_context *intel, + struct block *block) +{ + if (block->on_hardware) { + assert(intel->bm->need_fence); + bmSetFence(intel); + assert(!block->on_hardware); + } + + + if (block->fenced) { + bmFinishFence(intel, block->fence); + } + + assert(!block->on_hardware); + assert(!block->fenced); +} + + + +/* If buffer size changes, free and reallocate. Otherwise update in + * place. + */ +int bmBufferData(struct intel_context *intel, + struct buffer *buf, + unsigned size, + const void *data, + unsigned flags ) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + LOCK(bm); + { + DBG("bmBufferData %d sz 0x%x data: %p\n", buf->id, size, data); + + assert(!buf->mapped); + + if (buf->block) { + struct block *block = buf->block; + + /* Optimistic check to see if we can reuse the block -- not + * required for correctness: + */ + if (block->fenced) + check_fenced(intel); + + if (block->on_hardware || + block->fenced || + (buf->size && buf->size != size) || + (data == NULL)) { + + assert(!block->referenced); + + free_block(intel, block); + buf->block = NULL; + buf->dirty = 1; + } + } + + buf->size = size; + if (buf->block) { + assert (buf->block->mem->size >= size); + } + + if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { + + assert(intel->locked || data == NULL); + + if (data != NULL) { + if (!buf->block && !evict_and_alloc_block(intel, buf)) { + bm->fail = 1; + retval = -1; + goto out; + } + + wait_quiescent(intel, buf->block); + + DBG("bmBufferData %d offset 0x%x sz 0x%x\n", + buf->id, buf->block->mem->ofs, size); + + assert(buf->block->virtual == buf->block->pool->virtual + buf->block->mem->ofs); + + do_memcpy(buf->block->virtual, data, size); + } + buf->dirty = 0; + } + else { + DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); + set_dirty(intel, buf); + free_backing_store(intel, buf); + + if (data != NULL) { + alloc_backing_store(intel, buf); + do_memcpy(buf->backing_store, data, size); + } + } + } + out: + UNLOCK(bm); + return retval; +} + + +/* Update the buffer in place, in whatever space it is currently resident: + */ +int bmBufferSubData(struct intel_context *intel, + struct buffer *buf, + unsigned offset, + unsigned size, + const void *data ) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + if (size == 0) + return 0; + + LOCK(bm); + { + DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); + + assert(offset+size <= buf->size); + + if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { + + assert(intel->locked); + + if (!buf->block && !evict_and_alloc_block(intel, buf)) { + bm->fail = 1; + retval = -1; + goto out; + } + + if (!(buf->flags & BM_NO_FENCE_SUBDATA)) + wait_quiescent(intel, buf->block); + + buf->dirty = 0; + + do_memcpy(buf->block->virtual + offset, data, size); + } + else { + DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); + set_dirty(intel, buf); + + if (buf->backing_store == NULL) + alloc_backing_store(intel, buf); + + do_memcpy(buf->backing_store + offset, data, size); + } + } + out: + UNLOCK(bm); + return retval; +} + +unsigned bmBufferOffset(struct intel_context *intel, + struct buffer *buf) +{ + struct bufmgr *bm = intel->bm; + unsigned retval = 0; + + LOCK(bm); + { + assert(intel->locked); + + if (!buf->block && + !evict_and_alloc_block(intel, buf)) { + bm->fail = 1; + retval = ~0; + } + else { + assert(buf->block); + assert(buf->block->buf == buf); + + DBG("Add buf %d (block %p, dirty %d) to referenced list\n", buf->id, buf->block, + buf->dirty); + + move_to_tail(&bm->referenced, buf->block); + buf->block->referenced = 1; + + retval = buf->block->mem->ofs; + } + } + UNLOCK(bm); + + return retval; +} + + + +/* Extract data from the buffer: + */ +void bmBufferGetSubData(struct intel_context *intel, + struct buffer *buf, + unsigned offset, + unsigned size, + void *data ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buf->id, offset, size); + + if (buf->flags & (BM_NO_EVICT|BM_NO_BACKING_STORE)) { + if (buf->block && size) { + wait_quiescent(intel, buf->block); + do_memcpy(data, buf->block->virtual + offset, size); + } + } + else { + if (buf->backing_store && size) { + do_memcpy(data, buf->backing_store + offset, size); + } + } + } + UNLOCK(bm); +} + + +/* Return a pointer to whatever space the buffer is currently resident in: + */ +void *bmMapBuffer( struct intel_context *intel, + struct buffer *buf, + unsigned flags ) +{ + struct bufmgr *bm = intel->bm; + void *retval = NULL; + + LOCK(bm); + { + DBG("bmMapBuffer %d\n", buf->id); + + if (buf->mapped) { + _mesa_printf("%s: already mapped\n", __FUNCTION__); + retval = NULL; + } + else if (buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT)) { + + assert(intel->locked); + + if (!buf->block && !evict_and_alloc_block(intel, buf)) { + DBG("%s: alloc failed\n", __FUNCTION__); + bm->fail = 1; + retval = NULL; + } + else { + assert(buf->block); + buf->dirty = 0; + + if (!(buf->flags & BM_NO_FENCE_SUBDATA)) + wait_quiescent(intel, buf->block); + + buf->mapped = 1; + retval = buf->block->virtual; + } + } + else { + DBG("%s - set buf %d dirty\n", __FUNCTION__, buf->id); + set_dirty(intel, buf); + + if (buf->backing_store == 0) + alloc_backing_store(intel, buf); + + buf->mapped = 1; + retval = buf->backing_store; + } + } + UNLOCK(bm); + return retval; +} + +void bmUnmapBuffer( struct intel_context *intel, struct buffer *buf ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + DBG("bmUnmapBuffer %d\n", buf->id); + buf->mapped = 0; + } + UNLOCK(bm); +} + + + + +/* This is the big hack that turns on BM_NO_BACKING_STORE. Basically + * says that an external party will maintain the backing store, eg + * Mesa's local copy of texture data. + */ +void bmBufferSetInvalidateCB(struct intel_context *intel, + struct buffer *buf, + void (*invalidate_cb)( struct intel_context *, void *ptr ), + void *ptr, + GLboolean dont_fence_subdata) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + if (buf->backing_store) + free_backing_store(intel, buf); + + buf->flags |= BM_NO_BACKING_STORE; + + if (dont_fence_subdata) + buf->flags |= BM_NO_FENCE_SUBDATA; + + DBG("bmBufferSetInvalidateCB set buf %d dirty\n", buf->id); + buf->dirty = 1; + buf->invalidate_cb = invalidate_cb; + buf->invalidate_ptr = ptr; + + /* Note that it is invalid right from the start. Also note + * invalidate_cb is called with the bufmgr locked, so cannot + * itself make bufmgr calls. + */ + invalidate_cb( intel, ptr ); + } + UNLOCK(bm); +} + + + + + + + +/* This is only protected against thread interactions by the DRI lock + * and the policy of ensuring that all dma is flushed prior to + * releasing that lock. Otherwise you might have two threads building + * up a list of buffers to validate at once. + */ +int bmValidateBuffers( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + int retval = 0; + + LOCK(bm); + { + DBG("%s fail %d\n", __FUNCTION__, bm->fail); + assert(intel->locked); + + if (!bm->fail) { + struct block *block, *tmp; + + foreach_s(block, tmp, &bm->referenced) { + struct buffer *buf = block->buf; + + DBG("Validate buf %d / block %p / dirty %d\n", buf->id, block, buf->dirty); + + /* Upload the buffer contents if necessary: + */ + if (buf->dirty) { + DBG("Upload dirty buf %d (%s) sz %d offset 0x%x\n", buf->id, + buf->name, buf->size, block->mem->ofs); + + assert(!(buf->flags & (BM_NO_BACKING_STORE|BM_NO_EVICT))); + + wait_quiescent(intel, buf->block); + + do_memcpy(buf->block->virtual, + buf->backing_store, + buf->size); + + buf->dirty = 0; + } + + block->referenced = 0; + block->on_hardware = 1; + move_to_tail(&bm->on_hardware, block); + } + + bm->need_fence = 1; + } + + retval = bm->fail ? -1 : 0; + } + UNLOCK(bm); + + + if (retval != 0) + DBG("%s failed\n", __FUNCTION__); + + return retval; +} + + + + +void bmReleaseBuffers( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + struct block *block, *tmp; + + foreach_s (block, tmp, &bm->referenced) { + + DBG("remove block %p from referenced list\n", block); + + if (block->on_hardware) { + /* Return to the on-hardware list. + */ + move_to_tail(&bm->on_hardware, block); + } + else if (block->fenced) { + struct block *s; + + /* Hmm - have to scan the fenced list to insert the + * buffers in order. This is O(nm), but rare and the + * numbers are low. + */ + foreach (s, &bm->fenced) { + if (FENCE_LTE(block->fence, s->fence)) + break; + } + + move_to_tail(s, block); + } + else { + /* Return to the lru list: + */ + move_to_tail(&block->pool->lru, block); + } + + block->referenced = 0; + } + } + UNLOCK(bm); +} + + +/* This functionality is used by the buffer manager, not really sure + * if we need to be exposing it in this way, probably libdrm will + * offer equivalent calls. + * + * For now they can stay, but will likely change/move before final: + */ +unsigned bmSetFence( struct intel_context *intel ) +{ + assert(intel->locked); + + /* Emit MI_FLUSH here: + */ + if (intel->bm->need_fence) { + + /* Emit a flush without using a batchbuffer. Can't rely on the + * batchbuffer at this level really. Would really prefer that + * the IRQ ioctly emitted the flush at the same time. + */ + GLuint dword[2]; + dword[0] = intel->vtbl.flush_cmd(); + dword[1] = 0; + intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword)); + + intel->bm->last_fence = intelEmitIrqLocked( intel ); + + fence_blocks(intel, intel->bm->last_fence); + + intel->vtbl.note_fence(intel, intel->bm->last_fence); + intel->bm->need_fence = 0; + + if (intel->thrashing) { + intel->thrashing--; + if (!intel->thrashing) + DBG("not thrashing\n"); + } + + intel->bm->free_on_hardware = 0; + } + + return intel->bm->last_fence; +} + +unsigned bmSetFenceLock( struct intel_context *intel ) +{ + unsigned last; + LOCK(intel->bm); + last = bmSetFence(intel); + UNLOCK(intel->bm); + return last; +} +unsigned bmLockAndFence( struct intel_context *intel ) +{ + if (intel->bm->need_fence) { + LOCK_HARDWARE(intel); + LOCK(intel->bm); + bmSetFence(intel); + UNLOCK(intel->bm); + UNLOCK_HARDWARE(intel); + } + + return intel->bm->last_fence; +} + + +void bmFinishFence( struct intel_context *intel, unsigned fence ) +{ + if (!bmTestFence(intel, fence)) { + DBG("...wait on fence %d\n", fence); + intelWaitIrq( intel, fence ); + } + assert(bmTestFence(intel, fence)); + check_fenced(intel); +} + +void bmFinishFenceLock( struct intel_context *intel, unsigned fence ) +{ + LOCK(intel->bm); + bmFinishFence(intel, fence); + UNLOCK(intel->bm); +} + + +/* Specifically ignore texture memory sharing. + * -- just evict everything + * -- and wait for idle + */ +void bm_fake_NotifyContendedLockTake( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + struct block *block, *tmp; + GLuint i; + + assert(is_empty_list(&bm->referenced)); + + bm->need_fence = 1; + bm->fail = 0; + bmFinishFence(intel, bmSetFence(intel)); + + assert(is_empty_list(&bm->fenced)); + assert(is_empty_list(&bm->on_hardware)); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s(block, tmp, &bm->pool[i].lru) { + assert(bmTestFence(intel, block->fence)); + set_dirty(intel, block->buf); + } + } + } + } + UNLOCK(bm); +} + + + +void bmEvictAll( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + + LOCK(bm); + { + struct block *block, *tmp; + GLuint i; + + DBG("%s\n", __FUNCTION__); + + assert(is_empty_list(&bm->referenced)); + + bm->need_fence = 1; + bm->fail = 0; + bmFinishFence(intel, bmSetFence(intel)); + + assert(is_empty_list(&bm->fenced)); + assert(is_empty_list(&bm->on_hardware)); + + for (i = 0; i < bm->nr_pools; i++) { + if (!(bm->pool[i].flags & BM_NO_EVICT)) { + foreach_s(block, tmp, &bm->pool[i].lru) { + assert(bmTestFence(intel, block->fence)); + set_dirty(intel, block->buf); + block->buf->block = NULL; + + free_block(intel, block); + } + } + } + } + UNLOCK(bm); +} + + +GLboolean bmError( struct intel_context *intel ) +{ + struct bufmgr *bm = intel->bm; + GLboolean retval; + + LOCK(bm); + { + retval = bm->fail; + } + UNLOCK(bm); + + return retval; +} + + +GLuint bmCtxId( struct intel_context *intel ) +{ + return intel->bm->ctxId; +} diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index e4557a3847..2aaa10e1c2 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -28,24 +28,13 @@ #include "imports.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" static void intel_batchbuffer_reset( struct intel_batchbuffer *batch ) { assert(batch->map == NULL); - if (batch->buf != NULL) { - dri_bo_unreference(batch->buf); - batch->buf = NULL; - } - - batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", - intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT); - dri_bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - batch->offset = (unsigned long)batch->ptr; batch->offset = (batch->offset + 63) & ~63; batch->ptr = (unsigned char *) batch->offset; diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.h b/src/mesa/drivers/dri/i965/intel_batchbuffer.h index a824966d2e..25e0a65e99 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.h @@ -29,7 +29,7 @@ #define INTEL_BATCHBUFFER_H #include "mtypes.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" struct intel_context; @@ -43,7 +43,7 @@ struct intel_context; struct intel_batchbuffer { struct intel_context *intel; - dri_bo *buffer; + struct buffer *buffer; GLuint flags; unsigned long offset; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 4502c551a7..f88cbb2328 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -41,7 +41,7 @@ #include "intel_regions.h" #include "intel_structs.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" @@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intelFlush( &intel->ctx ); - dri_fence_wait(intel, intel->last_swap_fence); + bmFinishFenceLock(intel, intel->last_swap_fence); /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets * should work regardless. @@ -154,10 +154,8 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, } intel_batchbuffer_flush( intel->batch ); - - dri_fence_unreference(intel->second_last_swap_fence); intel->second_last_swap_fence = intel->last_swap_fence; - intel->last_swap_fence = dri_fence_reference(intel->bmbmSetFenceLock( intel ); + intel->last_swap_fence = bmSetFenceLock( intel ); UNLOCK_HARDWARE( intel ); if (!rect) @@ -180,7 +178,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -252,11 +250,11 @@ static GLuint translate_raster_op(GLenum logicop) void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - dri_bo *src_buffer, + struct buffer *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort src_x, GLshort src_y, @@ -530,7 +528,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index 45dd33db66..e361545c8f 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_ioctl.h" -dri_bo; +struct buffer; extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, const drm_clip_rect_t *rect ); @@ -40,11 +40,11 @@ extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask); extern void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, GLshort src_pitch, - dri_bo *src_buffer, + struct buffer *src_buffer, GLuint src_offset, GLboolean src_tiled, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort srcx, GLshort srcy, @@ -55,7 +55,7 @@ extern void intelEmitCopyBlit( struct intel_context *intel, extern void intelEmitFillBlit( struct intel_context *intel, GLuint cpp, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort x, GLshort y, @@ -68,7 +68,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel, GLubyte *src_bits, GLuint src_size, GLuint fg_color, GLshort dst_pitch, - dri_bo *dst_buffer, + struct buffer *dst_buffer, GLuint dst_offset, GLboolean dst_tiled, GLshort dst_x, GLshort dst_y, diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c index 32c458987d..3349284f5d 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c @@ -32,7 +32,7 @@ #include "intel_context.h" #include "intel_buffer_objects.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" /** @@ -185,7 +185,7 @@ static GLboolean intel_bufferobj_unmap( GLcontext *ctx, return GL_TRUE; } -dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) +struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *intel_obj ) { assert(intel_obj->Base.Name); assert(intel_obj->buffer); diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.h b/src/mesa/drivers/dri/i965/intel_buffer_objects.h index a80f448716..4b38803e57 100644 --- a/src/mesa/drivers/dri/i965/intel_buffer_objects.h +++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.h @@ -39,13 +39,13 @@ struct gl_buffer_object; */ struct intel_buffer_object { struct gl_buffer_object Base; - dri_bo *buffer; /* the low-level buffer manager's buffer handle */ + struct buffer *buffer; /* the low-level buffer manager's buffer handle */ }; /* Get the bm buffer associated with a GL bufferobject: */ -dri_bo *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); +struct buffer *intel_bufferobj_buffer( const struct intel_buffer_object *obj ); /* Hook the bufferobject implementation into mesa: */ diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 37c9fa3ec3..022819d582 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -58,7 +58,7 @@ #include "intel_regions.h" #include "intel_buffer_objects.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "utils.h" #include "vblank.h" @@ -635,10 +635,10 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags ) /* As above, but don't evict the texture data on transitions * between contexts which all share a local buffer manager. */ - if (sarea->texAge != intel->hHWContext) { + if (sarea->texAge != my_bufmgr) { DBG("Lost Textures: sarea->texAge %x my_bufmgr %x\n", sarea->ctxOwner, my_bufmgr); - sarea->texAge = intel->hHWContext; - dri_bufmgr_fake_contended_lock_take(intel->intelScreen->bufmgr); + sarea->texAge = my_bufmgr; + bm_fake_NotifyContendedLockTake( intel ); } /* Drawable changed? @@ -668,6 +668,11 @@ void LOCK_HARDWARE( struct intel_context *intel ) intel->locked = 1; + if (bmError(intel)) { + bmEvictAll(intel); + intel->vtbl.lost_hardware( intel ); + } + /* Make sure nothing has been emitted prior to getting the lock: */ assert(intel->batch->map == 0); @@ -675,8 +680,16 @@ void LOCK_HARDWARE( struct intel_context *intel ) /* XXX: postpone, may not be needed: */ if (!intel_batchbuffer_map(intel->batch)) { - _mesa_printf("failure to map batchbuffer\n"); - assert(0); + bmEvictAll(intel); + intel->vtbl.lost_hardware( intel ); + + /* This could only fail if the batchbuffer was greater in size + * than the available texture memory: + */ + if (!intel_batchbuffer_map(intel->batch)) { + _mesa_printf("double failure to map batchbuffer\n"); + assert(0); + } } } diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index 88d5983027..e7e736079f 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -41,7 +41,7 @@ #include "intel_blit.h" #include "intel_regions.h" #include "drm.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" static int intelWaitIdleLocked( struct intel_context *intel ) { diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 8db61267b5..0fb33e27f4 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -28,7 +28,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_regions.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "enums.h" #include "imports.h" diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index 9bf858cacb..b78eba898f 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -42,7 +42,7 @@ #include "intel_context.h" #include "intel_regions.h" #include "intel_blit.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" #include "imports.h" /* XXX: Thread safety? @@ -51,7 +51,7 @@ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *regi { DBG("%s\n", __FUNCTION__); if (!region->map_refcount++) { - region->map = dri_bo_map(region->buffer, GL_TRUE); + region->map = bmMapBuffer(intel, region->buffer, 0); if (!region->map) region->map_refcount--; } @@ -64,7 +64,7 @@ void intel_region_unmap(struct intel_context *intel, { DBG("%s\n", __FUNCTION__); if (!--region->map_refcount) { - dri_bo_unmap(region->buffer); + bmUnmapBuffer(intel, region->buffer); region->map = NULL; } } @@ -84,8 +84,8 @@ struct intel_region *intel_region_alloc( struct intel_context *intel, region->height = height; /* needed? */ region->refcount = 1; - region->buffer = dri_bo_alloc(intelScreen->bufmgr, "region", - pitch * cpp * height, 64, DRM_BO_FLAG_MEM_TT); + bmGenBuffers(intel, "tex", 1, ®ion->buffer, 6); + bmBufferData(intel, region->buffer, pitch * cpp * height, NULL, 0); return region; } @@ -108,7 +108,7 @@ void intel_region_release( struct intel_context *intel, if (--(*region)->refcount == 0) { assert((*region)->map_refcount == 0); - dri_bo_unreference((*region)->buffer); + bmDeleteBuffers(intel, 1, &(*region)->buffer); free(*region); } *region = NULL; diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index 8505d7eedc..d2235f1275 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -29,7 +29,7 @@ #define INTEL_REGIONS_H #include "mtypes.h" -#include "dri_bufmgr.h" /* for DBG! */ +#include "bufmgr.h" /* for DBG! */ struct intel_context; /* A layer on top of the bufmgr buffers that adds a few useful things: @@ -40,7 +40,7 @@ struct intel_context; * - Blitter commands for copying 2D regions between buffers. */ struct intel_region { - dri_bo *buffer; + struct buffer *buffer; GLuint refcount; GLuint cpp; GLuint pitch; diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 06bf9214f0..5dac50df32 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -109,18 +109,12 @@ intelMapScreenRegions(__DRIscreenPrivate *sPriv) return GL_FALSE; } - if (intelScreen->tex.size != 0) { - intelScreen->ttm = GL_FALSE; - - if (drmMap(sPriv->fd, - intelScreen->tex.handle, - intelScreen->tex.size, - (drmAddress *)&intelScreen->tex.map) != 0) { - intelUnmapScreenRegions(intelScreen); - return GL_FALSE; - } - } else { - intelScreen->ttm = GL_TRUE; + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *)&intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; } if (0) @@ -169,32 +163,6 @@ intelUnmapScreenRegions(intelScreenPrivate *intelScreen) } } -/** Driver-specific fence emit implementation for the fake memory manager. */ -static unsigned int -intel_fence_emit(void *private) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; - unsigned int fence; - - /* XXX: Need to emit a flush, if we haven't already (at least with the - * current batchbuffer implementation, we have). - */ - - fence = intelEmitIrqLocked(intelScreen); - - return fence; -} - -/** Driver-specific fence wait implementation for the fake memory manager. */ -static int -intel_fence_wait(void *private, unsigned int cookie) -{ - intelScreenPrivate *intelScreen = (intelScreenPrivate *)private; - - intelWaitIrq(intelScreen, cookie); - - return 0; -} static void intelPrintDRIInfo(intelScreenPrivate *intelScreen, @@ -391,19 +359,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); (*glx_enable_extension)( psc, "GLX_MESA_copy_sub_buffer" ); } - - assert(!intelScreen->ttm); - intelScreen->bufmgr = dri_bufmgr_fake_init(intelScreen->tex.offset, - intelScreen->tex.map, - intelScreen->tex.size, - intel_fence_emit, - intel_fence_wait, - intelScreen); - if (intelScreen->bufmgr == FALSE) { - fprintf(stderr, "Couldn't initialize buffer manager\n"); - return GL_FALSE; - } - + return GL_TRUE; } @@ -413,7 +369,6 @@ static void intelDestroyScreen(__DRIscreenPrivate *sPriv) intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private; intelUnmapScreenRegions(intelScreen); - dri_bufmgr_destroy(intelScreen->bufmgr); FREE(intelScreen); sPriv->private = NULL; } diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index bb004822c4..bf9a716082 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -80,13 +80,6 @@ typedef struct * Configuration cache with default values for all contexts */ driOptionCache optionCache; - - /** - * This value indicates that the kernel memory manager is being used - * instead of the fake client-side memory manager. - */ - GLboolean ttm; - dri_bufmgr *bufmgr; } intelScreenPrivate; diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c deleted file mode 100644 index fcb5cc3906..0000000000 --- a/src/mesa/drivers/dri/i965/intel_tex_layout.c +++ /dev/null @@ -1,102 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - /* - * Authors: - * Keith Whitwell - * Michel Dänzer - */ - -#include "intel_mipmap_tree.h" -#include "intel_tex_layout.h" -#include "macros.h" - - -static int align(int value, int alignment) -{ - return (value + alignment - 1) & ~(alignment - 1); -} - -void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) -{ - GLint align_h = 2, align_w = 4; - GLuint level; - GLuint x = 0; - GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; - - mt->pitch = mt->width0; - - /* May need to adjust pitch to accomodate the placement of - * the 2nd mipmap. This occurs when the alignment - * constraints of mipmap placement push the right edge of the - * 2nd mipmap out past the width of its parent. - */ - if (mt->first_level != mt->last_level) { - GLuint mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); - - if (mip1_width > mt->width0) - mt->pitch = mip1_width; - } - - /* Pitch must be a whole number of dwords, even though we - * express it in texels. - */ - mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; - mt->total_height = 0; - - for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { - GLuint img_height; - - intel_miptree_set_level_info(mt, level, 1, x, y, width, - height, 1); - - if (mt->compressed) - img_height = MAX2(1, height/4); - else - img_height = align(height, align_h); - - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - mt->total_height = MAX2(mt->total_height, y + img_height); - - /* Layout_below: step right after second mipmap. - */ - if (level == mt->first_level + 1) { - x += align(width, align_w); - } - else { - y += img_height; - } - - width = minify(width); - height = minify(height); - } -} diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c new file mode 120000 index 0000000000..fe61b44194 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_tex_layout.c @@ -0,0 +1 @@ +../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/intel_tex_validate.c b/src/mesa/drivers/dri/i965/intel_tex_validate.c index 0cfb32f76d..8c05e7cdab 100644 --- a/src/mesa/drivers/dri/i965/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i965/intel_tex_validate.c @@ -31,7 +31,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" -#include "dri_bufmgr.h" +#include "bufmgr.h" /** * Compute which mipmap levels that really need to be sent to the hardware. diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c deleted file mode 100644 index 8ee48b5a68..0000000000 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "intel_batchbuffer.h" -#include "intel_ioctl.h" -#include "intel_decode.h" -#include "i915_debug.h" - -/* Relocations in kernel space: - * - pass dma buffer seperately - * - memory manager knows how to patch - * - pass list of dependent buffers - * - pass relocation list - * - * Either: - * - get back an offset for buffer to fire - * - memory manager knows how to fire buffer - * - * Really want the buffer to be AGP and pinned. - * - */ - -/* Cliprect fence: The highest fence protecting a dma buffer - * containing explicit cliprect information. Like the old drawable - * lock but irq-driven. X server must wait for this fence to expire - * before changing cliprects [and then doing sw rendering?]. For - * other dma buffers, the scheduler will grab current cliprect info - * and mix into buffer. X server must hold the lock while changing - * cliprects??? Make per-drawable. Need cliprects in shared memory - * -- beats storing them with every cmd buffer in the queue. - * - * ==> X server must wait for this fence to expire before touching the - * framebuffer with new cliprects. - * - * ==> Cliprect-dependent buffers associated with a - * cliprect-timestamp. All of the buffers associated with a timestamp - * must go to hardware before any buffer with a newer timestamp. - * - * ==> Dma should be queued per-drawable for correct X/GL - * synchronization. Or can fences be used for this? - * - * Applies to: Blit operations, metaops, X server operations -- X - * server automatically waits on its own dma to complete before - * modifying cliprects ??? - */ - -void -intel_batchbuffer_reset(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - - if (batch->buf != NULL) { - dri_bo_unreference(batch->buf); - batch->buf = NULL; - } - - batch->buf = dri_bo_alloc(intel->intelScreen->bufmgr, "batchbuffer", - intel->intelScreen->maxBatchSize, 4096, - DRM_BO_FLAG_MEM_TT); - dri_bo_map(batch->buf, GL_TRUE); - batch->map = batch->buf->virtual; - batch->size = intel->intelScreen->maxBatchSize; - batch->ptr = batch->map; -} - -struct intel_batchbuffer * -intel_batchbuffer_alloc(struct intel_context *intel) -{ - struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); - - batch->intel = intel; - batch->last_fence = NULL; - intel_batchbuffer_reset(batch); - - return batch; -} - -void -intel_batchbuffer_free(struct intel_batchbuffer *batch) -{ - if (batch->last_fence) { - dri_fence_wait(batch->last_fence); - dri_fence_unreference(batch->last_fence); - batch->last_fence = NULL; - } - if (batch->map) { - dri_bo_unmap(batch->buf); - batch->map = NULL; - } - dri_bo_unreference(batch->buf); - batch->buf = NULL; - free(batch); -} - -static int -relocation_sort(const void *a_in, const void *b_in) { - const struct buffer_reloc *a = a_in, *b = b_in; - - return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1; -} - - -/* TODO: Push this whole function into bufmgr. - */ -static void -do_flush_locked(struct intel_batchbuffer *batch, - GLuint used, - GLboolean ignore_cliprects, GLboolean allow_unlock) -{ - GLuint *ptr; - GLuint i; - struct intel_context *intel = batch->intel; - dri_fence *fo; - GLboolean performed_rendering = GL_FALSE; - - assert(batch->buf->virtual != NULL); - ptr = batch->buf->virtual; - - /* Sort our relocation list in terms of referenced buffer pointer. - * This lets us uniquely validate the buffers with the sum of all the flags, - * while avoiding O(n^2) on number of relocations. - */ - qsort(batch->reloc, batch->nr_relocs, sizeof(batch->reloc[0]), - relocation_sort); - - /* Perform the necessary validations of buffers, and enter the relocations - * in the batchbuffer. - */ - for (i = 0; i < batch->nr_relocs; i++) { - struct buffer_reloc *r = &batch->reloc[i]; - - if (r->validate_flags & DRM_BO_FLAG_WRITE) - performed_rendering = GL_TRUE; - - /* If this is the first time we've seen this buffer in the relocation - * list, figure out our flags and validate it. - */ - if (i == 0 || batch->reloc[i - 1].buf != r->buf) { - uint32_t validate_flags; - int j, ret; - - /* Accumulate the flags we need for validating this buffer. */ - validate_flags = r->validate_flags; - for (j = i + 1; j < batch->nr_relocs; j++) { - if (batch->reloc[j].buf != r->buf) - break; - validate_flags |= batch->reloc[j].validate_flags; - } - - /* Validate. If we fail, fence to clear the unfenced list and bail - * out. - */ - ret = dri_bo_validate(r->buf, validate_flags); - if (ret != 0) { - dri_bo_unmap(batch->buf); - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "batchbuffer failure fence", GL_TRUE); - dri_fence_unreference(fo); - goto done; - } - } - ptr[r->offset / 4] = r->buf->offset + r->delta; - dri_bo_unreference(r->buf); - } - - dri_bo_unmap(batch->buf); - batch->map = NULL; - batch->ptr = NULL; - - dri_bo_validate(batch->buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE); - - batch->list_count = 0; - batch->nr_relocs = 0; - batch->flags = 0; - - /* Throw away non-effective packets. Won't work once we have - * hardware contexts which would preserve statechanges beyond a - * single buffer. - */ - - if (!(intel->numClipRects == 0 && !ignore_cliprects)) { - intel_batch_ioctl(batch->intel, - batch->buf->offset, - used, ignore_cliprects, allow_unlock); - } - - /* Associate a fence with the validated buffers, and note that we included - * a flush at the end. - */ - fo = dri_fence_validated(intel->intelScreen->bufmgr, - "Batch fence", GL_TRUE); - - if (performed_rendering) { - dri_fence_unreference(batch->last_fence); - batch->last_fence = fo; - } else { - /* If we didn't validate any buffers for writing by the card, we don't - * need to track the fence for glFinish(). - */ - dri_fence_unreference(fo); - } - - if (intel->numClipRects == 0 && !ignore_cliprects) { - if (allow_unlock) { - /* If we are not doing any actual user-visible rendering, - * do a sched_yield to keep the app from pegging the cpu while - * achieving nothing. - */ - UNLOCK_HARDWARE(intel); - sched_yield(); - LOCK_HARDWARE(intel); - } - intel->vtbl.lost_hardware(intel); - } - -done: - if (INTEL_DEBUG & DEBUG_BATCH) { - dri_bo_map(batch->buf, GL_FALSE); - intel_decode(ptr, used / 4, batch->buf->offset); - dri_bo_unmap(batch->buf); - } -} - - -void -intel_batchbuffer_flush(struct intel_batchbuffer *batch) -{ - struct intel_context *intel = batch->intel; - GLuint used = batch->ptr - batch->map; - GLboolean was_locked = intel->locked; - - if (used == 0) - return; - - /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a - * performance drain that we would like to avoid. - */ - if (used & 4) { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = 0; - ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; - used += 12; - } - else { - ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); - ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; - used += 8; - } - - /* TODO: Just pass the relocation list and dma buffer up to the - * kernel. - */ - if (!was_locked) - LOCK_HARDWARE(intel); - - do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), - GL_FALSE); - - if (!was_locked) - UNLOCK_HARDWARE(intel); - - /* Reset the buffer: - */ - intel_batchbuffer_reset(batch); -} - -void -intel_batchbuffer_finish(struct intel_batchbuffer *batch) -{ - intel_batchbuffer_flush(batch); - if (batch->last_fence != NULL) - dri_fence_wait(batch->last_fence); -} - - -/* This is the only way buffers get added to the validate list. - */ -GLboolean -intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint delta) -{ - struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; - - assert(batch->nr_relocs <= MAX_RELOCS); - - dri_bo_reference(buffer); - r->buf = buffer; - r->offset = batch->ptr - batch->map; - r->delta = delta; - r->validate_flags = flags; - - batch->ptr += 4; - return GL_TRUE; -} - - - -void -intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags) -{ - assert((bytes & 3) == 0); - intel_batchbuffer_require_space(batch, bytes, flags); - __memcpy(batch->ptr, data, bytes); - batch->ptr += bytes; -} diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h deleted file mode 100644 index 850a91e1c9..0000000000 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef INTEL_BATCHBUFFER_H -#define INTEL_BATCHBUFFER_H - -#include "mtypes.h" -#include "dri_bufmgr.h" - -struct intel_context; - -#define BATCH_SZ 16384 -#define BATCH_RESERVED 16 - -#define MAX_RELOCS 4096 - -#define INTEL_BATCH_NO_CLIPRECTS 0x1 -#define INTEL_BATCH_CLIPRECTS 0x2 - -struct buffer_reloc -{ - dri_bo *buf; - GLuint offset; - GLuint delta; /* not needed? */ - GLuint validate_flags; -}; - -struct intel_batchbuffer -{ - struct intel_context *intel; - - dri_bo *buf; - dri_fence *last_fence; - GLuint flags; - - drmBOList list; - GLuint list_count; - GLubyte *map; - GLubyte *ptr; - - struct buffer_reloc reloc[MAX_RELOCS]; - GLuint nr_relocs; - GLuint size; -}; - -struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context - *intel); - -void intel_batchbuffer_free(struct intel_batchbuffer *batch); - - -void intel_batchbuffer_finish(struct intel_batchbuffer *batch); - -void intel_batchbuffer_flush(struct intel_batchbuffer *batch); - -void intel_batchbuffer_reset(struct intel_batchbuffer *batch); - - -/* Unlike bmBufferData, this currently requires the buffer be mapped. - * Consider it a convenience function wrapping multple - * intel_buffer_dword() calls. - */ -void intel_batchbuffer_data(struct intel_batchbuffer *batch, - const void *data, GLuint bytes, GLuint flags); - -void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, - GLuint bytes); - -GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, - dri_bo *buffer, - GLuint flags, GLuint offset); - -/* Inline functions - might actually be better off with these - * non-inlined. Certainly better off switching all command packets to - * be passed as structs rather than dwords, but that's a little bit of - * work... - */ -static INLINE GLuint -intel_batchbuffer_space(struct intel_batchbuffer *batch) -{ - return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); -} - - -static INLINE void -intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) -{ - assert(batch->map); - assert(intel_batchbuffer_space(batch) >= 4); - *(GLuint *) (batch->ptr) = dword; - batch->ptr += 4; -} - -static INLINE void -intel_batchbuffer_require_space(struct intel_batchbuffer *batch, - GLuint sz, GLuint flags) -{ - assert(sz < batch->size - 8); - if (intel_batchbuffer_space(batch) < sz || - (batch->flags != 0 && flags != 0 && batch->flags != flags)) - intel_batchbuffer_flush(batch); - - batch->flags |= flags; -} - -/* Here are the crusty old macros, to be removed: - */ -#define BATCH_LOCALS - -#define BEGIN_BATCH(n, flags) do { \ - assert(!intel->prim.flush); \ - intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ -} while (0) - -#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) - -#define OUT_RELOC(buf, flags, delta) do { \ - assert((delta) >= 0); \ - intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta); \ -} while (0) - -#define ADVANCE_BATCH() do { } while(0) - - -#endif -- cgit v1.2.3 From 35331a511fcd023a7b6f0eb298098d872b856a9f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 27 Sep 2007 15:06:06 -0700 Subject: [965] Add batchbuffer dumping under INTEL_DEBUG=bat, like 915. --- src/mesa/drivers/dri/i915/Makefile | 1 + src/mesa/drivers/dri/i915/intel_batchbuffer.c | 3 +- src/mesa/drivers/dri/i915/intel_decode.c | 833 +----------------------- src/mesa/drivers/dri/i915/intel_decode.h | 29 - src/mesa/drivers/dri/i965/Makefile | 2 + src/mesa/drivers/dri/i965/intel_batchbuffer.c | 11 + src/mesa/drivers/dri/i965/intel_context.c | 2 + src/mesa/drivers/dri/i965/intel_context.h | 17 +- src/mesa/drivers/dri/i965/intel_decode.c | 1 + src/mesa/drivers/dri/intel/intel_chipset.h | 78 +++ src/mesa/drivers/dri/intel/intel_decode.c | 900 ++++++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_decode.h | 29 + 12 files changed, 1028 insertions(+), 878 deletions(-) mode change 100644 => 120000 src/mesa/drivers/dri/i915/intel_decode.c delete mode 100644 src/mesa/drivers/dri/i915/intel_decode.h create mode 120000 src/mesa/drivers/dri/i965/intel_decode.c create mode 100644 src/mesa/drivers/dri/intel/intel_chipset.h create mode 100644 src/mesa/drivers/dri/intel/intel_decode.c create mode 100644 src/mesa/drivers/dri/intel/intel_decode.h (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index d3d0bd570c..38e4090211 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -66,6 +66,7 @@ DRIVER_DEFINES = -I../intel $(shell pkg-config libdrm --atleast-version=2.3.1 \ include ../Makefile.template +intel_decode.o: ../intel/intel_decode.c intel_tex_layout.o: ../intel/intel_tex_layout.c symlinks: diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index 8ee48b5a68..045ff0a5b0 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -240,7 +240,8 @@ do_flush_locked(struct intel_batchbuffer *batch, done: if (INTEL_DEBUG & DEBUG_BATCH) { dri_bo_map(batch->buf, GL_FALSE); - intel_decode(ptr, used / 4, batch->buf->offset); + intel_decode(ptr, used / 4, batch->buf->offset, + intel->intelScreen->deviceID); dri_bo_unmap(batch->buf); } } diff --git a/src/mesa/drivers/dri/i915/intel_decode.c b/src/mesa/drivers/dri/i915/intel_decode.c deleted file mode 100644 index bf3387b28e..0000000000 --- a/src/mesa/drivers/dri/i915/intel_decode.c +++ /dev/null @@ -1,832 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/* - * Copyright © 2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Eric Anholt - * - */ - -/** @file intel_decode.c - * This file contains code to print out batchbuffer contents in a - * human-readable format. - * - * The current version only supports i915 packets, and only pretty-prints a - * subset of them. The intention is for it to make just a best attempt to - * decode, but never crash in the process. - */ - -#include -#include -#include - -#include "intel_decode.h" -#include "i915_reg.h" - -#define BUFFER_FAIL(_count, _len, _name) do { \ - fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ - (_name), (_count), (_len)); \ - (*failures)++; \ - return count; \ -} while (0) - -static FILE *out; -static uint32_t saved_s2 = 0, saved_s4 = 0; -static char saved_s2_set = 0, saved_s4_set = 0; - -static float -int_as_float(uint32_t intval) -{ - union intfloat { - uint32_t i; - float f; - } uval; - - uval.i = intval; - return uval.f; -} - -static void -instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, - char *fmt, ...) -{ - va_list va; - - fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); - va_start(va, fmt); - vfprintf(out, fmt, va); - va_end(va); -} - - -static int -decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_mi[] = { - { 0x08, 1, 1, "MI_ARB_ON_OFF" }, - { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, - { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, - { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, - { 0x04, 1, 1, "MI_FLUSH" }, - { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, - { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, - { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, - { 0x00, 1, 1, "MI_NOOP" }, - { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, - { 0x07, 1, 1, "MI_REPORT_HEAD" }, - { 0x18, 2, 2, "MI_SET_CONTEXT" }, - { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, - { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, - { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, - { 0x02, 1, 1, "MI_USER_INTERRUPT" }, - { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, - }; - - - for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); - opcode++) { - if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { - unsigned int len = 1, i; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); - if (opcodes_mi[opcode].max_len > 1) { - len = (data[0] & 0x000000ff) + 2; - if (len < opcodes_mi[opcode].min_len || - len > opcodes_mi[opcode].max_len) - { - fprintf(out, "Bad length in %s\n", - opcodes_mi[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_mi[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode, len; - char *format; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_2d[] = { - { 0x40, 5, 5, "COLOR_BLT" }, - { 0x43, 6, 6, "SRC_COPY_BLT" }, - { 0x01, 8, 8, "XY_SETUP_BLT" }, - { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, - { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, - { 0x24, 2, 2, "XY_PIXEL_BLT" }, - { 0x25, 3, 3, "XY_SCANLINES_BLT" }, - { 0x26, 4, 4, "Y_TEXT_BLT" }, - { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, - { 0x50, 6, 6, "XY_COLOR_BLT" }, - { 0x51, 6, 6, "XY_PAT_BLT" }, - { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, - { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, - { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, - { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, - { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, - { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, - { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, - { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, - { 0x55, 9, 9, "XY_FULL_BLT" }, - { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, - { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, - { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, - { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, - { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, - }; - - switch ((data[0] & 0x1fc00000) >> 22) { - case 0x50: - instr_out(data, hw_offset, 0, - "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", - (data[0] & (1 << 20)) ? "en" : "dis", - (data[0] & (1 << 21)) ? "en" : "dis"); - - len = (data[0] & 0x000000ff) + 2; - if (len != 6) - fprintf(out, "Bad count in XY_COLOR_BLT\n"); - if (count < 6) - BUFFER_FAIL(count, len, "XY_COLOR_BLT"); - - switch ((data[1] >> 24) & 0x3) { - case 0: - format="8"; - break; - case 1: - format="565"; - break; - case 2: - format="1555"; - break; - case 3: - format="8888"; - break; - } - - instr_out(data, hw_offset, 1, "format %s, pitch %d, " - "clipping %sabled\n", format, - data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); - instr_out(data, hw_offset, 2, "(%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 3, "(%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); - instr_out(data, hw_offset, 5, "color\n"); - return len; - case 0x53: - instr_out(data, hw_offset, 0, - "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", - (data[0] & (1 << 20)) ? "en" : "dis", - (data[0] & (1 << 21)) ? "en" : "dis"); - - len = (data[0] & 0x000000ff) + 2; - if (len != 8) - fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); - if (count < 8) - BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); - - switch ((data[1] >> 24) & 0x3) { - case 0: - format="8"; - break; - case 1: - format="565"; - break; - case 2: - format="1555"; - break; - case 3: - format="8888"; - break; - } - - instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " - "clipping %sabled\n", format, - data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); - instr_out(data, hw_offset, 2, "dst (%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 3, "dst (%d,%d)\n", - data[2] & 0xffff, data[2] >> 16); - instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); - instr_out(data, hw_offset, 5, "src (%d,%d)\n", - data[5] & 0xffff, data[5] >> 16); - instr_out(data, hw_offset, 6, "src pitch %d\n", - data[6] & 0xffff); - instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); - return len; - } - - for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); - opcode++) { - if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { - unsigned int i; - - len = 1; - instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); - if (opcodes_2d[opcode].max_len > 1) { - len = (data[0] & 0x000000ff) + 2; - if (len < opcodes_2d[opcode].min_len || - len > opcodes_2d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_2d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - switch ((data[0] & 0x00f80000) >> 19) { - case 0x11: - instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); - return 1; - case 0x10: - instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); - return 1; - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int len, i, c, opcode, word, map, sampler, instr; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_3d_1d[] = { - { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, - { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, - { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, - { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, - { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, - { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, - { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, - { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, - { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, - { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, - { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, - { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, - { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, - { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, - { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, - { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, - { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, - }; - - switch ((data[0] & 0x00ff0000) >> 16) { - case 0x07: - /* This instruction is unusual. A 0 length means just 1 DWORD instead of - * 2. The 0 length is specified in one place to be unsupported, but - * stated to be required in another, and 0 length LOAD_INDIRECTs appear - * to cause no harm at least. - */ - instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); - len = (data[0] & 0x000000ff) + 1; - i = 1; - if (data[0] & (0x01 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "SIS.0\n"); - instr_out(data, hw_offset, i++, "SIS.1\n"); - } - if (data[0] & (0x02 << 8)) { - if (i + 1 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "DIS.0\n"); - } - if (data[0] & (0x04 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "SSB.0\n"); - instr_out(data, hw_offset, i++, "SSB.1\n"); - } - if (data[0] & (0x08 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "MSB.0\n"); - instr_out(data, hw_offset, i++, "MSB.1\n"); - } - if (data[0] & (0x10 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "PSP.0\n"); - instr_out(data, hw_offset, i++, "PSP.1\n"); - } - if (data[0] & (0x20 << 8)) { - if (i + 2 >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); - instr_out(data, hw_offset, i++, "PSC.0\n"); - instr_out(data, hw_offset, i++, "PSC.1\n"); - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); - (*failures)++; - return len; - } - return len; - case 0x04: - instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); - len = (data[0] & 0x0000000f) + 2; - i = 1; - for (word = 0; word <= 7; word++) { - if (data[0] & (1 << (4 + word))) { - if (i >= count) - BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); - - /* save vertex state for decode */ - if (word == 2) { - saved_s2_set = 1; - saved_s2 = data[i]; - } - if (word == 4) { - saved_s4_set = 1; - saved_s4 = data[i]; - } - - instr_out(data, hw_offset, i++, "S%d\n", word); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); - (*failures)++; - } - return len; - case 0x00: - instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); - len = (data[0] & 0x0000003f) + 2; - - i = 1; - for (map = 0; map <= 15; map++) { - if (data[1] & (1 << map)) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); - instr_out(data, hw_offset, i++, "map %d MS2\n", map); - instr_out(data, hw_offset, i++, "map %d MS3\n", map); - instr_out(data, hw_offset, i++, "map %d MS4\n", map); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); - (*failures)++; - return len; - } - return len; - case 0x06: - instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); - len = (data[0] & 0x000000ff) + 2; - - i = 1; - for (c = 0; c <= 31; c++) { - if (data[1] & (1 << c)) { - if (i + 4 >= count) - BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); - instr_out(data, hw_offset, i, "C%d.X = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.Y = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.Z = %f\n", - c, int_as_float(data[i])); - i++; - instr_out(data, hw_offset, i, "C%d.W = %f\n", - c, int_as_float(data[i])); - i++; - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); - (*failures)++; - } - return len; - case 0x05: - instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); - len = (data[0] & 0x000000ff) + 2; - if ((len - 1) % 3 != 0 || len > 370) { - fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); - (*failures)++; - } - i = 1; - for (instr = 0; instr < (len - 1) / 3; instr++) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - instr_out(data, hw_offset, i++, "PS%03x\n", instr); - } - return len; - case 0x01: - instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); - len = (data[0] & 0x0000003f) + 2; - i = 1; - for (sampler = 0; sampler <= 15; sampler++) { - if (data[1] & (1 << sampler)) { - if (i + 3 >= count) - BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); - instr_out(data, hw_offset, i++, "sampler %d SS2\n", - sampler); - instr_out(data, hw_offset, i++, "sampler %d SS3\n", - sampler); - instr_out(data, hw_offset, i++, "sampler %d SS4\n", - sampler); - } - } - if (len != i) { - fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); - (*failures)++; - } - return len; - } - - for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); - opcode++) - { - if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { - len = 1; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); - if (opcodes_3d_1d[opcode].max_len > 1) { - len = (data[0] & 0x0000ffff) + 2; - if (len < opcodes_3d_1d[opcode].min_len || - len > opcodes_3d_1d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", - opcodes_3d_1d[opcode].name); - (*failures)++; - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - - return len; - } - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -static int -decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, - int *failures) -{ - char immediate = (data[0] & (1 << 23)) == 0; - unsigned int len, i; - char *primtype; - - switch ((data[0] >> 18) & 0xf) { - case 0x0: primtype = "TRILIST"; break; - case 0x1: primtype = "TRISTRIP"; break; - case 0x2: primtype = "TRISTRIP_REVERSE"; break; - case 0x3: primtype = "TRIFAN"; break; - case 0x4: primtype = "POLYGON"; break; - case 0x5: primtype = "LINELIST"; break; - case 0x6: primtype = "LINESTRIP"; break; - case 0x7: primtype = "RECTLIST"; break; - case 0x8: primtype = "POINTLIST"; break; - case 0x9: primtype = "DIB"; break; - case 0xa: primtype = "CLEAR_RECT"; break; - default: primtype = "unknown"; break; - } - - /* XXX: 3DPRIM_DIB not supported */ - if (immediate) { - len = (data[0] & 0x0003ffff) + 2; - instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); - if (count < len) - BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); - if (!saved_s2_set || !saved_s4_set) { - fprintf(out, "unknown vertex format\n"); - for (i = 1; i < len; i++) { - instr_out(data, hw_offset, i, - " vertex data (%f float)\n", - int_as_float(data[i])); - } - } else { - unsigned int vertex = 0; - for (i = 1; i < len;) { - unsigned int tc; - -#define VERTEX_OUT(fmt, ...) do { \ - if (i < len) \ - instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ - else \ - fprintf(out, " missing data in V%d\n", vertex); \ - i++; \ -} while (0) - - VERTEX_OUT("X = %f", int_as_float(data[i])); - VERTEX_OUT("Y = %f", int_as_float(data[i])); - switch (saved_s4 >> 6 & 0x7) { - case 0x1: - VERTEX_OUT("Z = %f", int_as_float(data[i])); - break; - case 0x2: - VERTEX_OUT("Z = %f", int_as_float(data[i])); - VERTEX_OUT("W = %f", int_as_float(data[i])); - break; - case 0x3: - break; - case 0x4: - VERTEX_OUT("W = %f", int_as_float(data[i])); - break; - default: - fprintf(out, "bad S4 position mask\n"); - } - - if (saved_s4 & (1 << 10)) { - VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " - "B=0x%02x)", - data[i] >> 24, - (data[i] >> 16) & 0xff, - (data[i] >> 8) & 0xff, - data[i] & 0xff); - } - if (saved_s4 & (1 << 11)) { - VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " - "B=0x%02x)", - data[i] >> 24, - (data[i] >> 16) & 0xff, - (data[i] >> 8) & 0xff, - data[i] & 0xff); - } - if (saved_s4 & (1 << 12)) - VERTEX_OUT("width = 0x%08x)", data[i]); - - for (tc = 0; tc <= 7; tc++) { - switch ((saved_s2 >> (tc * 4)) & 0xf) { - case 0x0: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - break; - case 0x1: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); - break; - case 0x2: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); - VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); - break; - case 0x3: - VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); - break; - case 0x4: - VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); - break; - case 0x5: - VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); - VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); - break; - case 0xf: - break; - default: - fprintf(out, "bad S2.T%d format\n", tc); - } - } - vertex++; - } - } - } else { - /* indirect vertices */ - len = data[0] & 0x0000ffff; /* index count */ - if (data[0] & (1 << 17)) { - /* random vertex access */ - if (count < (len + 1) / 2 + 1) { - BUFFER_FAIL(count, (len + 1) / 2 + 1, - "3DPRIMITIVE random indirect"); - } - instr_out(data, hw_offset, 0, - "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); - if (len == 0) { - /* vertex indices continue until 0xffff is found */ - for (i = 1; i < count; i++) { - if ((data[i] & 0xffff) == 0xffff) { - instr_out(data, hw_offset, i, - " indices: (terminator)\n"); - return i; - } else if ((data[i] >> 16) == 0xffff) { - instr_out(data, hw_offset, i, - " indices: 0x%04x, " - "(terminator)\n", - data[i] & 0xffff); - return i; - } else { - instr_out(data, hw_offset, i, - " indices: 0x%04x, 0x%04x\n", - data[i] & 0xffff, data[i] >> 16); - } - } - fprintf(out, - "3DPRIMITIVE: no terminator found in index buffer\n"); - (*failures)++; - return count; - } else { - /* fixed size vertex index buffer */ - for (i = 0; i < len; i += 2) { - if (i * 2 == len - 1) { - instr_out(data, hw_offset, i, - " indices: 0x%04x\n", - data[i] & 0xffff); - } else { - instr_out(data, hw_offset, i, - " indices: 0x%04x, 0x%04x\n", - data[i] & 0xffff, data[i] >> 16); - } - } - } - return (len + 1) / 2 + 1; - } else { - /* sequential vertex access */ - if (count < 2) - BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); - instr_out(data, hw_offset, 0, - "3DPRIMITIVE sequential indirect %s, %d starting from " - "%d\n", primtype, len, data[1] & 0xffff); - instr_out(data, hw_offset, 1, " start\n"); - return 2; - } - } - - return len; -} - -static int -decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) -{ - unsigned int opcode; - - struct { - uint32_t opcode; - int min_len; - int max_len; - char *name; - } opcodes_3d[] = { - { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, - { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, - { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, - { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, - { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, - { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, - { 0x0d, 1, 1, "3DSTATE_MODES_4" }, - { 0x0c, 1, 1, "3DSTATE_MODES_5" }, - { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, - }; - - switch ((data[0] & 0x1f000000) >> 24) { - case 0x1f: - return decode_3d_primitive(data, count, hw_offset, failures); - case 0x1d: - return decode_3d_1d(data, count, hw_offset, failures); - case 0x1c: - return decode_3d_1c(data, count, hw_offset, failures); - } - - for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); - opcode++) { - if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { - unsigned int len = 1, i; - - instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); - if (opcodes_3d[opcode].max_len > 1) { - len = (data[0] & 0xff) + 2; - if (len < opcodes_3d[opcode].min_len || - len > opcodes_3d[opcode].max_len) - { - fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); - } - } - - for (i = 1; i < len; i++) { - if (i >= count) - BUFFER_FAIL(count, len, opcodes_3d[opcode].name); - instr_out(data, hw_offset, i, "dword %d\n", i); - } - return len; - } - } - - instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); - (*failures)++; - return 1; -} - -/** - * Decodes an i830-i915 batch buffer, writing the output to stdout. - * - * \param data batch buffer contents - * \param count number of DWORDs to decode in the batch buffer - * \param hw_offset hardware address for the buffer - */ -int -intel_decode(uint32_t *data, int count, uint32_t hw_offset) -{ - int index = 0; - int failures = 0; - - out = stdout; - - while (index < count) { - switch ((data[index] & 0xe0000000) >> 29) { - case 0x0: - index += decode_mi(data + index, count - index, - hw_offset + index * 4, &failures); - break; - case 0x2: - index += decode_2d(data + index, count - index, - hw_offset + index * 4, &failures); - break; - case 0x3: - index += decode_3d(data + index, count - index, - hw_offset + index * 4, &failures); - break; - default: - instr_out(data, hw_offset, index, "UNKNOWN\n"); - failures++; - index++; - break; - } - fflush(out); - } - - return failures; -} - -void intel_decode_context_reset() -{ - saved_s2_set = 0; - saved_s4_set = 1; -} - diff --git a/src/mesa/drivers/dri/i915/intel_decode.c b/src/mesa/drivers/dri/i915/intel_decode.c new file mode 120000 index 0000000000..f671b6cbb1 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_decode.c @@ -0,0 +1 @@ +../intel/intel_decode.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i915/intel_decode.h b/src/mesa/drivers/dri/i915/intel_decode.h deleted file mode 100644 index ef0cba153c..0000000000 --- a/src/mesa/drivers/dri/i915/intel_decode.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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: - * Eric Anholt - * - */ - -int intel_decode(uint32_t *data, int count, uint32_t hw_offset); -void intel_decode_context_reset(); diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 5748d7ff05..7e07bc9c1a 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -11,6 +11,7 @@ DRIVER_SOURCES = \ intel_buffer_objects.c \ intel_buffers.c \ intel_context.c \ + intel_decode.c \ intel_ioctl.c \ intel_mipmap_tree.c \ intel_regions.c \ @@ -92,6 +93,7 @@ DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_decode.o: ../intel/intel_decode.c intel_tex_layout.o: ../intel/intel_tex_layout.c server: diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c index 2aaa10e1c2..fb58c0e708 100644 --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c @@ -28,6 +28,7 @@ #include "imports.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "intel_decode.h" #include "bufmgr.h" @@ -168,6 +169,16 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch ) goto out; } + if (INTEL_DEBUG & DEBUG_BATCH) { + char *map; + + map = bmMapBuffer(batch->intel, batch->buffer, + BM_MEM_AGP|BM_MEM_LOCAL|BM_CLIENT); + intel_decode((uint32_t *)(map + batch->offset), used / 4, + offset + batch->offset, intel->intelScreen->deviceID); + bmUnmapBuffer(batch->intel, batch->buffer); + } + /* Fire the batch buffer, which was uploaded above: */ intel_batch_ioctl(batch->intel, diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 022819d582..2cf311c713 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -46,6 +46,7 @@ #include "drivers/common/driverfuncs.h" #include "intel_screen.h" +#include "intel_chipset.h" #include "i830_dri.h" #include "i830_common.h" @@ -225,6 +226,7 @@ static const struct dri_debug_control debug_control[] = { "thre", DEBUG_SINGLE_THREAD }, { "wm", DEBUG_WM }, { "vs", DEBUG_VS }, + { "bat", DEBUG_BATCH }, { NULL, 0 } }; diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 06cfc6946d..f63c2f613d 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -355,22 +355,7 @@ extern int INTEL_DEBUG; #define DEBUG_WM 0x10000 #define DEBUG_URB 0x20000 #define DEBUG_VS 0x40000 - - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I965_G 0x29A2 -#define PCI_CHIP_I965_Q 0x2992 -#define PCI_CHIP_I965_G_1 0x2982 -#define PCI_CHIP_I946_GZ 0x2972 -#define PCI_CHIP_I965_GM 0x2A02 -#define PCI_CHIP_I965_GME 0x2A12 - +#define DEBUG_BATCH 0x80000 /* ================================================================ * intel_context.c: diff --git a/src/mesa/drivers/dri/i965/intel_decode.c b/src/mesa/drivers/dri/i965/intel_decode.c new file mode 120000 index 0000000000..f671b6cbb1 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_decode.c @@ -0,0 +1 @@ +../intel/intel_decode.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h new file mode 100644 index 0000000000..a18ca5be08 --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_chipset.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 + +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 + +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GME 0x27AE + +#define PCI_CHIP_Q35_G 0x29B2 +#define PCI_CHIP_G33_G 0x29C2 +#define PCI_CHIP_Q33_G 0x29D2 + +#define PCI_CHIP_I965_G 0x29A2 +#define PCI_CHIP_I965_Q 0x2992 +#define PCI_CHIP_I965_G_1 0x2982 +#define PCI_CHIP_I946_GZ 0x2972 +#define PCI_CHIP_I965_GM 0x2A02 +#define PCI_CHIP_I965_GME 0x2A12 + +#define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \ + devid == PCI_CHIP_I915_GM || \ + devid == PCI_CHIP_I945_GM || \ + devid == PCI_CHIP_I945_GME || \ + devid == PCI_CHIP_I965_GM || \ + devid == PCI_CHIP_I965_GME) + +#define IS_965(devid) (devid = PCI_CHIP_I965_G || \ + devid == PCI_CHIP_I965_Q || \ + devid == PCI_CHIP_I965_G_1 || \ + devid == PCI_CHIP_I965_GM || \ + devid == PCI_CHIP_I965_GME || \ + devid == PCI_CHIP_I946_GZ) + +#define IS_9XX(devid) (devid == PCI_CHIP_I915G || \ + devid == PCI_CHIP_I915GM || \ + devid == PCI_CHIP_I945G || \ + devid == PCI_CHIP_I945GM || \ + devid == PCI_CHIP_I945GME || \ + devid == PCI_CHIP_G33_G || \ + devid == PCI_CHIP_Q35_G || \ + devid == PCI_CHIP_Q33_G || \ + IS_965(devid)) + diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c new file mode 100644 index 0000000000..16881f297d --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_decode.c @@ -0,0 +1,900 @@ +/* -*- c-basic-offset: 4 -*- */ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +/** @file intel_decode.c + * This file contains code to print out batchbuffer contents in a + * human-readable format. + * + * The current version only supports i915 packets, and only pretty-prints a + * subset of them. The intention is for it to make just a best attempt to + * decode, but never crash in the process. + */ + +#include +#include +#include + +#include "intel_decode.h" +#include "intel_chipset.h" + +#define BUFFER_FAIL(_count, _len, _name) do { \ + fprintf(out, "Buffer size too small in %s (%d < %d)\n", \ + (_name), (_count), (_len)); \ + (*failures)++; \ + return count; \ +} while (0) + +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; + +static float +int_as_float(uint32_t intval) +{ + union intfloat { + uint32_t i; + float f; + } uval; + + uval.i = intval; + return uval.f; +} + +static void +instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index, + char *fmt, ...) +{ + va_list va; + + fprintf(out, "0x%08x: 0x%08x: ", hw_offset + index * 4, data[index]); + va_start(va, fmt); + vfprintf(out, fmt, va); + va_end(va); +} + + +static int +decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_mi[] = { + { 0x08, 1, 1, "MI_ARB_ON_OFF" }, + { 0x0a, 1, 1, "MI_BATCH_BUFFER_END" }, + { 0x31, 2, 2, "MI_BATCH_BUFFER_START" }, + { 0x14, 3, 3, "MI_DISPLAY_BUFFER_INFO" }, + { 0x04, 1, 1, "MI_FLUSH" }, + { 0x22, 3, 3, "MI_LOAD_REGISTER_IMM" }, + { 0x13, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" }, + { 0x12, 2, 2, "MI_LOAD_SCAN_LINES_INCL" }, + { 0x00, 1, 1, "MI_NOOP" }, + { 0x11, 2, 2, "MI_OVERLAY_FLIP" }, + { 0x07, 1, 1, "MI_REPORT_HEAD" }, + { 0x18, 2, 2, "MI_SET_CONTEXT" }, + { 0x20, 3, 4, "MI_STORE_DATA_IMM" }, + { 0x21, 3, 4, "MI_STORE_DATA_INDEX" }, + { 0x24, 3, 3, "MI_STORE_REGISTER_MEM" }, + { 0x02, 1, 1, "MI_USER_INTERRUPT" }, + { 0x03, 1, 1, "MI_WAIT_FOR_EVENT" }, + }; + + + for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]); + opcode++) { + if ((data[0] & 0x1e000000) >> 23 == opcodes_mi[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_mi[opcode].name); + if (opcodes_mi[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_mi[opcode].min_len || + len > opcodes_mi[opcode].max_len) + { + fprintf(out, "Bad length in %s\n", + opcodes_mi[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_mi[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "MI UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode, len; + char *format = NULL; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_2d[] = { + { 0x40, 5, 5, "COLOR_BLT" }, + { 0x43, 6, 6, "SRC_COPY_BLT" }, + { 0x01, 8, 8, "XY_SETUP_BLT" }, + { 0x11, 9, 9, "XY_SETUP_MONO_PATTERN_SL_BLT" }, + { 0x03, 3, 3, "XY_SETUP_CLIP_BLT" }, + { 0x24, 2, 2, "XY_PIXEL_BLT" }, + { 0x25, 3, 3, "XY_SCANLINES_BLT" }, + { 0x26, 4, 4, "Y_TEXT_BLT" }, + { 0x31, 5, 134, "XY_TEXT_IMMEDIATE_BLT" }, + { 0x50, 6, 6, "XY_COLOR_BLT" }, + { 0x51, 6, 6, "XY_PAT_BLT" }, + { 0x76, 8, 8, "XY_PAT_CHROMA_BLT" }, + { 0x72, 7, 135, "XY_PAT_BLT_IMMEDIATE" }, + { 0x77, 9, 137, "XY_PAT_CHROMA_BLT_IMMEDIATE" }, + { 0x52, 9, 9, "XY_MONO_PAT_BLT" }, + { 0x59, 7, 7, "XY_MONO_PAT_FIXED_BLT" }, + { 0x53, 8, 8, "XY_SRC_COPY_BLT" }, + { 0x54, 8, 8, "XY_MONO_SRC_COPY_BLT" }, + { 0x71, 9, 137, "XY_MONO_SRC_COPY_IMMEDIATE_BLT" }, + { 0x55, 9, 9, "XY_FULL_BLT" }, + { 0x55, 9, 137, "XY_FULL_IMMEDIATE_PATTERN_BLT" }, + { 0x56, 9, 9, "XY_FULL_MONO_SRC_BLT" }, + { 0x75, 10, 138, "XY_FULL_MONO_SRC_IMMEDIATE_PATTERN_BLT" }, + { 0x57, 12, 12, "XY_FULL_MONO_PATTERN_BLT" }, + { 0x58, 12, 12, "XY_FULL_MONO_PATTERN_MONO_SRC_BLT" }, + }; + + switch ((data[0] & 0x1fc00000) >> 22) { + case 0x50: + instr_out(data, hw_offset, 0, + "XY_COLOR_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 6) + fprintf(out, "Bad count in XY_COLOR_BLT\n"); + if (count < 6) + BUFFER_FAIL(count, len, "XY_COLOR_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "(%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "color\n"); + return len; + case 0x53: + instr_out(data, hw_offset, 0, + "XY_SRC_COPY_BLT (rgb %sabled, alpha %sabled)\n", + (data[0] & (1 << 20)) ? "en" : "dis", + (data[0] & (1 << 21)) ? "en" : "dis"); + + len = (data[0] & 0x000000ff) + 2; + if (len != 8) + fprintf(out, "Bad count in XY_SRC_COPY_BLT\n"); + if (count < 8) + BUFFER_FAIL(count, len, "XY_SRC_COPY_BLT"); + + switch ((data[1] >> 24) & 0x3) { + case 0: + format="8"; + break; + case 1: + format="565"; + break; + case 2: + format="1555"; + break; + case 3: + format="8888"; + break; + } + + instr_out(data, hw_offset, 1, "format %s, dst pitch %d, " + "clipping %sabled\n", format, + data[1] & 0xffff, data[1] & (1 << 30) ? "en" : "dis"); + instr_out(data, hw_offset, 2, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 3, "dst (%d,%d)\n", + data[2] & 0xffff, data[2] >> 16); + instr_out(data, hw_offset, 4, "dst offset 0x%08x\n", data[4]); + instr_out(data, hw_offset, 5, "src (%d,%d)\n", + data[5] & 0xffff, data[5] >> 16); + instr_out(data, hw_offset, 6, "src pitch %d\n", + data[6] & 0xffff); + instr_out(data, hw_offset, 7, "src offset 0x%08x\n", data[7]); + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_2d) / sizeof(opcodes_2d[0]); + opcode++) { + if ((data[0] & 0x1fc00000) >> 22 == opcodes_2d[opcode].opcode) { + unsigned int i; + + len = 1; + instr_out(data, hw_offset, 0, "%s\n", opcodes_2d[opcode].name); + if (opcodes_2d[opcode].max_len > 1) { + len = (data[0] & 0x000000ff) + 2; + if (len < opcodes_2d[opcode].min_len || + len > opcodes_2d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_2d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_2d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "2D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + switch ((data[0] & 0x00f80000) >> 19) { + case 0x11: + instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); + return 1; + case 0x10: + instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); + return 1; + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int len, i, c, opcode, word, map, sampler, instr; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d_1d[] = { + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" }, + { 0x9c, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, + { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" }, + { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" }, + { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, + { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" }, + { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" }, + { 0x85, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" }, + { 0x80, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x8e, 3, 3, "3DSTATE_BUFFER_INFO" }, + { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" }, + { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" }, + { 0x89, 4, 4, "3DSTATE_FOG_MODE" }, + { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" }, + { 0x81, 3, 3, "3DSTATE_SCISSOR_RECTANGLE" }, + { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" }, + }; + + switch ((data[0] & 0x00ff0000) >> 16) { + case 0x07: + /* This instruction is unusual. A 0 length means just 1 DWORD instead of + * 2. The 0 length is specified in one place to be unsupported, but + * stated to be required in another, and 0 length LOAD_INDIRECTs appear + * to cause no harm at least. + */ + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_INDIRECT\n"); + len = (data[0] & 0x000000ff) + 1; + i = 1; + if (data[0] & (0x01 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SIS.0\n"); + instr_out(data, hw_offset, i++, "SIS.1\n"); + } + if (data[0] & (0x02 << 8)) { + if (i + 1 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "DIS.0\n"); + } + if (data[0] & (0x04 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "SSB.0\n"); + instr_out(data, hw_offset, i++, "SSB.1\n"); + } + if (data[0] & (0x08 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "MSB.0\n"); + instr_out(data, hw_offset, i++, "MSB.1\n"); + } + if (data[0] & (0x10 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSP.0\n"); + instr_out(data, hw_offset, i++, "PSP.1\n"); + } + if (data[0] & (0x20 << 8)) { + if (i + 2 >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_INDIRECT"); + instr_out(data, hw_offset, i++, "PSC.0\n"); + instr_out(data, hw_offset, i++, "PSC.1\n"); + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + return len; + } + return len; + case 0x04: + instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); + len = (data[0] & 0x0000000f) + 2; + i = 1; + for (word = 0; word <= 7; word++) { + if (data[0] & (1 << (4 + word))) { + if (i >= count) + BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1"); + + /* save vertex state for decode */ + if (word == 2) { + saved_s2_set = 1; + saved_s2 = data[i]; + } + if (word == 4) { + saved_s4_set = 1; + saved_s4 = data[i]; + } + + instr_out(data, hw_offset, i++, "S%d\n", word); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); + (*failures)++; + } + return len; + case 0x00: + instr_out(data, hw_offset, 0, "3DSTATE_MAP_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + + i = 1; + for (map = 0; map <= 15; map++) { + if (data[1] & (1 << map)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "map %d MS2\n", map); + instr_out(data, hw_offset, i++, "map %d MS3\n", map); + instr_out(data, hw_offset, i++, "map %d MS4\n", map); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + return len; + } + return len; + case 0x06: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n"); + len = (data[0] & 0x000000ff) + 2; + + i = 1; + for (c = 0; c <= 31; c++) { + if (data[1] & (1 << c)) { + if (i + 4 >= count) + BUFFER_FAIL(count, len, "3DSTATE_PIXEL_SHADER_CONSTANTS"); + instr_out(data, hw_offset, i, "C%d.X = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Y = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.Z = %f\n", + c, int_as_float(data[i])); + i++; + instr_out(data, hw_offset, i, "C%d.W = %f\n", + c, int_as_float(data[i])); + i++; + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_MAP_STATE\n"); + (*failures)++; + } + return len; + case 0x05: + instr_out(data, hw_offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n"); + len = (data[0] & 0x000000ff) + 2; + if ((len - 1) % 3 != 0 || len > 370) { + fprintf(out, "Bad count in 3DSTATE_PIXEL_SHADER_PROGRAM\n"); + (*failures)++; + } + i = 1; + for (instr = 0; instr < (len - 1) / 3; instr++) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + instr_out(data, hw_offset, i++, "PS%03x\n", instr); + } + return len; + case 0x01: + instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n"); + len = (data[0] & 0x0000003f) + 2; + i = 1; + for (sampler = 0; sampler <= 15; sampler++) { + if (data[1] & (1 << sampler)) { + if (i + 3 >= count) + BUFFER_FAIL(count, len, "3DSTATE_SAMPLER_STATE"); + instr_out(data, hw_offset, i++, "sampler %d SS2\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS3\n", + sampler); + instr_out(data, hw_offset, i++, "sampler %d SS4\n", + sampler); + } + } + if (len != i) { + fprintf(out, "Bad count in 3DSTATE_SAMPLER_STATE\n"); + (*failures)++; + } + return len; + } + + for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); + opcode++) + { + if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { + len = 1; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); + if (opcodes_3d_1d[opcode].max_len > 1) { + len = (data[0] & 0x0000ffff) + 2; + if (len < opcodes_3d_1d[opcode].min_len || + len > opcodes_3d_1d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", + opcodes_3d_1d[opcode].name); + (*failures)++; + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d_1d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset, + int *failures) +{ + char immediate = (data[0] & (1 << 23)) == 0; + unsigned int len, i; + char *primtype; + + switch ((data[0] >> 18) & 0xf) { + case 0x0: primtype = "TRILIST"; break; + case 0x1: primtype = "TRISTRIP"; break; + case 0x2: primtype = "TRISTRIP_REVERSE"; break; + case 0x3: primtype = "TRIFAN"; break; + case 0x4: primtype = "POLYGON"; break; + case 0x5: primtype = "LINELIST"; break; + case 0x6: primtype = "LINESTRIP"; break; + case 0x7: primtype = "RECTLIST"; break; + case 0x8: primtype = "POINTLIST"; break; + case 0x9: primtype = "DIB"; break; + case 0xa: primtype = "CLEAR_RECT"; break; + default: primtype = "unknown"; break; + } + + /* XXX: 3DPRIM_DIB not supported */ + if (immediate) { + len = (data[0] & 0x0003ffff) + 2; + instr_out(data, hw_offset, 0, "3DPRIMITIVE inline %s\n", primtype); + if (count < len) + BUFFER_FAIL(count, len, "3DPRIMITIVE inline"); + if (!saved_s2_set || !saved_s4_set) { + fprintf(out, "unknown vertex format\n"); + for (i = 1; i < len; i++) { + instr_out(data, hw_offset, i, + " vertex data (%f float)\n", + int_as_float(data[i])); + } + } else { + unsigned int vertex = 0; + for (i = 1; i < len;) { + unsigned int tc; + +#define VERTEX_OUT(fmt, ...) do { \ + if (i < len) \ + instr_out(data, hw_offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \ + else \ + fprintf(out, " missing data in V%d\n", vertex); \ + i++; \ +} while (0) + + VERTEX_OUT("X = %f", int_as_float(data[i])); + VERTEX_OUT("Y = %f", int_as_float(data[i])); + switch (saved_s4 >> 6 & 0x7) { + case 0x1: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("Z = %f", int_as_float(data[i])); + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + case 0x3: + break; + case 0x4: + VERTEX_OUT("W = %f", int_as_float(data[i])); + break; + default: + fprintf(out, "bad S4 position mask\n"); + } + + if (saved_s4 & (1 << 10)) { + VERTEX_OUT("color = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 11)) { + VERTEX_OUT("spec = (A=0x%02x, R=0x%02x, G=0x%02x, " + "B=0x%02x)", + data[i] >> 24, + (data[i] >> 16) & 0xff, + (data[i] >> 8) & 0xff, + data[i] & 0xff); + } + if (saved_s4 & (1 << 12)) + VERTEX_OUT("width = 0x%08x)", data[i]); + + for (tc = 0; tc <= 7; tc++) { + switch ((saved_s2 >> (tc * 4)) & 0xf) { + case 0x0: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + break; + case 0x1: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + break; + case 0x2: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Y = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.Z = %f", tc, int_as_float(data[i])); + VERTEX_OUT("T%d.W = %f", tc, int_as_float(data[i])); + break; + case 0x3: + VERTEX_OUT("T%d.X = %f", tc, int_as_float(data[i])); + break; + case 0x4: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + break; + case 0x5: + VERTEX_OUT("T%d.XY = 0x%08x half-float", tc, data[i]); + VERTEX_OUT("T%d.ZW = 0x%08x half-float", tc, data[i]); + break; + case 0xf: + break; + default: + fprintf(out, "bad S2.T%d format\n", tc); + } + } + vertex++; + } + } + } else { + /* indirect vertices */ + len = data[0] & 0x0000ffff; /* index count */ + if (data[0] & (1 << 17)) { + /* random vertex access */ + if (count < (len + 1) / 2 + 1) { + BUFFER_FAIL(count, (len + 1) / 2 + 1, + "3DPRIMITIVE random indirect"); + } + instr_out(data, hw_offset, 0, + "3DPRIMITIVE random indirect %s (%d)\n", primtype, len); + if (len == 0) { + /* vertex indices continue until 0xffff is found */ + for (i = 1; i < count; i++) { + if ((data[i] & 0xffff) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: (terminator)\n"); + return i; + } else if ((data[i] >> 16) == 0xffff) { + instr_out(data, hw_offset, i, + " indices: 0x%04x, " + "(terminator)\n", + data[i] & 0xffff); + return i; + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + fprintf(out, + "3DPRIMITIVE: no terminator found in index buffer\n"); + (*failures)++; + return count; + } else { + /* fixed size vertex index buffer */ + for (i = 0; i < len; i += 2) { + if (i * 2 == len - 1) { + instr_out(data, hw_offset, i, + " indices: 0x%04x\n", + data[i] & 0xffff); + } else { + instr_out(data, hw_offset, i, + " indices: 0x%04x, 0x%04x\n", + data[i] & 0xffff, data[i] >> 16); + } + } + } + return (len + 1) / 2 + 1; + } else { + /* sequential vertex access */ + if (count < 2) + BUFFER_FAIL(count, 2, "3DPRIMITIVE seq indirect"); + instr_out(data, hw_offset, 0, + "3DPRIMITIVE sequential indirect %s, %d starting from " + "%d\n", primtype, len, data[1] & 0xffff); + instr_out(data, hw_offset, 1, " start\n"); + return 2; + } + } + + return len; +} + +static int +decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" }, + { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" }, + { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" }, + { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" }, + { 0x15, 1, 1, "3DSTATE_FOG_COLOR" }, + { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" }, + { 0x0d, 1, 1, "3DSTATE_MODES_4" }, + { 0x0c, 1, 1, "3DSTATE_MODES_5" }, + { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, + }; + + switch ((data[0] & 0x1f000000) >> 24) { + case 0x1f: + return decode_3d_primitive(data, count, hw_offset, failures); + case 0x1d: + return decode_3d_1d(data, count, hw_offset, failures); + case 0x1c: + return decode_3d_1c(data, count, hw_offset, failures); + } + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +static int +decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures) +{ + unsigned int opcode; + + struct { + uint32_t opcode; + int min_len; + int max_len; + char *name; + } opcodes_3d[] = { + { 0x6000, 3, 3, "URB_FENCE" }, + { 0x6001, 2, 2, "CS_URB_STATE" }, + { 0x6002, 2, 2, "CONSTANT_BUFFER" }, + { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, + { 0x6102, 2, 2 , "STATE_SIP" }, + { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, + { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" }, + { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" }, + { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" }, + { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" }, + { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" }, + /* 0x7808: 3DSTATE_VERTEX_BUFFERS */ + /* 0x7809: 3DSTATE_VERTEX_ELEMENTS */ + { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, + { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" }, + { 0x7905, 5, 5, "3DSTATE_DEPTH_BUFFER" }, + { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" }, + { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" }, + { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, + { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" }, + { 0x7b00, 6, 6, "3DPRIMITIVE" }, + }; + + for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); + opcode++) { + if ((data[0] & 0xffff0000) >> 16 == opcodes_3d[opcode].opcode) { + unsigned int len = 1, i; + + instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); + if (opcodes_3d[opcode].max_len > 1) { + len = (data[0] & 0xff) + 2; + if (len < opcodes_3d[opcode].min_len || + len > opcodes_3d[opcode].max_len) + { + fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); + } + } + + for (i = 1; i < len; i++) { + if (i >= count) + BUFFER_FAIL(count, len, opcodes_3d[opcode].name); + instr_out(data, hw_offset, i, "dword %d\n", i); + } + return len; + } + } + + instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); + (*failures)++; + return 1; +} + +/** + * Decodes an i830-i915 batch buffer, writing the output to stdout. + * + * \param data batch buffer contents + * \param count number of DWORDs to decode in the batch buffer + * \param hw_offset hardware address for the buffer + */ +int +intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid) +{ + int index = 0; + int failures = 0; + + out = stdout; + + while (index < count) { + switch ((data[index] & 0xe0000000) >> 29) { + case 0x0: + index += decode_mi(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x2: + index += decode_2d(data + index, count - index, + hw_offset + index * 4, &failures); + break; + case 0x3: + if (IS_965(devid)) { + index += decode_3d_965(data + index, count - index, + hw_offset + index * 4, &failures); + } else { + index += decode_3d(data + index, count - index, + hw_offset + index * 4, &failures); + } + break; + default: + instr_out(data, hw_offset, index, "UNKNOWN\n"); + failures++; + index++; + break; + } + fflush(out); + } + + return failures; +} + +void intel_decode_context_reset(void) +{ + saved_s2_set = 0; + saved_s4_set = 1; +} + diff --git a/src/mesa/drivers/dri/intel/intel_decode.h b/src/mesa/drivers/dri/intel/intel_decode.h new file mode 100644 index 0000000000..c50644a46b --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_decode.h @@ -0,0 +1,29 @@ +/* + * Copyright © 2007 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Eric Anholt + * + */ + +int intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid); +void intel_decode_context_reset(void); -- cgit v1.2.3 From d99f6c4a2aa8207a2fbacd9b3a5ec87dd25ba496 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 28 Sep 2007 10:11:52 -0700 Subject: Go back to using old drm_i915_flip_t field name This field shouldn't have been renamed in the first place. Go back to using the old name so that the tree is backward and forward compatible again. --- src/mesa/drivers/dri/i915/intel_buffers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c index cb151ab94d..938bed6da7 100644 --- a/src/mesa/drivers/dri/i915/intel_buffers.c +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -50,7 +50,7 @@ #define DRM_VBLANK_FLIP 0x8000000 typedef struct drm_i915_flip { - int planes; + int pipes; } drm_i915_flip_t; #undef DRM_IOCTL_I915_FLIP @@ -287,7 +287,7 @@ intelWindowMoved(struct intel_context *intel) ((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % intel_fb->pf_num_pages) << 2; - flip.planes = 0x2; + flip.pipes = 0x2; } else { intel->sarea->pf_current_page = intel->sarea->pf_current_page & (0x3 << 2); @@ -295,7 +295,7 @@ intelWindowMoved(struct intel_context *intel) (intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) % intel_fb->pf_num_pages; - flip.planes = 0x1; + flip.pipes = 0x1; } drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); @@ -761,7 +761,7 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv) if (dPriv->numClipRects && intel_fb->pf_active) { drm_i915_flip_t flip; - flip.planes = intel_fb->pf_planes; + flip.pipes = intel_fb->pf_planes; ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip)); } -- cgit v1.2.3 From 6775c1e8ccc2c543d97eb273a342140a62d99aee Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 28 Sep 2007 16:06:01 -0600 Subject: Remove test for EXT_blend_logic_op in glGetString when determining GL version. EXT_blend_logic_op is slightly different from GL 1.1's RGBA logicop mode and does not have to be supported. Per conversation with Roland. --- src/mesa/main/extensions.c | 2 +- src/mesa/main/getstring.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 80dce56c0c..709499f730 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -309,6 +309,7 @@ _mesa_enable_imaging_extensions(GLcontext *ctx) { ctx->Extensions.ARB_imaging = GL_TRUE; ctx->Extensions.EXT_blend_color = GL_TRUE; + ctx->Extensions.EXT_blend_logic_op = GL_TRUE; ctx->Extensions.EXT_blend_minmax = GL_TRUE; ctx->Extensions.EXT_blend_subtract = GL_TRUE; ctx->Extensions.EXT_convolution = GL_TRUE; @@ -353,7 +354,6 @@ _mesa_enable_1_4_extensions(GLcontext *ctx) ctx->Extensions.ARB_window_pos = GL_TRUE; ctx->Extensions.EXT_blend_color = GL_TRUE; ctx->Extensions.EXT_blend_func_separate = GL_TRUE; - ctx->Extensions.EXT_blend_logic_op = GL_TRUE; ctx->Extensions.EXT_blend_minmax = GL_TRUE; ctx->Extensions.EXT_blend_subtract = GL_TRUE; ctx->Extensions.EXT_fog_coord = GL_TRUE; diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c index 973649da0d..c15f6a39bc 100644 --- a/src/mesa/main/getstring.c +++ b/src/mesa/main/getstring.c @@ -96,7 +96,6 @@ _mesa_GetString( GLenum name ) ctx->Extensions.ARB_window_pos && ctx->Extensions.EXT_blend_color && ctx->Extensions.EXT_blend_func_separate && - ctx->Extensions.EXT_blend_logic_op && ctx->Extensions.EXT_blend_minmax && ctx->Extensions.EXT_blend_subtract && ctx->Extensions.EXT_fog_coord && -- cgit v1.2.3 From 2a3e33865dd9a3d064a3c0af94ef11d4aa4a6ce4 Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Fri, 28 Sep 2007 18:42:21 -0600 Subject: add support for LDFLAGS env var --- bin/mklib | 30 ++++++++++++++++++------------ configs/default | 1 + progs/demos/Makefile | 12 ++++++------ progs/directfb/Makefile | 2 +- progs/egl/Makefile | 10 +++++----- progs/fbdev/Makefile | 2 +- progs/glsl/Makefile | 4 ++-- progs/miniglx/Makefile | 2 +- progs/osdemos/Makefile | 10 +++++----- progs/redbook/Makefile | 2 +- progs/samples/Makefile | 4 ++-- progs/slang/Makefile | 6 +++--- progs/tests/Makefile | 12 ++++++------ progs/tools/trace/Makefile | 2 +- progs/trivial/Makefile | 6 +++--- progs/vp/Makefile | 2 +- progs/xdemos/Makefile | 10 +++++----- src/egl/drivers/demo/Makefile | 2 +- src/egl/drivers/dri/Makefile | 2 +- src/egl/main/Makefile | 2 +- src/glu/mesa/Makefile | 2 +- src/glu/sgi/Makefile | 2 +- src/glut/beos/Makefile | 3 ++- src/glut/directfb/Makefile | 2 +- src/glut/fbdev/Makefile | 2 +- src/glut/ggi/Makefile | 2 +- src/glut/glx/Makefile | 2 +- src/glut/mini/Makefile | 2 +- src/glw/Makefile | 2 +- src/glx/mini/Makefile | 2 +- src/glx/x11/Makefile | 2 +- src/mesa/Makefile | 10 +++++----- src/mesa/drivers/beos/Makefile | 3 ++- src/mesa/drivers/dri/Makefile.template | 2 +- src/mesa/drivers/dri/glcore/Makefile | 3 ++- 35 files changed, 87 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/bin/mklib b/bin/mklib index 8ee8d8ce49..2bfd1b9e04 100755 --- a/bin/mklib +++ b/bin/mklib @@ -34,6 +34,7 @@ MINOR=0 PATCH="" DEPS="" LINK="" +LDFLAGS="" CPLUSPLUS=0 STATIC=0 DLOPEN=0 @@ -63,6 +64,7 @@ do echo ' -LDIR search in DIR for library dependencies' echo ' -linker L explicity specify the linker program to use (eg: gcc, g++)' echo ' Not observed on all systems at this time.' + echo ' -ldflags OPT specify any additional linker flags in OPT' echo ' -cplusplus link with C++ runtime' echo ' -static make a static library (default is dynamic/shared)' echo ' -dlopen make a shared library suitable for dynamic loading' @@ -94,6 +96,10 @@ do shift 1; LINK=$1 ;; + '-ldflags') + shift 1; + LDFLAGS=$1 + ;; -l*) DEPS="$DEPS $1" ;; @@ -215,7 +221,7 @@ case $ARCH in rm -f ${LIBNAME} # make lib - ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} # finish up FINAL_LIBS="${LIBNAME}" elif [ $STATIC = 1 ] ; then @@ -273,7 +279,7 @@ case $ARCH in rm -f ${LIBNAME}.so # make lib - ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} # make usual symlinks ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR} ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so @@ -345,10 +351,10 @@ case $ARCH in #echo "mklib: linker is" ${LINK} ${OPTS} if [ $NOPREFIX = 1 ] ; then rm -f ${LIBNAME} - ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} else rm -f ${LIBNAME}.${MAJOR} ${LIBNAME} - ${LINK} ${OPTS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.${MAJOR} ${OBJECTS} ${DEPS} ln -s ${LIBNAME}.${MAJOR} ${LIBNAME} fi FINAL_LIBS="${LIBNAME}.${MAJOR} ${LIBNAME}" @@ -372,7 +378,7 @@ case $ARCH in echo "mklib: Making FreeBSD shared library: " ${LIBNAME} OPTS="-shared" rm -f ${LIBNAME} - ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} FINAL_LIBS=${LIBNAME} elif [ $STATIC = 1 ] ; then STLIB="lib${LIBNAME}.a" @@ -386,7 +392,7 @@ case $ARCH in OPTS="-shared -Wl,-soname,${SHLIB}" echo "mklib: Making FreeBSD shared library: " ${SHLIB} rm -f ${SHLIB} - ${LINK} ${OPTS} -o ${SHLIB} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${SHLIB} ${OBJECTS} ${DEPS} ln -sf ${SHLIB} "lib${LIBNAME}.so" FINAL_LIBS="${SHLIB} lib${LIBNAME}.so" fi @@ -444,7 +450,7 @@ case $ARCH in fi echo "mklib: Making IRIX " ${ABI} " shared library: " ${LIBNAME} - ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} FINAL_LIBS=${LIBNAME} fi ;; @@ -520,9 +526,9 @@ case $ARCH in # On AIX a shared library is linked differently when # you want to dlopen the file if [ $DLOPEN = "1" ] ; then - cc -G ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + cc -G ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} else - cc ${OPTS} -o ${OFILE} ${OBJECTS} ${DEPS} + cc ${OPTS} ${LDFLAGS} -o ${OFILE} ${OBJECTS} ${DEPS} ar ${X64} -r ${LIBNAME} ${OFILE} fi @@ -604,7 +610,7 @@ case $ARCH in fi echo "mklib: Making Darwin shared library: " ${LIBNAME} - ${LINK} ${OPTS} -o ${LIBNAME} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME} ${OBJECTS} ${DEPS} ln -s ${LIBNAME} ${LINKNAME} FINAL_LIBS="${LIBNAME} ${LINKNAME}" fi @@ -681,7 +687,7 @@ case $ARCH in rm -f ${LIBNAME}.so.${MAJOR} rm -f ${LIBNAME}.so # make lib - ${LINK} ${OPTS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${LIBNAME}.so.${VERSION} ${OBJECTS} ${DEPS} # make usual symlinks ln -s ${LIBNAME}.so.${VERSION} ${LIBNAME}.so.${MAJOR} ln -s ${LIBNAME}.so.${MAJOR} ${LIBNAME}.so @@ -753,7 +759,7 @@ case $ARCH in rm -f ${LIBNAME}.a # make lib - ${LINK} ${OPTS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS} + ${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS} # make usual symlinks ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a # finish up diff --git a/configs/default b/configs/default index a7de3f813d..620445f684 100644 --- a/configs/default +++ b/configs/default @@ -20,6 +20,7 @@ CC = cc CXX = CC CFLAGS = -O CXXFLAGS = -O +LDFLAGS = GLU_CFLAGS = # Misc tools and flags diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 7bfcefd02d..4d9eb30b68 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -75,7 +75,7 @@ PROGS = \ # make executable from .c file: .c: $(LIB_DEP) readtex.o - $(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@ ##### TARGETS ##### @@ -119,35 +119,35 @@ extfuncs.h: $(TOP)/progs/util/extfuncs.h reflect: reflect.o showbuffer.o readtex.o - $(CC) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@ reflect.o: reflect.c showbuffer.h $(CC) -c -I$(INCDIR) $(CFLAGS) reflect.c shadowtex: shadowtex.o showbuffer.o - $(CC) shadowtex.o showbuffer.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) shadowtex.o showbuffer.o $(APP_LIB_DEPS) -o $@ shadowtex.o: shadowtex.c showbuffer.h $(CC) -c -I$(INCDIR) $(CFLAGS) shadowtex.c gloss: gloss.o trackball.o readtex.o - $(CC) gloss.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) gloss.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@ gloss.o: gloss.c trackball.h $(CC) -c -I$(INCDIR) $(CFLAGS) gloss.c engine: engine.o trackball.o readtex.o - $(CC) engine.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) engine.o trackball.o readtex.o $(APP_LIB_DEPS) -o $@ engine.o: engine.c trackball.h $(CC) -c -I$(INCDIR) $(CFLAGS) engine.c fslight: fslight.o - $(CC) fslight.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) fslight.o $(APP_LIB_DEPS) -o $@ fslight.o: fslight.c extfuncs.h $(CC) -c -I$(INCDIR) $(CFLAGS) fslight.c diff --git a/progs/directfb/Makefile b/progs/directfb/Makefile index 53b100a18d..e03680e516 100644 --- a/progs/directfb/Makefile +++ b/progs/directfb/Makefile @@ -22,7 +22,7 @@ PROGS = df_gears \ .SUFFIXES: .c .c: $(LIB_DEP) - $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@ ##### TARGETS ##### diff --git a/progs/egl/Makefile b/progs/egl/Makefile index 33447a9d57..07215604d3 100644 --- a/progs/egl/Makefile +++ b/progs/egl/Makefile @@ -25,35 +25,35 @@ default: $(PROGRAMS) demo1: demo1.o $(TOP)/$(LIB_DIR)/libEGL.so - $(CC) $(CFLAGS) demo1.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) demo1.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@ demo1.o: demo1.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include demo1.c demo2: demo2.o $(TOP)/$(LIB_DIR)/libEGL.so - $(CC) $(CFLAGS) demo2.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) demo2.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ demo2.o: demo2.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include demo2.c demo3: demo3.o $(TOP)/$(LIB_DIR)/libEGL.so - $(CC) $(CFLAGS) demo3.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) demo3.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ demo3.o: demo3.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include demo3.c eglinfo: eglinfo.o $(TOP)/$(LIB_DIR)/libEGL.so - $(CC) $(CFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@ eglinfo.o: eglinfo.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include eglinfo.c eglgears: eglgears.o $(TOP)/$(LIB_DIR)/libEGL.so - $(CC) $(CFLAGS) eglgears.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) eglgears.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@ eglgears.o: eglgears.c $(HEADERS) $(CC) -c $(CFLAGS) -I$(TOP)/include eglgears.c diff --git a/progs/fbdev/Makefile b/progs/fbdev/Makefile index 0a0c77906f..92bfd043c1 100644 --- a/progs/fbdev/Makefile +++ b/progs/fbdev/Makefile @@ -22,7 +22,7 @@ INCLUDES = \ .SUFFIXES: .c .c: - $(CC) $(INCLUDES) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@ .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@ diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index a9800c5414..8b44239b43 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -28,7 +28,7 @@ PROGS = \ # make executable from .c file: .c: $(LIB_DEP) - $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@ ##### TARGETS ##### @@ -64,7 +64,7 @@ points.c: extfuncs.h toyball.c: extfuncs.h texdemo1: texdemo1.o readtex.o - $(CC) -I$(INCDIR) $(CFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@ texdemo1.o: texdemo1.c readtex.h extfuncs.h $(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c diff --git a/progs/miniglx/Makefile b/progs/miniglx/Makefile index 7f1e162186..56cecf4081 100644 --- a/progs/miniglx/Makefile +++ b/progs/miniglx/Makefile @@ -27,7 +27,7 @@ INCLUDES = \ .SUFFIXES: .c .c: - $(CC) $(INCLUDES) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@ .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< -o $@ diff --git a/progs/osdemos/Makefile b/progs/osdemos/Makefile index f8cba9ee99..7e657744e3 100644 --- a/progs/osdemos/Makefile +++ b/progs/osdemos/Makefile @@ -26,7 +26,7 @@ PROGS = \ # make executable from .c file: .c: $(LIB_DEP) readtex.o - $(CC) -I$(INCDIR) $(CFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< readtex.o $(APP_LIB_DEPS) -o $@ ##### TARGETS ##### @@ -56,19 +56,19 @@ showbuffer.o: showbuffer.c showbuffer.h # special case: need the -lOSMesa library: osdemo: osdemo.c - $(CC) -I$(INCDIR) $(CFLAGS) osdemo.c $(OSMESA_LIBS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo.c $(OSMESA_LIBS) -o $@ # special case: need the -lOSMesa library: ostest1: ostest1.c - $(CC) -I$(INCDIR) $(CFLAGS) ostest1.c $(OSMESA_LIBS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) ostest1.c $(OSMESA_LIBS) -o $@ # another special case: need the -lOSMesa16 library: osdemo16: osdemo16.c - $(CC) -I$(INCDIR) $(CFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo16.c $(OSMESA16_LIBS) -o $@ # another special case: need the -lOSMesa32 library: osdemo32: osdemo32.c - $(CC) -I$(INCDIR) $(CFLAGS) osdemo32.c $(OSMESA32_LIBS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) osdemo32.c $(OSMESA32_LIBS) -o $@ diff --git a/progs/redbook/Makefile b/progs/redbook/Makefile index febc74441b..078f19125a 100644 --- a/progs/redbook/Makefile +++ b/progs/redbook/Makefile @@ -24,7 +24,7 @@ PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \ .SUFFIXES: .c .c: $(LIB_DEP) - $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@ diff --git a/progs/samples/Makefile b/progs/samples/Makefile index 063008dccf..8c99e8df25 100644 --- a/progs/samples/Makefile +++ b/progs/samples/Makefile @@ -18,7 +18,7 @@ PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \ .SUFFIXES: .c .c: $(LIB_DEP) - $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@ ##### TARGETS ##### @@ -27,7 +27,7 @@ default: $(PROGS) sphere: sphere.o readtex.o - $(CC) -I$(INCDIR) $(CFLAGS) sphere.o readtex.o $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) sphere.o readtex.o $(APP_LIB_DEPS) -o $@ sphere.o: sphere.c readtex.h $(CC) -c -I$(INCDIR) $(CFLAGS) sphere.c diff --git a/progs/slang/Makefile b/progs/slang/Makefile index 1c602ce49c..61db26d080 100644 --- a/progs/slang/Makefile +++ b/progs/slang/Makefile @@ -29,13 +29,13 @@ clean: # cltest: cltest.o framework.o $(LIB_DEP) - $(CC) cltest.o framework.o $(APP_LIB_DEPS) -o cltest + $(CC) $(LDFLAGS) cltest.o framework.o $(APP_LIB_DEPS) -o cltest sotest: sotest.o framework.o $(LIB_DEP) - $(CC) sotest.o framework.o $(APP_LIB_DEPS) -o sotest + $(CC) $(LDFLAGS) sotest.o framework.o $(APP_LIB_DEPS) -o sotest vstest: vstest.o framework.o $(LIB_DEP) - $(CC) vstest.o framework.o $(APP_LIB_DEPS) -o vstest + $(CC) $(LDFLAGS) vstest.o framework.o $(APP_LIB_DEPS) -o vstest # # objects diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 7d9f7b62ac..e8d0edda3a 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -103,7 +103,7 @@ clean: .SUFFIXES: .c .c: - $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@ + $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@ .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ @@ -124,31 +124,31 @@ arraytexture.o: arraytexture.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) arraytexture.c -o $@ afsmultiarb: afsmultiarb.o readtex.o - $(CC) $(CFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) afsmultiarb.o readtex.o $(LIBS) -o $@ afsmultiarb.o: afsmultiarb.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) afsmultiarb.c -o $@ drawbuffers: drawbuffers.o - $(CC) $(CFLAGS) drawbuffers.o $(LIBS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) drawbuffers.o $(LIBS) -o $@ drawbuffers.o: drawbuffers.c extfuncs.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) drawbuffers.c -o $@ texrect: texrect.o readtex.o - $(CC) $(CFLAGS) texrect.o readtex.o $(LIBS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@ texrect.o: texrect.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) texrect.c -o $@ bug_3195: bug_3195.o readtex.o - $(CC) $(CFLAGS) bug_3195.o readtex.o $(LIBS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) bug_3195.o readtex.o $(LIBS) -o $@ bug_3195.o: bug_3195.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) bug_3195.c -o $@ invert: invert.o readtex.o - $(CC) $(CFLAGS) invert.o readtex.o $(LIBS) -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@ invert.o: invert.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) invert.c -o $@ diff --git a/progs/tools/trace/Makefile b/progs/tools/trace/Makefile index 3f7bdcbc93..4b05fd87a5 100644 --- a/progs/tools/trace/Makefile +++ b/progs/tools/trace/Makefile @@ -17,7 +17,7 @@ default: $(TRACER) $(TRACER): $(OBJECTS) $(TOP)/bin/mklib -o $(TRACER) -noprefix -cplusplus \ - $(MKLIB_OPTIONS) $(OBJECTS) + -ldflags '$(LDFLAGS)' $(MKLIB_OPTIONS) $(OBJECTS) gltrace.cc: gltrace.py PYTHONPATH=$(TOP)/src/mesa/glapi python gltrace.py -f $(TOP)/src/mesa/glapi/gl_API.xml > gltrace.cc diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index 341c115c07..259e20aa57 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -88,7 +88,7 @@ UTIL_FILES = readtex.h readtex.c .SUFFIXES: .c .c: - $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@ + $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@ .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ @@ -115,13 +115,13 @@ getproclist.h: $(TOP)/src/mesa/glapi/gl_API.xml getprocaddress.c getprocaddress. texrect: texrect.o readtex.o - $(CC) texrect.o readtex.o $(LIBS) -o $@ + $(CC) $(LDFLAGS) texrect.o readtex.o $(LIBS) -o $@ texrect.o: texrect.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ invert: invert.o readtex.o - $(CC) invert.o readtex.o $(LIBS) -o $@ + $(CC) $(LDFLAGS) invert.o readtex.o $(LIBS) -o $@ invert.o: invert.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ diff --git a/progs/vp/Makefile b/progs/vp/Makefile index c3faeb5b60..4952a52fc9 100644 --- a/progs/vp/Makefile +++ b/progs/vp/Makefile @@ -26,7 +26,7 @@ INCLUDES = -I. -I$(TOP)/include -I../samples .SUFFIXES: .c .c: - $(CC) $(INCLUDES) $(CFLAGS) $< $(LIBS) -o $@ + $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@ .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile index ba83a7dda4..c585026ad3 100644 --- a/progs/xdemos/Makefile +++ b/progs/xdemos/Makefile @@ -38,7 +38,7 @@ PROGS = glthreads \ .SUFFIXES: .c .c: $(LIB_DEP) - $(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(APP_LIB_DEPS) -o $@ ##### TARGETS ##### @@ -53,10 +53,10 @@ clean: # special cases pbinfo: pbinfo.o pbutil.o - $(CC) pbinfo.o pbutil.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) pbinfo.o pbutil.o $(APP_LIB_DEPS) -o $@ pbdemo: pbdemo.o pbutil.o - $(CC) pbdemo.o pbutil.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) pbdemo.o pbutil.o $(APP_LIB_DEPS) -o $@ pbinfo.o: pbinfo.c pbutil.h $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) pbinfo.c @@ -68,13 +68,13 @@ pbutil.o: pbutil.c pbutil.h $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) pbutil.c glxgears_fbconfig: glxgears_fbconfig.o pbutil.o - $(CC) glxgears_fbconfig.o pbutil.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) glxgears_fbconfig.o pbutil.o $(APP_LIB_DEPS) -o $@ glxgears_fbconfig.o: glxgears_fbconfig.c pbutil.h $(CC) -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) -c -I. $(CFLAGS) glxgears_fbconfig.c xrotfontdemo: xrotfontdemo.o xuserotfont.o - $(CC) xrotfontdemo.o xuserotfont.o $(APP_LIB_DEPS) -o $@ + $(CC) $(LDFLAGS) xrotfontdemo.o xuserotfont.o $(APP_LIB_DEPS) -o $@ xuserotfont.o: xuserotfont.c xuserotfont.h $(CC) -c -I. -I$(INCDIR) $(X11_INCLUDES) $(CFLAGS) xuserotfont.c diff --git a/src/egl/drivers/demo/Makefile b/src/egl/drivers/demo/Makefile index 5c05633df5..ad2ef38a72 100644 --- a/src/egl/drivers/demo/Makefile +++ b/src/egl/drivers/demo/Makefile @@ -21,7 +21,7 @@ default: $(TOP)/$(LIB_DIR)/demodriver.so $(TOP)/$(LIB_DIR)/demodriver.so: $(OBJECTS) - $(TOP)/bin/mklib -o demodriver.so -noprefix \ + $(TOP)/bin/mklib -o demodriver.so -noprefix -ldflags '$(LDFLAGS)' \ -install $(TOP)/$(LIB_DIR) $(OBJECTS) diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile index cb11971c64..0214cf65a2 100644 --- a/src/egl/drivers/dri/Makefile +++ b/src/egl/drivers/dri/Makefile @@ -42,7 +42,7 @@ default: depend library Makefile library: $(TOP)/$(LIB_DIR)/libEGLdri.so $(TOP)/$(LIB_DIR)/libEGLdri.so: $(OBJECTS) - $(TOP)/bin/mklib -o EGLdri -major 1 -minor 0 \ + $(TOP)/bin/mklib -o EGLdri -ldflags '$(LDFLAGS)' -major 1 -minor 0 \ -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS) diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index 431eda4197..2a7046fb14 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -46,7 +46,7 @@ default: depend library library: $(TOP)/$(LIB_DIR)/libEGL.so $(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS) - $(TOP)/bin/mklib -o EGL -major 1 -minor 0 \ + $(TOP)/bin/mklib -o EGL -ldflags '$(LDFLAGS)' -major 1 -minor 0 \ -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS) diff --git a/src/glu/mesa/Makefile b/src/glu/mesa/Makefile index 611d7a630c..fb377555be 100644 --- a/src/glu/mesa/Makefile +++ b/src/glu/mesa/Makefile @@ -45,7 +45,7 @@ $(TOP)/$(LIB_DIR): # Make the library: $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME): $(OBJECTS) - @ $(TOP)/bin/mklib -o $(GLU_LIB) -linker '$(CC)' \ + @ $(TOP)/bin/mklib -o $(GLU_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLU_MAJOR) -minor $(GLU_MINOR) -patch $(GLU_TINY) \ $(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \ $(GLU_LIB_DEPS) $(OBJECTS) diff --git a/src/glu/sgi/Makefile b/src/glu/sgi/Makefile index 2ce6ac0430..bb1c0a8aba 100644 --- a/src/glu/sgi/Makefile +++ b/src/glu/sgi/Makefile @@ -136,7 +136,7 @@ $(TOP)/$(LIB_DIR): # Make the library: $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME): $(OBJECTS) - $(TOP)/bin/mklib -o $(GLU_LIB) -linker '$(CXX)' \ + $(TOP)/bin/mklib -o $(GLU_LIB) -linker '$(CXX)' -ldflags '$(LDFLAGS)' \ -major $(GLU_MAJOR) -minor $(GLU_MINOR) -patch $(GLU_TINY) \ -cplusplus $(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \ $(GLU_LIB_DEPS) $(OBJECTS) diff --git a/src/glut/beos/Makefile b/src/glut/beos/Makefile index 3ff928bfd7..165f43a6ce 100644 --- a/src/glut/beos/Makefile +++ b/src/glut/beos/Makefile @@ -83,7 +83,8 @@ $(TOP)/$(LIB_DIR): # Make the library $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) - @$(TOP)/bin/mklib -o $(GLUT_LIB) -major $(GLUT_MAJOR) -minor $(GLUT_MINOR) -patch $(GLUT_TINY) \ + @$(TOP)/bin/mklib -o $(GLUT_LIB) -ldflags '$(LDFLAGS)' \ + -major $(GLUT_MAJOR) -minor $(GLUT_MINOR) -patch $(GLUT_TINY) \ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) $(GLUT_LIB_DEPS) \ $(OBJECTS) diff --git a/src/glut/directfb/Makefile b/src/glut/directfb/Makefile index 3791b16df8..aa77db91c6 100644 --- a/src/glut/directfb/Makefile +++ b/src/glut/directfb/Makefile @@ -61,7 +61,7 @@ default: depend $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) # Make the library $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) - $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLUT_MAJOR) -minor $(GLUT_MINOR) -patch $(GLUT_TINY) \ $(GLUT_LIB_DEPS) -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(OBJECTS) diff --git a/src/glut/fbdev/Makefile b/src/glut/fbdev/Makefile index d84d52ec48..948be0c7ba 100644 --- a/src/glut/fbdev/Makefile +++ b/src/glut/fbdev/Makefile @@ -63,7 +63,7 @@ default: depend $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) # Make the library $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) - $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLUT_MAJOR) -minor $(GLUT_MINOR) -patch $(GLUT_TINY) \ $(GLUT_LIB_DEPS) -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(OBJECTS) diff --git a/src/glut/ggi/Makefile b/src/glut/ggi/Makefile index 1bef6c23a3..c8805c27c0 100644 --- a/src/glut/ggi/Makefile +++ b/src/glut/ggi/Makefile @@ -32,7 +32,7 @@ default: $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) # Make the library $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) - $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLUT_MAJOR) -minor $(GLUT_MINOR) \ -patch $(GLUT_TINY) $(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \ $(GLUT_LIB_DEPS) $(OBJECTS) diff --git a/src/glut/glx/Makefile b/src/glut/glx/Makefile index f73158ad38..9f995667b4 100644 --- a/src/glut/glx/Makefile +++ b/src/glut/glx/Makefile @@ -91,7 +91,7 @@ default: $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) # Make the library $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) - $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLUT_MAJOR) -minor $(GLUT_MINOR) -patch $(GLUT_TINY) \ $(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \ $(GLUT_LIB_DEPS) $(OBJECTS) diff --git a/src/glut/mini/Makefile b/src/glut/mini/Makefile index 177bfe2d2b..87ff43ce56 100644 --- a/src/glut/mini/Makefile +++ b/src/glut/mini/Makefile @@ -55,7 +55,7 @@ default: depend $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) # Make the library $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME): depend $(OBJECTS) - $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GLUT_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GLUT_MAJOR) -minor $(GLUT_MINOR) -patch $(GLUT_TINY) \ $(GLUT_LIB_DEPS) -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(OBJECTS) diff --git a/src/glw/Makefile b/src/glw/Makefile index c32fc0ccad..727c5838be 100644 --- a/src/glw/Makefile +++ b/src/glw/Makefile @@ -48,7 +48,7 @@ clean: # Make the library $(TOP)/$(LIB_DIR)/$(GLW_LIB_NAME): $(OBJECTS) - $(TOP)/bin/mklib -o $(GLW_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GLW_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(MAJOR) -minor $(MINOR) -patch $(TINY) \ $(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \ $(GLW_LIB_DEPS) $(OBJECTS) diff --git a/src/glx/mini/Makefile b/src/glx/mini/Makefile index 71f085d5cd..96750d2c24 100644 --- a/src/glx/mini/Makefile +++ b/src/glx/mini/Makefile @@ -49,7 +49,7 @@ default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/miniglx.conf # Make libGL $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) Makefile - @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \ + @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major 1 -minor 2 $(MKLIB_OPTIONS) \ -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS) \ $(LIBDRM_LIB) $(PCIACCESS_LIB) diff --git a/src/glx/x11/Makefile b/src/glx/x11/Makefile index 296747e0dd..9f0943a146 100644 --- a/src/glx/x11/Makefile +++ b/src/glx/x11/Makefile @@ -64,7 +64,7 @@ default: depend $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) # Make libGL $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) Makefile - $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \ + $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major 1 -minor 2 $(MKLIB_OPTIONS) \ -install $(TOP)/$(LIB_DIR) $(GL_LIB_DEPS) $(OBJECTS) diff --git a/src/mesa/Makefile b/src/mesa/Makefile index c05b195957..a47cd4c023 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -65,7 +65,7 @@ linux-solo: depend subdirs libmesa.a # Stand-alone Mesa libGL, no built-in drivers (DirectFB) libgl-core: $(CORE_OBJECTS) - @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \ + @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS) \ -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) $(CORE_OBJECTS) \ $(GL_LIB_DEPS) @@ -78,7 +78,7 @@ directfb: depend subdirs libgl-core # fbdev Mesa driver (libGL.so) fbdev: $(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) $(COMMON_DRIVER_OBJECTS) - @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \ + @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ $(CORE_OBJECTS) $(FBDEV_DRIVER_OBJECTS) \ @@ -111,7 +111,7 @@ osmesa-only: depend subdirs $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME) # Make the GL library $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) - @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' \ + @ $(TOP)/bin/mklib -o $(GL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) \ $(MKLIB_OPTIONS) $(GL_LIB_DEPS) $(STAND_ALONE_OBJECTS) @@ -120,13 +120,13 @@ $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(STAND_ALONE_OBJECTS) $(TOP)/$(LIB_DIR)/$(OSMESA_LIB_NAME): $(OSMESA_DRIVER_OBJECTS) $(OSMESA16_OBJECTS) @ if [ "${DRIVER_DIRS}" = "osmesa" ] ; then \ $(TOP)/bin/mklib -o $(OSMESA_LIB) -linker '$(CC)' \ - -major $(MESA_MAJOR) \ + -ldflags '$(LDFLAGS)' -major $(MESA_MAJOR) \ -minor $(MESA_MINOR) -patch $(MESA_TINY) \ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ $(OSMESA_LIB_DEPS) $(OSMESA16_OBJECTS) ; \ else \ $(TOP)/bin/mklib -o $(OSMESA_LIB) -linker '$(CC)' \ - -major $(MESA_MAJOR) \ + -ldflags '$(LDFLAGS)' -major $(MESA_MAJOR) \ -minor $(MESA_MINOR) -patch $(GL_TINY) \ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ $(OSMESA_LIB_DEPS) $(OSMESA_DRIVER_OBJECTS) ; \ diff --git a/src/mesa/drivers/beos/Makefile b/src/mesa/drivers/beos/Makefile index 1897d6aa3e..9c7d6affc3 100644 --- a/src/mesa/drivers/beos/Makefile +++ b/src/mesa/drivers/beos/Makefile @@ -179,7 +179,8 @@ $(TOP)/$(LIB_DIR): mkdir $(TOP)/$(LIB_DIR) $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME): $(OBJECTS) $(MESA_MODULES) $(GLU_MODULES) - @$(TOP)/bin/mklib -o $(GL_LIB) -install $(TOP)/$(LIB_DIR) -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ + @$(TOP)/bin/mklib -o $(GL_LIB) -ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \ + -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \ $(MKLIB_OPTIONS) $(GL_LIB_DEPS) $(OBJECTS) $(MESA_MODULES) $(GLU_MODULES) # $(GLU_OBJECTS): diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 770b19e161..3abce004c9 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -70,7 +70,7 @@ default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template - $(TOP)/bin/mklib -noprefix -o $@ \ + $(TOP)/bin/mklib -ldflags '$(LDFLAGS)' -noprefix -o $@ \ $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) diff --git a/src/mesa/drivers/dri/glcore/Makefile b/src/mesa/drivers/dri/glcore/Makefile index a9e96970fa..968190acfc 100644 --- a/src/mesa/drivers/dri/glcore/Makefile +++ b/src/mesa/drivers/dri/glcore/Makefile @@ -61,7 +61,8 @@ default: depend $(TOP)/$(LIB_DIR)/$(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile - CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(LIBNAME) -noprefix -install $(TOP)/$(LIB_DIR) \ + CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(LIBNAME) -noprefix \ + -ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \ $(OBJECTS) $(WINLIB) $(LIB_DEPS) $(WINOBJ) $(MESA_MODULES) -- cgit v1.2.3 From 4f96000e294fa0d6ba6f5915ff508017d9c26d50 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Sat, 29 Sep 2007 18:14:06 +0200 Subject: r200: Implement SetTexOffset hook. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implementation guidance by Michel Dänzer, final testing by Timo Aaltonen. --- src/mesa/drivers/dri/r200/r200_context.h | 1 + src/mesa/drivers/dri/r200/r200_tex.h | 4 ++ src/mesa/drivers/dri/r200/r200_texmem.c | 5 +- src/mesa/drivers/dri/r200/r200_texstate.c | 94 ++++++++++++++++++++--------- src/mesa/drivers/dri/radeon/radeon_screen.c | 4 +- 5 files changed, 76 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index bec09e8ef6..c80180bdbc 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -179,6 +179,7 @@ struct r200_tex_obj { drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; /* Six, for the cube faces */ + GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ GLuint pp_txfilter; /* hardware register values */ GLuint pp_txformat; diff --git a/src/mesa/drivers/dri/r200/r200_tex.h b/src/mesa/drivers/dri/r200/r200_tex.h index e6c0e00eb0..10ff8e8a66 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.h +++ b/src/mesa/drivers/dri/r200/r200_tex.h @@ -35,6 +35,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __R200_TEX_H__ #define __R200_TEX_H__ +extern void r200SetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, + GLuint pitch); + extern void r200UpdateTextureState( GLcontext *ctx ); extern int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ); diff --git a/src/mesa/drivers/dri/r200/r200_texmem.c b/src/mesa/drivers/dri/r200/r200_texmem.c index d926313d57..183c4ca424 100644 --- a/src/mesa/drivers/dri/r200/r200_texmem.c +++ b/src/mesa/drivers/dri/r200/r200_texmem.c @@ -181,7 +181,8 @@ static void r200UploadRectSubImage( r200ContextPtr rmesa, /* In this case, could also use GART texturing. This is * currently disabled, but has been tested & works. */ - t->pp_txoffset = r200GartOffsetFromVirtual( rmesa, texImage->Data ); + if ( !t->image_override ) + t->pp_txoffset = r200GartOffsetFromVirtual( rmesa, texImage->Data ); t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32; if (R200_DEBUG & DEBUG_TEXTURE) @@ -467,7 +468,7 @@ int r200UploadTexImages( r200ContextPtr rmesa, r200TexObjPtr t, GLuint face ) t->base.firstLevel, t->base.lastLevel ); } - if ( !t || t->base.totalSize == 0 ) + if ( !t || t->base.totalSize == 0 || t->image_override ) return 0; if (R200_DEBUG & DEBUG_SYNC) { diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index ae02ec4b63..93c0fb7a65 100644 --- a/src/mesa/drivers/dri/r200/r200_texstate.c +++ b/src/mesa/drivers/dri/r200/r200_texstate.c @@ -37,6 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "context.h" #include "macros.h" #include "texformat.h" +#include "texobj.h" #include "enums.h" #include "r200_context.h" @@ -72,10 +73,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ && (tx_table_le[f].format != 0xffffffff) ) -static const struct { +struct tx_table { GLuint format, filter; -} -tx_table_be[] = +}; + +static const struct tx_table tx_table_be[] = { [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 }, _ALPHA_REV(RGBA8888), @@ -104,16 +106,13 @@ tx_table_be[] = _ALPHA(RGBA_DXT5), }; -static const struct { - GLuint format, filter; -} -tx_table_le[] = +static const struct tx_table tx_table_le[] = { _ALPHA(RGBA8888), [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 }, _ALPHA(ARGB8888), _ALPHA_REV(ARGB8888), - _INVALID(RGB888), + [ MESA_FORMAT_RGB888 ] = { R200_TXFORMAT_ARGB8888, 0 }, _COLOR(RGB565), _COLOR_REV(RGB565), _ALPHA(ARGB4444), @@ -160,30 +159,23 @@ static void r200SetTexImages( r200ContextPtr rmesa, GLint i, texelBytes; GLint numLevels; GLint log2Width, log2Height, log2Depth; - const GLuint ui = 1; - const GLubyte littleEndian = *((const GLubyte *) &ui); /* Set the hardware texture format */ + if ( !t->image_override ) { + if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { + t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | + R200_TXFORMAT_ALPHA_IN_MAP); + t->pp_txfilter &= ~R200_YUV_TO_RGB; - t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | - R200_TXFORMAT_ALPHA_IN_MAP); - t->pp_txfilter &= ~R200_YUV_TO_RGB; - - if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { - if (littleEndian) { t->pp_txformat |= tx_table_le[ baseImage->TexFormat->MesaFormat ].format; t->pp_txfilter |= tx_table_le[ baseImage->TexFormat->MesaFormat ].filter; } else { - t->pp_txformat |= tx_table_be[ baseImage->TexFormat->MesaFormat ].format; - t->pp_txfilter |= tx_table_be[ baseImage->TexFormat->MesaFormat ].filter; + _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); + return; } } - else { - _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); - return; - } texelBytes = baseImage->TexFormat->TexelBytes; @@ -380,11 +372,13 @@ static void r200SetTexImages( r200ContextPtr rmesa, * requires 64-byte aligned pitches, and we may/may not need the * blitter. NPOT only! */ - if (baseImage->IsCompressed) - t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); - else - t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); - t->pp_txpitch -= 32; + if ( !t->image_override ) { + if (baseImage->IsCompressed) + t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); + else + t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); + t->pp_txpitch -= 32; + } t->dirty_state = TEX_ALL; @@ -979,6 +973,46 @@ static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit, int slot, GLuin return GL_TRUE; } +void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch) +{ + r200ContextPtr rmesa = + (r200ContextPtr) ((__DRIcontextPrivate *) pDRICtx->private)-> + driverPrivate; + struct gl_texture_object *tObj = + _mesa_lookup_texture(rmesa->glCtx, texname); + r200TexObjPtr t; + + if (!tObj) + return; + + t = (r200TexObjPtr) tObj->DriverData; + + t->image_override = GL_TRUE; + + if (!offset) + return; + + t->pp_txoffset = offset; + t->pp_txpitch = pitch - 32; + + switch (depth) { + case 32: + t->pp_txformat = tx_table_le[2].format; + t->pp_txfilter |= tx_table_le[2].filter; + break; + case 24: + default: + t->pp_txformat = tx_table_le[4].format; + t->pp_txfilter |= tx_table_le[4].filter; + break; + case 16: + t->pp_txformat = tx_table_le[5].format; + t->pp_txfilter |= tx_table_le[5].filter; + break; + } +} + #define REF_COLOR 1 #define REF_ALPHA 2 @@ -1560,7 +1594,7 @@ static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) R200_FIREVERTICES( rmesa ); r200SetTexImages( rmesa, tObj ); r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); - if ( !t->base.memBlock ) + if ( !t->base.memBlock && !t->image_override ) return GL_FALSE; } @@ -1668,7 +1702,9 @@ static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) R200_FIREVERTICES( rmesa ); r200SetTexImages( rmesa, tObj ); r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); - if ( !t->base.memBlock && !rmesa->prefer_gart_client_texturing ) + if ( !t->base.memBlock && + !t->image_override && + !rmesa->prefer_gart_client_texturing ) return GL_FALSE; } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index aa7fb633dd..682cf3a5ee 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -53,6 +53,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" #include "r200_ioctl.h" #include "r200_span.h" +#include "r200_tex.h" #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) #include "r300_context.h" #include "r300_fragprog.h" @@ -973,7 +974,8 @@ static const struct __DriverAPIRec r200API = { .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, - .CopySubBuffer = r200CopySubBuffer + .CopySubBuffer = r200CopySubBuffer, + .setTexOffset = r200SetTexOffset }; #endif -- cgit v1.2.3 From f8ee72d98f2d23e034e90870ff6a760659a462a5 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 29 Sep 2007 12:01:34 -0600 Subject: fix VBO-split infinite loop (bug 12164) --- src/mesa/tnl/t_draw.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index 5b2b2ae549..46b8b536a2 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -368,7 +367,7 @@ void _tnl_draw_prims( GLcontext *ctx, _tnl_draw_prims ); return; } - else if (max_index >= max) { + else if (max_index > max) { /* The software TNL pipeline has a fixed amount of storage for * vertices and it is necessary to split incoming drawing commands * if they exceed that limit. -- cgit v1.2.3