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