aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/api_arrayelt.c14
-rw-r--r--mesalib/src/mesa/main/api_loopback.c1
-rw-r--r--mesalib/src/mesa/main/api_loopback.h1
-rw-r--r--mesalib/src/mesa/main/api_validate.c7
-rw-r--r--mesalib/src/mesa/main/arrayobj.c12
-rw-r--r--mesalib/src/mesa/main/attrib.c1
-rw-r--r--mesalib/src/mesa/main/bufferobj.c443
-rw-r--r--mesalib/src/mesa/main/bufferobj.h23
-rw-r--r--mesalib/src/mesa/main/context.c114
-rw-r--r--mesalib/src/mesa/main/dd.h21
-rw-r--r--mesalib/src/mesa/main/dlist.c9
-rw-r--r--mesalib/src/mesa/main/drawpix.c4
-rw-r--r--mesalib/src/mesa/main/enable.c33
-rw-r--r--mesalib/src/mesa/main/errors.c487
-rw-r--r--mesalib/src/mesa/main/errors.h3
-rw-r--r--mesalib/src/mesa/main/execmem.c11
-rw-r--r--mesalib/src/mesa/main/extensions.c5
-rw-r--r--mesalib/src/mesa/main/fbobject.c22
-rw-r--r--mesalib/src/mesa/main/format_pack.c22
-rw-r--r--mesalib/src/mesa/main/format_unpack.c34
-rw-r--r--mesalib/src/mesa/main/formats.c16
-rw-r--r--mesalib/src/mesa/main/formats.h100
-rw-r--r--mesalib/src/mesa/main/framebuffer.c14
-rw-r--r--mesalib/src/mesa/main/get.c21
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py6
-rw-r--r--mesalib/src/mesa/main/getstring.c20
-rw-r--r--mesalib/src/mesa/main/glformats.c24
-rw-r--r--mesalib/src/mesa/main/hash.c45
-rw-r--r--mesalib/src/mesa/main/imports.h2
-rw-r--r--mesalib/src/mesa/main/mtypes.h94
-rw-r--r--mesalib/src/mesa/main/pbo.c22
-rw-r--r--mesalib/src/mesa/main/pipelineobj.c445
-rw-r--r--mesalib/src/mesa/main/pipelineobj.h95
-rw-r--r--mesalib/src/mesa/main/readpix.c4
-rw-r--r--mesalib/src/mesa/main/renderbuffer.c12
-rw-r--r--mesalib/src/mesa/main/samplerobj.c12
-rw-r--r--mesalib/src/mesa/main/shaderapi.c131
-rw-r--r--mesalib/src/mesa/main/shaderapi.h8
-rw-r--r--mesalib/src/mesa/main/shaderobj.c1
-rw-r--r--mesalib/src/mesa/main/shared.c22
-rw-r--r--mesalib/src/mesa/main/syncobj.c14
-rw-r--r--mesalib/src/mesa/main/texcompress_etc.c3
-rw-r--r--mesalib/src/mesa/main/texformat.c6
-rw-r--r--mesalib/src/mesa/main/texgetimage.c25
-rw-r--r--mesalib/src/mesa/main/teximage.c44
-rw-r--r--mesalib/src/mesa/main/teximage.h4
-rw-r--r--mesalib/src/mesa/main/texobj.c34
-rw-r--r--mesalib/src/mesa/main/texparam.c3
-rw-r--r--mesalib/src/mesa/main/texstore.c8
-rw-r--r--mesalib/src/mesa/main/uniform_query.cpp36
-rw-r--r--mesalib/src/mesa/main/uniforms.c393
-rw-r--r--mesalib/src/mesa/main/uniforms.h83
-rw-r--r--mesalib/src/mesa/main/vdpau.c9
-rw-r--r--mesalib/src/mesa/main/vdpau.h2
-rw-r--r--mesalib/src/mesa/main/version.c1
55 files changed, 2263 insertions, 763 deletions
diff --git a/mesalib/src/mesa/main/api_arrayelt.c b/mesalib/src/mesa/main/api_arrayelt.c
index 29a57c8e5..05cbc0f1f 100644
--- a/mesalib/src/mesa/main/api_arrayelt.c
+++ b/mesalib/src/mesa/main/api_arrayelt.c
@@ -1458,7 +1458,8 @@ _ae_destroy_context(struct gl_context *ctx)
static void
check_vbo(AEcontext *actx, struct gl_buffer_object *vbo)
{
- if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo)) {
+ if (_mesa_is_bufferobj(vbo) &&
+ !_mesa_bufferobj_mapped(vbo, MAP_INTERNAL)) {
GLuint i;
for (i = 0; i < actx->nr_vbos; i++)
if (actx->vbo[i] == vbo)
@@ -1633,7 +1634,8 @@ _ae_map_vbos(struct gl_context *ctx)
ctx->Driver.MapBufferRange(ctx, 0,
actx->vbo[i]->Size,
GL_MAP_READ_BIT,
- actx->vbo[i]);
+ actx->vbo[i],
+ MAP_INTERNAL);
if (actx->nr_vbos)
actx->mapped_vbos = GL_TRUE;
@@ -1655,7 +1657,7 @@ _ae_unmap_vbos(struct gl_context *ctx)
assert (!actx->NewState);
for (i = 0; i < actx->nr_vbos; i++)
- ctx->Driver.UnmapBuffer(ctx, actx->vbo[i]);
+ ctx->Driver.UnmapBuffer(ctx, actx->vbo[i], MAP_INTERNAL);
actx->mapped_vbos = GL_FALSE;
}
@@ -1701,7 +1703,8 @@ _ae_ArrayElement(GLint elt)
/* emit generic attribute elements */
for (at = actx->attribs; at->func; at++) {
const GLubyte *src
- = ADD_POINTERS(at->array->BufferObj->Pointer, at->array->Ptr)
+ = ADD_POINTERS(at->array->BufferObj->Mappings[MAP_INTERNAL].Pointer,
+ at->array->Ptr)
+ elt * at->array->StrideB;
at->func(at->index, src);
}
@@ -1709,7 +1712,8 @@ _ae_ArrayElement(GLint elt)
/* emit conventional arrays elements */
for (aa = actx->arrays; aa->offset != -1 ; aa++) {
const GLubyte *src
- = ADD_POINTERS(aa->array->BufferObj->Pointer, aa->array->Ptr)
+ = ADD_POINTERS(aa->array->BufferObj->Mappings[MAP_INTERNAL].Pointer,
+ aa->array->Ptr)
+ elt * aa->array->StrideB;
CALL_by_offset(disp, (array_func), aa->offset, ((const void *) src));
}
diff --git a/mesalib/src/mesa/main/api_loopback.c b/mesalib/src/mesa/main/api_loopback.c
index 8a04174c7..d10ae15ea 100644
--- a/mesalib/src/mesa/main/api_loopback.c
+++ b/mesalib/src/mesa/main/api_loopback.c
@@ -34,7 +34,6 @@
#include "api_loopback.h"
#include "mtypes.h"
#include "glapi/glapi.h"
-#include "glapi/glthread.h"
#include "main/dispatch.h"
#include "main/context.h"
diff --git a/mesalib/src/mesa/main/api_loopback.h b/mesalib/src/mesa/main/api_loopback.h
index 0b014ad5a..2195e01e3 100644
--- a/mesalib/src/mesa/main/api_loopback.h
+++ b/mesalib/src/mesa/main/api_loopback.h
@@ -32,7 +32,6 @@
#include "main/macros.h" // ?
#include "main/mtypes.h" // ?
#include "glapi/glapi.h" // ?
-#include "glapi/glthread.h" // ?
#include "main/dispatch.h" // ?
#include "main/context.h" // ?
diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c
index af469e046..f3fd1a475 100644
--- a/mesalib/src/mesa/main/api_validate.c
+++ b/mesalib/src/mesa/main/api_validate.c
@@ -69,7 +69,8 @@ _mesa_max_buffer_index(struct gl_context *ctx, GLuint count, GLenum type,
if (_mesa_is_bufferobj(elementBuf)) {
/* elements are in a user-defined buffer object. need to map it */
map = ctx->Driver.MapBufferRange(ctx, 0, elementBuf->Size,
- GL_MAP_READ_BIT, elementBuf);
+ GL_MAP_READ_BIT, elementBuf,
+ MAP_INTERNAL);
/* Actual address is the sum of pointers */
indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices);
}
@@ -92,7 +93,7 @@ _mesa_max_buffer_index(struct gl_context *ctx, GLuint count, GLenum type,
}
if (map) {
- ctx->Driver.UnmapBuffer(ctx, elementBuf);
+ ctx->Driver.UnmapBuffer(ctx, elementBuf, MAP_INTERNAL);
}
return max;
@@ -865,7 +866,7 @@ valid_draw_indirect(struct gl_context *ctx,
return GL_FALSE;
}
- if (_mesa_bufferobj_mapped(ctx->DrawIndirectBuffer)) {
+ if (_mesa_check_disallowed_mapping(ctx->DrawIndirectBuffer)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(DRAW_INDIRECT_BUFFER is mapped)", name);
return GL_FALSE;
diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c
index b33ba8016..efb993012 100644
--- a/mesalib/src/mesa/main/arrayobj.c
+++ b/mesalib/src/mesa/main/arrayobj.c
@@ -119,7 +119,7 @@ _mesa_delete_vao(struct gl_context *ctx, struct gl_vertex_array_object *obj)
{
unbind_array_object_vbos(ctx, obj);
_mesa_reference_buffer_object(ctx, &obj->IndexBufferObj, NULL);
- _glthread_DESTROY_MUTEX(obj->Mutex);
+ mtx_destroy(&obj->Mutex);
free(obj->Label);
free(obj);
}
@@ -142,7 +142,7 @@ _mesa_reference_vao_(struct gl_context *ctx,
GLboolean deleteFlag = GL_FALSE;
struct gl_vertex_array_object *oldObj = *ptr;
- _glthread_LOCK_MUTEX(oldObj->Mutex);
+ mtx_lock(&oldObj->Mutex);
ASSERT(oldObj->RefCount > 0);
oldObj->RefCount--;
#if 0
@@ -150,7 +150,7 @@ _mesa_reference_vao_(struct gl_context *ctx,
(void *) oldObj, oldObj->Name, oldObj->RefCount);
#endif
deleteFlag = (oldObj->RefCount == 0);
- _glthread_UNLOCK_MUTEX(oldObj->Mutex);
+ mtx_unlock(&oldObj->Mutex);
if (deleteFlag) {
ASSERT(ctx->Driver.DeleteArrayObject);
@@ -163,7 +163,7 @@ _mesa_reference_vao_(struct gl_context *ctx,
if (vao) {
/* reference new array object */
- _glthread_LOCK_MUTEX(vao->Mutex);
+ mtx_lock(&vao->Mutex);
if (vao->RefCount == 0) {
/* this array's being deleted (look just above) */
/* Not sure this can every really happen. Warn if it does. */
@@ -178,7 +178,7 @@ _mesa_reference_vao_(struct gl_context *ctx,
#endif
*ptr = vao;
}
- _glthread_UNLOCK_MUTEX(vao->Mutex);
+ mtx_unlock(&vao->Mutex);
}
}
@@ -226,7 +226,7 @@ _mesa_initialize_vao(struct gl_context *ctx,
obj->Name = name;
- _glthread_INIT_MUTEX(obj->Mutex);
+ mtx_init(&obj->Mutex, mtx_plain);
obj->RefCount = 1;
/* Init the individual arrays */
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index 004528044..5a626f2f4 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -1457,6 +1457,7 @@ copy_array_object(struct gl_context *ctx,
/* _Enabled must be the same than on push */
dest->_Enabled = src->_Enabled;
+ dest->NewArrays = src->NewArrays;
dest->_MaxElement = src->_MaxElement;
}
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 966e61c4c..c4417c922 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -207,11 +207,12 @@ static bool
bufferobj_range_mapped(const struct gl_buffer_object *obj,
GLintptr offset, GLsizeiptr size)
{
- if (_mesa_bufferobj_mapped(obj)) {
+ if (_mesa_bufferobj_mapped(obj, MAP_USER)) {
const GLintptr end = offset + size;
- const GLintptr mapEnd = obj->Offset + obj->Length;
+ const GLintptr mapEnd = obj->Mappings[MAP_USER].Offset +
+ obj->Mappings[MAP_USER].Length;
- if (!(end <= obj->Offset || offset >= mapEnd)) {
+ if (!(end <= obj->Mappings[MAP_USER].Offset || offset >= mapEnd)) {
return true;
}
}
@@ -269,6 +270,9 @@ buffer_object_subdata_range_good(struct gl_context * ctx, GLenum target,
return NULL;
}
+ if (bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_PERSISTENT_BIT)
+ return bufObj;
+
if (mappedRange) {
if (bufferobj_range_mapped(bufObj, offset, size)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
@@ -276,7 +280,7 @@ buffer_object_subdata_range_good(struct gl_context * ctx, GLenum target,
}
}
else {
- if (_mesa_bufferobj_mapped(bufObj)) {
+ if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
return NULL;
}
@@ -413,7 +417,7 @@ _mesa_delete_buffer_object(struct gl_context *ctx,
bufObj->RefCount = -1000;
bufObj->Name = ~0;
- _glthread_DESTROY_MUTEX(bufObj->Mutex);
+ mtx_destroy(&bufObj->Mutex);
free(bufObj->Label);
free(bufObj);
}
@@ -435,7 +439,7 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
GLboolean deleteFlag = GL_FALSE;
struct gl_buffer_object *oldObj = *ptr;
- _glthread_LOCK_MUTEX(oldObj->Mutex);
+ mtx_lock(&oldObj->Mutex);
ASSERT(oldObj->RefCount > 0);
oldObj->RefCount--;
#if 0
@@ -443,7 +447,7 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
(void *) oldObj, oldObj->Name, oldObj->RefCount);
#endif
deleteFlag = (oldObj->RefCount == 0);
- _glthread_UNLOCK_MUTEX(oldObj->Mutex);
+ mtx_unlock(&oldObj->Mutex);
if (deleteFlag) {
@@ -465,7 +469,7 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
if (bufObj) {
/* reference new buffer */
- _glthread_LOCK_MUTEX(bufObj->Mutex);
+ mtx_lock(&bufObj->Mutex);
if (bufObj->RefCount == 0) {
/* this buffer's being deleted (look just above) */
/* Not sure this can every really happen. Warn if it does. */
@@ -480,7 +484,7 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
#endif
*ptr = bufObj;
}
- _glthread_UNLOCK_MUTEX(bufObj->Mutex);
+ mtx_unlock(&bufObj->Mutex);
}
}
@@ -496,11 +500,10 @@ _mesa_initialize_buffer_object( struct gl_context *ctx,
(void) target;
memset(obj, 0, sizeof(struct gl_buffer_object));
- _glthread_INIT_MUTEX(obj->Mutex);
+ mtx_init(&obj->Mutex, mtx_plain);
obj->RefCount = 1;
obj->Name = name;
obj->Usage = GL_STATIC_DRAW_ARB;
- obj->AccessFlags = 0;
}
@@ -555,21 +558,21 @@ _mesa_total_buffer_object_memory(struct gl_context *ctx)
*/
GLboolean
_mesa_buffer_data( struct gl_context *ctx, GLenum target, GLsizeiptrARB size,
- const GLvoid * data, GLenum usage,
+ const GLvoid * data, GLenum usage, GLenum storageFlags,
struct gl_buffer_object * bufObj )
{
void * new_data;
(void) target;
- if (bufObj->Data)
- _mesa_align_free( bufObj->Data );
+ _mesa_align_free( bufObj->Data );
new_data = _mesa_align_malloc( size, ctx->Const.MinMapBufferAlignment );
if (new_data) {
bufObj->Data = (GLubyte *) new_data;
bufObj->Size = size;
bufObj->Usage = usage;
+ bufObj->StorageFlags = storageFlags;
if (data) {
memcpy( bufObj->Data, data, size );
@@ -672,33 +675,11 @@ _mesa_buffer_clear_subdata(struct gl_context *ctx,
GLsizeiptr i;
GLubyte *dest;
- if (_mesa_bufferobj_mapped(bufObj)) {
- GLubyte *data = malloc(size);
- GLubyte *dataStart = data;
- if (data == NULL) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data");
- return;
- }
-
- if (clearValue == NULL) {
- /* Clear with zeros, per the spec */
- memset(data, 0, size);
- }
- else {
- for (i = 0; i < size/clearValueSize; ++i) {
- memcpy(data, clearValue, clearValueSize);
- data += clearValueSize;
- }
- }
- ctx->Driver.BufferSubData(ctx, offset, size, dataStart, bufObj);
- return;
- }
-
ASSERT(ctx->Driver.MapBufferRange);
dest = ctx->Driver.MapBufferRange(ctx, offset, size,
GL_MAP_WRITE_BIT |
GL_MAP_INVALIDATE_RANGE_BIT,
- bufObj);
+ bufObj, MAP_INTERNAL);
if (!dest) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data");
@@ -708,7 +689,7 @@ _mesa_buffer_clear_subdata(struct gl_context *ctx,
if (clearValue == NULL) {
/* Clear with zeros, per the spec */
memset(dest, 0, size);
- ctx->Driver.UnmapBuffer(ctx, bufObj);
+ ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL);
return;
}
@@ -717,7 +698,7 @@ _mesa_buffer_clear_subdata(struct gl_context *ctx,
dest += clearValueSize;
}
- ctx->Driver.UnmapBuffer(ctx, bufObj);
+ ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL);
}
@@ -728,16 +709,17 @@ _mesa_buffer_clear_subdata(struct gl_context *ctx,
static void *
_mesa_buffer_map_range( struct gl_context *ctx, GLintptr offset,
GLsizeiptr length, GLbitfield access,
- struct gl_buffer_object *bufObj )
+ struct gl_buffer_object *bufObj,
+ gl_map_buffer_index index)
{
(void) ctx;
- assert(!_mesa_bufferobj_mapped(bufObj));
+ assert(!_mesa_bufferobj_mapped(bufObj, index));
/* Just return a direct pointer to the data */
- bufObj->Pointer = bufObj->Data + offset;
- bufObj->Length = length;
- bufObj->Offset = offset;
- bufObj->AccessFlags = access;
- return bufObj->Pointer;
+ bufObj->Mappings[index].Pointer = bufObj->Data + offset;
+ bufObj->Mappings[index].Length = length;
+ bufObj->Mappings[index].Offset = offset;
+ bufObj->Mappings[index].AccessFlags = access;
+ return bufObj->Mappings[index].Pointer;
}
@@ -748,7 +730,8 @@ _mesa_buffer_map_range( struct gl_context *ctx, GLintptr offset,
static void
_mesa_buffer_flush_mapped_range( struct gl_context *ctx,
GLintptr offset, GLsizeiptr length,
- struct gl_buffer_object *obj )
+ struct gl_buffer_object *obj,
+ gl_map_buffer_index index)
{
(void) ctx;
(void) offset;
@@ -766,14 +749,15 @@ _mesa_buffer_flush_mapped_range( struct gl_context *ctx,
* \sa glUnmapBufferARB, dd_function_table::UnmapBuffer
*/
GLboolean
-_mesa_buffer_unmap( struct gl_context *ctx, struct gl_buffer_object *bufObj )
+_mesa_buffer_unmap(struct gl_context *ctx, struct gl_buffer_object *bufObj,
+ gl_map_buffer_index index)
{
(void) ctx;
/* XXX we might assert here that bufObj->Pointer is non-null */
- bufObj->Pointer = NULL;
- bufObj->Length = 0;
- bufObj->Offset = 0;
- bufObj->AccessFlags = 0x0;
+ bufObj->Mappings[index].Pointer = NULL;
+ bufObj->Mappings[index].Length = 0;
+ bufObj->Mappings[index].Offset = 0;
+ bufObj->Mappings[index].AccessFlags = 0x0;
return GL_TRUE;
}
@@ -791,14 +775,11 @@ _mesa_copy_buffer_subdata(struct gl_context *ctx,
{
GLubyte *srcPtr, *dstPtr;
- /* the buffers should not be mapped */
- assert(!_mesa_bufferobj_mapped(src));
- assert(!_mesa_bufferobj_mapped(dst));
-
if (src == dst) {
srcPtr = dstPtr = ctx->Driver.MapBufferRange(ctx, 0, src->Size,
GL_MAP_READ_BIT |
- GL_MAP_WRITE_BIT, src);
+ GL_MAP_WRITE_BIT, src,
+ MAP_INTERNAL);
if (!srcPtr)
return;
@@ -807,10 +788,12 @@ _mesa_copy_buffer_subdata(struct gl_context *ctx,
dstPtr += writeOffset;
} else {
srcPtr = ctx->Driver.MapBufferRange(ctx, readOffset, size,
- GL_MAP_READ_BIT, src);
+ GL_MAP_READ_BIT, src,
+ MAP_INTERNAL);
dstPtr = ctx->Driver.MapBufferRange(ctx, writeOffset, size,
(GL_MAP_WRITE_BIT |
- GL_MAP_INVALIDATE_RANGE_BIT), dst);
+ GL_MAP_INVALIDATE_RANGE_BIT), dst,
+ MAP_INTERNAL);
}
/* Note: the src and dst regions will never overlap. Trying to do so
@@ -819,9 +802,9 @@ _mesa_copy_buffer_subdata(struct gl_context *ctx,
if (srcPtr && dstPtr)
memcpy(dstPtr, srcPtr, size);
- ctx->Driver.UnmapBuffer(ctx, src);
+ ctx->Driver.UnmapBuffer(ctx, src, MAP_INTERNAL);
if (dst != src)
- ctx->Driver.UnmapBuffer(ctx, dst);
+ ctx->Driver.UnmapBuffer(ctx, dst, MAP_INTERNAL);
}
@@ -835,7 +818,7 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
GLuint i;
memset(&DummyBufferObject, 0, sizeof(DummyBufferObject));
- _glthread_INIT_MUTEX(DummyBufferObject.Mutex);
+ mtx_init(&DummyBufferObject.Mutex, mtx_plain);
DummyBufferObject.RefCount = 1000*1000*1000; /* never delete */
_mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj,
@@ -955,10 +938,6 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer)
/* bind new buffer */
_mesa_reference_buffer_object(ctx, bindTarget, newBufObj);
-
- /* Pass BindBuffer call to device driver */
- if (ctx->Driver.BindBuffer)
- ctx->Driver.BindBuffer( ctx, target, newBufObj );
}
@@ -1023,7 +1002,6 @@ _mesa_init_buffer_object_functions(struct dd_function_table *driver)
/* GL_ARB_vertex/pixel_buffer_object */
driver->NewBufferObject = _mesa_new_buffer_object;
driver->DeleteBuffer = _mesa_delete_buffer_object;
- driver->BindBuffer = NULL;
driver->BufferData = _mesa_buffer_data;
driver->BufferSubData = _mesa_buffer_subdata;
driver->GetBufferSubData = _mesa_buffer_get_subdata;
@@ -1041,6 +1019,21 @@ _mesa_init_buffer_object_functions(struct dd_function_table *driver)
}
+void
+_mesa_buffer_unmap_all_mappings(struct gl_context *ctx,
+ struct gl_buffer_object *bufObj)
+{
+ int i;
+
+ for (i = 0; i < MAP_COUNT; i++) {
+ if (_mesa_bufferobj_mapped(bufObj, i)) {
+ ctx->Driver.UnmapBuffer(ctx, bufObj, i);
+ ASSERT(bufObj->Mappings[i].Pointer == NULL);
+ bufObj->Mappings[i].AccessFlags = 0;
+ }
+ }
+}
+
/**********************************************************************/
/* API Functions */
@@ -1077,7 +1070,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
return;
}
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
for (i = 0; i < n; i++) {
struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, ids[i]);
@@ -1087,12 +1080,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
ASSERT(bufObj->Name == ids[i] || bufObj == &DummyBufferObject);
- if (_mesa_bufferobj_mapped(bufObj)) {
- /* if mapped, unmap it now */
- ctx->Driver.UnmapBuffer(ctx, bufObj);
- bufObj->AccessFlags = 0;
- bufObj->Pointer = NULL;
- }
+ _mesa_buffer_unmap_all_mappings(ctx, bufObj);
/* unbind any vertex pointers bound to this buffer */
for (j = 0; j < Elements(vao->VertexBinding); j++) {
@@ -1169,7 +1157,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
}
}
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
@@ -1201,7 +1189,7 @@ _mesa_GenBuffers(GLsizei n, GLuint *buffer)
/*
* This must be atomic (generation and allocation of buffer object IDs)
*/
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
first = _mesa_HashFindFreeKeyBlock(ctx->Shared->BufferObjects, n);
@@ -1212,7 +1200,7 @@ _mesa_GenBuffers(GLsizei n, GLuint *buffer)
buffer[i] = first + i;
}
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
@@ -1230,15 +1218,73 @@ _mesa_IsBuffer(GLuint id)
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
bufObj = _mesa_lookup_bufferobj(ctx, id);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
return bufObj && bufObj != &DummyBufferObject;
}
void GLAPIENTRY
+_mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
+ GLbitfield flags)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+
+ if (size <= 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(size <= 0)");
+ return;
+ }
+
+ if (flags & ~(GL_MAP_READ_BIT |
+ GL_MAP_WRITE_BIT |
+ GL_MAP_PERSISTENT_BIT |
+ GL_MAP_COHERENT_BIT |
+ GL_DYNAMIC_STORAGE_BIT |
+ GL_CLIENT_STORAGE_BIT)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags)");
+ return;
+ }
+
+ if (flags & GL_MAP_PERSISTENT_BIT &&
+ !(flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags!=READ/WRITE)");
+ return;
+ }
+
+ if (flags & GL_MAP_COHERENT_BIT && !(flags & GL_MAP_PERSISTENT_BIT)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags!=PERSISTENT)");
+ return;
+ }
+
+ bufObj = get_buffer(ctx, "glBufferStorage", target, GL_INVALID_OPERATION);
+ if (!bufObj)
+ return;
+
+ if (bufObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferStorage(immutable)");
+ return;
+ }
+
+ /* Unmap the existing buffer. We'll replace it now. Not an error. */
+ _mesa_buffer_unmap_all_mappings(ctx, bufObj);
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
+
+ bufObj->Written = GL_TRUE;
+ bufObj->Immutable = GL_TRUE;
+
+ ASSERT(ctx->Driver.BufferData);
+ if (!ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW,
+ flags, bufObj)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()");
+ }
+}
+
+
+void GLAPIENTRY
_mesa_BufferData(GLenum target, GLsizeiptrARB size,
const GLvoid * data, GLenum usage)
{
@@ -1290,12 +1336,13 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size,
if (!bufObj)
return;
- if (_mesa_bufferobj_mapped(bufObj)) {
- /* Unmap the existing buffer. We'll replace it now. Not an error. */
- ctx->Driver.UnmapBuffer(ctx, bufObj);
- bufObj->AccessFlags = 0;
- ASSERT(bufObj->Pointer == NULL);
- }
+ if (bufObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferData(immutable)");
+ return;
+ }
+
+ /* Unmap the existing buffer. We'll replace it now. Not an error. */
+ _mesa_buffer_unmap_all_mappings(ctx, bufObj);
FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
@@ -1311,7 +1358,11 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size,
#endif
ASSERT(ctx->Driver.BufferData);
- if (!ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj )) {
+ if (!ctx->Driver.BufferData(ctx, target, size, data, usage,
+ GL_MAP_READ_BIT |
+ GL_MAP_WRITE_BIT |
+ GL_DYNAMIC_STORAGE_BIT,
+ bufObj)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB()");
}
}
@@ -1332,6 +1383,12 @@ _mesa_BufferSubData(GLenum target, GLintptrARB offset,
return;
}
+ if (bufObj->Immutable &&
+ !(bufObj->StorageFlags & GL_DYNAMIC_STORAGE_BIT)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferSubData");
+ return;
+ }
+
if (size == 0)
return;
@@ -1377,7 +1434,7 @@ _mesa_ClearBufferData(GLenum target, GLenum internalformat, GLenum format,
return;
}
- if (_mesa_bufferobj_mapped(bufObj)) {
+ if (_mesa_check_disallowed_mapping(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glClearBufferData(buffer currently mapped)");
return;
@@ -1451,8 +1508,10 @@ _mesa_ClearBufferSubData(GLenum target, GLenum internalformat,
if (data == NULL) {
/* clear to zeros, per the spec */
- ctx->Driver.ClearBufferSubData(ctx, offset, size,
- NULL, 0, bufObj);
+ if (size > 0) {
+ ctx->Driver.ClearBufferSubData(ctx, offset, size,
+ NULL, 0, bufObj);
+ }
return;
}
@@ -1462,8 +1521,10 @@ _mesa_ClearBufferSubData(GLenum target, GLenum internalformat,
return;
}
- ctx->Driver.ClearBufferSubData(ctx, offset, size,
- clearValue, clearValueSize, bufObj);
+ if (size > 0) {
+ ctx->Driver.ClearBufferSubData(ctx, offset, size,
+ clearValue, clearValueSize, bufObj);
+ }
}
@@ -1505,7 +1566,21 @@ _mesa_MapBuffer(GLenum target, GLenum access)
if (!bufObj)
return NULL;
- if (_mesa_bufferobj_mapped(bufObj)) {
+ if (accessFlags & GL_MAP_READ_BIT &&
+ !(bufObj->StorageFlags & GL_MAP_READ_BIT)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMapBuffer(invalid read flag)");
+ return NULL;
+ }
+
+ if (accessFlags & GL_MAP_WRITE_BIT &&
+ !(bufObj->StorageFlags & GL_MAP_WRITE_BIT)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMapBuffer(invalid write flag)");
+ return NULL;
+ }
+
+ if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)");
return NULL;
}
@@ -1517,7 +1592,8 @@ _mesa_MapBuffer(GLenum target, GLenum access)
}
ASSERT(ctx->Driver.MapBufferRange);
- map = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, accessFlags, bufObj);
+ map = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, accessFlags, bufObj,
+ MAP_USER);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
return NULL;
@@ -1527,10 +1603,10 @@ _mesa_MapBuffer(GLenum target, GLenum access)
* This is important because other modules (like VBO) might call
* the driver function directly.
*/
- ASSERT(bufObj->Pointer == map);
- ASSERT(bufObj->Length == bufObj->Size);
- ASSERT(bufObj->Offset == 0);
- bufObj->AccessFlags = accessFlags;
+ ASSERT(bufObj->Mappings[MAP_USER].Pointer == map);
+ ASSERT(bufObj->Mappings[MAP_USER].Length == bufObj->Size);
+ ASSERT(bufObj->Mappings[MAP_USER].Offset == 0);
+ bufObj->Mappings[MAP_USER].AccessFlags = accessFlags;
}
if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB)
@@ -1558,7 +1634,7 @@ _mesa_MapBuffer(GLenum target, GLenum access)
}
#endif
- return bufObj->Pointer;
+ return bufObj->Mappings[MAP_USER].Pointer;
}
@@ -1574,7 +1650,7 @@ _mesa_UnmapBuffer(GLenum target)
if (!bufObj)
return GL_FALSE;
- if (!_mesa_bufferobj_mapped(bufObj)) {
+ if (!_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB");
return GL_FALSE;
}
@@ -1615,11 +1691,11 @@ _mesa_UnmapBuffer(GLenum target)
}
#endif
- status = ctx->Driver.UnmapBuffer( ctx, bufObj );
- bufObj->AccessFlags = 0;
- ASSERT(bufObj->Pointer == NULL);
- ASSERT(bufObj->Offset == 0);
- ASSERT(bufObj->Length == 0);
+ status = ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_USER);
+ bufObj->Mappings[MAP_USER].AccessFlags = 0;
+ ASSERT(bufObj->Mappings[MAP_USER].Pointer == NULL);
+ ASSERT(bufObj->Mappings[MAP_USER].Offset == 0);
+ ASSERT(bufObj->Mappings[MAP_USER].Length == 0);
return status;
}
@@ -1644,25 +1720,36 @@ _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
*params = bufObj->Usage;
return;
case GL_BUFFER_ACCESS_ARB:
- *params = simplified_access_mode(ctx, bufObj->AccessFlags);
+ *params = simplified_access_mode(ctx,
+ bufObj->Mappings[MAP_USER].AccessFlags);
return;
case GL_BUFFER_MAPPED_ARB:
- *params = _mesa_bufferobj_mapped(bufObj);
+ *params = _mesa_bufferobj_mapped(bufObj, MAP_USER);
return;
case GL_BUFFER_ACCESS_FLAGS:
if (!ctx->Extensions.ARB_map_buffer_range)
goto invalid_pname;
- *params = bufObj->AccessFlags;
+ *params = bufObj->Mappings[MAP_USER].AccessFlags;
return;
case GL_BUFFER_MAP_OFFSET:
if (!ctx->Extensions.ARB_map_buffer_range)
goto invalid_pname;
- *params = (GLint) bufObj->Offset;
+ *params = (GLint) bufObj->Mappings[MAP_USER].Offset;
return;
case GL_BUFFER_MAP_LENGTH:
if (!ctx->Extensions.ARB_map_buffer_range)
goto invalid_pname;
- *params = (GLint) bufObj->Length;
+ *params = (GLint) bufObj->Mappings[MAP_USER].Length;
+ return;
+ case GL_BUFFER_IMMUTABLE_STORAGE:
+ if (!ctx->Extensions.ARB_buffer_storage)
+ goto invalid_pname;
+ *params = bufObj->Immutable;
+ return;
+ case GL_BUFFER_STORAGE_FLAGS:
+ if (!ctx->Extensions.ARB_buffer_storage)
+ goto invalid_pname;
+ *params = bufObj->StorageFlags;
return;
default:
; /* fall-through */
@@ -1698,25 +1785,36 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
*params = bufObj->Usage;
return;
case GL_BUFFER_ACCESS_ARB:
- *params = simplified_access_mode(ctx, bufObj->AccessFlags);
+ *params = simplified_access_mode(ctx,
+ bufObj->Mappings[MAP_USER].AccessFlags);
return;
case GL_BUFFER_ACCESS_FLAGS:
if (!ctx->Extensions.ARB_map_buffer_range)
goto invalid_pname;
- *params = bufObj->AccessFlags;
+ *params = bufObj->Mappings[MAP_USER].AccessFlags;
return;
case GL_BUFFER_MAPPED_ARB:
- *params = _mesa_bufferobj_mapped(bufObj);
+ *params = _mesa_bufferobj_mapped(bufObj, MAP_USER);
return;
case GL_BUFFER_MAP_OFFSET:
if (!ctx->Extensions.ARB_map_buffer_range)
goto invalid_pname;
- *params = bufObj->Offset;
+ *params = bufObj->Mappings[MAP_USER].Offset;
return;
case GL_BUFFER_MAP_LENGTH:
if (!ctx->Extensions.ARB_map_buffer_range)
goto invalid_pname;
- *params = bufObj->Length;
+ *params = bufObj->Mappings[MAP_USER].Length;
+ return;
+ case GL_BUFFER_IMMUTABLE_STORAGE:
+ if (!ctx->Extensions.ARB_buffer_storage)
+ goto invalid_pname;
+ *params = bufObj->Immutable;
+ return;
+ case GL_BUFFER_STORAGE_FLAGS:
+ if (!ctx->Extensions.ARB_buffer_storage)
+ goto invalid_pname;
+ *params = bufObj->StorageFlags;
return;
default:
; /* fall-through */
@@ -1744,7 +1842,7 @@ _mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params)
if (!bufObj)
return;
- *params = bufObj->Pointer;
+ *params = bufObj->Mappings[MAP_USER].Pointer;
}
@@ -1766,13 +1864,13 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
if (!dst)
return;
- if (_mesa_bufferobj_mapped(src)) {
+ if (_mesa_check_disallowed_mapping(src)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBufferSubData(readBuffer is mapped)");
return;
}
- if (_mesa_bufferobj_mapped(dst)) {
+ if (_mesa_check_disallowed_mapping(dst)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBufferSubData(writeBuffer is mapped)");
return;
@@ -1839,6 +1937,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *bufObj;
void *map;
+ GLbitfield allowed_access;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
@@ -1873,13 +1972,20 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
return NULL;
}
- if (access & ~(GL_MAP_READ_BIT |
- GL_MAP_WRITE_BIT |
- GL_MAP_INVALIDATE_RANGE_BIT |
- GL_MAP_INVALIDATE_BUFFER_BIT |
- GL_MAP_FLUSH_EXPLICIT_BIT |
- GL_MAP_UNSYNCHRONIZED_BIT)) {
- /* generate an error if any undefind bit is set */
+ allowed_access = GL_MAP_READ_BIT |
+ GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT |
+ GL_MAP_INVALIDATE_BUFFER_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT |
+ GL_MAP_UNSYNCHRONIZED_BIT;
+
+ if (ctx->Extensions.ARB_buffer_storage) {
+ allowed_access |= GL_MAP_PERSISTENT_BIT |
+ GL_MAP_COHERENT_BIT;
+ }
+
+ if (access & ~allowed_access) {
+ /* generate an error if any other than allowed bit is set */
_mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(access)");
return NULL;
}
@@ -1910,13 +2016,41 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
if (!bufObj)
return NULL;
+ if (access & GL_MAP_READ_BIT &&
+ !(bufObj->StorageFlags & GL_MAP_READ_BIT)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMapBufferRange(invalid read flag)");
+ return NULL;
+ }
+
+ if (access & GL_MAP_WRITE_BIT &&
+ !(bufObj->StorageFlags & GL_MAP_WRITE_BIT)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMapBufferRange(invalid write flag)");
+ return NULL;
+ }
+
+ if (access & GL_MAP_COHERENT_BIT &&
+ !(bufObj->StorageFlags & GL_MAP_COHERENT_BIT)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMapBufferRange(invalid coherent flag)");
+ return NULL;
+ }
+
+ if (access & GL_MAP_PERSISTENT_BIT &&
+ !(bufObj->StorageFlags & GL_MAP_PERSISTENT_BIT)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glMapBufferRange(invalid persistent flag)");
+ return NULL;
+ }
+
if (offset + length > bufObj->Size) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glMapBufferRange(offset + length > size)");
return NULL;
}
- if (_mesa_bufferobj_mapped(bufObj)) {
+ if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(buffer already mapped)");
return NULL;
@@ -1931,15 +2065,16 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
/* Mapping zero bytes should return a non-null pointer. */
if (!length) {
static long dummy = 0;
- bufObj->Pointer = &dummy;
- bufObj->Length = length;
- bufObj->Offset = offset;
- bufObj->AccessFlags = access;
- return bufObj->Pointer;
+ bufObj->Mappings[MAP_USER].Pointer = &dummy;
+ bufObj->Mappings[MAP_USER].Length = length;
+ bufObj->Mappings[MAP_USER].Offset = offset;
+ bufObj->Mappings[MAP_USER].AccessFlags = access;
+ return bufObj->Mappings[MAP_USER].Pointer;
}
ASSERT(ctx->Driver.MapBufferRange);
- map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj);
+ map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj,
+ MAP_USER);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
}
@@ -1948,10 +2083,10 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
* This is important because other modules (like VBO) might call
* the driver function directly.
*/
- ASSERT(bufObj->Pointer == map);
- ASSERT(bufObj->Length == length);
- ASSERT(bufObj->Offset == offset);
- ASSERT(bufObj->AccessFlags == access);
+ ASSERT(bufObj->Mappings[MAP_USER].Pointer == map);
+ ASSERT(bufObj->Mappings[MAP_USER].Length == length);
+ ASSERT(bufObj->Mappings[MAP_USER].Offset == offset);
+ ASSERT(bufObj->Mappings[MAP_USER].AccessFlags == access);
}
return map;
@@ -1990,30 +2125,33 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
if (!bufObj)
return;
- if (!_mesa_bufferobj_mapped(bufObj)) {
+ if (!_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
/* buffer is not mapped */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFlushMappedBufferRange(buffer is not mapped)");
return;
}
- if ((bufObj->AccessFlags & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) {
+ if ((bufObj->Mappings[MAP_USER].AccessFlags &
+ GL_MAP_FLUSH_EXPLICIT_BIT) == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFlushMappedBufferRange(GL_MAP_FLUSH_EXPLICIT_BIT not set)");
return;
}
- if (offset + length > bufObj->Length) {
+ if (offset + length > bufObj->Mappings[MAP_USER].Length) {
_mesa_error(ctx, GL_INVALID_VALUE,
"glFlushMappedBufferRange(offset %ld + length %ld > mapped length %ld)",
- (long)offset, (long)length, (long)bufObj->Length);
+ (long)offset, (long)length,
+ (long)bufObj->Mappings[MAP_USER].Length);
return;
}
- ASSERT(bufObj->AccessFlags & GL_MAP_WRITE_BIT);
+ ASSERT(bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_WRITE_BIT);
if (ctx->Driver.FlushMappedBufferRange)
- ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj);
+ ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj,
+ MAP_USER);
}
@@ -2660,13 +2798,15 @@ _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset,
return;
}
- /* The GL_ARB_invalidate_subdata spec says:
+ /* The OpenGL 4.4 (Core Profile) spec says:
*
- * "An INVALID_OPERATION error is generated if the buffer is currently
- * mapped by MapBuffer, or if the invalidate range intersects the range
- * currently mapped by MapBufferRange."
+ * "An INVALID_OPERATION error is generated if buffer is currently
+ * mapped by MapBuffer or if the invalidate range intersects the range
+ * currently mapped by MapBufferRange, unless it was mapped
+ * with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
*/
- if (bufferobj_range_mapped(bufObj, offset, length)) {
+ if (!(bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_PERSISTENT_BIT) &&
+ bufferobj_range_mapped(bufObj, offset, length)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glInvalidateBufferSubData(intersection with mapped "
"range)");
@@ -2693,13 +2833,14 @@ _mesa_InvalidateBufferData(GLuint buffer)
return;
}
- /* The GL_ARB_invalidate_subdata spec says:
+ /* The OpenGL 4.4 (Core Profile) spec says:
*
- * "An INVALID_OPERATION error is generated if the buffer is currently
- * mapped by MapBuffer, or if the invalidate range intersects the range
- * currently mapped by MapBufferRange."
+ * "An INVALID_OPERATION error is generated if buffer is currently
+ * mapped by MapBuffer or if the invalidate range intersects the range
+ * currently mapped by MapBufferRange, unless it was mapped
+ * with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
*/
- if (_mesa_bufferobj_mapped(bufObj)) {
+ if (_mesa_check_disallowed_mapping(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glInvalidateBufferData(intersection with mapped "
"range)");
diff --git a/mesalib/src/mesa/main/bufferobj.h b/mesalib/src/mesa/main/bufferobj.h
index 71988b0d9..9814552eb 100644
--- a/mesalib/src/mesa/main/bufferobj.h
+++ b/mesalib/src/mesa/main/bufferobj.h
@@ -37,11 +37,21 @@
*/
-/** Is the given buffer object currently mapped? */
+/** Is the given buffer object currently mapped by the GL user? */
static inline GLboolean
-_mesa_bufferobj_mapped(const struct gl_buffer_object *obj)
+_mesa_bufferobj_mapped(const struct gl_buffer_object *obj,
+ gl_map_buffer_index index)
{
- return obj->Pointer != NULL;
+ return obj->Mappings[index].Pointer != NULL;
+}
+
+/** Can we not use this buffer while mapped? */
+static inline GLboolean
+_mesa_check_disallowed_mapping(const struct gl_buffer_object *obj)
+{
+ return _mesa_bufferobj_mapped(obj, MAP_USER) &&
+ !(obj->Mappings[MAP_USER].AccessFlags &
+ GL_MAP_PERSISTENT_BIT);
}
/**
@@ -101,6 +111,9 @@ _mesa_total_buffer_object_memory(struct gl_context *ctx);
extern void
_mesa_init_buffer_object_functions(struct dd_function_table *driver);
+extern void
+_mesa_buffer_unmap_all_mappings(struct gl_context *ctx,
+ struct gl_buffer_object *bufObj);
/*
* API functions
@@ -118,6 +131,10 @@ GLboolean GLAPIENTRY
_mesa_IsBuffer(GLuint buffer);
void GLAPIENTRY
+_mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
+ GLbitfield flags);
+
+void GLAPIENTRY
_mesa_BufferData(GLenum target, GLsizeiptrARB size,
const GLvoid * data, GLenum usage);
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index 9372b3bea..a19180870 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -106,6 +106,7 @@
#include "matrix.h"
#include "multisample.h"
#include "performance_monitor.h"
+#include "pipelineobj.h"
#include "pixel.h"
#include "pixelstore.h"
#include "points.h"
@@ -363,7 +364,7 @@ dummy_enum_func(void)
*
* \sa Used by one_time_init().
*/
-_glthread_DECLARE_STATIC_MUTEX(OneTimeLock);
+mtx_t OneTimeLock = _MTX_INITIALIZER_NP;
@@ -381,7 +382,7 @@ one_time_init( struct gl_context *ctx )
{
static GLbitfield api_init_mask = 0x0;
- _glthread_LOCK_MUTEX(OneTimeLock);
+ mtx_lock(&OneTimeLock);
/* truly one-time init */
if (!api_init_mask) {
@@ -422,7 +423,7 @@ one_time_init( struct gl_context *ctx )
api_init_mask |= 1 << ctx->API;
- _glthread_UNLOCK_MUTEX(OneTimeLock);
+ mtx_unlock(&OneTimeLock);
/* Hopefully atexit() is widely available. If not, we may need some
* #ifdef tests here.
@@ -603,9 +604,6 @@ _mesa_init_constants(struct gl_context *ctx)
ctx->Const.ViewportBounds.Min = 0;
ctx->Const.ViewportBounds.Max = 0;
- /* Driver must override if it supports ARB_viewport_array */
- ctx->Const.MaxViewports = 1;
-
/** GL_ARB_uniform_buffer_object */
ctx->Const.MaxCombinedUniformBlocks = 36;
ctx->Const.MaxUniformBufferBindings = 36;
@@ -814,6 +812,7 @@ init_attrib_groups(struct gl_context *ctx)
_mesa_init_matrix( ctx );
_mesa_init_multisample( ctx );
_mesa_init_performance_monitors( ctx );
+ _mesa_init_pipeline( ctx );
_mesa_init_pixel( ctx );
_mesa_init_pixelstore( ctx );
_mesa_init_point( ctx );
@@ -1219,6 +1218,7 @@ _mesa_free_context_data( struct gl_context *ctx )
_mesa_free_texture_data( ctx );
_mesa_free_matrix_data( ctx );
_mesa_free_viewport_data( ctx );
+ _mesa_free_pipeline_data(ctx);
_mesa_free_program_data(ctx);
_mesa_free_shader_state(ctx);
_mesa_free_queryobj_data(ctx);
@@ -1769,93 +1769,59 @@ _mesa_check_blend_func_error(struct gl_context *ctx)
return GL_TRUE;
}
-/**
- * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
- * is called to see if it's valid to render. This involves checking that
- * the current shader is valid and the framebuffer is complete.
- * If an error is detected it'll be recorded here.
- * \return GL_TRUE if OK to render, GL_FALSE if not
- */
-GLboolean
-_mesa_valid_to_render(struct gl_context *ctx, const char *where)
+static bool
+shader_linked_or_absent(struct gl_context *ctx,
+ const struct gl_shader_program *shProg,
+ bool *shader_present, const char *where)
{
- bool vert_from_glsl_shader = false;
- bool geom_from_glsl_shader = false;
- bool frag_from_glsl_shader = false;
-
- /* This depends on having up to date derived state (shaders) */
- if (ctx->NewState)
- _mesa_update_state(ctx);
+ if (shProg) {
+ *shader_present = true;
- if (ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX]) {
- vert_from_glsl_shader = true;
-
- if (!ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX]->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(shader not linked)", where);
- return GL_FALSE;
+ if (!shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(shader not linked)", where);
+ return false;
}
#if 0 /* not normally enabled */
{
char errMsg[100];
- if (!_mesa_validate_shader_program(ctx,
- ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX],
- errMsg)) {
+ if (!_mesa_validate_shader_program(ctx, shProg, errMsg)) {
_mesa_warning(ctx, "Shader program %u is invalid: %s",
- ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX]->Name, errMsg);
+ shProg->Name, errMsg);
}
}
#endif
}
- if (ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY]) {
- geom_from_glsl_shader = true;
+ return true;
+}
- if (!ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY]->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(shader not linked)", where);
- return GL_FALSE;
- }
-#if 0 /* not normally enabled */
- {
- char errMsg[100];
- if (!_mesa_validate_shader_program(ctx,
- ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY],
- errMsg)) {
- _mesa_warning(ctx, "Shader program %u is invalid: %s",
- ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY]->Name,
- errMsg);
- }
- }
-#endif
- }
+/**
+ * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
+ * is called to see if it's valid to render. This involves checking that
+ * the current shader is valid and the framebuffer is complete.
+ * If an error is detected it'll be recorded here.
+ * \return GL_TRUE if OK to render, GL_FALSE if not
+ */
+GLboolean
+_mesa_valid_to_render(struct gl_context *ctx, const char *where)
+{
+ bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false };
+ unsigned i;
- if (ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT]) {
- frag_from_glsl_shader = true;
+ /* This depends on having up to date derived state (shaders) */
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
- if (!ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT]->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(shader not linked)", where);
+ for (i = 0; i < MESA_SHADER_COMPUTE; i++) {
+ if (!shader_linked_or_absent(ctx, ctx->Shader.CurrentProgram[i],
+ &from_glsl_shader[i], where))
return GL_FALSE;
- }
-#if 0 /* not normally enabled */
- {
- char errMsg[100];
- if (!_mesa_validate_shader_program(ctx,
- ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT],
- errMsg)) {
- _mesa_warning(ctx, "Shader program %u is invalid: %s",
- ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT]->Name,
- errMsg);
- }
- }
-#endif
}
/* Any shader stages that are not supplied by the GLSL shader and have
* assembly shaders enabled must now be validated.
*/
- if (!vert_from_glsl_shader
+ if (!from_glsl_shader[MESA_SHADER_VERTEX]
&& ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(vertex program not valid)", where);
@@ -1865,9 +1831,9 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
/* FINISHME: If GL_NV_geometry_program4 is ever supported, the current
* FINISHME: geometry program should validated here.
*/
- (void) geom_from_glsl_shader;
+ (void) from_glsl_shader[MESA_SHADER_GEOMETRY];
- if (!frag_from_glsl_shader) {
+ if (!from_glsl_shader[MESA_SHADER_FRAGMENT]) {
if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(fragment program not valid)", where);
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index ac317e399..971524135 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -399,6 +399,13 @@ struct dd_function_table {
void (*UnmapRenderbuffer)(struct gl_context *ctx,
struct gl_renderbuffer *rb);
+ /**
+ * Optional driver entrypoint that binds a non-texture renderbuffer's
+ * contents to a texture image.
+ */
+ GLboolean (*BindRenderbufferTexImage)(struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ struct gl_texture_image *texImage);
/*@}*/
@@ -564,9 +571,6 @@ struct dd_function_table {
* \name Vertex/pixel buffer object functions
*/
/*@{*/
- void (*BindBuffer)( struct gl_context *ctx, GLenum target,
- struct gl_buffer_object *obj );
-
struct gl_buffer_object * (*NewBufferObject)(struct gl_context *ctx,
GLuint buffer, GLenum target);
@@ -574,7 +578,7 @@ struct dd_function_table {
GLboolean (*BufferData)(struct gl_context *ctx, GLenum target,
GLsizeiptrARB size, const GLvoid *data, GLenum usage,
- struct gl_buffer_object *obj);
+ GLenum storageFlags, struct gl_buffer_object *obj);
void (*BufferSubData)( struct gl_context *ctx, GLintptrARB offset,
GLsizeiptrARB size, const GLvoid *data,
@@ -601,14 +605,17 @@ struct dd_function_table {
*/
void * (*MapBufferRange)( struct gl_context *ctx, GLintptr offset,
GLsizeiptr length, GLbitfield access,
- struct gl_buffer_object *obj);
+ struct gl_buffer_object *obj,
+ gl_map_buffer_index index);
void (*FlushMappedBufferRange)(struct gl_context *ctx,
GLintptr offset, GLsizeiptr length,
- struct gl_buffer_object *obj);
+ struct gl_buffer_object *obj,
+ gl_map_buffer_index index);
GLboolean (*UnmapBuffer)( struct gl_context *ctx,
- struct gl_buffer_object *obj );
+ struct gl_buffer_object *obj,
+ gl_map_buffer_index index);
/*@}*/
/**
diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c
index 08943c9f9..d431fd221 100644
--- a/mesalib/src/mesa/main/dlist.c
+++ b/mesalib/src/mesa/main/dlist.c
@@ -914,7 +914,8 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
map = (GLubyte *)
ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
- GL_MAP_READ_BIT, unpack->BufferObj);
+ GL_MAP_READ_BIT, unpack->BufferObj,
+ MAP_INTERNAL);
if (!map) {
/* unable to map src buffer! */
_mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
@@ -928,7 +929,7 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
image = _mesa_unpack_image(dimensions, width, height, depth,
format, type, src, unpack);
- ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
+ ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
@@ -8176,7 +8177,7 @@ _mesa_GenLists(GLsizei range)
/*
* Make this an atomic operation
*/
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range);
if (base) {
@@ -8188,7 +8189,7 @@ _mesa_GenLists(GLsizei range)
}
}
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
return base;
}
diff --git a/mesalib/src/mesa/main/drawpix.c b/mesalib/src/mesa/main/drawpix.c
index 096615c05..63e5870e6 100644
--- a/mesalib/src/mesa/main/drawpix.c
+++ b/mesalib/src/mesa/main/drawpix.c
@@ -151,7 +151,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
"glDrawPixels(invalid PBO access)");
goto end;
}
- if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
+ if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(PBO is mapped)");
@@ -335,7 +335,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
"glBitmap(invalid PBO access)");
return;
}
- if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
+ if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBitmap(PBO is mapped)");
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index 40508a456..edd4751e1 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -32,6 +32,7 @@
#include "clip.h"
#include "context.h"
#include "enable.h"
+#include "errors.h"
#include "light.h"
#include "simple_list.h"
#include "mtypes.h"
@@ -367,14 +368,26 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
ctx->Depth.Test = state;
break;
case GL_DEBUG_OUTPUT:
- if (!_mesa_is_desktop_gl(ctx))
+ if (!_mesa_is_desktop_gl(ctx)) {
goto invalid_enum_error;
- ctx->Debug.DebugOutput = state;
+ }
+ else {
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ if (debug) {
+ debug->DebugOutput = state;
+ }
+ }
break;
case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
- if (!_mesa_is_desktop_gl(ctx))
+ if (!_mesa_is_desktop_gl(ctx)) {
goto invalid_enum_error;
- ctx->Debug.SyncOutput = state;
+ }
+ else {
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ if (debug) {
+ debug->SyncOutput = state;
+ }
+ }
break;
case GL_DITHER:
if (ctx->Color.DitherFlag == state)
@@ -1228,11 +1241,19 @@ _mesa_IsEnabled( GLenum cap )
case GL_DEBUG_OUTPUT:
if (!_mesa_is_desktop_gl(ctx))
goto invalid_enum_error;
- return ctx->Debug.DebugOutput;
+ if (ctx->Debug) {
+ return ctx->Debug->DebugOutput;
+ } else {
+ return GL_FALSE;
+ }
case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB:
if (!_mesa_is_desktop_gl(ctx))
goto invalid_enum_error;
- return ctx->Debug.SyncOutput;
+ if (ctx->Debug) {
+ return ctx->Debug->SyncOutput;
+ } else {
+ return GL_FALSE;
+ }
case GL_DEPTH_TEST:
return ctx->Depth.Test;
case GL_DITHER:
diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c
index 28357e0e8..ca73a6686 100644
--- a/mesalib/src/mesa/main/errors.c
+++ b/mesalib/src/mesa/main/errors.c
@@ -37,12 +37,11 @@
#include "mtypes.h"
#include "version.h"
#include "hash_table.h"
-#include "glapi/glthread.h"
#define MESSAGE_LOG 1
#define MESSAGE_LOG_ARB 2
-_glthread_DECLARE_STATIC_MUTEX(DynamicIDMutex);
+static mtx_t DynamicIDMutex = _MTX_INITIALIZER_NP;
static GLuint NextDynamicID = 1;
struct gl_debug_severity
@@ -81,6 +80,7 @@ static const GLenum debug_severity_enums[] = {
GL_DEBUG_SEVERITY_NOTIFICATION,
};
+
static enum mesa_debug_source
gl_enum_to_debug_source(GLenum e)
{
@@ -117,6 +117,7 @@ gl_enum_to_debug_severity(GLenum e)
return i;
}
+
/**
* Handles generating a GL_ARB_debug_output message ID generated by the GL or
* GLSL compiler.
@@ -134,13 +135,14 @@ static void
debug_get_id(GLuint *id)
{
if (!(*id)) {
- _glthread_LOCK_MUTEX(DynamicIDMutex);
+ mtx_lock(&DynamicIDMutex);
if (!(*id))
*id = NextDynamicID++;
- _glthread_UNLOCK_MUTEX(DynamicIDMutex);
+ mtx_unlock(&DynamicIDMutex);
}
}
+
/*
* We store a bitfield in the hash table, with five possible values total.
*
@@ -182,6 +184,50 @@ enum {
ENABLED = ENABLED_BIT | FOUND_BIT
};
+
+/**
+ * Return debug state for the context. The debug state will be allocated
+ * and initialized upon the first call.
+ */
+struct gl_debug_state *
+_mesa_get_debug_state(struct gl_context *ctx)
+{
+ if (!ctx->Debug) {
+ ctx->Debug = CALLOC_STRUCT(gl_debug_state);
+ if (!ctx->Debug) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "allocating debug state");
+ }
+ else {
+ struct gl_debug_state *debug = ctx->Debug;
+ int s, t, sev;
+
+ /* Enable all the messages with severity HIGH or MEDIUM by default. */
+ memset(debug->Defaults[0][MESA_DEBUG_SEVERITY_HIGH], GL_TRUE,
+ sizeof debug->Defaults[0][MESA_DEBUG_SEVERITY_HIGH]);
+ memset(debug->Defaults[0][MESA_DEBUG_SEVERITY_MEDIUM], GL_TRUE,
+ sizeof debug->Defaults[0][MESA_DEBUG_SEVERITY_MEDIUM]);
+ memset(debug->Defaults[0][MESA_DEBUG_SEVERITY_LOW], GL_FALSE,
+ sizeof debug->Defaults[0][MESA_DEBUG_SEVERITY_LOW]);
+
+ /* Initialize state for filtering known debug messages. */
+ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) {
+ for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) {
+ debug->Namespaces[0][s][t].IDs = _mesa_NewHashTable();
+ assert(debug->Namespaces[0][s][t].IDs);
+
+ for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) {
+ make_empty_list(&debug->Namespaces[0][s][t].Severity[sev]);
+ }
+ }
+ }
+ }
+ }
+
+ return ctx->Debug;
+}
+
+
+
/**
* Returns the state of the given message source/type/ID tuple.
*/
@@ -192,52 +238,64 @@ should_log(struct gl_context *ctx,
GLuint id,
enum mesa_debug_severity severity)
{
- GLint gstack = ctx->Debug.GroupStackDepth;
- struct gl_debug_namespace *nspace =
- &ctx->Debug.Namespaces[gstack][source][type];
- uintptr_t state;
+ struct gl_debug_state *debug;
+ uintptr_t state = 0;
- if (!ctx->Debug.DebugOutput)
+ if (!ctx->Debug) {
+ /* no debug state set so far */
return GL_FALSE;
+ }
- /* In addition to not being able to store zero as a value, HashTable also
- can't use zero as a key. */
- if (id)
- state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id);
- else
- state = nspace->ZeroID;
-
- /* Only do this once for each ID. This makes sure the ID exists in,
- at most, one list, and does not pointlessly appear multiple times. */
- if (!(state & KNOWN_SEVERITY)) {
- struct gl_debug_severity *entry;
-
- if (state == NOT_FOUND) {
- if (ctx->Debug.Defaults[gstack][severity][source][type])
- state = ENABLED;
- else
- state = DISABLED;
- }
-
- entry = malloc(sizeof *entry);
- if (!entry)
- goto out;
+ debug = _mesa_get_debug_state(ctx);
+ if (debug) {
+ const GLint gstack = debug->GroupStackDepth;
+ struct gl_debug_namespace *nspace =
+ &debug->Namespaces[gstack][source][type];
- state |= KNOWN_SEVERITY;
+ if (!debug->DebugOutput)
+ return GL_FALSE;
+ /* In addition to not being able to store zero as a value, HashTable also
+ * can't use zero as a key.
+ */
if (id)
- _mesa_HashInsert(nspace->IDs, id, (void*)state);
+ state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id);
else
- nspace->ZeroID = state;
+ state = nspace->ZeroID;
- entry->ID = id;
- insert_at_tail(&nspace->Severity[severity], &entry->link);
- }
+ /* Only do this once for each ID. This makes sure the ID exists in,
+ * at most, one list, and does not pointlessly appear multiple times.
+ */
+ if (!(state & KNOWN_SEVERITY)) {
+ struct gl_debug_severity *entry;
+
+ if (state == NOT_FOUND) {
+ if (debug->Defaults[gstack][severity][source][type])
+ state = ENABLED;
+ else
+ state = DISABLED;
+ }
+
+ entry = malloc(sizeof *entry);
+ if (!entry)
+ goto out;
+
+ state |= KNOWN_SEVERITY;
+ if (id)
+ _mesa_HashInsert(nspace->IDs, id, (void*)state);
+ else
+ nspace->ZeroID = state;
+
+ entry->ID = id;
+ insert_at_tail(&nspace->Severity[severity], &entry->link);
+ }
+ }
out:
return !!(state & ENABLED_BIT);
}
+
/**
* Sets the state of the given message source/type/ID tuple.
*/
@@ -247,33 +305,39 @@ set_message_state(struct gl_context *ctx,
enum mesa_debug_type type,
GLuint id, GLboolean enabled)
{
- GLint gstack = ctx->Debug.GroupStackDepth;
- struct gl_debug_namespace *nspace =
- &ctx->Debug.Namespaces[gstack][source][type];
- uintptr_t state;
-
- /* In addition to not being able to store zero as a value, HashTable also
- can't use zero as a key. */
- if (id)
- state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id);
- else
- state = nspace->ZeroID;
-
- if (state == NOT_FOUND)
- state = enabled ? ENABLED : DISABLED;
- else {
- if (enabled)
- state |= ENABLED_BIT;
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+
+ if (debug) {
+ GLint gstack = debug->GroupStackDepth;
+ struct gl_debug_namespace *nspace =
+ &debug->Namespaces[gstack][source][type];
+ uintptr_t state;
+
+ /* In addition to not being able to store zero as a value, HashTable also
+ * can't use zero as a key.
+ */
+ if (id)
+ state = (uintptr_t)_mesa_HashLookup(nspace->IDs, id);
else
- state &= ~ENABLED_BIT;
- }
+ state = nspace->ZeroID;
- if (id)
- _mesa_HashInsert(nspace->IDs, id, (void*)state);
- else
- nspace->ZeroID = state;
+ if (state == NOT_FOUND)
+ state = enabled ? ENABLED : DISABLED;
+ else {
+ if (enabled)
+ state |= ENABLED_BIT;
+ else
+ state &= ~ENABLED_BIT;
+ }
+
+ if (id)
+ _mesa_HashInsert(nspace->IDs, id, (void*)state);
+ else
+ nspace->ZeroID = state;
+ }
}
+
static void
store_message_details(struct gl_debug_msg *emptySlot,
enum mesa_debug_source source,
@@ -307,7 +371,8 @@ store_message_details(struct gl_debug_msg *emptySlot,
}
}
- /**
+
+/**
* Remap any type exclusive to KHR_debug to something suitable
* for ARB_debug_output
*/
@@ -326,6 +391,7 @@ remap_type(GLenum type) {
return type;
}
+
/**
* Remap severity exclusive to KHR_debug to something suitable
* for ARB_debug_output
@@ -339,6 +405,7 @@ remap_severity(GLenum severity) {
return severity;
}
+
/**
* 'buf' is not necessarily a null-terminated string. When logging, copy
* 'len' characters from it, store them in a new, null-terminated string,
@@ -346,49 +413,51 @@ remap_severity(GLenum severity) {
* the null terminator this time.
*/
static void
-_mesa_log_msg(struct gl_context *ctx, enum mesa_debug_source source,
- enum mesa_debug_type type, GLuint id,
- enum mesa_debug_severity severity, GLint len, const char *buf)
+log_msg(struct gl_context *ctx, enum mesa_debug_source source,
+ enum mesa_debug_type type, GLuint id,
+ enum mesa_debug_severity severity, GLint len, const char *buf)
{
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
GLint nextEmpty;
struct gl_debug_msg *emptySlot;
+ if (!debug)
+ return;
+
assert(len >= 0 && len < MAX_DEBUG_MESSAGE_LENGTH);
if (!should_log(ctx, source, type, id, severity))
return;
- if (ctx->Debug.Callback) {
+ if (debug->Callback) {
GLenum gl_type = debug_type_enums[type];
GLenum gl_severity = debug_severity_enums[severity];
- if (ctx->Debug.ARBCallback) {
+ if (debug->ARBCallback) {
gl_severity = remap_severity(gl_severity);
gl_type = remap_type(gl_type);
}
- ctx->Debug.Callback(debug_source_enums[source],
- gl_type,
- id,
- gl_severity,
- len, buf, ctx->Debug.CallbackData);
+ debug->Callback(debug_source_enums[source], gl_type, id, gl_severity,
+ len, buf, debug->CallbackData);
return;
}
- if (ctx->Debug.NumMessages == MAX_DEBUG_LOGGED_MESSAGES)
+ if (debug->NumMessages == MAX_DEBUG_LOGGED_MESSAGES)
return;
- nextEmpty = (ctx->Debug.NextMsg + ctx->Debug.NumMessages)
+ nextEmpty = (debug->NextMsg + debug->NumMessages)
% MAX_DEBUG_LOGGED_MESSAGES;
- emptySlot = &ctx->Debug.Log[nextEmpty];
+ emptySlot = &debug->Log[nextEmpty];
store_message_details(emptySlot, source, type, id, severity, len, buf);
- if (ctx->Debug.NumMessages == 0)
- ctx->Debug.NextMsgLength = ctx->Debug.Log[ctx->Debug.NextMsg].length;
+ if (debug->NumMessages == 0)
+ debug->NextMsgLength = debug->Log[debug->NextMsg].length;
- ctx->Debug.NumMessages++;
+ debug->NumMessages++;
}
+
/**
* Pop the oldest debug message out of the log.
* Writes the message string, including the null terminator, into 'buf',
@@ -400,20 +469,21 @@ _mesa_log_msg(struct gl_context *ctx, enum mesa_debug_source source,
* indicates failure.
*/
static GLsizei
-_mesa_get_msg(struct gl_context *ctx, GLenum *source, GLenum *type,
- GLuint *id, GLenum *severity, GLsizei bufSize, char *buf,
- unsigned caller)
+get_msg(struct gl_context *ctx, GLenum *source, GLenum *type,
+ GLuint *id, GLenum *severity, GLsizei bufSize, char *buf,
+ unsigned caller)
{
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
struct gl_debug_msg *msg;
GLsizei length;
- if (ctx->Debug.NumMessages == 0)
+ if (!debug || debug->NumMessages == 0)
return 0;
- msg = &ctx->Debug.Log[ctx->Debug.NextMsg];
+ msg = &debug->Log[debug->NextMsg];
length = msg->length;
- assert(length > 0 && length == ctx->Debug.NextMsgLength);
+ assert(length > 0 && length == debug->NextMsgLength);
if (bufSize < length && buf != NULL)
return 0;
@@ -423,15 +493,20 @@ _mesa_get_msg(struct gl_context *ctx, GLenum *source, GLenum *type,
if (caller == MESSAGE_LOG_ARB)
*severity = remap_severity(*severity);
}
- if (source)
+
+ if (source) {
*source = debug_source_enums[msg->source];
+ }
+
if (type) {
*type = debug_type_enums[msg->type];
if (caller == MESSAGE_LOG_ARB)
*type = remap_type(*type);
}
- if (id)
+
+ if (id) {
*id = msg->id;
+ }
if (buf) {
assert(msg->message[length-1] == '\0');
@@ -443,14 +518,15 @@ _mesa_get_msg(struct gl_context *ctx, GLenum *source, GLenum *type,
msg->message = NULL;
msg->length = 0;
- ctx->Debug.NumMessages--;
- ctx->Debug.NextMsg++;
- ctx->Debug.NextMsg %= MAX_DEBUG_LOGGED_MESSAGES;
- ctx->Debug.NextMsgLength = ctx->Debug.Log[ctx->Debug.NextMsg].length;
+ debug->NumMessages--;
+ debug->NextMsg++;
+ debug->NextMsg %= MAX_DEBUG_LOGGED_MESSAGES;
+ debug->NextMsgLength = debug->Log[debug->NextMsg].length;
return length;
}
+
/**
* Verify that source, type, and severity are valid enums.
* glDebugMessageInsertARB only accepts two values for 'source',
@@ -523,14 +599,14 @@ validate_params(struct gl_context *ctx, unsigned caller,
return GL_TRUE;
error:
- {
- _mesa_error(ctx, GL_INVALID_ENUM, "bad values passed to %s"
- "(source=0x%x, type=0x%x, severity=0x%x)", callerstr,
- source, type, severity);
- }
+ _mesa_error(ctx, GL_INVALID_ENUM, "bad values passed to %s"
+ "(source=0x%x, type=0x%x, severity=0x%x)", callerstr,
+ source, type, severity);
+
return GL_FALSE;
}
+
/**
* Set the state of all message IDs found in the given intersection of
* 'source', 'type', and 'severity'. The _COUNT enum can be used for
@@ -549,8 +625,12 @@ control_messages(struct gl_context *ctx,
enum mesa_debug_severity severity,
GLboolean enabled)
{
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
int s, t, sev, smax, tmax, sevmax;
- GLint gstack = ctx->Debug.GroupStackDepth;
+ const GLint gstack = debug ? debug->GroupStackDepth : 0;
+
+ if (!debug)
+ return;
if (source == MESA_DEBUG_SOURCE_COUNT) {
source = 0;
@@ -573,23 +653,26 @@ control_messages(struct gl_context *ctx,
sevmax = severity+1;
}
- for (sev = severity; sev < sevmax; sev++)
- for (s = source; s < smax; s++)
+ for (sev = severity; sev < sevmax; sev++) {
+ for (s = source; s < smax; s++) {
for (t = type; t < tmax; t++) {
struct simple_node *node;
struct gl_debug_severity *entry;
/* change the default for IDs we've never seen before. */
- ctx->Debug.Defaults[gstack][sev][s][t] = enabled;
+ debug->Defaults[gstack][sev][s][t] = enabled;
/* Now change the state of IDs we *have* seen... */
- foreach(node, &ctx->Debug.Namespaces[gstack][s][t].Severity[sev]) {
+ foreach(node, &debug->Namespaces[gstack][s][t].Severity[sev]) {
entry = (struct gl_debug_severity *)node;
set_message_state(ctx, s, t, entry->ID, enabled);
}
}
+ }
+ }
}
+
/**
* Debugging-message namespaces with the source APPLICATION or THIRD_PARTY
* require special handling, since the IDs in them are controlled by clients,
@@ -621,6 +704,7 @@ control_app_messages(struct gl_context *ctx, GLenum esource, GLenum etype,
control_messages(ctx, source, type, severity, enabled);
}
+
/**
* This is a generic message control function for use by both
* glDebugMessageControlARB and glDebugMessageControl.
@@ -658,6 +742,7 @@ message_control(GLenum gl_source, GLenum gl_type,
count, ids, enabled);
}
+
/**
* This is a generic message insert function.
* Validation of source, type and severity parameters should be done
@@ -665,7 +750,7 @@ message_control(GLenum gl_source, GLenum gl_type,
*/
static void
message_insert(GLenum source, GLenum type, GLuint id,
- GLenum severity, GLint length, const GLchar* buf,
+ GLenum severity, GLint length, const GLchar *buf,
const char *callerstr)
{
GET_CURRENT_CONTEXT(ctx);
@@ -681,20 +766,21 @@ message_insert(GLenum source, GLenum type, GLuint id,
return;
}
- _mesa_log_msg(ctx,
- gl_enum_to_debug_source(source),
- gl_enum_to_debug_type(type), id,
- gl_enum_to_debug_severity(severity), length, buf);
+ log_msg(ctx,
+ gl_enum_to_debug_source(source),
+ gl_enum_to_debug_type(type), id,
+ gl_enum_to_debug_severity(severity), length, buf);
}
+
/**
* This is a generic message insert function for use by both
* glGetDebugMessageLogARB and glGetDebugMessageLog.
*/
static GLuint
-get_message_log(GLuint count, GLsizei logSize, GLenum* sources,
- GLenum* types, GLenum* ids, GLenum* severities,
- GLsizei* lengths, GLchar* messageLog,
+get_message_log(GLuint count, GLsizei logSize, GLenum *sources,
+ GLenum *types, GLenum *ids, GLenum *severities,
+ GLsizei *lengths, GLchar *messageLog,
unsigned caller, const char *callerstr)
{
GET_CURRENT_CONTEXT(ctx);
@@ -711,8 +797,8 @@ get_message_log(GLuint count, GLsizei logSize, GLenum* sources,
}
for (ret = 0; ret < count; ret++) {
- GLsizei written = _mesa_get_msg(ctx, sources, types, ids, severities,
- logSize, messageLog, caller);
+ GLsizei written = get_msg(ctx, sources, types, ids, severities,
+ logSize, messageLog, caller);
if (!written)
break;
@@ -738,41 +824,52 @@ get_message_log(GLuint count, GLsizei logSize, GLenum* sources,
return ret;
}
+
static void
do_nothing(GLuint key, void *data, void *userData)
{
}
+
+/**
+ * Free context state pertaining to error/debug state for the given stack
+ * depth.
+ */
static void
free_errors_data(struct gl_context *ctx, GLint gstack)
{
+ struct gl_debug_state *debug = ctx->Debug;
enum mesa_debug_type t;
enum mesa_debug_source s;
enum mesa_debug_severity sev;
+ assert(debug);
+
/* Tear down state for filtering debug messages. */
- for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++)
+ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) {
for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) {
- _mesa_HashDeleteAll(ctx->Debug.Namespaces[gstack][s][t].IDs,
+ _mesa_HashDeleteAll(debug->Namespaces[gstack][s][t].IDs,
do_nothing, NULL);
- _mesa_DeleteHashTable(ctx->Debug.Namespaces[gstack][s][t].IDs);
+ _mesa_DeleteHashTable(debug->Namespaces[gstack][s][t].IDs);
for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) {
struct simple_node *node, *tmp;
struct gl_debug_severity *entry;
foreach_s(node, tmp,
- &ctx->Debug.Namespaces[gstack][s][t].Severity[sev]) {
+ &debug->Namespaces[gstack][s][t].Severity[sev]) {
entry = (struct gl_debug_severity *)node;
free(entry);
}
}
}
+ }
}
+
void GLAPIENTRY
_mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id,
GLenum severity, GLint length,
- const GLchar* buf)
+ const GLchar *buf)
{
const char *callerstr = "glDebugMessageInsert";
@@ -781,14 +878,14 @@ _mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id,
if (!validate_params(ctx, INSERT, callerstr, source, type, severity))
return; /* GL_INVALID_ENUM */
- message_insert(source, type, id, severity, length, buf,
- callerstr);
+ message_insert(source, type, id, severity, length, buf, callerstr);
}
+
GLuint GLAPIENTRY
-_mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum* sources,
- GLenum* types, GLenum* ids, GLenum* severities,
- GLsizei* lengths, GLchar* messageLog)
+_mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum *sources,
+ GLenum *types, GLenum *ids, GLenum *severities,
+ GLsizei *lengths, GLchar *messageLog)
{
const char *callerstr = "glGetDebugMessageLog";
@@ -796,6 +893,7 @@ _mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum* sources,
lengths, messageLog, MESSAGE_LOG, callerstr);
}
+
void GLAPIENTRY
_mesa_DebugMessageControl(GLenum source, GLenum type, GLenum severity,
GLsizei count, const GLuint *ids,
@@ -807,28 +905,36 @@ _mesa_DebugMessageControl(GLenum source, GLenum type, GLenum severity,
enabled, CONTROL, callerstr);
}
+
void GLAPIENTRY
_mesa_DebugMessageCallback(GLDEBUGPROC callback, const void *userParam)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Debug.Callback = callback;
- ctx->Debug.CallbackData = userParam;
- ctx->Debug.ARBCallback = GL_FALSE;
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ if (debug) {
+ debug->Callback = callback;
+ debug->CallbackData = userParam;
+ debug->ARBCallback = GL_FALSE;
+ }
}
+
void GLAPIENTRY
_mesa_PushDebugGroup(GLenum source, GLuint id, GLsizei length,
const GLchar *message)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
const char *callerstr = "glPushDebugGroup";
int s, t, sev;
GLint prevStackDepth;
GLint currStackDepth;
struct gl_debug_msg *emptySlot;
- GET_CURRENT_CONTEXT(ctx);
+ if (!debug)
+ return;
- if (ctx->Debug.GroupStackDepth >= MAX_DEBUG_GROUP_STACK_DEPTH-1) {
+ if (debug->GroupStackDepth >= MAX_DEBUG_GROUP_STACK_DEPTH-1) {
_mesa_error(ctx, GL_STACK_OVERFLOW, "%s", callerstr);
return;
}
@@ -847,14 +953,14 @@ _mesa_PushDebugGroup(GLenum source, GLuint id, GLsizei length,
GL_DEBUG_SEVERITY_NOTIFICATION, length,
message, callerstr);
- prevStackDepth = ctx->Debug.GroupStackDepth;
- ctx->Debug.GroupStackDepth++;
- currStackDepth = ctx->Debug.GroupStackDepth;
+ prevStackDepth = debug->GroupStackDepth;
+ debug->GroupStackDepth++;
+ currStackDepth = debug->GroupStackDepth;
/* pop reuses the message details from push so we store this */
if (length < 0)
length = strlen(message);
- emptySlot = &ctx->Debug.DebugGroupMsgs[ctx->Debug.GroupStackDepth];
+ emptySlot = &debug->DebugGroupMsgs[debug->GroupStackDepth];
store_message_details(emptySlot, gl_enum_to_debug_source(source),
gl_enum_to_debug_type(GL_DEBUG_TYPE_PUSH_GROUP),
id,
@@ -864,60 +970,66 @@ _mesa_PushDebugGroup(GLenum source, GLuint id, GLsizei length,
/* inherit the control volume of the debug group previously residing on
* the top of the debug group stack
*/
- for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++)
+ for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++) {
for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) {
/* copy id settings */
- ctx->Debug.Namespaces[currStackDepth][s][t].IDs =
- _mesa_HashClone(ctx->Debug.Namespaces[prevStackDepth][s][t].IDs);
+ debug->Namespaces[currStackDepth][s][t].IDs =
+ _mesa_HashClone(debug->Namespaces[prevStackDepth][s][t].IDs);
for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++) {
struct gl_debug_severity *entry, *prevEntry;
struct simple_node *node;
/* copy default settings for unknown ids */
- ctx->Debug.Defaults[currStackDepth][sev][s][t] = ctx->Debug.Defaults[prevStackDepth][sev][s][t];
+ debug->Defaults[currStackDepth][sev][s][t] =
+ debug->Defaults[prevStackDepth][sev][s][t];
/* copy known id severity settings */
- make_empty_list(&ctx->Debug.Namespaces[currStackDepth][s][t].Severity[sev]);
- foreach(node, &ctx->Debug.Namespaces[prevStackDepth][s][t].Severity[sev]) {
+ make_empty_list(&debug->Namespaces[currStackDepth][s][t].Severity[sev]);
+ foreach(node, &debug->Namespaces[prevStackDepth][s][t].Severity[sev]) {
prevEntry = (struct gl_debug_severity *)node;
entry = malloc(sizeof *entry);
if (!entry)
return;
entry->ID = prevEntry->ID;
- insert_at_tail(&ctx->Debug.Namespaces[currStackDepth][s][t].Severity[sev], &entry->link);
+ insert_at_tail(&debug->Namespaces[currStackDepth][s][t].Severity[sev], &entry->link);
}
}
}
+ }
}
+
void GLAPIENTRY
-_mesa_PopDebugGroup()
+_mesa_PopDebugGroup(void)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
const char *callerstr = "glPopDebugGroup";
struct gl_debug_msg *gdmessage;
GLint prevStackDepth;
- GET_CURRENT_CONTEXT(ctx);
+ if (!debug)
+ return;
- if (ctx->Debug.GroupStackDepth <= 0) {
+ if (debug->GroupStackDepth <= 0) {
_mesa_error(ctx, GL_STACK_UNDERFLOW, "%s", callerstr);
return;
}
- prevStackDepth = ctx->Debug.GroupStackDepth;
- ctx->Debug.GroupStackDepth--;
+ prevStackDepth = debug->GroupStackDepth;
+ debug->GroupStackDepth--;
- gdmessage = &ctx->Debug.DebugGroupMsgs[prevStackDepth];
- /* using _mesa_log_msg() directly here as verification of parameters
+ gdmessage = &debug->DebugGroupMsgs[prevStackDepth];
+ /* using log_msg() directly here as verification of parameters
* already done in push
*/
- _mesa_log_msg(ctx, gdmessage->source,
- gl_enum_to_debug_type(GL_DEBUG_TYPE_POP_GROUP),
- gdmessage->id,
- gl_enum_to_debug_severity(GL_DEBUG_SEVERITY_NOTIFICATION),
- gdmessage->length, gdmessage->message);
+ log_msg(ctx, gdmessage->source,
+ gl_enum_to_debug_type(GL_DEBUG_TYPE_POP_GROUP),
+ gdmessage->id,
+ gl_enum_to_debug_severity(GL_DEBUG_SEVERITY_NOTIFICATION),
+ gdmessage->length, gdmessage->message);
if (gdmessage->message != (char*)out_of_memory)
free(gdmessage->message);
@@ -928,10 +1040,11 @@ _mesa_PopDebugGroup()
free_errors_data(ctx, prevStackDepth);
}
+
void GLAPIENTRY
_mesa_DebugMessageInsertARB(GLenum source, GLenum type, GLuint id,
GLenum severity, GLint length,
- const GLcharARB* buf)
+ const GLcharARB *buf)
{
const char *callerstr = "glDebugMessageInsertARB";
@@ -940,14 +1053,14 @@ _mesa_DebugMessageInsertARB(GLenum source, GLenum type, GLuint id,
if (!validate_params(ctx, INSERT_ARB, callerstr, source, type, severity))
return; /* GL_INVALID_ENUM */
- message_insert(source, type, id, severity, length, buf,
- callerstr);
+ message_insert(source, type, id, severity, length, buf, callerstr);
}
+
GLuint GLAPIENTRY
-_mesa_GetDebugMessageLogARB(GLuint count, GLsizei logSize, GLenum* sources,
- GLenum* types, GLenum* ids, GLenum* severities,
- GLsizei* lengths, GLcharARB* messageLog)
+_mesa_GetDebugMessageLogARB(GLuint count, GLsizei logSize, GLenum *sources,
+ GLenum *types, GLenum *ids, GLenum *severities,
+ GLsizei *lengths, GLcharARB *messageLog)
{
const char *callerstr = "glGetDebugMessageLogARB";
@@ -955,6 +1068,7 @@ _mesa_GetDebugMessageLogARB(GLuint count, GLsizei logSize, GLenum* sources,
lengths, messageLog, MESSAGE_LOG_ARB, callerstr);
}
+
void GLAPIENTRY
_mesa_DebugMessageControlARB(GLenum gl_source, GLenum gl_type,
GLenum gl_severity,
@@ -967,47 +1081,27 @@ _mesa_DebugMessageControlARB(GLenum gl_source, GLenum gl_type,
enabled, CONTROL_ARB, callerstr);
}
+
void GLAPIENTRY
_mesa_DebugMessageCallbackARB(GLDEBUGPROCARB callback, const void *userParam)
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Debug.Callback = callback;
- ctx->Debug.CallbackData = userParam;
- ctx->Debug.ARBCallback = GL_TRUE;
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ if (debug) {
+ debug->Callback = callback;
+ debug->CallbackData = userParam;
+ debug->ARBCallback = GL_TRUE;
+ }
}
+
void
_mesa_init_errors(struct gl_context *ctx)
{
- int s, t, sev;
-
- ctx->Debug.Callback = NULL;
- ctx->Debug.SyncOutput = GL_FALSE;
- ctx->Debug.Log[0].length = 0;
- ctx->Debug.NumMessages = 0;
- ctx->Debug.NextMsg = 0;
- ctx->Debug.NextMsgLength = 0;
- ctx->Debug.GroupStackDepth = 0;
-
- /* Enable all the messages with severity HIGH or MEDIUM by default. */
- memset(ctx->Debug.Defaults[0][MESA_DEBUG_SEVERITY_HIGH], GL_TRUE,
- sizeof ctx->Debug.Defaults[0][MESA_DEBUG_SEVERITY_HIGH]);
- memset(ctx->Debug.Defaults[0][MESA_DEBUG_SEVERITY_MEDIUM], GL_TRUE,
- sizeof ctx->Debug.Defaults[0][MESA_DEBUG_SEVERITY_MEDIUM]);
- memset(ctx->Debug.Defaults[0][MESA_DEBUG_SEVERITY_LOW], GL_FALSE,
- sizeof ctx->Debug.Defaults[0][MESA_DEBUG_SEVERITY_LOW]);
-
- /* Initialize state for filtering known debug messages. */
- for (s = 0; s < MESA_DEBUG_SOURCE_COUNT; s++)
- for (t = 0; t < MESA_DEBUG_TYPE_COUNT; t++) {
- ctx->Debug.Namespaces[0][s][t].IDs = _mesa_NewHashTable();
- assert(ctx->Debug.Namespaces[0][s][t].IDs);
-
- for (sev = 0; sev < MESA_DEBUG_SEVERITY_COUNT; sev++)
- make_empty_list(&ctx->Debug.Namespaces[0][s][t].Severity[sev]);
- }
+ /* no-op */
}
+
/**
* Loop through debug group stack tearing down states for
* filtering debug messages.
@@ -1015,13 +1109,16 @@ _mesa_init_errors(struct gl_context *ctx)
void
_mesa_free_errors_data(struct gl_context *ctx)
{
- GLint i;
+ if (ctx->Debug) {
+ GLint i;
- for (i = 0; i <= ctx->Debug.GroupStackDepth; i++) {
- free_errors_data(ctx, i);
+ for (i = 0; i <= ctx->Debug->GroupStackDepth; i++) {
+ free_errors_data(ctx, i);
+ }
}
}
+
/**********************************************************************/
/** \name Diagnostics */
/*@{*/
@@ -1077,6 +1174,7 @@ output_if_debug(const char *prefixString, const char *outputString,
}
}
+
/**
* When a new type of error is recorded, print a message describing
* previous errors which were accumulated.
@@ -1149,6 +1247,7 @@ _mesa_problem( const struct gl_context *ctx, const char *fmtString, ... )
}
}
+
static GLboolean
should_output(struct gl_context *ctx, GLenum error, const char *fmtString)
{
@@ -1185,6 +1284,7 @@ should_output(struct gl_context *ctx, GLenum error, const char *fmtString)
return GL_FALSE;
}
+
void
_mesa_gl_debug(struct gl_context *ctx,
GLuint *id,
@@ -1202,8 +1302,7 @@ _mesa_gl_debug(struct gl_context *ctx,
len = _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args);
va_end(args);
- _mesa_log_msg(ctx, MESA_DEBUG_SOURCE_API, type,
- *id, severity, len, s);
+ log_msg(ctx, MESA_DEBUG_SOURCE_API, type, *id, severity, len, s);
}
@@ -1248,7 +1347,8 @@ _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
if (len >= MAX_DEBUG_MESSAGE_LENGTH) {
/* Too long error message. Whoever calls _mesa_error should use
- * shorter strings. */
+ * shorter strings.
+ */
ASSERT(0);
return;
}
@@ -1268,11 +1368,8 @@ _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... )
/* Log the error via ARB_debug_output if needed.*/
if (do_log) {
- _mesa_log_msg(ctx,
- MESA_DEBUG_SOURCE_API,
- MESA_DEBUG_TYPE_ERROR,
- error_msg_id,
- MESA_DEBUG_SEVERITY_HIGH, len, s2);
+ log_msg(ctx, MESA_DEBUG_SOURCE_API, MESA_DEBUG_TYPE_ERROR,
+ error_msg_id, MESA_DEBUG_SEVERITY_HIGH, len, s2);
}
}
@@ -1329,7 +1426,7 @@ _mesa_shader_debug( struct gl_context *ctx, GLenum type, GLuint *id,
if (len >= MAX_DEBUG_MESSAGE_LENGTH)
len = MAX_DEBUG_MESSAGE_LENGTH - 1;
- _mesa_log_msg(ctx, source, type, *id, severity, len, msg);
+ log_msg(ctx, source, type, *id, severity, len, msg);
}
/*@}*/
diff --git a/mesalib/src/mesa/main/errors.h b/mesalib/src/mesa/main/errors.h
index a837dc8e1..cd414e6b6 100644
--- a/mesalib/src/mesa/main/errors.h
+++ b/mesalib/src/mesa/main/errors.h
@@ -83,6 +83,9 @@ _mesa_gl_debug(struct gl_context *ctx,
} \
} while (0)
+struct gl_debug_state *
+_mesa_get_debug_state(struct gl_context *ctx);
+
extern void
_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
const char *msg, int len);
diff --git a/mesalib/src/mesa/main/execmem.c b/mesalib/src/mesa/main/execmem.c
index d63bb4a4e..7267cf85f 100644
--- a/mesalib/src/mesa/main/execmem.c
+++ b/mesalib/src/mesa/main/execmem.c
@@ -32,7 +32,6 @@
#include "imports.h"
-#include "glapi/glthread.h"
@@ -59,7 +58,7 @@
#define EXEC_HEAP_SIZE (10*1024*1024)
-_glthread_DECLARE_STATIC_MUTEX(exec_mutex);
+static mtx_t exec_mutex = _MTX_INITIALIZER_NP;
static struct mem_block *exec_heap = NULL;
static unsigned char *exec_mem = NULL;
@@ -93,7 +92,7 @@ _mesa_exec_malloc(GLuint size)
struct mem_block *block = NULL;
void *addr = NULL;
- _glthread_LOCK_MUTEX(exec_mutex);
+ mtx_lock(&exec_mutex);
if (!init_heap())
goto bail;
@@ -109,7 +108,7 @@ _mesa_exec_malloc(GLuint size)
printf("_mesa_exec_malloc failed\n");
bail:
- _glthread_UNLOCK_MUTEX(exec_mutex);
+ mtx_unlock(&exec_mutex);
return addr;
}
@@ -118,7 +117,7 @@ bail:
void
_mesa_exec_free(void *addr)
{
- _glthread_LOCK_MUTEX(exec_mutex);
+ mtx_lock(&exec_mutex);
if (exec_heap) {
struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem);
@@ -127,7 +126,7 @@ _mesa_exec_free(void *addr)
mmFreeMem(block);
}
- _glthread_UNLOCK_MUTEX(exec_mutex);
+ mtx_unlock(&exec_mutex);
}
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 5f741fbd2..c46d70b20 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -83,6 +83,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_arrays_of_arrays", o(ARB_arrays_of_arrays), GL, 2012 },
{ "GL_ARB_base_instance", o(ARB_base_instance), GL, 2011 },
{ "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 },
+ { "GL_ARB_buffer_storage", o(ARB_buffer_storage), GL, 2013 },
{ "GL_ARB_clear_buffer_object", o(dummy_true), GL, 2012 },
{ "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 },
{ "GL_ARB_compute_shader", o(ARB_compute_shader), GL, 2012 },
@@ -106,7 +107,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_framebuffer_sRGB", o(EXT_framebuffer_sRGB), GL, 1998 },
{ "GL_ARB_get_program_binary", o(dummy_true), GL, 2010 },
{ "GL_ARB_gpu_shader5", o(ARB_gpu_shader5), GL, 2010 },
- { "GL_ARB_half_float_pixel", o(ARB_half_float_pixel), GL, 2003 },
+ { "GL_ARB_half_float_pixel", o(dummy_true), GL, 2003 },
{ "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), GL, 2008 },
{ "GL_ARB_instanced_arrays", o(ARB_instanced_arrays), GL, 2008 },
{ "GL_ARB_internalformat_query", o(ARB_internalformat_query), GL, 2011 },
@@ -126,6 +127,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_sample_shading", o(ARB_sample_shading), GL, 2009 },
{ "GL_ARB_sampler_objects", o(dummy_true), GL, 2009 },
{ "GL_ARB_seamless_cube_map", o(ARB_seamless_cube_map), GL, 2009 },
+ { "GL_ARB_separate_shader_objects", o(ARB_separate_shader_objects), GL, 2010 },
{ "GL_ARB_shader_atomic_counters", o(ARB_shader_atomic_counters), GL, 2011 },
{ "GL_ARB_shader_bit_encoding", o(ARB_shader_bit_encoding), GL, 2010 },
{ "GL_ARB_shader_image_load_store", o(ARB_shader_image_load_store), GL, 2011 },
@@ -401,7 +403,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
ctx->Extensions.ARB_fragment_shader = GL_TRUE;
ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
- ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index e459e0c63..a9dcc5144 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -89,9 +89,9 @@ delete_dummy_framebuffer(struct gl_framebuffer *fb)
void
_mesa_init_fbobjects(struct gl_context *ctx)
{
- _glthread_INIT_MUTEX(DummyFramebuffer.Mutex);
- _glthread_INIT_MUTEX(DummyRenderbuffer.Mutex);
- _glthread_INIT_MUTEX(IncompleteFramebuffer.Mutex);
+ mtx_init(&DummyFramebuffer.Mutex, mtx_plain);
+ mtx_init(&DummyRenderbuffer.Mutex, mtx_plain);
+ mtx_init(&IncompleteFramebuffer.Mutex, mtx_plain);
DummyFramebuffer.Delete = delete_dummy_framebuffer;
DummyRenderbuffer.Delete = delete_dummy_renderbuffer;
IncompleteFramebuffer.Delete = delete_dummy_framebuffer;
@@ -484,7 +484,7 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
{
struct gl_renderbuffer_attachment *att;
- _glthread_LOCK_MUTEX(fb->Mutex);
+ mtx_lock(&fb->Mutex);
att = get_attachment(ctx, fb, attachment);
ASSERT(att);
@@ -504,7 +504,7 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
invalidate_framebuffer(fb);
- _glthread_UNLOCK_MUTEX(fb->Mutex);
+ mtx_unlock(&fb->Mutex);
}
@@ -1352,9 +1352,9 @@ _mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
GLuint name = first + i;
renderbuffers[i] = name;
/* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
_mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
}
@@ -2218,9 +2218,9 @@ _mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
GLuint name = first + i;
framebuffers[i] = name;
/* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
_mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
}
@@ -2433,7 +2433,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
FLUSH_VERTICES(ctx, _NEW_BUFFERS);
- _glthread_LOCK_MUTEX(fb->Mutex);
+ mtx_lock(&fb->Mutex);
if (texObj) {
if (attachment == GL_DEPTH_ATTACHMENT &&
texObj == fb->Attachment[BUFFER_STENCIL].Texture &&
@@ -2491,7 +2491,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
invalidate_framebuffer(fb);
- _glthread_UNLOCK_MUTEX(fb->Mutex);
+ mtx_unlock(&fb->Mutex);
}
diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c
index dee253c40..2772ff2d3 100644
--- a/mesalib/src/mesa/main/format_pack.c
+++ b/mesalib/src/mesa/main/format_pack.c
@@ -1936,9 +1936,9 @@ _mesa_get_pack_ubyte_rgba_function(mesa_format format)
/* should never convert RGBA to these formats */
table[MESA_FORMAT_S8_UINT_Z24_UNORM] = NULL;
- table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL;
- table[MESA_FORMAT_Z_UNORM16] = NULL;
table[MESA_FORMAT_Z24_UNORM_S8_UINT] = NULL;
+ table[MESA_FORMAT_Z_UNORM16] = NULL;
+ table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL;
table[MESA_FORMAT_X8Z24_UNORM] = NULL;
table[MESA_FORMAT_Z_UNORM32] = NULL;
table[MESA_FORMAT_S_UINT8] = NULL;
@@ -2099,9 +2099,9 @@ _mesa_get_pack_float_rgba_function(mesa_format format)
/* should never convert RGBA to these formats */
table[MESA_FORMAT_S8_UINT_Z24_UNORM] = NULL;
- table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL;
- table[MESA_FORMAT_Z_UNORM16] = NULL;
table[MESA_FORMAT_Z24_UNORM_S8_UINT] = NULL;
+ table[MESA_FORMAT_Z_UNORM16] = NULL;
+ table[MESA_FORMAT_Z24_UNORM_X8_UINT] = NULL;
table[MESA_FORMAT_X8Z24_UNORM] = NULL;
table[MESA_FORMAT_Z_UNORM32] = NULL;
table[MESA_FORMAT_S_UINT8] = NULL;
@@ -2433,8 +2433,8 @@ _mesa_get_pack_float_z_func(mesa_format format)
case MESA_FORMAT_S8_UINT_Z24_UNORM:
case MESA_FORMAT_X8Z24_UNORM:
return pack_float_z_Z24_S8;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
return pack_float_z_S8_Z24;
case MESA_FORMAT_Z_UNORM16:
return pack_float_z_Z16;
@@ -2518,8 +2518,8 @@ _mesa_get_pack_uint_z_func(mesa_format format)
case MESA_FORMAT_S8_UINT_Z24_UNORM:
case MESA_FORMAT_X8Z24_UNORM:
return pack_uint_z_Z24_S8;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
return pack_uint_z_S8_Z24;
case MESA_FORMAT_Z_UNORM16:
return pack_uint_z_Z16;
@@ -2581,7 +2581,7 @@ _mesa_get_pack_ubyte_stencil_func(mesa_format format)
switch (format) {
case MESA_FORMAT_S8_UINT_Z24_UNORM:
return pack_ubyte_stencil_Z24_S8;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
return pack_ubyte_stencil_S8_Z24;
case MESA_FORMAT_S_UINT8:
return pack_ubyte_stencil_S8;
@@ -2616,8 +2616,8 @@ _mesa_pack_float_z_row(mesa_format format, GLuint n,
}
}
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
{
/* don't disturb the stencil values */
GLuint *d = ((GLuint *) dst);
@@ -2690,8 +2690,8 @@ _mesa_pack_uint_z_row(mesa_format format, GLuint n,
}
}
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
{
/* don't disturb the stencil values */
GLuint *d = ((GLuint *) dst);
@@ -2762,7 +2762,7 @@ _mesa_pack_ubyte_stencil_row(mesa_format format, GLuint n,
}
}
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
{
/* don't disturb the Z values */
GLuint *d = ((GLuint *) dst);
@@ -2803,7 +2803,7 @@ _mesa_pack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n,
case MESA_FORMAT_S8_UINT_Z24_UNORM:
memcpy(dst, src, n * sizeof(GLuint));
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
{
GLuint *d = ((GLuint *) dst);
GLuint i;
diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c
index 02ad00a9d..276ba556a 100644
--- a/mesalib/src/mesa/main/format_unpack.c
+++ b/mesalib/src/mesa/main/format_unpack.c
@@ -2366,9 +2366,9 @@ get_unpack_rgba_function(mesa_format format)
table[MESA_FORMAT_B10G10R10A2_UINT] = unpack_ARGB2101010_UINT;
table[MESA_FORMAT_R10G10B10A2_UINT] = unpack_ABGR2101010_UINT;
table[MESA_FORMAT_S8_UINT_Z24_UNORM] = unpack_Z24_S8;
- table[MESA_FORMAT_Z24_UNORM_X8_UINT] = unpack_S8_Z24;
+ table[MESA_FORMAT_Z24_UNORM_S8_UINT] = unpack_S8_Z24;
table[MESA_FORMAT_Z_UNORM16] = unpack_Z16;
- table[MESA_FORMAT_Z24_UNORM_S8_UINT] = unpack_X8_Z24;
+ table[MESA_FORMAT_Z24_UNORM_X8_UINT] = unpack_X8_Z24;
table[MESA_FORMAT_X8Z24_UNORM] = unpack_Z24_X8;
table[MESA_FORMAT_Z_UNORM32] = unpack_Z32;
table[MESA_FORMAT_S_UINT8] = unpack_S8;
@@ -3986,8 +3986,8 @@ _mesa_unpack_float_z_row(mesa_format format, GLuint n,
case MESA_FORMAT_X8Z24_UNORM:
unpack = unpack_float_z_Z24_X8;
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
unpack = unpack_float_z_X8_Z24;
break;
case MESA_FORMAT_Z_UNORM16:
@@ -4091,8 +4091,8 @@ _mesa_unpack_uint_z_row(mesa_format format, GLuint n,
case MESA_FORMAT_X8Z24_UNORM:
unpack = unpack_uint_z_Z24_X8;
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
unpack = unpack_uint_z_X8_Z24;
break;
case MESA_FORMAT_Z_UNORM16:
@@ -4164,7 +4164,7 @@ _mesa_unpack_ubyte_stencil_row(mesa_format format, GLuint n,
case MESA_FORMAT_S8_UINT_Z24_UNORM:
unpack_ubyte_s_Z24_S8(src, dst, n);
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
unpack_ubyte_s_S8_Z24(src, dst, n);
break;
case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
@@ -4189,11 +4189,30 @@ unpack_uint_24_8_depth_stencil_S8_Z24(const GLuint *src, GLuint *dst, GLuint n)
}
static void
+unpack_uint_24_8_depth_stencil_Z32_S8X24(const GLuint *src,
+ GLuint *dst, GLuint n)
+{
+ GLuint i;
+
+ for (i = 0; i < n; i++) {
+ /* 8 bytes per pixel (float + uint32) */
+ GLfloat zf = ((GLfloat *) src)[i * 2 + 0];
+ GLuint z24 = (GLuint) (zf * (GLfloat) 0xffffff);
+ GLuint s = src[i * 2 + 1] & 0xff;
+ dst[i] = (z24 << 8) | s;
+ }
+}
+
+static void
unpack_uint_24_8_depth_stencil_Z24_S8(const GLuint *src, GLuint *dst, GLuint n)
{
memcpy(dst, src, n * 4);
}
+/**
+ * Unpack depth/stencil returning as GL_UNSIGNED_INT_24_8.
+ * \param format the source data format
+ */
void
_mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n,
const void *src, GLuint *dst)
@@ -4202,9 +4221,12 @@ _mesa_unpack_uint_24_8_depth_stencil_row(mesa_format format, GLuint n,
case MESA_FORMAT_S8_UINT_Z24_UNORM:
unpack_uint_24_8_depth_stencil_Z24_S8(src, dst, n);
break;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
unpack_uint_24_8_depth_stencil_S8_Z24(src, dst, n);
break;
+ case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
+ unpack_uint_24_8_depth_stencil_Z32_S8X24(src, dst, n);
+ break;
default:
_mesa_problem(NULL,
"bad format %s in _mesa_unpack_uint_24_8_depth_stencil_row",
diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c
index 10731d5a4..f6c399ede 100644
--- a/mesalib/src/mesa/main/formats.c
+++ b/mesalib/src/mesa/main/formats.c
@@ -439,8 +439,8 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
1, 1, 4 /* BlockWidth/Height,Bytes */
},
{
- MESA_FORMAT_Z24_UNORM_X8_UINT, /* Name */
- "MESA_FORMAT_Z24_UNORM_X8_UINT", /* StrName */
+ MESA_FORMAT_Z24_UNORM_S8_UINT, /* Name */
+ "MESA_FORMAT_Z24_UNORM_S8_UINT", /* StrName */
GL_DEPTH_STENCIL, /* BaseFormat */
GL_UNSIGNED_NORMALIZED, /* DataType */
0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
@@ -457,8 +457,8 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
1, 1, 2 /* BlockWidth/Height,Bytes */
},
{
- MESA_FORMAT_Z24_UNORM_S8_UINT, /* Name */
- "MESA_FORMAT_Z24_UNORM_S8_UINT", /* StrName */
+ MESA_FORMAT_Z24_UNORM_X8_UINT, /* Name */
+ "MESA_FORMAT_Z24_UNORM_X8_UINT", /* StrName */
GL_DEPTH_COMPONENT, /* BaseFormat */
GL_UNSIGNED_NORMALIZED, /* DataType */
0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
@@ -2472,7 +2472,7 @@ _mesa_format_to_type_and_comps(mesa_format format,
*comps = 2;
return;
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
*datatype = GL_UNSIGNED_INT_8_24_REV_MESA;
*comps = 2;
return;
@@ -2482,7 +2482,7 @@ _mesa_format_to_type_and_comps(mesa_format format,
*comps = 1;
return;
- case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
*datatype = GL_UNSIGNED_INT;
*comps = 1;
return;
@@ -3123,14 +3123,14 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format,
return format == GL_DEPTH_STENCIL && type == GL_UNSIGNED_INT_24_8 &&
!swapBytes;
case MESA_FORMAT_X8Z24_UNORM:
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
return GL_FALSE;
case MESA_FORMAT_Z_UNORM16:
return format == GL_DEPTH_COMPONENT && type == GL_UNSIGNED_SHORT &&
!swapBytes;
- case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
return GL_FALSE;
case MESA_FORMAT_Z_UNORM32:
diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h
index 63d9565e3..3102584b6 100644
--- a/mesalib/src/mesa/main/formats.h
+++ b/mesalib/src/mesa/main/formats.h
@@ -339,33 +339,33 @@ typedef enum
/* Type P formats */ /* msb <------ TEXEL BITS -----------> lsb */
/* ---- ---- ---- ---- ---- ---- ---- ---- */
- MESA_FORMAT_A8B8G8R8_UNORM, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */
- MESA_FORMAT_R8G8B8A8_UNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
- MESA_FORMAT_B8G8R8A8_UNORM, /* BBBB BBBB GGGG GGGG RRRR RRRR AAAA AAAA */
- MESA_FORMAT_A8R8G8B8_UNORM, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
- MESA_FORMAT_X8B8G8R8_UNORM, /* xxxx xxxx BBBB BBBB GGGG GGGG RRRR RRRR */
- MESA_FORMAT_R8G8B8X8_UNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB xxxx xxxx */
- MESA_FORMAT_B8G8R8X8_UNORM, /* BBBB BBBB GGGG GGGG RRRR RRRR xxxx xxxx */
- MESA_FORMAT_X8R8G8B8_UNORM, /* xxxx xxxx RRRR RRRR GGGG GGGG BBBB BBBB */
+ MESA_FORMAT_A8B8G8R8_UNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
+ MESA_FORMAT_R8G8B8A8_UNORM, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_B8G8R8A8_UNORM, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
+ MESA_FORMAT_A8R8G8B8_UNORM, /* BBBB BBBB GGGG GGGG RRRR RRRR AAAA AAAA */
+ MESA_FORMAT_X8B8G8R8_UNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB xxxx xxxx */
+ MESA_FORMAT_R8G8B8X8_UNORM, /* xxxx xxxx BBBB BBBB GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_B8G8R8X8_UNORM, /* xxxx xxxx RRRR RRRR GGGG GGGG BBBB BBBB */
+ MESA_FORMAT_X8R8G8B8_UNORM, /* BBBB BBBB GGGG GGGG RRRR RRRR xxxx xxxx */
/* Type A formats */
MESA_FORMAT_BGR_UNORM8, /* uchar[i * 3] = B, [i * 3 + 1] = G, [i *3 + 2] = R */
MESA_FORMAT_RGB_UNORM8, /* uchar[i * 3] = R, [i * 3 + 1] = G, [i *3 + 2] = B */
/* Type P formats */
- MESA_FORMAT_B5G6R5_UNORM, /* BBBB BGGG GGGR RRRR */
- MESA_FORMAT_R5G6B5_UNORM, /* RRRR RGGG GGGB BBBB */
- MESA_FORMAT_B4G4R4A4_UNORM, /* BBBB GGGG RRRR AAAA */
- MESA_FORMAT_A4R4G4B4_UNORM, /* AAAA RRRR GGGG BBBB */
- MESA_FORMAT_A1B5G5R5_UNORM, /* ABBB BBGG GGGR RRRR */
- MESA_FORMAT_B5G5R5A1_UNORM, /* BBBB BGGG GGRR RRRA */
- MESA_FORMAT_A1R5G5B5_UNORM, /* ARRR RRGG GGGB BBBB */
- MESA_FORMAT_L4A4_UNORM, /* LLLL AAAA */
- MESA_FORMAT_L8A8_UNORM, /* LLLL LLLL AAAA AAAA */
- MESA_FORMAT_A8L8_UNORM, /* AAAA AAAA LLLL LLLL */
- MESA_FORMAT_L16A16_UNORM, /* LLLL LLLL LLLL LLLL AAAA AAAA AAAA AAAA */
- MESA_FORMAT_A16L16_UNORM, /* AAAA AAAA AAAA AAAA LLLL LLLL LLLL LLLL */
- MESA_FORMAT_B2G3R3_UNORM, /* BBGG GRRR */
+ MESA_FORMAT_B5G6R5_UNORM, /* RRRR RGGG GGGB BBBB */
+ MESA_FORMAT_R5G6B5_UNORM, /* BBBB BGGG GGGR RRRR */
+ MESA_FORMAT_B4G4R4A4_UNORM, /* AAAA RRRR GGGG BBBB */
+ MESA_FORMAT_A4R4G4B4_UNORM, /* BBBB GGGG RRRR AAAA */
+ MESA_FORMAT_A1B5G5R5_UNORM, /* RRRR RGGG GGBB BBBA */
+ MESA_FORMAT_B5G5R5A1_UNORM, /* ARRR RRGG GGGB BBBB */
+ MESA_FORMAT_A1R5G5B5_UNORM, /* BBBB BGGG GGRR RRRA */
+ MESA_FORMAT_L4A4_UNORM, /* AAAA LLLL */
+ MESA_FORMAT_L8A8_UNORM, /* AAAA AAAA LLLL LLLL */
+ MESA_FORMAT_A8L8_UNORM, /* LLLL LLLL AAAA AAAA */
+ MESA_FORMAT_L16A16_UNORM, /* AAAA AAAA AAAA AAAA LLLL LLLL LLLL LLLL */
+ MESA_FORMAT_A16L16_UNORM, /* LLLL LLLL LLLL LLLL AAAA AAAA AAAA AAAA */
+ MESA_FORMAT_B2G3R3_UNORM, /* RRRG GGBB */
/* Type A formats */
MESA_FORMAT_A_UNORM8, /* uchar[i] = A */
@@ -383,25 +383,25 @@ typedef enum
MESA_FORMAT_R_UNORM8, /* uchar[i] = R */
/* Type P formats */
- MESA_FORMAT_R8G8_UNORM, /* RRRR RRRR GGGG GGGG */
- MESA_FORMAT_G8R8_UNORM, /* GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_R8G8_UNORM, /* GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_G8R8_UNORM, /* RRRR RRRR GGGG GGGG */
/* Type A format(s) */
MESA_FORMAT_R_UNORM16, /* ushort[i] = R */
/* Type P formats */
- MESA_FORMAT_R16G16_UNORM, /* RRRR RRRR RRRR RRRR GGGG GGGG GGGG GGGG */
- MESA_FORMAT_G16R16_UNORM, /* GGGG GGGG GGGG GGGG RRRR RRRR RRRR RRRR */
- MESA_FORMAT_B10G10R10A2_UNORM,/* BBBB BBBB BBGG GGGG GGGG RRRR RRRR RRAA */
- MESA_FORMAT_S8_UINT_Z24_UNORM,/* SSSS SSSS ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */
- MESA_FORMAT_Z24_UNORM_X8_UINT,/* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ xxxx xxxx */
+ MESA_FORMAT_R16G16_UNORM, /* GGGG GGGG GGGG GGGG RRRR RRRR RRRR RRRR */
+ MESA_FORMAT_G16R16_UNORM, /* RRRR RRRR RRRR RRRR GGGG GGGG GGGG GGGG */
+ MESA_FORMAT_B10G10R10A2_UNORM,/* AARR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */
+ MESA_FORMAT_S8_UINT_Z24_UNORM,/* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ SSSS SSSS */
+ MESA_FORMAT_Z24_UNORM_S8_UINT,/* SSSS SSSS ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */
/* Type A format(s) */
MESA_FORMAT_Z_UNORM16, /* ushort[i] = Z */
/* Type P formats */
- MESA_FORMAT_Z24_UNORM_S8_UINT,/* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ SSSS SSSS */
- MESA_FORMAT_X8Z24_UNORM, /* xxxx xxxx ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */
+ MESA_FORMAT_Z24_UNORM_X8_UINT,/* xxxx xxxx ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ */
+ MESA_FORMAT_X8Z24_UNORM, /* ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ ZZZZ xxxx xxxx */
/* Type A formats */
MESA_FORMAT_Z_UNORM32, /* uint[i] = Z */
@@ -416,14 +416,14 @@ typedef enum
MESA_FORMAT_BGR_SRGB8, /* uchar[i * 3] = B, [i * 3 + 1] = G, [i *3 + 2] = R */
/* Type P formats */
- MESA_FORMAT_A8B8G8R8_SRGB, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR*/
- MESA_FORMAT_B8G8R8A8_SRGB, /* BBBB BBBB GGGG GGGG RRRR RRRR AAAA AAAA */
+ MESA_FORMAT_A8B8G8R8_SRGB, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
+ MESA_FORMAT_B8G8R8A8_SRGB, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
/* Type A format(s) */
MESA_FORMAT_L_SRGB8, /* uchar[i] = L */
/* Type P formats */
- MESA_FORMAT_L8A8_SRGB, /* LLLL LLLL AAAA AAAA */
+ MESA_FORMAT_L8A8_SRGB, /* AAAA AAAA LLLL LLLL */
/* Type C formats */
MESA_FORMAT_SRGB_DXT1,
@@ -548,16 +548,16 @@ typedef enum
MESA_FORMAT_R_SNORM8, /* char[i] = R */
/* Type P formats */
- MESA_FORMAT_R8G8_SNORM, /* RRRR RRRR GGGG GGGG */
- MESA_FORMAT_X8B8G8R8_SNORM, /* xxxx xxxx BBBB BBBB GGGG GGGG RRRR RRRR */
- MESA_FORMAT_A8B8G8R8_SNORM, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */
- MESA_FORMAT_R8G8B8A8_SNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
+ MESA_FORMAT_R8G8_SNORM, /* GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_X8B8G8R8_SNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB xxxx xxxx */
+ MESA_FORMAT_A8B8G8R8_SNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
+ MESA_FORMAT_R8G8B8A8_SNORM, /* AAAA AAAA BBBB BBBB GGGG GGGG RRRR RRRR */
/* Type A format(s) */
MESA_FORMAT_R_SNORM16, /* short[i] = R */
/* Type P format(s) */
- MESA_FORMAT_R16G16_SNORM, /* RRRR RRRR RRRR RRRR GGGG GGGG GGGG GGGG */
+ MESA_FORMAT_R16G16_SNORM, /* GGGG GGGG GGGG GGGG RRRR RRRR RRRR RRRR */
/* Type A format(s) */
MESA_FORMAT_RGB_SNORM16, /* short[i * 3] = R, [i * 3 + 1] = G, [i *3 + 2] = B */
@@ -597,7 +597,7 @@ typedef enum
MESA_FORMAT_L_SNORM8, /* char[i] = L */
/* Type P format(s) */
- MESA_FORMAT_L8A8_SNORM, /* LLLL LLLL AAAA AAAA */
+ MESA_FORMAT_L8A8_SNORM, /* AAAA AAAA LLLL LLLL */
/* Type A format(s) */
MESA_FORMAT_I_SNORM8, /* char[i] = I */
@@ -608,21 +608,21 @@ typedef enum
/* Type P format(s) */
MESA_FORMAT_R9G9B9E5_FLOAT,
- MESA_FORMAT_R11G11B10_FLOAT,
+ MESA_FORMAT_R11G11B10_FLOAT, /* BBBB BBBB BBGG GGGG GGGG GRRR RRRR RRRR */
/* Type A format(s) */
MESA_FORMAT_Z_FLOAT32,
/* Type P formats */
- MESA_FORMAT_Z32_FLOAT_S8X24_UINT,
+ MESA_FORMAT_Z32_FLOAT_S8X24_UINT, /* (float, x24s8) */
- MESA_FORMAT_B10G10R10A2_UINT,
- MESA_FORMAT_R10G10B10A2_UINT,
+ MESA_FORMAT_B10G10R10A2_UINT, /* AARR RRRR RRRR GGGG GGGG GGBB BBBB BBBB */
+ MESA_FORMAT_R10G10B10A2_UINT, /* AABB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */
- MESA_FORMAT_B4G4R4X4_UNORM, /* BBBB GGGG RRRR xxxx */
- MESA_FORMAT_B5G5R5X1_UNORM, /* BBBB BGGG GGRR RRRx */
- MESA_FORMAT_R8G8B8X8_SNORM, /* RRRR RRRR GGGG GGGG BBBB BBBB xxxx xxxx */
- MESA_FORMAT_R8G8B8X8_SRGB, /* RRRR RRRR GGGG GGGG BBBB BBBB xxxx xxxx */
+ MESA_FORMAT_B4G4R4X4_UNORM, /* xxxx RRRR GGGG BBBB */
+ MESA_FORMAT_B5G5R5X1_UNORM, /* xRRR RRGG GGGB BBBB */
+ MESA_FORMAT_R8G8B8X8_SNORM, /* xxxx xxxx BBBB BBBB GGGG GGGG RRRR RRRR */
+ MESA_FORMAT_R8G8B8X8_SRGB, /* xxxx xxxx BBBB BBBB GGGG GGGG RRRR RRRR */
/* Type A formats */
MESA_FORMAT_RGBX_UINT8, /* uchar[i * 4] = R, [i * 4 + 1] = G, [i * 4 + 2] = B, [i * 4 + 3] = x */
@@ -643,9 +643,9 @@ typedef enum
MESA_FORMAT_RGBX_SINT32, /* ... */
/* Type P formats */
- MESA_FORMAT_R10G10B10A2_UNORM,
- MESA_FORMAT_G8R8_SNORM,
- MESA_FORMAT_G16R16_SNORM,
+ MESA_FORMAT_R10G10B10A2_UNORM, /* AABB BBBB BBBB GGGG GGGG GGRR RRRR RRRR */
+ MESA_FORMAT_G8R8_SNORM, /* RRRR RRRR GGGG GGGG */
+ MESA_FORMAT_G16R16_SNORM, /* RRRR RRRR RRRR RRRR GGGG GGGG GGGG GGGG */
MESA_FORMAT_COUNT
} mesa_format;
diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c
index 54eeda2b2..7416bb118 100644
--- a/mesalib/src/mesa/main/framebuffer.c
+++ b/mesalib/src/mesa/main/framebuffer.c
@@ -130,7 +130,7 @@ _mesa_initialize_window_framebuffer(struct gl_framebuffer *fb,
memset(fb, 0, sizeof(struct gl_framebuffer));
- _glthread_INIT_MUTEX(fb->Mutex);
+ mtx_init(&fb->Mutex, mtx_plain);
fb->RefCount = 1;
@@ -182,7 +182,7 @@ _mesa_initialize_user_framebuffer(struct gl_framebuffer *fb, GLuint name)
fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
fb->_ColorReadBufferIndex = BUFFER_COLOR0;
fb->Delete = _mesa_destroy_framebuffer;
- _glthread_INIT_MUTEX(fb->Mutex);
+ mtx_init(&fb->Mutex, mtx_plain);
}
@@ -213,7 +213,7 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
assert(fb);
assert(fb->RefCount == 0);
- _glthread_DESTROY_MUTEX(fb->Mutex);
+ mtx_destroy(&fb->Mutex);
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
@@ -244,11 +244,11 @@ _mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
GLboolean deleteFlag = GL_FALSE;
struct gl_framebuffer *oldFb = *ptr;
- _glthread_LOCK_MUTEX(oldFb->Mutex);
+ mtx_lock(&oldFb->Mutex);
ASSERT(oldFb->RefCount > 0);
oldFb->RefCount--;
deleteFlag = (oldFb->RefCount == 0);
- _glthread_UNLOCK_MUTEX(oldFb->Mutex);
+ mtx_unlock(&oldFb->Mutex);
if (deleteFlag)
oldFb->Delete(oldFb);
@@ -258,9 +258,9 @@ _mesa_reference_framebuffer_(struct gl_framebuffer **ptr,
assert(!*ptr);
if (fb) {
- _glthread_LOCK_MUTEX(fb->Mutex);
+ mtx_lock(&fb->Mutex);
fb->RefCount++;
- _glthread_UNLOCK_MUTEX(fb->Mutex);
+ mtx_unlock(&fb->Mutex);
*ptr = fb;
}
}
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 54f7d7745..b1908515c 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -28,6 +28,7 @@
#include "blend.h"
#include "enable.h"
#include "enums.h"
+#include "errors.h"
#include "extensions.h"
#include "get.h"
#include "macros.h"
@@ -973,6 +974,26 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
_mesa_problem(ctx, "driver doesn't implement GetTimestamp");
}
break;
+ /* GL_KHR_DEBUG */
+ case GL_DEBUG_LOGGED_MESSAGES:
+ {
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ v->value_int = debug ? debug->NumMessages : 0;
+ }
+ break;
+ case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+ {
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ v->value_int = debug ? debug->NextMsgLength : 0;
+ }
+ break;
+ case GL_DEBUG_GROUP_STACK_DEPTH:
+ {
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ v->value_int = debug ? debug->GroupStackDepth : 0;
+ }
+ break;
+
/* GL_ARB_shader_atomic_counters */
case GL_ATOMIC_COUNTER_BUFFER_BINDING:
v->value_int = ctx->AtomicBuffer->Name;
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index f47cbd881..674d0032a 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -698,13 +698,13 @@ descriptor=[
[ "RESET_NOTIFICATION_STRATEGY_ARB", "CONTEXT_ENUM(Const.ResetStrategy), NO_EXTRA" ],
# GL_KHR_debug (GL 4.3)/ GL_ARB_debug_output
- [ "DEBUG_LOGGED_MESSAGES", "CONTEXT_INT(Debug.NumMessages), NO_EXTRA" ],
- [ "DEBUG_NEXT_LOGGED_MESSAGE_LENGTH", "CONTEXT_INT(Debug.NextMsgLength), NO_EXTRA" ],
+ [ "DEBUG_LOGGED_MESSAGES", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
+ [ "DEBUG_NEXT_LOGGED_MESSAGE_LENGTH", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
[ "MAX_DEBUG_LOGGED_MESSAGES", "CONST(MAX_DEBUG_LOGGED_MESSAGES), NO_EXTRA" ],
[ "MAX_DEBUG_MESSAGE_LENGTH", "CONST(MAX_DEBUG_MESSAGE_LENGTH), NO_EXTRA" ],
[ "MAX_LABEL_LENGTH", "CONST(MAX_LABEL_LENGTH), NO_EXTRA" ],
[ "MAX_DEBUG_GROUP_STACK_DEPTH", "CONST(MAX_DEBUG_GROUP_STACK_DEPTH), NO_EXTRA" ],
- [ "DEBUG_GROUP_STACK_DEPTH", "CONTEXT_INT(Debug.GroupStackDepth), NO_EXTRA" ],
+ [ "DEBUG_GROUP_STACK_DEPTH", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ],
[ "MAX_DUAL_SOURCE_DRAW_BUFFERS", "CONTEXT_INT(Const.MaxDualSourceDrawBuffers), extra_ARB_blend_func_extended" ],
diff --git a/mesalib/src/mesa/main/getstring.c b/mesalib/src/mesa/main/getstring.c
index 674126702..3ac62d402 100644
--- a/mesalib/src/mesa/main/getstring.c
+++ b/mesalib/src/mesa/main/getstring.c
@@ -253,14 +253,22 @@ _mesa_GetPointerv( GLenum pname, GLvoid **params )
*params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr;
break;
case GL_DEBUG_CALLBACK_FUNCTION_ARB:
- if (!_mesa_is_desktop_gl(ctx))
+ if (!_mesa_is_desktop_gl(ctx)) {
goto invalid_pname;
- *params = (GLvoid *) ctx->Debug.Callback;
+ }
+ else {
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ *params = debug ? (void *) debug->Callback : NULL;
+ }
break;
case GL_DEBUG_CALLBACK_USER_PARAM_ARB:
- if (!_mesa_is_desktop_gl(ctx))
+ if (!_mesa_is_desktop_gl(ctx)) {
goto invalid_pname;
- *params = (GLvoid *) ctx->Debug.CallbackData;
+ }
+ else {
+ struct gl_debug_state *debug = _mesa_get_debug_state(ctx);
+ *params = debug ? (void *) debug->CallbackData : NULL;
+ }
break;
default:
goto invalid_pname;
@@ -326,7 +334,7 @@ _mesa_GetGraphicsResetStatusARB( void )
*/
status = ctx->Driver.GetGraphicsResetStatus(ctx);
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
/* If this context has not been affected by a GPU reset, check to see if
* some other context in the share group has been affected by a reset.
@@ -340,7 +348,7 @@ _mesa_GetGraphicsResetStatusARB( void )
}
ctx->ShareGroupReset = ctx->Shared->ShareGroupReset;
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
if (!ctx->Driver.GetGraphicsResetStatus && (MESA_VERBOSE & VERBOSE_API))
diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c
index 7d4a31057..77cf26337 100644
--- a/mesalib/src/mesa/main/glformats.c
+++ b/mesalib/src/mesa/main/glformats.c
@@ -1323,10 +1323,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
- return GL_NO_ERROR;
case GL_HALF_FLOAT:
- return ctx->Extensions.ARB_half_float_pixel
- ? GL_NO_ERROR : GL_INVALID_ENUM;
+ return GL_NO_ERROR;
default:
return GL_INVALID_ENUM;
}
@@ -1349,10 +1347,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
- return GL_NO_ERROR;
case GL_HALF_FLOAT:
- return ctx->Extensions.ARB_half_float_pixel
- ? GL_NO_ERROR : GL_INVALID_ENUM;
+ return GL_NO_ERROR;
default:
return GL_INVALID_ENUM;
}
@@ -1368,10 +1364,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
- return GL_NO_ERROR;
case GL_HALF_FLOAT:
- return ctx->Extensions.ARB_half_float_pixel
- ? GL_NO_ERROR : GL_INVALID_ENUM;
+ return GL_NO_ERROR;
default:
return GL_INVALID_ENUM;
}
@@ -1389,14 +1383,12 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_UNSIGNED_BYTE_2_3_3_REV:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
+ case GL_HALF_FLOAT:
return GL_NO_ERROR;
case GL_UNSIGNED_INT_2_10_10_10_REV:
/* OK by GL_EXT_texture_type_2_10_10_10_REV */
return (ctx->API == API_OPENGLES2)
? GL_NO_ERROR : GL_INVALID_ENUM;
- case GL_HALF_FLOAT:
- return ctx->Extensions.ARB_half_float_pixel
- ? GL_NO_ERROR : GL_INVALID_ENUM;
case GL_UNSIGNED_INT_5_9_9_9_REV:
return ctx->Extensions.EXT_texture_shared_exponent
? GL_NO_ERROR : GL_INVALID_ENUM;
@@ -1419,10 +1411,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
- return GL_NO_ERROR;
case GL_HALF_FLOAT:
- return ctx->Extensions.ARB_half_float_pixel
- ? GL_NO_ERROR : GL_INVALID_ENUM;
+ return GL_NO_ERROR;
default:
return GL_INVALID_ENUM;
}
@@ -1446,10 +1436,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
- return GL_NO_ERROR;
case GL_HALF_FLOAT:
- return ctx->Extensions.ARB_half_float_pixel
- ? GL_NO_ERROR : GL_INVALID_ENUM;
+ return GL_NO_ERROR;
default:
return GL_INVALID_ENUM;
}
diff --git a/mesalib/src/mesa/main/hash.c b/mesalib/src/mesa/main/hash.c
index b31fd4839..4c92005e0 100644
--- a/mesalib/src/mesa/main/hash.c
+++ b/mesalib/src/mesa/main/hash.c
@@ -36,7 +36,6 @@
#include "glheader.h"
#include "imports.h"
-#include "glapi/glthread.h"
#include "hash.h"
#include "hash_table.h"
@@ -59,8 +58,8 @@
struct _mesa_HashTable {
struct hash_table *ht;
GLuint MaxKey; /**< highest key inserted so far */
- _glthread_Mutex Mutex; /**< mutual exclusion lock */
- _glthread_Mutex WalkMutex; /**< for _mesa_HashWalk() */
+ mtx_t Mutex; /**< mutual exclusion lock */
+ mtx_t WalkMutex; /**< for _mesa_HashWalk() */
GLboolean InDeleteAll; /**< Debug check */
/** Value that would be in the table for DELETED_KEY_VALUE. */
void *deleted_key_data;
@@ -117,8 +116,8 @@ _mesa_NewHashTable(void)
if (table) {
table->ht = _mesa_hash_table_create(NULL, uint_key_compare);
_mesa_hash_table_set_deleted_key(table->ht, uint_key(DELETED_KEY_VALUE));
- _glthread_INIT_MUTEX(table->Mutex);
- _glthread_INIT_MUTEX(table->WalkMutex);
+ mtx_init(&table->Mutex, mtx_plain);
+ mtx_init(&table->WalkMutex, mtx_plain);
}
return table;
}
@@ -144,8 +143,8 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table)
_mesa_hash_table_destroy(table->ht, NULL);
- _glthread_DESTROY_MUTEX(table->Mutex);
- _glthread_DESTROY_MUTEX(table->WalkMutex);
+ mtx_destroy(&table->Mutex);
+ mtx_destroy(&table->WalkMutex);
free(table);
}
@@ -187,9 +186,9 @@ _mesa_HashLookup(struct _mesa_HashTable *table, GLuint key)
{
void *res;
assert(table);
- _glthread_LOCK_MUTEX(table->Mutex);
+ mtx_lock(&table->Mutex);
res = _mesa_HashLookup_unlocked(table, key);
- _glthread_UNLOCK_MUTEX(table->Mutex);
+ mtx_unlock(&table->Mutex);
return res;
}
@@ -211,7 +210,7 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
assert(table);
assert(key);
- _glthread_LOCK_MUTEX(table->Mutex);
+ mtx_lock(&table->Mutex);
if (key > table->MaxKey)
table->MaxKey = key;
@@ -227,7 +226,7 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data)
}
}
- _glthread_UNLOCK_MUTEX(table->Mutex);
+ mtx_unlock(&table->Mutex);
}
@@ -256,14 +255,14 @@ _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key)
return;
}
- _glthread_LOCK_MUTEX(table->Mutex);
+ mtx_lock(&table->Mutex);
if (key == DELETED_KEY_VALUE) {
table->deleted_key_data = NULL;
} else {
entry = _mesa_hash_table_search(table->ht, uint_hash(key), uint_key(key));
_mesa_hash_table_remove(table->ht, entry);
}
- _glthread_UNLOCK_MUTEX(table->Mutex);
+ mtx_unlock(&table->Mutex);
}
@@ -286,7 +285,7 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table,
ASSERT(table);
ASSERT(callback);
- _glthread_LOCK_MUTEX(table->Mutex);
+ mtx_lock(&table->Mutex);
table->InDeleteAll = GL_TRUE;
hash_table_foreach(table->ht, entry) {
callback((uintptr_t)entry->key, entry->data, userData);
@@ -297,7 +296,7 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table,
table->deleted_key_data = NULL;
}
table->InDeleteAll = GL_FALSE;
- _glthread_UNLOCK_MUTEX(table->Mutex);
+ mtx_unlock(&table->Mutex);
}
@@ -315,7 +314,7 @@ _mesa_HashClone(const struct _mesa_HashTable *table)
struct _mesa_HashTable *clonetable;
ASSERT(table);
- _glthread_LOCK_MUTEX(table2->Mutex);
+ mtx_lock(&table2->Mutex);
clonetable = _mesa_NewHashTable();
assert(clonetable);
@@ -323,7 +322,7 @@ _mesa_HashClone(const struct _mesa_HashTable *table)
_mesa_HashInsert(clonetable, (GLint)(uintptr_t)entry->key, entry->data);
}
- _glthread_UNLOCK_MUTEX(table2->Mutex);
+ mtx_unlock(&table2->Mutex);
return clonetable;
}
@@ -352,13 +351,13 @@ _mesa_HashWalk(const struct _mesa_HashTable *table,
ASSERT(table);
ASSERT(callback);
- _glthread_LOCK_MUTEX(table2->WalkMutex);
+ mtx_lock(&table2->WalkMutex);
hash_table_foreach(table->ht, entry) {
callback((uintptr_t)entry->key, entry->data, userData);
}
if (table->deleted_key_data)
callback(DELETED_KEY_VALUE, table->deleted_key_data, userData);
- _glthread_UNLOCK_MUTEX(table2->WalkMutex);
+ mtx_unlock(&table2->WalkMutex);
}
static void
@@ -398,10 +397,10 @@ GLuint
_mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys)
{
const GLuint maxKey = ~((GLuint) 0) - 1;
- _glthread_LOCK_MUTEX(table->Mutex);
+ mtx_lock(&table->Mutex);
if (maxKey - numKeys > table->MaxKey) {
/* the quick solution */
- _glthread_UNLOCK_MUTEX(table->Mutex);
+ mtx_unlock(&table->Mutex);
return table->MaxKey + 1;
}
else {
@@ -419,13 +418,13 @@ _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys)
/* this key not in use, check if we've found enough */
freeCount++;
if (freeCount == numKeys) {
- _glthread_UNLOCK_MUTEX(table->Mutex);
+ mtx_unlock(&table->Mutex);
return freeStart;
}
}
}
/* cannot allocate a block of numKeys consecutive keys */
- _glthread_UNLOCK_MUTEX(table->Mutex);
+ mtx_unlock(&table->Mutex);
return 0;
}
}
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h
index 53e40b445..29772be6e 100644
--- a/mesalib/src/mesa/main/imports.h
+++ b/mesalib/src/mesa/main/imports.h
@@ -132,7 +132,7 @@ typedef union { GLfloat f; GLint i; GLuint u; } fi_type;
#define atanhf(f) ((float) atanh(f))
#endif
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (_MSC_VER < 1800) /* Not req'd on VS2013 and above */
static inline float truncf(float x) { return x < 0.0f ? ceilf(x) : floorf(x); }
static inline float exp2f(float x) { return powf(2.0f, x); }
static inline float log2f(float x) { return logf(x) * 1.442695041f; }
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index ceabd9df7..bbc377280 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1190,7 +1190,7 @@ struct gl_sampler_object
*/
struct gl_texture_object
{
- _glthread_Mutex Mutex; /**< for thread safety */
+ mtx_t Mutex; /**< for thread safety */
GLint RefCount; /**< reference count */
GLuint Name; /**< the user-visible texture object ID */
GLchar *Label; /**< GL_KHR_debug */
@@ -1439,28 +1439,44 @@ struct gl_viewport_attrib
};
+typedef enum {
+ MAP_USER,
+ MAP_INTERNAL,
+
+ MAP_COUNT
+} gl_map_buffer_index;
+
+
+/**
+ * Fields describing a mapped buffer range.
+ */
+struct gl_buffer_mapping {
+ GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */
+ GLvoid *Pointer; /**< User-space address of mapping */
+ GLintptr Offset; /**< Mapped offset */
+ GLsizeiptr Length; /**< Mapped length */
+};
+
+
/**
* GL_ARB_vertex/pixel_buffer_object buffer object
*/
struct gl_buffer_object
{
- _glthread_Mutex Mutex;
+ mtx_t Mutex;
GLint RefCount;
GLuint Name;
GLchar *Label; /**< GL_KHR_debug */
GLenum Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */
+ GLbitfield StorageFlags; /**< GL_MAP_PERSISTENT_BIT, etc. */
GLsizeiptrARB Size; /**< Size of buffer storage in bytes */
GLubyte *Data; /**< Location of storage either in RAM or VRAM. */
- /** Fields describing a mapped buffer */
- /*@{*/
- GLbitfield AccessFlags; /**< Mask of GL_MAP_x_BIT flags */
- GLvoid *Pointer; /**< User-space address of mapping */
- GLintptr Offset; /**< Mapped offset */
- GLsizeiptr Length; /**< Mapped length */
- /*@}*/
GLboolean DeletePending; /**< true if buffer object is removed from the hash */
GLboolean Written; /**< Ever written to? (for debugging) */
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
+ GLboolean Immutable; /**< GL_ARB_buffer_storage */
+
+ struct gl_buffer_mapping Mappings[MAP_COUNT];
};
@@ -1560,7 +1576,7 @@ struct gl_vertex_array_object
GLchar *Label; /**< GL_KHR_debug */
GLint RefCount;
- _glthread_Mutex Mutex;
+ mtx_t Mutex;
/**
* Does the VAO use ARB semantics or Apple semantics?
@@ -2013,6 +2029,7 @@ typedef enum
SYSTEM_VALUE_SAMPLE_ID, /**< Fragment shader only */
SYSTEM_VALUE_SAMPLE_POS, /**< Fragment shader only */
SYSTEM_VALUE_SAMPLE_MASK_IN, /**< Fragment shader only */
+ SYSTEM_VALUE_INVOCATION_ID, /**< Geometry shader only */
SYSTEM_VALUE_MAX /**< Number of values */
} gl_system_value;
@@ -2143,6 +2160,7 @@ struct gl_geometry_program
GLint VerticesIn;
GLint VerticesOut;
+ GLint Invocations;
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
@@ -2419,6 +2437,11 @@ struct gl_shader
struct {
GLint VerticesOut;
/**
+ * 0 - Invocations count not declared in shader, or
+ * 1 .. MAX_GEOMETRY_SHADER_INVOCATIONS
+ */
+ GLint Invocations;
+ /**
* GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or
* GL_TRIANGLES_ADJACENCY, or PRIM_UNKNOWN if it's not set in this
* shader.
@@ -2579,6 +2602,12 @@ struct gl_shader_program
*/
GLboolean InternalSeparateShader;
+ /**
+ * Indicates whether program can be bound for individual pipeline stages
+ * using UseProgramStages after it is next linked.
+ */
+ GLboolean SeparateShader;
+
GLuint NumShaders; /**< number of attached shaders */
struct gl_shader **Shaders; /**< List of attached the shaders */
@@ -2627,6 +2656,10 @@ struct gl_shader_program
struct {
GLint VerticesIn;
GLint VerticesOut;
+ /**
+ * 1 .. MAX_GEOMETRY_SHADER_INVOCATIONS
+ */
+ GLint Invocations;
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
@@ -2746,9 +2779,19 @@ struct gl_shader_program
/**
* Context state for GLSL vertex/fragment shaders.
+ * Extended to support pipeline object
*/
-struct gl_shader_state
+struct gl_pipeline_object
{
+ /** Name of the pipeline object as received from glGenProgramPipelines.
+ * It would be 0 for shaders without separate shader objects.
+ */
+ GLuint Name;
+
+ GLint RefCount;
+
+ mtx_t Mutex;
+
/**
* Programs used for rendering
*
@@ -2768,8 +2811,21 @@ struct gl_shader_state
struct gl_shader_program *ActiveProgram;
GLbitfield Flags; /**< Mask of GLSL_x flags */
+
+ GLboolean EverBound; /**< Has the pipeline object been created */
};
+/**
+ * Context state for GLSL pipeline shaders.
+ */
+struct gl_pipeline_shader_state
+{
+ /** Currently bound pipeline object. See _mesa_BindProgramPipeline() */
+ struct gl_pipeline_object *Current;
+
+ /** Pipeline objects */
+ struct _mesa_HashTable *Objects;
+};
/**
* Compiler options for a single GLSL shaders type
@@ -2871,7 +2927,7 @@ struct gl_sync_object
*/
struct gl_shared_state
{
- _glthread_Mutex Mutex; /**< for thread safety */
+ mtx_t Mutex; /**< for thread safety */
GLint RefCount; /**< Reference count */
struct _mesa_HashTable *DisplayList; /**< Display lists hash table */
struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */
@@ -2889,7 +2945,7 @@ struct gl_shared_state
* \todo Improve the granularity of locking.
*/
/*@{*/
- _glthread_Mutex TexMutex; /**< texobj thread safety */
+ mtx_t TexMutex; /**< texobj thread safety */
GLuint TextureStateStamp; /**< state notification for shared tex */
/*@}*/
@@ -2946,7 +3002,7 @@ struct gl_shared_state
*/
struct gl_renderbuffer
{
- _glthread_Mutex Mutex; /**< for thread safety */
+ mtx_t Mutex; /**< for thread safety */
GLuint ClassID; /**< Useful for drivers */
GLuint Name;
GLchar *Label; /**< GL_KHR_debug */
@@ -3024,7 +3080,7 @@ struct gl_renderbuffer_attachment
*/
struct gl_framebuffer
{
- _glthread_Mutex Mutex; /**< for thread safety */
+ mtx_t Mutex; /**< for thread safety */
/**
* If zero, this is a window system framebuffer. If non-zero, this
* is a FBO framebuffer; note that for some devices (i.e. those with
@@ -3433,6 +3489,7 @@ struct gl_extensions
GLboolean ARB_arrays_of_arrays;
GLboolean ARB_base_instance;
GLboolean ARB_blend_func_extended;
+ GLboolean ARB_buffer_storage;
GLboolean ARB_color_buffer_float;
GLboolean ARB_compute_shader;
GLboolean ARB_conservative_depth;
@@ -3451,7 +3508,6 @@ struct gl_extensions
GLboolean ARB_explicit_attrib_location;
GLboolean ARB_geometry_shader4;
GLboolean ARB_gpu_shader5;
- GLboolean ARB_half_float_pixel;
GLboolean ARB_half_float_vertex;
GLboolean ARB_instanced_arrays;
GLboolean ARB_internalformat_query;
@@ -3461,6 +3517,7 @@ struct gl_extensions
GLboolean ARB_point_sprite;
GLboolean ARB_sample_shading;
GLboolean ARB_seamless_cube_map;
+ GLboolean ARB_separate_shader_objects;
GLboolean ARB_shader_atomic_counters;
GLboolean ARB_shader_bit_encoding;
GLboolean ARB_shader_image_load_store;
@@ -4070,7 +4127,8 @@ struct gl_context
struct gl_geometry_program_state GeometryProgram;
struct gl_ati_fragment_shader_state ATIFragmentShader;
- struct gl_shader_state Shader; /**< GLSL shader object state */
+ struct gl_pipeline_shader_state Pipeline; /**< GLSL pipeline shader object state */
+ struct gl_pipeline_object Shader; /**< GLSL shader object state */
struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_STAGES];
struct gl_query_state Query; /**< occlusion, timer queries */
@@ -4132,7 +4190,7 @@ struct gl_context
GLuint ErrorDebugCount;
/* GL_ARB_debug_output/GL_KHR_debug */
- struct gl_debug_state Debug;
+ struct gl_debug_state *Debug;
GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
GLbitfield NewState; /**< bitwise-or of _NEW_* flags */
diff --git a/mesalib/src/mesa/main/pbo.c b/mesalib/src/mesa/main/pbo.c
index 400cec3f0..a0d61a643 100644
--- a/mesalib/src/mesa/main/pbo.c
+++ b/mesalib/src/mesa/main/pbo.c
@@ -149,7 +149,8 @@ _mesa_map_pbo_source(struct gl_context *ctx,
buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0,
unpack->BufferObj->Size,
GL_MAP_READ_BIT,
- unpack->BufferObj);
+ unpack->BufferObj,
+ MAP_INTERNAL);
if (!buf)
return NULL;
@@ -201,7 +202,7 @@ _mesa_map_validate_pbo_source(struct gl_context *ctx,
return ptr;
}
- if (_mesa_bufferobj_mapped(unpack->BufferObj)) {
+ if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {
/* buffer is already mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);
return NULL;
@@ -221,7 +222,7 @@ _mesa_unmap_pbo_source(struct gl_context *ctx,
{
ASSERT(unpack != &ctx->Pack); /* catch pack/unpack mismatch */
if (_mesa_is_bufferobj(unpack->BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
+ ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL);
}
}
@@ -246,7 +247,8 @@ _mesa_map_pbo_dest(struct gl_context *ctx,
buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0,
pack->BufferObj->Size,
GL_MAP_WRITE_BIT,
- pack->BufferObj);
+ pack->BufferObj,
+ MAP_INTERNAL);
if (!buf)
return NULL;
@@ -297,7 +299,7 @@ _mesa_map_validate_pbo_dest(struct gl_context *ctx,
return ptr;
}
- if (_mesa_bufferobj_mapped(unpack->BufferObj)) {
+ if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {
/* buffer is already mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);
return NULL;
@@ -317,7 +319,7 @@ _mesa_unmap_pbo_dest(struct gl_context *ctx,
{
ASSERT(pack != &ctx->Unpack); /* catch pack/unpack mismatch */
if (_mesa_is_bufferobj(pack->BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, pack->BufferObj);
+ ctx->Driver.UnmapBuffer(ctx, pack->BufferObj, MAP_INTERNAL);
}
}
@@ -351,7 +353,8 @@ _mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions,
buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0,
unpack->BufferObj->Size,
GL_MAP_READ_BIT,
- unpack->BufferObj);
+ unpack->BufferObj,
+ MAP_INTERNAL);
if (!buf) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(PBO is mapped)", funcName,
dimensions);
@@ -393,7 +396,8 @@ _mesa_validate_pbo_compressed_teximage(struct gl_context *ctx,
buf = (GLubyte*) ctx->Driver.MapBufferRange(ctx, 0,
packing->BufferObj->Size,
GL_MAP_READ_BIT,
- packing->BufferObj);
+ packing->BufferObj,
+ MAP_INTERNAL);
if (!buf) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(PBO is mapped)", funcName,
dimensions);
@@ -413,6 +417,6 @@ _mesa_unmap_teximage_pbo(struct gl_context *ctx,
const struct gl_pixelstore_attrib *unpack)
{
if (_mesa_is_bufferobj(unpack->BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
+ ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL);
}
}
diff --git a/mesalib/src/mesa/main/pipelineobj.c b/mesalib/src/mesa/main/pipelineobj.c
new file mode 100644
index 000000000..27012df72
--- /dev/null
+++ b/mesalib/src/mesa/main/pipelineobj.c
@@ -0,0 +1,445 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright © 2013 Gregory Hainaut <gregory.hainaut@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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.
+ */
+
+/**
+ * \file pipelineobj.c
+ * \author Hainaut Gregory <gregory.hainaut@gmail.com>
+ *
+ * Implementation of pipeline object related API functions. Based on
+ * GL_ARB_separate_shader_objects extension.
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/dispatch.h"
+#include "main/enums.h"
+#include "main/hash.h"
+#include "main/mtypes.h"
+#include "main/pipelineobj.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "main/transformfeedback.h"
+#include "main/uniforms.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "ralloc.h"
+#include <stdbool.h>
+#include "../glsl/glsl_parser_extras.h"
+#include "../glsl/ir_uniform.h"
+
+/**
+ * Delete a pipeline object.
+ */
+void
+_mesa_delete_pipeline_object(struct gl_context *ctx,
+ struct gl_pipeline_object *obj)
+{
+ unsigned i;
+
+ _mesa_reference_shader_program(ctx, &obj->_CurrentFragmentProgram, NULL);
+
+ for (i = 0; i < MESA_SHADER_STAGES; i++)
+ _mesa_reference_shader_program(ctx, &obj->CurrentProgram[i], NULL);
+
+ _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL);
+ mtx_destroy(&obj->Mutex);
+ ralloc_free(obj);
+}
+
+/**
+ * Allocate and initialize a new pipeline object.
+ */
+static struct gl_pipeline_object *
+_mesa_new_pipeline_object(struct gl_context *ctx, GLuint name)
+{
+ struct gl_pipeline_object *obj = rzalloc(NULL, struct gl_pipeline_object);
+ if (obj) {
+ obj->Name = name;
+ mtx_init(&obj->Mutex, mtx_plain);
+ obj->RefCount = 1;
+ obj->Flags = _mesa_get_shader_flags();
+ }
+
+ return obj;
+}
+
+/**
+ * Initialize pipeline object state for given context.
+ */
+void
+_mesa_init_pipeline(struct gl_context *ctx)
+{
+ ctx->Pipeline.Objects = _mesa_NewHashTable();
+
+ ctx->Pipeline.Current = NULL;
+}
+
+
+/**
+ * Callback for deleting a pipeline object. Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_pipelineobj_cb(GLuint id, void *data, void *userData)
+{
+ struct gl_pipeline_object *obj = (struct gl_pipeline_object *) data;
+ struct gl_context *ctx = (struct gl_context *) userData;
+ _mesa_delete_pipeline_object(ctx, obj);
+}
+
+
+/**
+ * Free pipeline state for given context.
+ */
+void
+_mesa_free_pipeline_data(struct gl_context *ctx)
+{
+ _mesa_HashDeleteAll(ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx);
+ _mesa_DeleteHashTable(ctx->Pipeline.Objects);
+}
+
+/**
+ * Look up the pipeline object for the given ID.
+ *
+ * \returns
+ * Either a pointer to the pipeline object with the specified ID or \c NULL for
+ * a non-existent ID. The spec defines ID 0 as being technically
+ * non-existent.
+ */
+static inline struct gl_pipeline_object *
+lookup_pipeline_object(struct gl_context *ctx, GLuint id)
+{
+ if (id == 0)
+ return NULL;
+ else
+ return (struct gl_pipeline_object *)
+ _mesa_HashLookup(ctx->Pipeline.Objects, id);
+}
+
+/**
+ * Add the given pipeline object to the pipeline object pool.
+ */
+static void
+save_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj)
+{
+ if (obj->Name > 0) {
+ _mesa_HashInsert(ctx->Pipeline.Objects, obj->Name, obj);
+ }
+}
+
+/**
+ * Remove the given pipeline object from the pipeline object pool.
+ * Do not deallocate the pipeline object though.
+ */
+static void
+remove_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj)
+{
+ if (obj->Name > 0) {
+ _mesa_HashRemove(ctx->Pipeline.Objects, obj->Name);
+ }
+}
+
+/**
+ * Set ptr to obj w/ reference counting.
+ * Note: this should only be called from the _mesa_reference_pipeline_object()
+ * inline function.
+ */
+void
+_mesa_reference_pipeline_object_(struct gl_context *ctx,
+ struct gl_pipeline_object **ptr,
+ struct gl_pipeline_object *obj)
+{
+ assert(*ptr != obj);
+
+ if (*ptr) {
+ /* Unreference the old pipeline object */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_pipeline_object *oldObj = *ptr;
+
+ mtx_lock(&oldObj->Mutex);
+ ASSERT(oldObj->RefCount > 0);
+ oldObj->RefCount--;
+ deleteFlag = (oldObj->RefCount == 0);
+ mtx_unlock(&oldObj->Mutex);
+
+ if (deleteFlag) {
+ _mesa_delete_pipeline_object(ctx, oldObj);
+ }
+
+ *ptr = NULL;
+ }
+ ASSERT(!*ptr);
+
+ if (obj) {
+ /* reference new pipeline object */
+ mtx_lock(&obj->Mutex);
+ if (obj->RefCount == 0) {
+ /* this pipeline's being deleted (look just above) */
+ /* Not sure this can ever really happen. Warn if it does. */
+ _mesa_problem(NULL, "referencing deleted pipeline object");
+ *ptr = NULL;
+ }
+ else {
+ obj->RefCount++;
+ *ptr = obj;
+ }
+ mtx_unlock(&obj->Mutex);
+ }
+}
+
+/**
+ * Bound program to severals stages of the pipeline
+ */
+void GLAPIENTRY
+_mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+}
+
+/**
+ * Use the named shader program for subsequent glUniform calls (if pipeline
+ * bound)
+ */
+void GLAPIENTRY
+_mesa_ActiveShaderProgram(GLuint pipeline, GLuint program)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg = NULL;
+ struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+
+ if (program != 0) {
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glActiveShaderProgram(program)");
+ if (shProg == NULL)
+ return;
+ }
+
+ if (!pipe) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveShaderProgram(pipeline)");
+ return;
+ }
+
+ /* Object is created by any Pipeline call but glGenProgramPipelines,
+ * glIsProgramPipeline and GetProgramPipelineInfoLog
+ */
+ pipe->EverBound = GL_TRUE;
+
+ if ((shProg != NULL) && !shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glActiveShaderProgram(program %u not linked)", shProg->Name);
+ return;
+ }
+
+ _mesa_reference_shader_program(ctx, &pipe->ActiveProgram, shProg);
+}
+
+/**
+ * Make program of the pipeline current
+ */
+void GLAPIENTRY
+_mesa_BindProgramPipeline(GLuint pipeline)
+{
+}
+
+/**
+ * Delete a set of pipeline objects.
+ *
+ * \param n Number of pipeline objects to delete.
+ * \param ids pipeline of \c n pipeline object IDs.
+ */
+void GLAPIENTRY
+_mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLsizei i;
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteProgramPipelines(n<0)");
+ return;
+ }
+
+ for (i = 0; i < n; i++) {
+ struct gl_pipeline_object *obj =
+ lookup_pipeline_object(ctx, pipelines[i]);
+
+ if (obj) {
+ ASSERT(obj->Name == pipelines[i]);
+
+ /* If the pipeline object is currently bound, the spec says "If an
+ * object that is currently bound is deleted, the binding for that
+ * object reverts to zero and no program pipeline object becomes
+ * current."
+ */
+ if (obj == ctx->Pipeline.Current) {
+ _mesa_BindProgramPipeline(0);
+ }
+
+ /* The ID is immediately freed for re-use */
+ remove_pipeline_object(ctx, obj);
+
+ /* Unreference the pipeline object.
+ * If refcount hits zero, the object will be deleted.
+ */
+ _mesa_reference_pipeline_object(ctx, &obj, NULL);
+ }
+ }
+}
+
+/**
+ * Generate a set of unique pipeline object IDs and store them in \c pipelines.
+ * \param n Number of IDs to generate.
+ * \param pipelines pipeline of \c n locations to store the IDs.
+ */
+void GLAPIENTRY
+_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ GLuint first;
+ GLint i;
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGenProgramPipelines(n<0)");
+ return;
+ }
+
+ if (!pipelines) {
+ return;
+ }
+
+ first = _mesa_HashFindFreeKeyBlock(ctx->Pipeline.Objects, n);
+
+ for (i = 0; i < n; i++) {
+ struct gl_pipeline_object *obj;
+ GLuint name = first + i;
+
+ obj = _mesa_new_pipeline_object(ctx, name);
+ if (!obj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenProgramPipelines");
+ return;
+ }
+
+ save_pipeline_object(ctx, obj);
+ pipelines[i] = first + i;
+ }
+
+}
+
+/**
+ * Determine if ID is the name of an pipeline object.
+ *
+ * \param id ID of the potential pipeline object.
+ * \return \c GL_TRUE if \c id is the name of a pipeline object,
+ * \c GL_FALSE otherwise.
+ */
+GLboolean GLAPIENTRY
+_mesa_IsProgramPipeline(GLuint pipeline)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ struct gl_pipeline_object *obj = lookup_pipeline_object(ctx, pipeline);
+ if (obj == NULL)
+ return GL_FALSE;
+
+ return obj->EverBound;
+}
+
+/**
+ * glGetProgramPipelineiv() - get pipeline shader state.
+ */
+void GLAPIENTRY
+_mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_pipeline_object *pipe = lookup_pipeline_object(ctx, pipeline);
+
+ /* Are geometry shaders available in this context?
+ */
+ const bool has_gs = _mesa_has_geometry_shaders(ctx);
+
+ if (!pipe) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetProgramPipelineiv(pipeline)");
+ return;
+ }
+
+ /* Object is created by any Pipeline call but glGenProgramPipelines,
+ * glIsProgramPipeline and GetProgramPipelineInfoLog
+ */
+ pipe->EverBound = GL_TRUE;
+
+ switch (pname) {
+ case GL_ACTIVE_PROGRAM:
+ *params = pipe->ActiveProgram ? pipe->ActiveProgram->Name : 0;
+ return;
+ case GL_INFO_LOG_LENGTH:
+ /* FINISHME: Implement the info log.
+ */
+ *params = 0;
+ return;
+ case GL_VALIDATE_STATUS:
+ /* FINISHME: Implement validation status.
+ */
+ *params = 0;
+ return;
+ case GL_VERTEX_SHADER:
+ *params = pipe->CurrentProgram[MESA_SHADER_VERTEX]
+ ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name : 0;
+ return;
+ case GL_TESS_EVALUATION_SHADER:
+ /* NOT YET SUPPORTED */
+ break;
+ case GL_TESS_CONTROL_SHADER:
+ /* NOT YET SUPPORTED */
+ break;
+ case GL_GEOMETRY_SHADER:
+ if (!has_gs)
+ break;
+ *params = pipe->CurrentProgram[MESA_SHADER_GEOMETRY]
+ ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name : 0;
+ return;
+ case GL_FRAGMENT_SHADER:
+ *params = pipe->CurrentProgram[MESA_SHADER_FRAGMENT]
+ ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Name : 0;
+ return;
+ default:
+ break;
+ }
+
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramPipelineiv(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
+}
+
+/**
+ * Check compatibility of pipeline's program
+ */
+void GLAPIENTRY
+_mesa_ValidateProgramPipeline(GLuint pipeline)
+{
+}
+
+void GLAPIENTRY
+_mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog)
+{
+}
diff --git a/mesalib/src/mesa/main/pipelineobj.h b/mesalib/src/mesa/main/pipelineobj.h
new file mode 100644
index 000000000..46d5fab42
--- /dev/null
+++ b/mesalib/src/mesa/main/pipelineobj.h
@@ -0,0 +1,95 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright © 2013 Gregory Hainaut <gregory.hainaut@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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.
+ */
+
+#ifndef PIPELINEOBJ_H
+#define PIPELINEOBJ_H
+
+#include "glheader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _glapi_table;
+struct gl_context;
+struct gl_pipeline_object;
+
+extern void
+_mesa_delete_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj);
+
+extern void
+_mesa_init_pipeline(struct gl_context *ctx);
+
+extern void
+_mesa_free_pipeline_data(struct gl_context *ctx);
+
+extern void
+_mesa_reference_pipeline_object_(struct gl_context *ctx,
+ struct gl_pipeline_object **ptr,
+ struct gl_pipeline_object *obj);
+
+static inline void
+_mesa_reference_pipeline_object(struct gl_context *ctx,
+ struct gl_pipeline_object **ptr,
+ struct gl_pipeline_object *obj)
+{
+ if (*ptr != obj)
+ _mesa_reference_pipeline_object_(ctx, ptr, obj);
+}
+
+
+extern void GLAPIENTRY
+_mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program);
+
+extern void GLAPIENTRY
+_mesa_ActiveShaderProgram(GLuint pipeline, GLuint program);
+
+extern void GLAPIENTRY
+_mesa_BindProgramPipeline(GLuint pipeline);
+
+extern void GLAPIENTRY
+_mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines);
+
+extern void GLAPIENTRY
+_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsProgramPipeline(GLuint pipeline);
+
+extern void GLAPIENTRY
+_mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_ValidateProgramPipeline(GLuint pipeline);
+
+extern void GLAPIENTRY
+_mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PIPELINEOBJ_H */
diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c
index e16346896..b09cf5499 100644
--- a/mesalib/src/mesa/main/readpix.c
+++ b/mesalib/src/mesa/main/readpix.c
@@ -595,7 +595,7 @@ fast_read_depth_stencil_pixels(struct gl_context *ctx,
return GL_FALSE;
if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM &&
- rb->Format != MESA_FORMAT_Z24_UNORM_X8_UINT)
+ rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT)
return GL_FALSE;
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
@@ -1033,7 +1033,7 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
}
if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
- _mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
+ _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
return;
diff --git a/mesalib/src/mesa/main/renderbuffer.c b/mesalib/src/mesa/main/renderbuffer.c
index 2ff96e548..0bc7f2b96 100644
--- a/mesalib/src/mesa/main/renderbuffer.c
+++ b/mesalib/src/mesa/main/renderbuffer.c
@@ -38,7 +38,7 @@
void
_mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name)
{
- _glthread_INIT_MUTEX(rb->Mutex);
+ mtx_init(&rb->Mutex, mtx_plain);
rb->ClassID = 0;
rb->Name = name;
@@ -83,7 +83,7 @@ _mesa_new_renderbuffer(struct gl_context *ctx, GLuint name)
void
_mesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
{
- _glthread_DESTROY_MUTEX(rb->Mutex);
+ mtx_destroy(&rb->Mutex);
free(rb->Label);
free(rb);
}
@@ -153,12 +153,12 @@ _mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr,
GLboolean deleteFlag = GL_FALSE;
struct gl_renderbuffer *oldRb = *ptr;
- _glthread_LOCK_MUTEX(oldRb->Mutex);
+ mtx_lock(&oldRb->Mutex);
ASSERT(oldRb->RefCount > 0);
oldRb->RefCount--;
/*printf("RB DECR %p (%d) to %d\n", (void*) oldRb, oldRb->Name, oldRb->RefCount);*/
deleteFlag = (oldRb->RefCount == 0);
- _glthread_UNLOCK_MUTEX(oldRb->Mutex);
+ mtx_unlock(&oldRb->Mutex);
if (deleteFlag) {
GET_CURRENT_CONTEXT(ctx);
@@ -171,10 +171,10 @@ _mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr,
if (rb) {
/* reference new renderbuffer */
- _glthread_LOCK_MUTEX(rb->Mutex);
+ mtx_lock(&rb->Mutex);
rb->RefCount++;
/*printf("RB INCR %p (%d) to %d\n", (void*) rb, rb->Name, rb->RefCount);*/
- _glthread_UNLOCK_MUTEX(rb->Mutex);
+ mtx_unlock(&rb->Mutex);
*ptr = rb;
}
}
diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c
index 7285ef5ed..4900d5256 100644
--- a/mesalib/src/mesa/main/samplerobj.c
+++ b/mesalib/src/mesa/main/samplerobj.c
@@ -66,7 +66,7 @@ _mesa_reference_sampler_object_(struct gl_context *ctx,
GLboolean deleteFlag = GL_FALSE;
struct gl_sampler_object *oldSamp = *ptr;
- /*_glthread_LOCK_MUTEX(oldSamp->Mutex);*/
+ /*mtx_lock(&oldSamp->Mutex);*/
ASSERT(oldSamp->RefCount > 0);
oldSamp->RefCount--;
#if 0
@@ -74,7 +74,7 @@ _mesa_reference_sampler_object_(struct gl_context *ctx,
(void *) oldSamp, oldSamp->Name, oldSamp->RefCount);
#endif
deleteFlag = (oldSamp->RefCount == 0);
- /*_glthread_UNLOCK_MUTEX(oldSamp->Mutex);*/
+ /*mtx_unlock(&oldSamp->Mutex);*/
if (deleteFlag) {
ASSERT(ctx->Driver.DeleteSamplerObject);
@@ -87,7 +87,7 @@ _mesa_reference_sampler_object_(struct gl_context *ctx,
if (samp) {
/* reference new sampler */
- /*_glthread_LOCK_MUTEX(samp->Mutex);*/
+ /*mtx_lock(&samp->Mutex);*/
if (samp->RefCount == 0) {
/* this sampler's being deleted (look just above) */
/* Not sure this can every really happen. Warn if it does. */
@@ -102,7 +102,7 @@ _mesa_reference_sampler_object_(struct gl_context *ctx,
#endif
*ptr = samp;
}
- /*_glthread_UNLOCK_MUTEX(samp->Mutex);*/
+ /*mtx_unlock(&samp->Mutex);*/
}
}
@@ -203,7 +203,7 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
return;
}
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
for (i = 0; i < count; i++) {
if (samplers[i]) {
@@ -228,7 +228,7 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
}
}
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index 65b6b16bb..5060cbb0b 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -65,8 +65,8 @@
/**
* Return mask of GLSL_x flags by examining the MESA_GLSL env var.
*/
-static GLbitfield
-get_shader_flags(void)
+GLbitfield
+_mesa_get_shader_flags(void)
{
GLbitfield flags = 0x0;
const char *env = _mesa_getenv("MESA_GLSL");
@@ -120,7 +120,11 @@ _mesa_init_shader_state(struct gl_context *ctx)
for (sh = 0; sh < MESA_SHADER_STAGES; ++sh)
memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
- ctx->Shader.Flags = get_shader_flags();
+ ctx->Shader.Flags = _mesa_get_shader_flags();
+
+ /* Extended for ARB_separate_shader_objects */
+ ctx->Shader.RefCount = 1;
+ mtx_init(&ctx->Shader.Mutex, mtx_plain);
}
@@ -138,6 +142,10 @@ _mesa_free_shader_state(struct gl_context *ctx)
_mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
NULL);
_mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
+
+ /* Extended for ARB_separate_shader_objects */
+ assert(ctx->Shader.RefCount == 1);
+ mtx_destroy(&ctx->Shader.Mutex);
}
@@ -383,30 +391,31 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
_mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
/* alloc new, smaller array */
- newList =
- malloc((n - 1) * sizeof(struct gl_shader *));
+ newList = malloc((n - 1) * sizeof(struct gl_shader *));
if (!newList) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
return;
}
+ /* Copy old list entries to new list, skipping removed entry at [i] */
for (j = 0; j < i; j++) {
newList[j] = shProg->Shaders[j];
}
- while (++i < n)
+ while (++i < n) {
newList[j++] = shProg->Shaders[i];
- free(shProg->Shaders);
+ }
+ /* Free old list and install new one */
+ free(shProg->Shaders);
shProg->Shaders = newList;
shProg->NumShaders = n - 1;
#ifdef DEBUG
- /* sanity check */
- {
- for (j = 0; j < shProg->NumShaders; j++) {
- assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
- shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
- assert(shProg->Shaders[j]->RefCount > 0);
- }
+ /* sanity check - make sure the new list's entries are sensible */
+ for (j = 0; j < shProg->NumShaders; j++) {
+ assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
+ shProg->Shaders[j]->Type == GL_GEOMETRY_SHADER ||
+ shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
+ assert(shProg->Shaders[j]->RefCount > 0);
}
#endif
@@ -605,6 +614,12 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
if (check_gs_query(ctx, shProg))
*params = shProg->Geom.VerticesOut;
return;
+ case GL_GEOMETRY_SHADER_INVOCATIONS:
+ if (!has_core_gs || !ctx->Extensions.ARB_gpu_shader5)
+ break;
+ if (check_gs_query(ctx, shProg))
+ *params = shProg->Geom.Invocations;
+ return;
case GL_GEOMETRY_INPUT_TYPE:
if (!has_core_gs)
break;
@@ -681,6 +696,12 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
params[i] = shProg->Comp.LocalSize[i];
return;
}
+ case GL_PROGRAM_SEPARABLE:
+ if (!ctx->Extensions.ARB_separate_shader_objects)
+ break;
+
+ *params = shProg->SeparateShader;
+ return;
default:
break;
}
@@ -817,9 +838,10 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
sh->CompileStatus = GL_FALSE;
} else {
if (ctx->Shader.Flags & GLSL_DUMP) {
- printf("GLSL source for %s shader %d:\n",
- _mesa_shader_stage_to_string(sh->Stage), sh->Name);
- printf("%s\n", sh->Source);
+ fprintf(stderr, "GLSL source for %s shader %d:\n",
+ _mesa_shader_stage_to_string(sh->Stage), sh->Name);
+ fprintf(stderr, "%s\n", sh->Source);
+ fflush(stderr);
}
/* this call will set the shader->CompileStatus field to indicate if
@@ -833,16 +855,17 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj)
if (ctx->Shader.Flags & GLSL_DUMP) {
if (sh->CompileStatus) {
- printf("GLSL IR for shader %d:\n", sh->Name);
- _mesa_print_ir(sh->ir, NULL);
- printf("\n\n");
+ fprintf(stderr, "GLSL IR for shader %d:\n", sh->Name);
+ _mesa_print_ir(stderr, sh->ir, NULL);
+ fprintf(stderr, "\n\n");
} else {
- printf("GLSL shader %d failed to compile.\n", sh->Name);
+ fprintf(stderr, "GLSL shader %d failed to compile.\n", sh->Name);
}
if (sh->InfoLog && sh->InfoLog[0] != 0) {
- printf("GLSL shader %d info log:\n", sh->Name);
- printf("%s\n", sh->InfoLog);
+ fprintf(stderr, "GLSL shader %d info log:\n", sh->Name);
+ fprintf(stderr, "%s\n", sh->InfoLog);
}
+ fflush(stderr);
}
}
@@ -1721,6 +1744,25 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
*/
shProg->BinaryRetreivableHint = value;
return;
+
+ case GL_PROGRAM_SEPARABLE:
+ if (!ctx->Extensions.ARB_separate_shader_objects)
+ break;
+
+ /* Spec imply that the behavior is the same as ARB_get_program_binary
+ * Chapter 7.3 Program Objects
+ */
+ if (value != GL_TRUE && value != GL_FALSE) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glProgramParameteri(pname=%s, value=%d): "
+ "value must be 0 or 1.",
+ _mesa_lookup_enum_by_nr(pname),
+ value);
+ return;
+ }
+ shProg->SeparateShader = value;
+ return;
+
default:
break;
}
@@ -1792,19 +1834,16 @@ _mesa_ActiveProgramEXT(GLuint program)
return;
}
-
-/**
- * For GL_EXT_separate_shader_objects
- */
-GLuint GLAPIENTRY
-_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
+static GLuint
+_mesa_create_shader_program(struct gl_context* ctx, GLboolean separate,
+ GLenum type, GLsizei count, const GLchar* const *strings)
{
- GET_CURRENT_CONTEXT(ctx);
const GLuint shader = create_shader(ctx, type);
GLuint program = 0;
if (shader) {
- shader_source(ctx, shader, _mesa_strdup(string));
+ _mesa_ShaderSource(shader, count, strings, NULL);
+
compile_shader(ctx, shader);
program = create_shader_program(ctx);
@@ -1816,6 +1855,8 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
shProg = _mesa_lookup_shader_program(ctx, program);
sh = _mesa_lookup_shader(ctx, shader);
+ shProg->SeparateShader = separate;
+
get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
if (compiled) {
attach_shader(ctx, program, shader);
@@ -1858,6 +1899,7 @@ _mesa_copy_linked_program_data(gl_shader_stage type,
struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst;
dst_gp->VerticesIn = src->Geom.VerticesIn;
dst_gp->VerticesOut = src->Geom.VerticesOut;
+ dst_gp->Invocations = src->Geom.Invocations;
dst_gp->InputType = src->Geom.InputType;
dst_gp->OutputType = src->Geom.OutputType;
dst->UsesClipDistanceOut = src->Geom.UsesClipDistance;
@@ -1875,3 +1917,30 @@ _mesa_copy_linked_program_data(gl_shader_stage type,
break;
}
}
+
+
+/**
+ * For GL_EXT_separate_shader_objects
+ */
+GLuint GLAPIENTRY
+_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ return _mesa_create_shader_program(ctx, GL_FALSE, type, 1, &string);
+}
+
+/**
+ * ARB_separate_shader_objects: Compile & Link Program
+ *
+ * Basically the same as _mesa_CreateShaderProgramEXT but with support of
+ * multiple strings and sets the SeparateShader flag to true.
+ */
+GLuint GLAPIENTRY
+_mesa_CreateShaderProgramv(GLenum type, GLsizei count,
+ const GLchar* const *strings)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings);
+}
diff --git a/mesalib/src/mesa/main/shaderapi.h b/mesalib/src/mesa/main/shaderapi.h
index 10f810caf..44426cc65 100644
--- a/mesalib/src/mesa/main/shaderapi.h
+++ b/mesalib/src/mesa/main/shaderapi.h
@@ -40,6 +40,9 @@ struct _glapi_table;
struct gl_context;
struct gl_shader_program;
+extern GLbitfield
+_mesa_get_shader_flags(void);
+
extern void
_mesa_copy_string(GLchar *dst, GLsizei maxLength,
GLsizei *length, const GLchar *src);
@@ -219,6 +222,11 @@ extern bool
_mesa_validate_shader_target(const struct gl_context *ctx, GLenum type);
+/* GL_ARB_separate_shader_objects */
+extern GLuint GLAPIENTRY
+_mesa_CreateShaderProgramv(GLenum type, GLsizei count,
+ const GLchar* const *strings);
+
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c
index 4f4bb69a8..d5c3d8099 100644
--- a/mesalib/src/mesa/main/shaderobj.c
+++ b/mesalib/src/mesa/main/shaderobj.c
@@ -355,6 +355,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx,
}
free(shProg->Label);
+ shProg->Label = NULL;
}
diff --git a/mesalib/src/mesa/main/shared.c b/mesalib/src/mesa/main/shared.c
index c11c7f9e9..dc22025c2 100644
--- a/mesalib/src/mesa/main/shared.c
+++ b/mesalib/src/mesa/main/shared.c
@@ -62,7 +62,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
if (!shared)
return NULL;
- _glthread_INIT_MUTEX(shared->Mutex);
+ mtx_init(&shared->Mutex, mtx_plain);
shared->DisplayList = _mesa_NewHashTable();
shared->TexObjects = _mesa_NewHashTable();
@@ -113,7 +113,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1);
/* Mutex and timestamp for texobj state validation */
- _glthread_INIT_MUTEX(shared->TexMutex);
+ mtx_init(&shared->TexMutex, mtx_plain);
shared->TextureStateStamp = 0;
shared->FrameBuffers = _mesa_NewHashTable();
@@ -186,10 +186,8 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData)
{
struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
struct gl_context *ctx = (struct gl_context *) userData;
- if (_mesa_bufferobj_mapped(bufObj)) {
- ctx->Driver.UnmapBuffer(ctx, bufObj);
- bufObj->Pointer = NULL;
- }
+
+ _mesa_buffer_unmap_all_mappings(ctx, bufObj);
_mesa_reference_buffer_object(ctx, &bufObj, NULL);
}
@@ -356,8 +354,8 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
_mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx);
_mesa_DeleteHashTable(shared->TexObjects);
- _glthread_DESTROY_MUTEX(shared->Mutex);
- _glthread_DESTROY_MUTEX(shared->TexMutex);
+ mtx_destroy(&shared->Mutex);
+ mtx_destroy(&shared->TexMutex);
free(shared);
}
@@ -380,11 +378,11 @@ _mesa_reference_shared_state(struct gl_context *ctx,
struct gl_shared_state *old = *ptr;
GLboolean delete;
- _glthread_LOCK_MUTEX(old->Mutex);
+ mtx_lock(&old->Mutex);
assert(old->RefCount >= 1);
old->RefCount--;
delete = (old->RefCount == 0);
- _glthread_UNLOCK_MUTEX(old->Mutex);
+ mtx_unlock(&old->Mutex);
if (delete) {
free_shared_state(ctx, old);
@@ -395,9 +393,9 @@ _mesa_reference_shared_state(struct gl_context *ctx,
if (state) {
/* reference new state */
- _glthread_LOCK_MUTEX(state->Mutex);
+ mtx_lock(&state->Mutex);
state->RefCount++;
*ptr = state;
- _glthread_UNLOCK_MUTEX(state->Mutex);
+ mtx_unlock(&state->Mutex);
}
}
diff --git a/mesalib/src/mesa/main/syncobj.c b/mesalib/src/mesa/main/syncobj.c
index ae49db2e4..9721b14b4 100644
--- a/mesalib/src/mesa/main/syncobj.c
+++ b/mesalib/src/mesa/main/syncobj.c
@@ -184,9 +184,9 @@ _mesa_validate_sync(struct gl_context *ctx,
void GLAPIENTRY
_mesa_ref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj)
{
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
syncObj->RefCount++;
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
@@ -195,7 +195,7 @@ _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj)
{
struct set_entry *entry;
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
syncObj->RefCount--;
if (syncObj->RefCount == 0) {
entry = _mesa_set_search(ctx->Shared->SyncObjects,
@@ -203,11 +203,11 @@ _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj)
syncObj);
assert (entry != NULL);
_mesa_set_remove(ctx->Shared->SyncObjects, entry);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
ctx->Driver.DeleteSyncObject(ctx, syncObj);
} else {
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
}
@@ -288,11 +288,11 @@ _mesa_FenceSync(GLenum condition, GLbitfield flags)
ctx->Driver.FenceSync(ctx, syncObj, condition, flags);
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
_mesa_set_add(ctx->Shared->SyncObjects,
_mesa_hash_pointer(syncObj),
syncObj);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
return (GLsync) syncObj;
}
diff --git a/mesalib/src/mesa/main/texcompress_etc.c b/mesalib/src/mesa/main/texcompress_etc.c
index e3862be45..cbda68940 100644
--- a/mesalib/src/mesa/main/texcompress_etc.c
+++ b/mesalib/src/mesa/main/texcompress_etc.c
@@ -429,8 +429,7 @@ etc2_rgb8_parse_block(struct etc2_block *block,
block->is_planar_mode = true;
/* opaque bit must be set in planar mode */
- if (!block->opaque)
- block->opaque = true;
+ block->opaque = true;
for (i = 0; i < 3; i++) {
block->base_colors[0][i] = etc2_base_color_o_planar(src, i);
diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c
index bda2d8e17..004e7ebac 100644
--- a/mesalib/src/mesa/main/texformat.c
+++ b/mesalib/src/mesa/main/texformat.c
@@ -209,13 +209,13 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
RETURN_IF_SUPPORTED(MESA_FORMAT_Z_UNORM32);
- RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT);
RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_X8_UINT);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT);
break;
case GL_DEPTH_COMPONENT16:
RETURN_IF_SUPPORTED(MESA_FORMAT_Z_UNORM16);
- RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT);
RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_X8_UINT);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT);
break;
case GL_COMPRESSED_ALPHA_ARB:
@@ -426,7 +426,7 @@ _mesa_choose_tex_format(struct gl_context *ctx, GLenum target,
case GL_DEPTH_STENCIL_EXT:
case GL_DEPTH24_STENCIL8_EXT:
RETURN_IF_SUPPORTED(MESA_FORMAT_S8_UINT_Z24_UNORM);
- RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_X8_UINT);
+ RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT);
break;
case GL_DEPTH_COMPONENT32F:
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index 133fa5376..daabf2e81 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -130,6 +130,10 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
const GLint depth = texImage->Depth;
GLint img, row;
+ assert(format == GL_DEPTH_STENCIL);
+ assert(type == GL_UNSIGNED_INT_24_8);
+ /* XXX type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV is not handled yet */
+
for (img = 0; img < depth; img++) {
GLubyte *srcMap;
GLint rowstride;
@@ -145,8 +149,11 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions,
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
width, height, format, type,
img, row, 0);
- /* XXX Z24_S8 vs. S8_Z24??? */
- memcpy(dest, src, width * sizeof(GLuint));
+ /* Unpack from texture's format to GL's z24_s8 layout */
+ _mesa_unpack_uint_24_8_depth_stencil_row(texImage->TexFormat,
+ width,
+ (const GLuint *) src,
+ dest);
if (ctx->Pack.SwapBytes) {
_mesa_swap4((GLuint *) dest, width);
}
@@ -635,7 +642,8 @@ _mesa_get_teximage(struct gl_context *ctx,
*/
GLubyte *buf = (GLubyte *)
ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size,
- GL_MAP_WRITE_BIT, ctx->Pack.BufferObj);
+ GL_MAP_WRITE_BIT, ctx->Pack.BufferObj,
+ MAP_INTERNAL);
if (!buf) {
/* out of memory or other unexpected error */
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)");
@@ -664,7 +672,7 @@ _mesa_get_teximage(struct gl_context *ctx,
}
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj);
+ ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj, MAP_INTERNAL);
}
}
@@ -689,7 +697,8 @@ _mesa_get_compressed_teximage(struct gl_context *ctx,
/* pack texture image into a PBO */
GLubyte *buf = (GLubyte *)
ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size,
- GL_MAP_WRITE_BIT, ctx->Pack.BufferObj);
+ GL_MAP_WRITE_BIT, ctx->Pack.BufferObj,
+ MAP_INTERNAL);
if (!buf) {
/* out of memory or other unexpected error */
_mesa_error(ctx, GL_OUT_OF_MEMORY,
@@ -731,7 +740,7 @@ _mesa_get_compressed_teximage(struct gl_context *ctx,
}
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
- ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj);
+ ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj, MAP_INTERNAL);
}
}
@@ -861,7 +870,7 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* PBO should not be mapped */
- if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
+ if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetTexImage(PBO is mapped)");
return GL_TRUE;
@@ -1004,7 +1013,7 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target,
}
/* make sure PBO is not mapped */
- if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
+ if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetCompressedTexImage(PBO is mapped)");
return GL_TRUE;
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 4d635fe7f..0519d221f 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -397,11 +397,6 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
if (ctx->Extensions.ARB_texture_rg) {
switch (internalFormat) {
case GL_R16F:
- /* R16F depends on both ARB_half_float_pixel and ARB_texture_float.
- */
- if (!ctx->Extensions.ARB_half_float_pixel)
- break;
- /* FALLTHROUGH */
case GL_R32F:
if (!ctx->Extensions.ARB_texture_float)
break;
@@ -422,11 +417,6 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
return GL_RED;
case GL_RG16F:
- /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float.
- */
- if (!ctx->Extensions.ARB_half_float_pixel)
- break;
- /* FALLTHROUGH */
case GL_RG32F:
if (!ctx->Extensions.ARB_texture_float)
break;
@@ -2254,9 +2244,10 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
/* This will detect any invalid internalFormat value */
if (!_mesa_is_compressed_format(ctx, internalFormat)) {
- reason = "internalFormat";
- error = GL_INVALID_ENUM;
- goto error;
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glCompressedTexImage%dD(internalFormat=%s)",
+ dimensions, _mesa_lookup_enum_by_nr(internalFormat));
+ return GL_TRUE;
}
switch (internalFormat) {
@@ -2348,6 +2339,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
return GL_FALSE;
error:
+ /* Note: not all error paths exit through here. */
_mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason);
return GL_TRUE;
}
@@ -2563,7 +2555,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
break;
default:
_mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage%dD(internalFormat)", dimensions);
+ "glCopyTexImage%dD(internalFormat=%s)", dimensions,
+ _mesa_lookup_enum_by_nr(internalFormat));
return GL_TRUE;
}
}
@@ -2571,7 +2564,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
baseFormat = _mesa_base_tex_format(ctx, internalFormat);
if (baseFormat < 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexImage%dD(internalFormat)", dimensions);
+ "glCopyTexImage%dD(internalFormat=%s)", dimensions,
+ _mesa_lookup_enum_by_nr(internalFormat));
return GL_TRUE;
}
@@ -2580,7 +2574,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
if (_mesa_is_color_format(internalFormat)) {
if (rb_base_format < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glCopyTexImage%dD(internalFormat)", dimensions);
+ "glCopyTexImage%dD(internalFormat=%s)", dimensions,
+ _mesa_lookup_enum_by_nr(internalFormat));
return GL_TRUE;
}
}
@@ -2606,7 +2601,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
}
if (!valid) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexImage%dD(internalFormat)", dimensions);
+ "glCopyTexImage%dD(internalFormat=%s)", dimensions,
+ _mesa_lookup_enum_by_nr(internalFormat));
return GL_TRUE;
}
}
@@ -4183,10 +4179,18 @@ _mesa_validate_texbuffer_format(const struct gl_context *ctx,
return MESA_FORMAT_NONE;
datatype = _mesa_get_format_datatype(format);
- if (datatype == GL_FLOAT && !ctx->Extensions.ARB_texture_float)
- return MESA_FORMAT_NONE;
- if (datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel)
+ /* The GL_ARB_texture_buffer_object spec says:
+ *
+ * "If ARB_texture_float is not supported, references to the
+ * floating-point internal formats provided by that extension should be
+ * removed, and such formats may not be passed to TexBufferARB."
+ *
+ * As a result, GL_HALF_FLOAT internal format depends on both
+ * GL_ARB_texture_float and GL_ARB_half_float_pixel.
+ */
+ if ((datatype == GL_FLOAT || datatype == GL_HALF_FLOAT) &&
+ !ctx->Extensions.ARB_texture_float)
return MESA_FORMAT_NONE;
if (!ctx->Extensions.ARB_texture_rg) {
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 5f8a47776..51d94d17e 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -163,7 +163,7 @@ _mesa_legal_texture_base_format_for_target(struct gl_context *ctx,
static inline void
_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
{
- _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
+ mtx_lock(&ctx->Shared->TexMutex);
ctx->Shared->TextureStateStamp++;
(void) texObj;
}
@@ -172,7 +172,7 @@ static inline void
_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
{
(void) texObj;
- _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
+ mtx_unlock(&ctx->Shared->TexMutex);
}
/*@}*/
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 6adc0ae84..3375fe36b 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -115,7 +115,7 @@ _mesa_initialize_texture_object( struct gl_context *ctx,
memset(obj, 0, sizeof(*obj));
/* init the non-zero fields */
- _glthread_INIT_MUTEX(obj->Mutex);
+ mtx_init(&obj->Mutex, mtx_plain);
obj->RefCount = 1;
obj->Name = name;
obj->Target = target;
@@ -237,7 +237,7 @@ _mesa_delete_texture_object(struct gl_context *ctx,
_mesa_reference_buffer_object(ctx, &texObj->BufferObject, NULL);
/* destroy the mutex -- it may have allocated memory (eg on bsd) */
- _glthread_DESTROY_MUTEX(texObj->Mutex);
+ mtx_destroy(&texObj->Mutex);
free(texObj->Label);
@@ -374,12 +374,12 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr,
ASSERT(valid_texture_object(oldTex));
(void) valid_texture_object; /* silence warning in release builds */
- _glthread_LOCK_MUTEX(oldTex->Mutex);
+ mtx_lock(&oldTex->Mutex);
ASSERT(oldTex->RefCount > 0);
oldTex->RefCount--;
deleteFlag = (oldTex->RefCount == 0);
- _glthread_UNLOCK_MUTEX(oldTex->Mutex);
+ mtx_unlock(&oldTex->Mutex);
if (deleteFlag) {
GET_CURRENT_CONTEXT(ctx);
@@ -396,7 +396,7 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr,
if (tex) {
/* reference new texture */
ASSERT(valid_texture_object(tex));
- _glthread_LOCK_MUTEX(tex->Mutex);
+ mtx_lock(&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. */
@@ -407,7 +407,7 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr,
tex->RefCount++;
*ptr = tex;
}
- _glthread_UNLOCK_MUTEX(tex->Mutex);
+ mtx_unlock(&tex->Mutex);
}
}
@@ -1009,7 +1009,7 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
/*
* This must be atomic (generation and allocation of texture IDs)
*/
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
@@ -1020,7 +1020,7 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
GLenum target = 0;
texObj = ctx->Driver.NewTextureObject(ctx, name, target);
if (!texObj) {
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
return;
}
@@ -1031,7 +1031,7 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
textures[i] = name;
}
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
@@ -1178,9 +1178,9 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
/* The texture _name_ is now free for re-use.
* Remove it from the hash table now.
*/
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
_mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
/* Unreference the texobj. If refcount hits zero, the texture
* will be deleted.
@@ -1313,9 +1313,9 @@ _mesa_BindTexture( GLenum target, GLuint texName )
}
/* and insert it into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
_mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
}
newTexObj->Target = target;
}
@@ -1327,10 +1327,10 @@ _mesa_BindTexture( GLenum target, GLuint texName )
*/
{
GLboolean early_out;
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_lock(&ctx->Shared->Mutex);
early_out = ((ctx->Shared->RefCount == 1)
&& (newTexObj == texUnit->CurrentTex[targetIndex]));
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ mtx_unlock(&ctx->Shared->Mutex);
if (early_out) {
return;
}
@@ -1493,7 +1493,7 @@ _mesa_IsTexture( GLuint texture )
void
_mesa_lock_context_textures( struct gl_context *ctx )
{
- _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
+ mtx_lock(&ctx->Shared->TexMutex);
if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) {
ctx->NewState |= _NEW_TEXTURE;
@@ -1506,7 +1506,7 @@ void
_mesa_unlock_context_textures( struct gl_context *ctx )
{
assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp);
- _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
+ mtx_unlock(&ctx->Shared->TexMutex);
}
void GLAPIENTRY
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index b7ed50dd5..bbdbc2763 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -986,6 +986,9 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
return ctx->Extensions.ARB_texture_cube_map;
+ case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB:
+ return ctx->Extensions.ARB_texture_cube_map_array;
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle;
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index 1e4308a04..3e22a0b46 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -1049,7 +1049,7 @@ _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
const GLuint depthScale = 0xffffff;
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
+ ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
{
/* general path */
@@ -2558,7 +2558,7 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
GLuint *depth;
GLubyte *stencil;
- ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
+ ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
srcFormat == GL_DEPTH_COMPONENT ||
srcFormat == GL_STENCIL_INDEX);
@@ -3699,9 +3699,9 @@ _mesa_get_texstore_func(mesa_format format)
table[MESA_FORMAT_G16R16_UNORM] = _mesa_texstore_unorm1616;
table[MESA_FORMAT_B10G10R10A2_UNORM] = _mesa_texstore_argb2101010;
table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8;
- table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_s8_z24;
+ table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24;
table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16;
- table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_x8_z24;
+ table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24;
table[MESA_FORMAT_X8Z24_UNORM] = _mesa_texstore_z24_x8;
table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32;
table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8;
diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp
index 82d7628e8..8cc5da752 100644
--- a/mesalib/src/mesa/main/uniform_query.cpp
+++ b/mesalib/src/mesa/main/uniform_query.cpp
@@ -684,6 +684,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
match = true;
break;
case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
match = (basicType == GLSL_TYPE_INT);
break;
default:
@@ -735,6 +736,22 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
}
}
+ if (uni->type->is_image()) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ const int unit = ((GLint *) values)[i];
+
+ /* check that the image unit is legal */
+ if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glUniform1i(invalid image unit index for uniform %d)",
+ location);
+ return;
+ }
+ }
+ }
+
/* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
*
* "When loading N elements starting at an arbitrary position k in a
@@ -830,6 +847,25 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
}
}
}
+
+ /* If the uniform is an image, update the mapping from image
+ * uniforms to image units present in the shader data structure.
+ */
+ if (uni->type->is_image()) {
+ int i, j;
+
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (uni->image[i].active) {
+ struct gl_shader *sh = shProg->_LinkedShaders[i];
+
+ for (j = 0; j < count; j++)
+ sh->ImageUnits[uni->image[i].index + offset + j] =
+ ((GLint *) values)[j];
+ }
+ }
+
+ ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
+ }
}
/**
diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c
index 071d668f3..c25c2df7e 100644
--- a/mesalib/src/mesa/main/uniforms.c
+++ b/mesalib/src/mesa/main/uniforms.c
@@ -270,6 +270,197 @@ _mesa_Uniform4iv(GLint location, GLsizei count, const GLint * value)
_mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
}
+/** Same as above with direct state access **/
+void GLAPIENTRY
+_mesa_ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform1f");
+ _mesa_uniform(ctx, shProg, location, 1, &v0, GL_FLOAT);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat v[2];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2f");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1,
+ GLfloat v2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat v[3];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3f");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1,
+ GLfloat v2, GLfloat v3)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat v[4];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4f");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1i(GLuint program, GLint location, GLint v0)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform1i");
+ _mesa_uniform(ctx, shProg, location, 1, &v0, GL_INT);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint v[2];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2i");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1,
+ GLint v2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint v[3];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3i");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1,
+ GLint v2, GLint v3)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint v[4];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4i");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1fv(GLuint program, GLint location, GLsizei count,
+ const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform1fv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2fv(GLuint program, GLint location, GLsizei count,
+ const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform2fv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3fv(GLuint program, GLint location, GLsizei count,
+ const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform3fv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4fv(GLuint program, GLint location, GLsizei count,
+ const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform4fv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1iv(GLuint program, GLint location, GLsizei count,
+ const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform1iv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_INT);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2iv(GLuint program, GLint location, GLsizei count,
+ const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform2iv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3iv(GLuint program, GLint location, GLsizei count,
+ const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform3iv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4iv(GLuint program, GLint location, GLsizei count,
+ const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform4iv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC4);
+}
+
/** OpenGL 3.0 GLuint-valued functions **/
void GLAPIENTRY
@@ -369,6 +560,140 @@ _mesa_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
4, 4, location, count, transpose, value);
}
+/** Same as above with direct state access **/
+
+void GLAPIENTRY
+_mesa_ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform1ui");
+ _mesa_uniform(ctx, shProg, location, 1, &v0, GL_UNSIGNED_INT);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint v[2];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform2ui");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1,
+ GLuint v2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint v[3];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform3ui");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1,
+ GLuint v2, GLuint v3)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLuint v[4];
+ struct gl_shader_program *shProg;
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4ui");
+ _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform1uiv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform2uiv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform3uiv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniform4uiv");
+ _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC4);
+}
+
+
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix2fv");
+ _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix3fv");
+ _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix4fv");
+ _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value);
+}
+
/**
* Non-square UniformMatrix are OpenGL 2.1
@@ -427,6 +752,74 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
4, 3, location, count, transpose, value);
}
+/** Same as above with direct state access **/
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix2x3fv");
+ _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix3x2fv");
+ _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix2x4fv");
+ _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix4x2fv");
+ _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix3x4fv");
+ _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program,
+ "glProgramUniformMatrix4x3fv");
+ _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value);
+}
+
void GLAPIENTRY
_mesa_GetnUniformfvARB(GLhandleARB program, GLint location,
diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h
index f7cac6328..bd50fd9b8 100644
--- a/mesalib/src/mesa/main/uniforms.h
+++ b/mesalib/src/mesa/main/uniforms.h
@@ -111,6 +111,89 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
void GLAPIENTRY
_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value);
+
+void GLAPIENTRY
+_mesa_ProgramUniform1f(GLuint program, GLint, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform2f(GLuint program, GLint, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform3f(GLuint program, GLint, GLfloat, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform4f(GLuint program, GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+void GLAPIENTRY
+_mesa_ProgramUniform1i(GLuint program, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform2i(GLuint program, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform3i(GLuint program, GLint, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform4i(GLuint program, GLint, GLint, GLint, GLint, GLint);
+void GLAPIENTRY
+_mesa_ProgramUniform1fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform2fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform3fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform4fv(GLuint program, GLint, GLsizei, const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniform1iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform2iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform3iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform4iv(GLuint program, GLint, GLsizei, const GLint *);
+void GLAPIENTRY
+_mesa_ProgramUniform1ui(GLuint program, GLint location, GLuint v0);
+void GLAPIENTRY
+_mesa_ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1);
+void GLAPIENTRY
+_mesa_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1,
+ GLuint v2);
+void GLAPIENTRY
+_mesa_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1,
+ GLuint v2, GLuint v3);
+void GLAPIENTRY
+_mesa_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
+ const GLuint *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2fv(GLuint program, GLint, GLsizei, GLboolean,
+ const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3fv(GLuint program, GLint, GLsizei, GLboolean,
+ const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4fv(GLuint program, GLint, GLsizei, GLboolean,
+ const GLfloat *);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+void GLAPIENTRY
+_mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *value);
+
void GLAPIENTRY
_mesa_GetnUniformfvARB(GLhandleARB, GLint, GLsizei, GLfloat *);
void GLAPIENTRY
diff --git a/mesalib/src/mesa/main/vdpau.c b/mesalib/src/mesa/main/vdpau.c
index 359757607..c2cf20664 100644
--- a/mesalib/src/mesa/main/vdpau.c
+++ b/mesalib/src/mesa/main/vdpau.c
@@ -205,7 +205,7 @@ _mesa_VDPAURegisterOutputSurfaceNV(const GLvoid *vdpSurface, GLenum target,
numTextureNames, textureNames);
}
-void GLAPIENTRY
+GLboolean GLAPIENTRY
_mesa_VDPAUIsSurfaceNV(GLintptr surface)
{
struct vdp_surface *surf = (struct vdp_surface *)surface;
@@ -213,13 +213,14 @@ _mesa_VDPAUIsSurfaceNV(GLintptr surface)
if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
_mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUIsSurfaceNV");
- return;
+ return false;
}
if (!_mesa_set_search(ctx->vdpSurfaces, _mesa_hash_pointer(surf), surf)) {
- _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUIsSurfaceNV");
- return;
+ return false;
}
+
+ return true;
}
void GLAPIENTRY
diff --git a/mesalib/src/mesa/main/vdpau.h b/mesalib/src/mesa/main/vdpau.h
index f32d6dacb..627609c50 100644
--- a/mesalib/src/mesa/main/vdpau.h
+++ b/mesalib/src/mesa/main/vdpau.h
@@ -50,7 +50,7 @@ _mesa_VDPAURegisterOutputSurfaceNV(const GLvoid *vdpSurface, GLenum target,
GLsizei numTextureNames,
const GLuint *textureNames);
-extern void GLAPIENTRY
+extern GLboolean GLAPIENTRY
_mesa_VDPAUIsSurfaceNV(GLintptr surface);
extern void GLAPIENTRY
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index 587cb9ad5..63cba26da 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -232,7 +232,6 @@ compute_version(struct gl_context *ctx)
(ctx->API == API_OPENGL_CORE ||
ctx->Extensions.ARB_color_buffer_float) &&
ctx->Extensions.ARB_depth_buffer_float &&
- ctx->Extensions.ARB_half_float_pixel &&
ctx->Extensions.ARB_half_float_vertex &&
ctx->Extensions.ARB_map_buffer_range &&
ctx->Extensions.ARB_shader_texture_lod &&