diff options
Diffstat (limited to 'src/mesa/drivers/dri/common')
-rw-r--r-- | src/mesa/drivers/dri/common/dri_bufmgr.c | 535 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/dri_bufmgr.h | 103 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/dri_util.h | 42 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/drirenderbuffer.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/utils.c | 134 | ||||
-rw-r--r-- | src/mesa/drivers/dri/common/utils.h | 3 |
6 files changed, 734 insertions, 85 deletions
diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c new file mode 100644 index 0000000000..5747307f3b --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -0,0 +1,535 @@ +/************************************************************************** + * + * 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 <thomas-at-tungstengraphics-dot-com> + * Keith Whitwell <keithw-at-tungstengraphics-dot-com> + */ + +#include <xf86drm.h> +#include <stdlib.h> +#include "glthread.h" +#include "errno.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. + */ + + + +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; + /* user-space buffer: */ + unsigned userBuffer; + void *userData; + unsigned userSize; +} 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) +{ + unsigned ret; + + _glthread_LOCK_MUTEX(bmMutex); + ret = fence->fence.flags; + _glthread_UNLOCK_MUTEX(bmMutex); + + return ret; +} + + +DriFenceObject * +driFenceReference(DriFenceObject * fence) +{ + _glthread_LOCK_MUTEX(bmMutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(bmMutex); + return fence; +} + +void +driFenceUnReference(DriFenceObject * fence) +{ + if (!fence) + return; + + _glthread_LOCK_MUTEX(bmMutex); + if (--fence->refCount == 0) { + drmFenceDestroy(fence->fd, &fence->fence); + free(fence); + } + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driFenceFinish(DriFenceObject * fence, unsigned type, int lazy) +{ + 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); +} + +int +driFenceSignaled(DriFenceObject * fence, unsigned type) +{ + 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) +{ + struct _DriBufferPool *pool; + void *priv; + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + priv = buf->private; + _glthread_UNLOCK_MUTEX(buf->mutex); + + assert(priv != NULL); + BM_CKFATAL(buf->pool->waitIdle(pool, priv, lazy)); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + if (buf->userBuffer) { + return buf->userData; + } + else { + 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) +{ + if (!buf->userBuffer) { + 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) { + if (buf->private) + 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; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _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, DRM_BO_HINT_DONT_FENCE, + 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; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _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; + + assert(!buf->userBuffer); /* XXX just do a memcpy? */ + + _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) +{ + assert(!buf->userBuffer); /* XXX what to do? */ + + _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) +{ + 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; + } +} + +void +driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject **buffers, + void *ptr, unsigned bytes) +{ + const unsigned alignment = 1, flags = 0, hint = 0; + + driGenBuffers(pool, name, 1, buffers, alignment, flags, hint); + + (*buffers)->userBuffer = 1; + (*buffers)->userData = ptr; + (*buffers)->userSize = bytes; +} + + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + + +void +driBOCreateList(int target, drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOCreateList(target, list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driBOResetList(drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOResetList(list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, + unsigned flags, unsigned mask) +{ + 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); +} + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOValidateList(int fd, drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOValidateList(fd, list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h new file mode 100644 index 0000000000..ee4ce2cbde --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -0,0 +1,103 @@ +/************************************************************************** + * + * 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 <thomas-at-tungstengraphics-dot-com> + * Keith Whitwell <keithw-at-tungstengraphics-dot-com> + */ + +#ifndef _DRI_BUFMGR_H_ +#define _DRI_BUFMGR_H_ +#include <xf86drm.h> + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; + +extern struct _DriFenceObject *driFenceBuffers(int fd, char *name, + unsigned flags); + +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +extern void driFenceUnReference(struct _DriFenceObject *fence); + +extern void +driFenceFinish(struct _DriFenceObject *fence, unsigned type, int lazy); + +extern int driFenceSignaled(struct _DriFenceObject *fence, unsigned type); +extern unsigned driFenceType(struct _DriFenceObject *fence); + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +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); +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); +extern void driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, unsigned flags, unsigned hint); +extern void driGenUserBuffer(struct _DriBufferPool *pool, + const char *name, + struct _DriBufferObject *buffers[], + void *ptr, unsigned bytes); +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); + +#endif diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index c0e1bea5e0..0feb57b3c6 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -1,25 +1,3 @@ -/* $XFree86: xc/lib/GL/dri/dri_util.h,v 1.1 2002/02/22 21:32:52 dawes Exp $ */ -/** - * \file dri_util.h - * DRI utility functions definitions. - * - * This module acts as glue between GLX and the actual hardware driver. A DRI - * driver doesn't really \e have to use any of this - it's optional. But, some - * useful stuff is done here that otherwise would have to be duplicated in most - * drivers. - * - * Basically, these utility functions take care of some of the dirty details of - * screen initialization, context creation, context binding, DRM setup, etc. - * - * These functions are compiled into each DRI driver so libGL.so knows nothing - * about them. - * - * \sa dri_util.c. - * - * \author Kevin E. Martin <kevin@precisioninsight.com> - * \author Brian Paul <brian@precisioninsight.com> - */ - /* * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. @@ -45,6 +23,26 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/** + * \file dri_util.h + * DRI utility functions definitions. + * + * This module acts as glue between GLX and the actual hardware driver. A DRI + * driver doesn't really \e have to use any of this - it's optional. But, some + * useful stuff is done here that otherwise would have to be duplicated in most + * drivers. + * + * Basically, these utility functions take care of some of the dirty details of + * screen initialization, context creation, context binding, DRM setup, etc. + * + * These functions are compiled into each DRI driver so libGL.so knows nothing + * about them. + * + * \sa dri_util.c. + * + * \author Kevin E. Martin <kevin@precisioninsight.com> + * \author Brian Paul <brian@precisioninsight.com> + */ #ifndef _DRI_UTIL_H_ #define _DRI_UTIL_H_ diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.c b/src/mesa/drivers/dri/common/drirenderbuffer.c index b99bf2033b..15af99136c 100644 --- a/src/mesa/drivers/dri/common/drirenderbuffer.c +++ b/src/mesa/drivers/dri/common/drirenderbuffer.c @@ -209,6 +209,8 @@ driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv) struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate; if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) { ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h); + /* if the driver needs the hw lock for ResizeBuffers, the drawable + might have changed again by now */ assert(fb->Width == dPriv->w); assert(fb->Height == dPriv->h); } diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index 30c860b96c..2a1ded3871 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -310,8 +310,10 @@ void driInitSingleExtension( GLcontext * ctx, */ offset = _glapi_add_dispatch( functions, parameter_signature ); if (offset == -1) { +#if 0 /* this causes noise with egl */ fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed " "to add %s!\n", functions[0]); +#endif } else if (ext->functions[i].remap_index != -1) { driDispatchRemapTable[ ext->functions[i].remap_index ] = @@ -504,6 +506,9 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, * \c GLX_SWAP_UNDEFINED_OML. See the * GLX_OML_swap_method extension spec for more details. * \param num_db_modes Number of entries in \c db_modes. + * \param msaa_samples Array of msaa sample count. 0 represents a visual + * without a multisample buffer. + * \param num_msaa_modes Number of entries in \c msaa_samples. * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or * \c GLX_DIRECT_COLOR. * @@ -523,7 +528,8 @@ __DRIconfig ** driCreateConfigs(GLenum fb_format, GLenum fb_type, const uint8_t * depth_bits, const uint8_t * stencil_bits, unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes) + const GLenum * db_modes, unsigned num_db_modes, + const u_int8_t * msaa_samples, unsigned num_msaa_modes) { static const uint8_t bits_table[4][4] = { /* R G B A */ @@ -583,9 +589,7 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type, int index; __DRIconfig **configs, **c; __GLcontextModes *modes; - unsigned i; - unsigned j; - unsigned k; + unsigned i, j, k, h; unsigned num_modes; unsigned num_accum_bits = 2; @@ -658,7 +662,7 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type, break; } - num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits; + num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes; configs = _mesa_calloc((num_modes + 1) * sizeof *configs); if (configs == NULL) return NULL; @@ -666,66 +670,72 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type, c = configs; for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { for ( i = 0 ; i < num_db_modes ; i++ ) { - for ( j = 0 ; j < num_accum_bits ; j++ ) { - *c = _mesa_malloc (sizeof **c); - modes = &(*c)->modes; - c++; - - memset(modes, 0, sizeof *modes); - modes->redBits = bits[0]; - modes->greenBits = bits[1]; - modes->blueBits = bits[2]; - modes->alphaBits = bits[3]; - modes->redMask = masks[0]; - modes->greenMask = masks[1]; - modes->blueMask = masks[2]; - modes->alphaMask = masks[3]; - modes->rgbBits = modes->redBits + modes->greenBits - + modes->blueBits + modes->alphaBits; - - modes->accumRedBits = 16 * j; - modes->accumGreenBits = 16 * j; - modes->accumBlueBits = 16 * j; - modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; - modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; - - modes->stencilBits = stencil_bits[k]; - modes->depthBits = depth_bits[k]; - - modes->transparentPixel = GLX_NONE; - modes->transparentRed = GLX_DONT_CARE; - modes->transparentGreen = GLX_DONT_CARE; - modes->transparentBlue = GLX_DONT_CARE; - modes->transparentAlpha = GLX_DONT_CARE; - modes->transparentIndex = GLX_DONT_CARE; - modes->visualType = GLX_DONT_CARE; - modes->renderType = GLX_RGBA_BIT; - modes->drawableType = GLX_WINDOW_BIT; - modes->rgbMode = GL_TRUE; - - if ( db_modes[i] == GLX_NONE ) { - modes->doubleBufferMode = GL_FALSE; - } - else { - modes->doubleBufferMode = GL_TRUE; - modes->swapMethod = db_modes[i]; - } - - modes->haveAccumBuffer = ((modes->accumRedBits + + for ( h = 0 ; h < num_msaa_modes; h++ ) { + for ( j = 0 ; j < num_accum_bits ; j++ ) { + *c = _mesa_malloc (sizeof **c); + modes = &(*c)->modes; + c++; + + memset(modes, 0, sizeof *modes); + modes->redBits = bits[0]; + modes->greenBits = bits[1]; + modes->blueBits = bits[2]; + modes->alphaBits = bits[3]; + modes->redMask = masks[0]; + modes->greenMask = masks[1]; + modes->blueMask = masks[2]; + modes->alphaMask = masks[3]; + modes->rgbBits = modes->redBits + modes->greenBits + + modes->blueBits + modes->alphaBits; + + modes->accumRedBits = 16 * j; + modes->accumGreenBits = 16 * j; + modes->accumBlueBits = 16 * j; + modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; + modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; + + modes->stencilBits = stencil_bits[k]; + modes->depthBits = depth_bits[k]; + + modes->transparentPixel = GLX_NONE; + modes->transparentRed = GLX_DONT_CARE; + modes->transparentGreen = GLX_DONT_CARE; + modes->transparentBlue = GLX_DONT_CARE; + modes->transparentAlpha = GLX_DONT_CARE; + modes->transparentIndex = GLX_DONT_CARE; + modes->visualType = GLX_DONT_CARE; + modes->renderType = GLX_RGBA_BIT; + modes->drawableType = GLX_WINDOW_BIT; + modes->rgbMode = GL_TRUE; + + if ( db_modes[i] == GLX_NONE ) { + modes->doubleBufferMode = GL_FALSE; + } + else { + modes->doubleBufferMode = GL_TRUE; + modes->swapMethod = db_modes[i]; + } + + modes->samples = msaa_samples[h]; + modes->sampleBuffers = modes->samples ? 1 : 0; + + + modes->haveAccumBuffer = ((modes->accumRedBits + modes->accumGreenBits + modes->accumBlueBits + modes->accumAlphaBits) > 0); - modes->haveDepthBuffer = (modes->depthBits > 0); - modes->haveStencilBuffer = (modes->stencilBits > 0); - - modes->bindToTextureRgb = GL_TRUE; - modes->bindToTextureRgba = GL_TRUE; - modes->bindToMipmapTexture = GL_FALSE; - modes->bindToTextureTargets = modes->rgbMode ? - __DRI_ATTRIB_TEXTURE_1D_BIT | - __DRI_ATTRIB_TEXTURE_2D_BIT | - __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT : - 0; + modes->haveDepthBuffer = (modes->depthBits > 0); + modes->haveStencilBuffer = (modes->stencilBits > 0); + + modes->bindToTextureRgb = GL_TRUE; + modes->bindToTextureRgba = GL_TRUE; + modes->bindToMipmapTexture = GL_FALSE; + modes->bindToTextureTargets = modes->rgbMode ? + __DRI_ATTRIB_TEXTURE_1D_BIT | + __DRI_ATTRIB_TEXTURE_2D_BIT | + __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT : + 0; + } } } } diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h index 0c974dbff3..4e27bd21a1 100644 --- a/src/mesa/drivers/dri/common/utils.h +++ b/src/mesa/drivers/dri/common/utils.h @@ -131,7 +131,8 @@ extern __DRIconfig ** driCreateConfigs(GLenum fb_format, GLenum fb_type, const uint8_t * depth_bits, const uint8_t * stencil_bits, unsigned num_depth_stencil_bits, - const GLenum * db_modes, unsigned num_db_modes); + const GLenum * db_modes, unsigned num_db_modes, + const uint8_t * msaa_samples, unsigned num_msaa_modes); const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b); |