From 321c01267ae1c446f1bd22b642567fcafa016c02 Mon Sep 17 00:00:00 2001 From: marha Date: Tue, 4 Mar 2014 08:57:07 +0100 Subject: libX11 libxcb mesa xserver xcb-proto xkeyboard-config git update 4 Mar 2014 xserver commit b634e909895f6001e7d9543e1350b20c82c8c01c libxcb commit 4ffa6f83b92763eb901c7ddb7c20775e24d507ca libxcb/xcb-proto commit 4270141a7cb3c68f50251be19a5a628aa18553e6 xkeyboard-config commit d9e3d0ec1a48a5f61ea6dd6d20b8682eeecf3a39 libX11 commit d6bd988bc00494914b38b95ee5df77ac4f32f19f libXdmcp commit 089081dca4ba3598c6f9bf401c029378943b5854 libXext commit d5447c0156f556114dbf97d6064c0c7b0fcd5f70 libfontenc commit 0037a42107b952c9d903719615747e760e4e7247 libXinerama commit edd95182b26eb5d576d4878c559e0f17dddaa909 libXau commit 1e4635be11154dd8262f37b379511bd627defa2a xkbcomp commit 31b90ee4ffc774e0da540277907fc5540c0b012c pixman commit 82d094654a46bd97d47f1f132a01ae0a74b986f3 xextproto commit 66afec3f49e8eb0d4c2e9af7088fc3116d4bafd7 randrproto commit a4a6694c059d74247c16527eef4a0ec9f56bbef6 glproto commit f84853d97d5749308992412a215fa518b6536eb3 mkfontscale commit eac564e0fc9052a39981ea47b271f7f3d2821944 xwininfo commit ba0d1b0da21d2dbdd81098ed5778f3792b472e13 libXft commit 4acfdaf95adb0a05c2a25550bdde036c865902f4 libXmu commit 22d9c590901e121936f50dee97dc60c4f7defb63 libxtrans commit 3f0de269abe59353acbd7a5587d68ce0da91db67 fontconfig commit e310d2fac2d874d5aa76c609df70cc7b871c0b6d mesa commit 1a568e0f2b65e4e1e1d19a6dece3a792a33da825 --- mesalib/src/mesa/main/api_arrayelt.c | 14 +- mesalib/src/mesa/main/api_loopback.c | 1 - mesalib/src/mesa/main/api_loopback.h | 1 - mesalib/src/mesa/main/api_validate.c | 7 +- mesalib/src/mesa/main/arrayobj.c | 12 +- mesalib/src/mesa/main/attrib.c | 1 + mesalib/src/mesa/main/bufferobj.c | 443 ++++++++++++++++++---------- mesalib/src/mesa/main/bufferobj.h | 23 +- mesalib/src/mesa/main/context.c | 114 +++----- mesalib/src/mesa/main/dd.h | 21 +- mesalib/src/mesa/main/dlist.c | 9 +- mesalib/src/mesa/main/drawpix.c | 4 +- mesalib/src/mesa/main/enable.c | 33 ++- mesalib/src/mesa/main/errors.c | 487 ++++++++++++++++++------------- mesalib/src/mesa/main/errors.h | 3 + mesalib/src/mesa/main/execmem.c | 11 +- mesalib/src/mesa/main/extensions.c | 5 +- mesalib/src/mesa/main/fbobject.c | 22 +- mesalib/src/mesa/main/format_pack.c | 22 +- mesalib/src/mesa/main/format_unpack.c | 34 ++- mesalib/src/mesa/main/formats.c | 16 +- mesalib/src/mesa/main/formats.h | 100 +++---- mesalib/src/mesa/main/framebuffer.c | 14 +- mesalib/src/mesa/main/get.c | 21 ++ mesalib/src/mesa/main/get_hash_params.py | 6 +- mesalib/src/mesa/main/getstring.c | 20 +- mesalib/src/mesa/main/glformats.c | 24 +- mesalib/src/mesa/main/hash.c | 45 ++- mesalib/src/mesa/main/imports.h | 2 +- mesalib/src/mesa/main/mtypes.h | 94 ++++-- mesalib/src/mesa/main/pbo.c | 22 +- mesalib/src/mesa/main/pipelineobj.c | 445 ++++++++++++++++++++++++++++ mesalib/src/mesa/main/pipelineobj.h | 95 ++++++ mesalib/src/mesa/main/readpix.c | 4 +- mesalib/src/mesa/main/renderbuffer.c | 12 +- mesalib/src/mesa/main/samplerobj.c | 12 +- mesalib/src/mesa/main/shaderapi.c | 131 +++++++-- mesalib/src/mesa/main/shaderapi.h | 8 + mesalib/src/mesa/main/shaderobj.c | 1 + mesalib/src/mesa/main/shared.c | 22 +- mesalib/src/mesa/main/syncobj.c | 14 +- mesalib/src/mesa/main/texcompress_etc.c | 3 +- mesalib/src/mesa/main/texformat.c | 6 +- mesalib/src/mesa/main/texgetimage.c | 25 +- mesalib/src/mesa/main/teximage.c | 44 +-- mesalib/src/mesa/main/teximage.h | 4 +- mesalib/src/mesa/main/texobj.c | 34 +-- mesalib/src/mesa/main/texparam.c | 3 + mesalib/src/mesa/main/texstore.c | 8 +- mesalib/src/mesa/main/uniform_query.cpp | 36 +++ mesalib/src/mesa/main/uniforms.c | 393 +++++++++++++++++++++++++ mesalib/src/mesa/main/uniforms.h | 83 ++++++ mesalib/src/mesa/main/vdpau.c | 9 +- mesalib/src/mesa/main/vdpau.h | 2 +- mesalib/src/mesa/main/version.c | 1 - 55 files changed, 2263 insertions(+), 763 deletions(-) create mode 100644 mesalib/src/mesa/main/pipelineobj.c create mode 100644 mesalib/src/mesa/main/pipelineobj.h (limited to 'mesalib/src/mesa/main') 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 ca55ef969..2e9e05918 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) */ static 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 */ static 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,14 +1218,72 @@ _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 @@ -117,6 +130,10 @@ _mesa_GenBuffers(GLsizei n, GLuint * buffer); 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 458d8e59b..5b77ce103 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: @@ -4188,12 +4188,31 @@ 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 d79e2a339..9e221cccb 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 */ @@ -2418,6 +2436,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 @@ -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 + * + * Permission is hereby granted, free of charge, to 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 + * + * 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 +#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 + * + * Permission is hereby granted, free of charge, to 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 ad21f3b67..a88d7e469 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 _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 9af5f091e..1c0bedf4b 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 && -- cgit v1.2.3