From 4ba9be2882d9f1567809edb0a31fcdf11320d41f Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 20 Apr 2015 21:25:25 +0200 Subject: randrproto xkeyboard-config fontconfig libX11 libXdmcp libXmu pixman xkbcomp xserver mesa git update 20 Apr 2015 xserver commit b1029716e41e252f149b82124a149da180607c96 xkeyboard-config commit 7d00bcc2d9c3944bbdfcbe472ee3299729dc7687 libX11 commit 748d47e69f5c12d8557d56a8a8ec166588da7b93 libXdmcp commit b10f382e3aa2e86cd5a2bc27d6758da55f0ab1f6 xkbcomp commit 1ae525b3d236b59e6437b2b5433d460e18370973 pixman commit 58e21d3e45c5227c2ca9ac00cf044f22a7975180 randrproto commit 98da0d6e48b7d124d6788ea568e9f9e3dc204322 libXmu commit 4459e6940fe3fdf26a8d5d4c71989498bc400a62 fontconfig commit 07be485a0a84995ce69bf60e3b1bb22cb35f6b0e mesa commit c1485f4b7d044724b3dbc1011f3c3a8a53132010 --- mesalib/src/mesa/main/.gitignore | 1 + mesalib/src/mesa/main/atifragshader.c | 4 +- mesalib/src/mesa/main/attrib.c | 1 - mesalib/src/mesa/main/bufferobj.c | 11 +- mesalib/src/mesa/main/colormac.h | 45 -- mesalib/src/mesa/main/context.c | 12 +- mesalib/src/mesa/main/debug.c | 2 +- mesalib/src/mesa/main/dlopen.h | 6 +- mesalib/src/mesa/main/errors.c | 43 +- mesalib/src/mesa/main/errors.h | 7 + mesalib/src/mesa/main/extensions.c | 1 + mesalib/src/mesa/main/fbobject.c | 439 +++++++++++------ mesalib/src/mesa/main/fbobject.h | 16 + mesalib/src/mesa/main/ffvertex_prog.c | 6 +- mesalib/src/mesa/main/format_pack.py | 1 - mesalib/src/mesa/main/format_unpack.h | 2 + mesalib/src/mesa/main/format_unpack.py | 5 +- mesalib/src/mesa/main/glformats.c | 2 +- mesalib/src/mesa/main/imports.h | 24 + mesalib/src/mesa/main/macros.h | 7 + mesalib/src/mesa/main/mtypes.h | 184 +------ mesalib/src/mesa/main/multisample.c | 9 + mesalib/src/mesa/main/pipelineobj.c | 35 +- mesalib/src/mesa/main/pipelineobj.h | 3 + mesalib/src/mesa/main/pixel.c | 1 - mesalib/src/mesa/main/pixeltransfer.c | 2 +- mesalib/src/mesa/main/program_resource.c | 417 ++++++++++++++++ mesalib/src/mesa/main/program_resource.h | 58 +++ mesalib/src/mesa/main/queryobj.c | 131 ++++- mesalib/src/mesa/main/queryobj.h | 14 + mesalib/src/mesa/main/samplerobj.c | 25 +- mesalib/src/mesa/main/samplerobj.h | 5 + mesalib/src/mesa/main/shader_query.cpp | 764 ++++++++++++++++++++++++++---- mesalib/src/mesa/main/shaderapi.c | 25 +- mesalib/src/mesa/main/shaderapi.h | 45 ++ mesalib/src/mesa/main/shaderobj.c | 6 + mesalib/src/mesa/main/state.c | 27 +- mesalib/src/mesa/main/texcompress.c | 1 - mesalib/src/mesa/main/texcompress_fxt1.c | 1 - mesalib/src/mesa/main/texcompress_rgtc.c | 1 - mesalib/src/mesa/main/texcompress_s3tc.c | 9 - mesalib/src/mesa/main/texparam.c | 1 - mesalib/src/mesa/main/texstate.c | 2 - mesalib/src/mesa/main/texstore.c | 1 - mesalib/src/mesa/main/transformfeedback.c | 386 ++++++++++++--- mesalib/src/mesa/main/transformfeedback.h | 30 +- mesalib/src/mesa/main/uniform_query.cpp | 138 +++--- mesalib/src/mesa/main/uniforms.c | 294 ++++-------- mesalib/src/mesa/main/uniforms.h | 5 - mesalib/src/mesa/main/version.c | 1 + mesalib/src/mesa/main/viewport.c | 48 +- mesalib/src/mesa/main/viewport.h | 3 - 52 files changed, 2328 insertions(+), 979 deletions(-) create mode 100644 mesalib/src/mesa/main/program_resource.c create mode 100644 mesalib/src/mesa/main/program_resource.h (limited to 'mesalib/src/mesa/main') diff --git a/mesalib/src/mesa/main/.gitignore b/mesalib/src/mesa/main/.gitignore index 8256ad792..355b426e2 100644 --- a/mesalib/src/mesa/main/.gitignore +++ b/mesalib/src/mesa/main/.gitignore @@ -7,5 +7,6 @@ remap_helper.h get_hash.h get_hash.h.tmp format_info.h +format_info.c format_pack.c format_unpack.c diff --git a/mesalib/src/mesa/main/atifragshader.c b/mesalib/src/mesa/main/atifragshader.c index 9d967b9e6..9fc35520a 100644 --- a/mesalib/src/mesa/main/atifragshader.c +++ b/mesalib/src/mesa/main/atifragshader.c @@ -476,7 +476,7 @@ _mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle) curI->swizzle = swizzle; #if MESA_DEBUG_ATI_FS - _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, + _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__, _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord), _mesa_lookup_enum_by_nr(swizzle)); #endif @@ -549,7 +549,7 @@ _mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle) curI->swizzle = swizzle; #if MESA_DEBUG_ATI_FS - _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, + _mesa_debug(ctx, "%s(%s, %s, %s)\n", __func__, _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp), _mesa_lookup_enum_by_nr(swizzle)); #endif diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 20216a87d..b163c0aa6 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -32,7 +32,6 @@ #include "buffers.h" #include "bufferobj.h" #include "clear.h" -#include "colormac.h" #include "context.h" #include "depth.h" #include "enable.h" diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 965877084..66dee6802 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -1333,6 +1333,7 @@ create_buffers(GLsizei n, GLuint *buffers, bool dsa) buf = ctx->Driver.NewBufferObject(ctx, buffers[i]); if (!buf) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); + mtx_unlock(&ctx->Shared->Mutex); return; } } @@ -3885,8 +3886,10 @@ _mesa_BindBufferRange(GLenum target, GLuint index, switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER: - _mesa_bind_buffer_range_transform_feedback(ctx, index, bufObj, - offset, size); + _mesa_bind_buffer_range_transform_feedback(ctx, + ctx->TransformFeedback.CurrentObject, + index, bufObj, offset, size, + false); return; case GL_UNIFORM_BUFFER: bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size); @@ -3950,7 +3953,9 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer) switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER: - _mesa_bind_buffer_base_transform_feedback(ctx, index, bufObj); + _mesa_bind_buffer_base_transform_feedback(ctx, + ctx->TransformFeedback.CurrentObject, + index, bufObj, false); return; case GL_UNIFORM_BUFFER: bind_buffer_base_uniform_buffer(ctx, index, bufObj); diff --git a/mesalib/src/mesa/main/colormac.h b/mesalib/src/mesa/main/colormac.h index bc69f4673..33ca5af07 100644 --- a/mesalib/src/mesa/main/colormac.h +++ b/mesalib/src/mesa/main/colormac.h @@ -52,70 +52,25 @@ _mesa_unclamped_float_rgba_to_ubyte(GLubyte dst[4], const GLfloat src[4]) /** * \name Generic color packing macros. All inputs should be GLubytes. - * - * \todo We may move these into texstore.h at some point. */ /*@{*/ #define PACK_COLOR_8888( X, Y, Z, W ) \ (((X) << 24) | ((Y) << 16) | ((Z) << 8) | (W)) -#define PACK_COLOR_8888_REV( X, Y, Z, W ) \ - (((W) << 24) | ((Z) << 16) | ((Y) << 8) | (X)) - -#define PACK_COLOR_888( X, Y, Z ) \ - (((X) << 16) | ((Y) << 8) | (Z)) - #define PACK_COLOR_565( X, Y, Z ) \ ((((X) & 0xf8) << 8) | (((Y) & 0xfc) << 3) | (((Z) & 0xf8) >> 3)) -#define PACK_COLOR_5551( R, G, B, A ) \ - ((((R) & 0xf8) << 8) | (((G) & 0xf8) << 3) | (((B) & 0xf8) >> 2) | \ - ((A) >> 7)) - #define PACK_COLOR_1555( A, B, G, R ) \ ((((B) & 0xf8) << 7) | (((G) & 0xf8) << 2) | (((R) & 0xf8) >> 3) | \ (((A) & 0x80) << 8)) -#define PACK_COLOR_1555_REV( A, B, G, R ) \ - ((((B) & 0xf8) >> 1) | (((G) & 0xc0) >> 6) | (((G) & 0x38) << 10) | (((R) & 0xf8) << 5) | \ - ((A) ? 0x80 : 0)) - -#define PACK_COLOR_2101010_UB( A, B, G, R ) \ - (((B) << 22) | ((G) << 12) | ((R) << 2) | \ - (((A) & 0xc0) << 24)) - -#define PACK_COLOR_2101010_US( A, B, G, R ) \ - ((((B) >> 6) << 20) | (((G) >> 6) << 10) | ((R) >> 6) | \ - (((A) >> 14) << 30)) - #define PACK_COLOR_4444( R, G, B, A ) \ ((((R) & 0xf0) << 8) | (((G) & 0xf0) << 4) | ((B) & 0xf0) | ((A) >> 4)) -#define PACK_COLOR_4444_REV( R, G, B, A ) \ - ((((B) & 0xf0) << 8) | (((A) & 0xf0) << 4) | ((R) & 0xf0) | ((G) >> 4)) - -#define PACK_COLOR_44( L, A ) \ - (((L) & 0xf0) | (((A) & 0xf0) >> 4)) - #define PACK_COLOR_88( L, A ) \ (((L) << 8) | (A)) -#define PACK_COLOR_88_REV( L, A ) \ - (((A) << 8) | (L)) - -#define PACK_COLOR_1616( L, A ) \ - (((L) << 16) | (A)) - -#define PACK_COLOR_1616_REV( L, A ) \ - (((A) << 16) | (L)) - -#define PACK_COLOR_332( R, G, B ) \ - (((R) & 0xe0) | (((G) & 0xe0) >> 3) | (((B) & 0xc0) >> 6)) - -#define PACK_COLOR_233( B, G, R ) \ - (((B) & 0xc0) | (((G) & 0xe0) >> 2) | (((R) & 0xe0) >> 5)) - /*@}*/ diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index c1acda980..adf64976e 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1288,7 +1288,6 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_free_eval_data( 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); @@ -1449,17 +1448,10 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst, dst->Transform = src->Transform; } if (mask & GL_VIEWPORT_BIT) { - /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */ unsigned i; for (i = 0; i < src->Const.MaxViewports; i++) { - dst->ViewportArray[i].X = src->ViewportArray[i].X; - dst->ViewportArray[i].Y = src->ViewportArray[i].Y; - dst->ViewportArray[i].Width = src->ViewportArray[i].Width; - dst->ViewportArray[i].Height = src->ViewportArray[i].Height; - dst->ViewportArray[i].Near = src->ViewportArray[i].Near; - dst->ViewportArray[i].Far = src->ViewportArray[i].Far; - _math_matrix_copy(&dst->ViewportArray[i]._WindowMap, - &src->ViewportArray[i]._WindowMap); + /* OK to memcpy */ + dst->ViewportArray[i] = src->ViewportArray[i]; } } diff --git a/mesalib/src/mesa/main/debug.c b/mesalib/src/mesa/main/debug.c index b50d79e0c..c93e84a04 100644 --- a/mesalib/src/mesa/main/debug.c +++ b/mesalib/src/mesa/main/debug.c @@ -26,11 +26,11 @@ #include #include "mtypes.h" #include "attrib.h" -#include "colormac.h" #include "enums.h" #include "formats.h" #include "hash.h" #include "imports.h" +#include "macros.h" #include "debug.h" #include "get.h" #include "pixelstore.h" diff --git a/mesalib/src/mesa/main/dlopen.h b/mesalib/src/mesa/main/dlopen.h index 1e7784914..4d20ff2c7 100644 --- a/mesalib/src/mesa/main/dlopen.h +++ b/mesalib/src/mesa/main/dlopen.h @@ -50,7 +50,7 @@ _mesa_dlopen(const char *libname, int flags) #if defined(HAVE_DLOPEN) flags = RTLD_LAZY | RTLD_GLOBAL; /* Overriding flags at this time */ return dlopen(libname, flags); -#elif defined(__MINGW32__) +#elif defined(_WIN32) return LoadLibraryA(libname); #else return NULL; @@ -71,7 +71,7 @@ _mesa_dlsym(void *handle, const char *fname) } u; #if defined(HAVE_DLOPEN) u.v = dlsym(handle, fname); -#elif defined(__MINGW32__) +#elif defined(_WIN32) u.v = (void *) GetProcAddress(handle, fname); #else u.v = NULL; @@ -87,7 +87,7 @@ _mesa_dlclose(void *handle) { #if defined(HAVE_DLOPEN) dlclose(handle); -#elif defined(__MINGW32__) +#elif defined(_WIN32) FreeLibrary(handle); #else (void) handle; diff --git a/mesalib/src/mesa/main/errors.c b/mesalib/src/mesa/main/errors.c index 8ffbf413c..2aa1deb63 100644 --- a/mesalib/src/mesa/main/errors.c +++ b/mesalib/src/mesa/main/errors.c @@ -1232,12 +1232,14 @@ _mesa_free_errors_data(struct gl_context *ctx) /** \name Diagnostics */ /*@{*/ +static FILE *LogFile = NULL; + + static void output_if_debug(const char *prefixString, const char *outputString, GLboolean newline) { static int debug = -1; - static FILE *fout = NULL; /* Init the local 'debug' var once. * Note: the _mesa_init_debug() function should have been called @@ -1249,9 +1251,9 @@ output_if_debug(const char *prefixString, const char *outputString, */ const char *logFile = getenv("MESA_LOG_FILE"); if (logFile) - fout = fopen(logFile, "w"); - if (!fout) - fout = stderr; + LogFile = fopen(logFile, "w"); + if (!LogFile) + LogFile = stderr; #ifdef DEBUG /* in debug builds, print messages unless MESA_DEBUG="silent" */ if (MESA_DEBUG_FLAGS & DEBUG_SILENT) @@ -1266,10 +1268,13 @@ output_if_debug(const char *prefixString, const char *outputString, /* Now only print the string if we're required to do so. */ if (debug) { - fprintf(fout, "%s: %s", prefixString, outputString); + if (prefixString) + fprintf(LogFile, "%s: %s", prefixString, outputString); + else + fprintf(LogFile, "%s", outputString); if (newline) - fprintf(fout, "\n"); - fflush(fout); + fprintf(LogFile, "\n"); + fflush(LogFile); #if defined(_WIN32) /* stderr from windows applications without console is not usually @@ -1284,6 +1289,18 @@ output_if_debug(const char *prefixString, const char *outputString, } +/** + * Return the file handle to use for debug/logging. Defaults to stderr + * unless MESA_LOG_FILE is defined. + */ +FILE * +_mesa_get_log_file(void) +{ + assert(LogFile); + return LogFile; +} + + /** * When a new type of error is recorded, print a message describing * previous errors which were accumulated. @@ -1525,6 +1542,18 @@ _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) } +void +_mesa_log(const char *fmtString, ...) +{ + char s[MAX_DEBUG_MESSAGE_LENGTH]; + va_list args; + va_start(args, fmtString); + _mesa_vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args); + va_end(args); + output_if_debug("", s, GL_FALSE); +} + + /** * Report debug information from the shader compiler via GL_ARB_debug_output. * diff --git a/mesalib/src/mesa/main/errors.h b/mesalib/src/mesa/main/errors.h index 0c521c0d0..e6dc9b5f1 100644 --- a/mesalib/src/mesa/main/errors.h +++ b/mesalib/src/mesa/main/errors.h @@ -36,6 +36,7 @@ #define ERRORS_H +#include #include "compiler.h" #include "glheader.h" #include "mtypes.h" @@ -68,6 +69,12 @@ _mesa_error_no_memory(const char *caller); extern void _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLIKE(2, 3); +extern void +_mesa_log(const char *fmtString, ...) PRINTFLIKE(1, 2); + +extern FILE * +_mesa_get_log_file(void); + extern void _mesa_gl_debug(struct gl_context *ctx, GLuint *id, diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index f21201538..861b15006 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -139,6 +139,7 @@ static const struct extension extension_table[] = { { "GL_ARB_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 }, { "GL_ARB_point_parameters", o(EXT_point_parameters), GLL, 1997 }, { "GL_ARB_point_sprite", o(ARB_point_sprite), GL, 2003 }, + { "GL_ARB_program_interface_query", o(dummy_true), GL, 2012 }, { "GL_ARB_provoking_vertex", o(EXT_provoking_vertex), GL, 2009 }, { "GL_ARB_robustness", o(dummy_true), GL, 2010 }, { "GL_ARB_sample_shading", o(ARB_sample_shading), GL, 2009 }, diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index f8d0d92bf..8032585ab 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -212,13 +212,13 @@ get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, */ i = attachment - GL_COLOR_ATTACHMENT0_EXT; if (i >= ctx->Const.MaxColorAttachments - || (i > 0 && ctx->API == API_OPENGLES)) { - return NULL; + || (i > 0 && ctx->API == API_OPENGLES)) { + return NULL; } return &fb->Attachment[BUFFER_COLOR0 + i]; case GL_DEPTH_STENCIL_ATTACHMENT: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) - return NULL; + return NULL; /* fall-through */ case GL_DEPTH_ATTACHMENT_EXT: return &fb->Attachment[BUFFER_DEPTH]; @@ -1122,28 +1122,28 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) { /* Check that all DrawBuffers are present */ for (j = 0; j < ctx->Const.MaxDrawBuffers; j++) { - if (fb->ColorDrawBuffer[j] != GL_NONE) { - const struct gl_renderbuffer_attachment *att - = get_attachment(ctx, fb, fb->ColorDrawBuffer[j]); - assert(att); - if (att->Type == GL_NONE) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT; - fbo_incomplete(ctx, "missing drawbuffer", j); - return; - } - } + if (fb->ColorDrawBuffer[j] != GL_NONE) { + const struct gl_renderbuffer_attachment *att + = get_attachment(ctx, fb, fb->ColorDrawBuffer[j]); + assert(att); + if (att->Type == GL_NONE) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT; + fbo_incomplete(ctx, "missing drawbuffer", j); + return; + } + } } /* Check that the ReadBuffer is present */ if (fb->ColorReadBuffer != GL_NONE) { - const struct gl_renderbuffer_attachment *att - = get_attachment(ctx, fb, fb->ColorReadBuffer); - assert(att); - if (att->Type == GL_NONE) { - fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT; + const struct gl_renderbuffer_attachment *att + = get_attachment(ctx, fb, fb->ColorReadBuffer); + assert(att); + if (att->Type == GL_NONE) { + fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT; fbo_incomplete(ctx, "missing readbuffer", -1); - return; - } + return; + } } } @@ -1205,6 +1205,28 @@ _mesa_IsRenderbuffer(GLuint renderbuffer) } +static struct gl_renderbuffer * +allocate_renderbuffer(struct gl_context *ctx, GLuint renderbuffer, + const char *func) +{ + struct gl_renderbuffer *newRb; + + /* create new renderbuffer object */ + newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer); + if (!newRb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); + return NULL; + } + assert(newRb->AllocStorage); + mtx_lock(&ctx->Shared->Mutex); + _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb); + newRb->RefCount = 1; /* referenced by hash table */ + mtx_unlock(&ctx->Shared->Mutex); + + return newRb; +} + + static void bind_renderbuffer(GLenum target, GLuint renderbuffer, bool allow_user_names) { @@ -1233,15 +1255,7 @@ bind_renderbuffer(GLenum target, GLuint renderbuffer, bool allow_user_names) } if (!newRb) { - /* create new renderbuffer object */ - newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer); - if (!newRb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT"); - return; - } - assert(newRb->AllocStorage); - _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb); - newRb->RefCount = 1; /* referenced by hash table */ + newRb = allocate_renderbuffer(ctx, renderbuffer, "glBindRenderbufferEXT"); } } else { @@ -1333,9 +1347,9 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) for (i = 0; i < n; i++) { if (renderbuffers[i] > 0) { - struct gl_renderbuffer *rb; - rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]); - if (rb) { + struct gl_renderbuffer *rb; + rb = _mesa_lookup_renderbuffer(ctx, renderbuffers[i]); + if (rb) { /* check if deleting currently bound renderbuffer object */ if (rb == ctx->CurrentRenderbuffer) { /* bind default */ @@ -1368,31 +1382,31 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, rb); } - /* Remove from hash table immediately, to free the ID. + /* Remove from hash table immediately, to free the ID. * But the object will not be freed until it's no longer * referenced anywhere else. */ - _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]); + _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]); if (rb != &DummyRenderbuffer) { /* no longer referenced by hash table */ _mesa_reference_renderbuffer(&rb, NULL); - } - } + } + } } } } - -void GLAPIENTRY -_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers) +static void +create_render_buffers(struct gl_context *ctx, GLsizei n, GLuint *renderbuffers, + bool dsa) { - GET_CURRENT_CONTEXT(ctx); + const char *func = dsa ? "glCreateRenderbuffers" : "glGenRenderbuffers"; GLuint first; GLint i; if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)"); + _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", func); return; } @@ -1404,14 +1418,35 @@ _mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers) for (i = 0; i < n; i++) { GLuint name = first + i; renderbuffers[i] = name; - /* insert dummy placeholder into hash table */ - mtx_lock(&ctx->Shared->Mutex); - _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer); - mtx_unlock(&ctx->Shared->Mutex); + + if (dsa) { + allocate_renderbuffer(ctx, name, func); + } else { + /* insert a dummy renderbuffer into the hash table */ + mtx_lock(&ctx->Shared->Mutex); + _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer); + mtx_unlock(&ctx->Shared->Mutex); + } } } +void GLAPIENTRY +_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ + GET_CURRENT_CONTEXT(ctx); + create_render_buffers(ctx, n, renderbuffers, false); +} + + +void GLAPIENTRY +_mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ + GET_CURRENT_CONTEXT(ctx); + create_render_buffers(ctx, n, renderbuffers, true); +} + + /** * Given an internal format token for a render buffer, return the * corresponding base format (one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, @@ -1749,40 +1784,17 @@ invalidate_rb(GLuint key, void *data, void *userData) /** - * Helper function used by _mesa_RenderbufferStorage() and - * _mesa_RenderbufferStorageMultisample(). - * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorage(). + * Helper function used by renderbuffer_storage_direct() and + * renderbuffer_storage_target(). + * samples will be NO_SAMPLES if called by a non-multisample function. */ static void -renderbuffer_storage(GLenum target, GLenum internalFormat, - GLsizei width, GLsizei height, GLsizei samples) +renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei samples, const char *func) { - const char *func = samples == NO_SAMPLES ? - "glRenderbufferStorage" : "glRenderbufferStorageMultisample"; - struct gl_renderbuffer *rb; GLenum baseFormat; GLenum sample_count_error; - GET_CURRENT_CONTEXT(ctx); - - if (MESA_VERBOSE & VERBOSE_API) { - if (samples == NO_SAMPLES) - _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n", - func, - _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(internalFormat), - width, height); - else - _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n", - func, - _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(internalFormat), - width, height, samples); - } - - if (target != GL_RENDERBUFFER_EXT) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); - return; - } baseFormat = _mesa_base_fbo_format(ctx, internalFormat); if (baseFormat == 0) { @@ -1792,12 +1804,14 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, } if (width < 0 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s(width)", func); + _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid width %d)", func, + width); return; } if (height < 0 || height > (GLsizei) ctx->Const.MaxRenderbufferSize) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s(height)", func); + _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid height %d)", func, + height); return; } @@ -1809,7 +1823,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, /* check the sample count; * note: driver may choose to use more samples than what's requested */ - sample_count_error = _mesa_check_sample_count(ctx, target, + sample_count_error = _mesa_check_sample_count(ctx, GL_RENDERBUFFER, internalFormat, samples); if (sample_count_error != GL_NO_ERROR) { _mesa_error(ctx, sample_count_error, "%s(samples)", func); @@ -1817,12 +1831,6 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, } } - rb = ctx->CurrentRenderbuffer; - if (!rb) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func); - return; - } - FLUSH_VERTICES(ctx, _NEW_BUFFERS); if (rb->InternalFormat == internalFormat && @@ -1864,6 +1872,83 @@ renderbuffer_storage(GLenum target, GLenum internalFormat, } } +/** + * Helper function used by _mesa_NamedRenderbufferStorage*(). + * samples will be NO_SAMPLES if called by a non-multisample function. + */ +static void +renderbuffer_storage_named(GLuint renderbuffer, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei samples, + const char *func) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) { + if (samples == NO_SAMPLES) + _mesa_debug(ctx, "%s(%u, %s, %d, %d)\n", + func, renderbuffer, + _mesa_lookup_enum_by_nr(internalFormat), + width, height); + else + _mesa_debug(ctx, "%s(%u, %s, %d, %d, %d)\n", + func, renderbuffer, + _mesa_lookup_enum_by_nr(internalFormat), + width, height, samples); + } + + struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); + if (!rb || rb == &DummyRenderbuffer) { + /* ID was reserved, but no real renderbuffer object made yet */ + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid renderbuffer %u)", + func, renderbuffer); + return; + } + + renderbuffer_storage(ctx, rb, internalFormat, width, height, samples, func); +} + +/** + * Helper function used by _mesa_RenderbufferStorage() and + * _mesa_RenderbufferStorageMultisample(). + * samples will be NO_SAMPLES if called by _mesa_RenderbufferStorage(). + */ +static void +renderbuffer_storage_target(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei samples, + const char *func) +{ + GET_CURRENT_CONTEXT(ctx); + + if (MESA_VERBOSE & VERBOSE_API) { + if (samples == NO_SAMPLES) + _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n", + func, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internalFormat), + width, height); + else + _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n", + func, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internalFormat), + width, height, samples); + } + + if (target != GL_RENDERBUFFER_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); + return; + } + + if (!ctx->CurrentRenderbuffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no renderbuffer bound)", + func); + return; + } + + renderbuffer_storage(ctx, ctx->CurrentRenderbuffer, internalFormat, width, + height, samples, func); +} + void GLAPIENTRY _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) @@ -1923,7 +2008,8 @@ _mesa_RenderbufferStorage(GLenum target, GLenum internalFormat, * glRenderbufferStorageMultisample() with samples=0. We pass in * a token value here just for error reporting purposes. */ - renderbuffer_storage(target, internalFormat, width, height, NO_SAMPLES); + renderbuffer_storage_target(target, internalFormat, width, height, + NO_SAMPLES, "glRenderbufferStorage"); } @@ -1932,7 +2018,8 @@ _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) { - renderbuffer_storage(target, internalFormat, width, height, samples); + renderbuffer_storage_target(target, internalFormat, width, height, + samples, "glRenderbufferStorageMultisample"); } @@ -1941,7 +2028,7 @@ _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples, */ void GLAPIENTRY _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, - GLsizei width, GLsizei height) + GLsizei width, GLsizei height) { switch (internalFormat) { case GL_RGB565: @@ -1953,29 +2040,38 @@ _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, break; } - renderbuffer_storage(target, internalFormat, width, height, 0); + renderbuffer_storage_target(target, internalFormat, width, height, 0, + "glRenderbufferStorageEXT"); } - void GLAPIENTRY -_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) +_mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat, + GLsizei width, GLsizei height) { - struct gl_renderbuffer *rb; - GET_CURRENT_CONTEXT(ctx); + /* GL_ARB_fbo says calling this function is equivalent to calling + * glRenderbufferStorageMultisample() with samples=0. We pass in + * a token value here just for error reporting purposes. + */ + renderbuffer_storage_named(renderbuffer, internalformat, width, height, + NO_SAMPLES, "glNamedRenderbufferStorage"); +} - if (target != GL_RENDERBUFFER_EXT) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetRenderbufferParameterivEXT(target)"); - return; - } +void GLAPIENTRY +_mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples, + GLenum internalformat, + GLsizei width, GLsizei height) +{ + renderbuffer_storage_named(renderbuffer, internalformat, width, height, + samples, + "glNamedRenderbufferStorageMultisample"); +} - rb = ctx->CurrentRenderbuffer; - if (!rb) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetRenderbufferParameterivEXT"); - return; - } +static void +get_render_buffer_parameteriv(struct gl_context *ctx, + struct gl_renderbuffer *rb, GLenum pname, + GLint *params, const char *func) +{ /* No need to flush here since we're just quering state which is * not effected by rendering. */ @@ -2006,10 +2102,51 @@ _mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) } /* fallthrough */ default: + _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname=%s)", func, + _mesa_lookup_enum_by_nr(pname)); + return; + } +} + + +void GLAPIENTRY +_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + + if (target != GL_RENDERBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetRenderbufferParameterivEXT(target)"); return; } + + if (!ctx->CurrentRenderbuffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetRenderbufferParameterivEXT" + "(no renderbuffer bound)"); + return; + } + + get_render_buffer_parameteriv(ctx, ctx->CurrentRenderbuffer, pname, + params, "glGetRenderbufferParameteriv"); +} + + +void GLAPIENTRY +_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, + GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + + struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); + if (!rb || rb == &DummyRenderbuffer) { + /* ID was reserved, but no real renderbuffer object made yet */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetNamedRenderbufferParameteriv" + "(invalid renderbuffer %i)", renderbuffer); + return; + } + + get_render_buffer_parameteriv(ctx, rb, pname, params, + "glGetNamedRenderbufferParameteriv"); } @@ -2116,12 +2253,12 @@ bind_framebuffer(GLenum target, GLuint framebuffer, bool allow_user_names) } if (!newDrawFb) { - /* create new framebuffer object */ - newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer); - if (!newDrawFb) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT"); - return; - } + /* create new framebuffer object */ + newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer); + if (!newDrawFb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT"); + return; + } _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb); } newReadFb = newDrawFb; @@ -2224,9 +2361,9 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) for (i = 0; i < n; i++) { if (framebuffers[i] > 0) { - struct gl_framebuffer *fb; - fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]); - if (fb) { + struct gl_framebuffer *fb; + fb = _mesa_lookup_framebuffer(ctx, framebuffers[i]); + if (fb) { assert(fb == &DummyFramebuffer || fb->Name == framebuffers[i]); /* check if deleting currently bound framebuffer object */ @@ -2241,16 +2378,16 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) _mesa_BindFramebuffer(GL_READ_FRAMEBUFFER, 0); } - /* remove from hash table immediately, to free the ID */ - _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]); + /* remove from hash table immediately, to free the ID */ + _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]); if (fb != &DummyFramebuffer) { /* But the object will not be freed until it's no longer * bound in any context. */ _mesa_reference_framebuffer(&fb, NULL); - } - } + } + } } } } @@ -2498,34 +2635,34 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, _mesa_tex_target_to_face(textarget) == fb->Attachment[BUFFER_STENCIL].CubeMapFace && zoffset == fb->Attachment[BUFFER_STENCIL].Zoffset) { - /* The texture object is already attached to the stencil attachment - * point. Don't create a new renderbuffer; just reuse the stencil - * attachment's. This is required to prevent a GL error in - * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL). - */ - reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH, - BUFFER_STENCIL); + /* The texture object is already attached to the stencil attachment + * point. Don't create a new renderbuffer; just reuse the stencil + * attachment's. This is required to prevent a GL error in + * glGetFramebufferAttachmentParameteriv(GL_DEPTH_STENCIL). + */ + reuse_framebuffer_texture_attachment(fb, BUFFER_DEPTH, + BUFFER_STENCIL); } else if (attachment == GL_STENCIL_ATTACHMENT && - texObj == fb->Attachment[BUFFER_DEPTH].Texture && + texObj == fb->Attachment[BUFFER_DEPTH].Texture && level == fb->Attachment[BUFFER_DEPTH].TextureLevel && _mesa_tex_target_to_face(textarget) == fb->Attachment[BUFFER_DEPTH].CubeMapFace && zoffset == fb->Attachment[BUFFER_DEPTH].Zoffset) { - /* As above, but with depth and stencil transposed. */ - reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL, - BUFFER_DEPTH); + /* As above, but with depth and stencil transposed. */ + reuse_framebuffer_texture_attachment(fb, BUFFER_STENCIL, + BUFFER_DEPTH); } else { - set_texture_attachment(ctx, fb, att, texObj, textarget, - level, zoffset, layered); - if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { - /* Above we created a new renderbuffer and attached it to the - * depth attachment point. Now attach it to the stencil attachment - * point too. - */ - assert(att == &fb->Attachment[BUFFER_DEPTH]); - reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL, - BUFFER_DEPTH); - } + set_texture_attachment(ctx, fb, att, texObj, textarget, + level, zoffset, layered); + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { + /* Above we created a new renderbuffer and attached it to the + * depth attachment point. Now attach it to the stencil attachment + * point too. + */ + assert(att == &fb->Attachment[BUFFER_DEPTH]); + reuse_framebuffer_texture_attachment(fb,BUFFER_STENCIL, + BUFFER_DEPTH); + } } /* Set the render-to-texture flag. We'll check this flag in @@ -2541,8 +2678,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, else { remove_attachment(ctx, att); if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { - assert(att == &fb->Attachment[BUFFER_DEPTH]); - remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]); + assert(att == &fb->Attachment[BUFFER_DEPTH]); + remove_attachment(ctx, &fb->Attachment[BUFFER_STENCIL]); } } @@ -2721,16 +2858,16 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment, if (renderbuffer) { rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); if (!rb) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glFramebufferRenderbuffer(non-existant" + _mesa_error(ctx, GL_INVALID_OPERATION, + "glFramebufferRenderbuffer(non-existant" " renderbuffer %u)", renderbuffer); - return; + return; } else if (rb == &DummyRenderbuffer) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glFramebufferRenderbuffer(renderbuffer %u)", + _mesa_error(ctx, GL_INVALID_OPERATION, + "glFramebufferRenderbuffer(renderbuffer %u)", renderbuffer); - return; + return; } } else { @@ -2795,9 +2932,9 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object) && !_mesa_is_gles3(ctx)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetFramebufferAttachmentParameteriv(bound FBO = 0)"); - return; + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetFramebufferAttachmentParameteriv(bound FBO = 0)"); + return; } if (_mesa_is_gles3(ctx) && attachment != GL_BACK && @@ -2855,10 +2992,10 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, return; case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT: if (att->Type == GL_RENDERBUFFER_EXT) { - *params = att->Renderbuffer->Name; + *params = att->Renderbuffer->Name; } else if (att->Type == GL_TEXTURE) { - *params = att->Texture->Name; + *params = att->Texture->Name; } else { assert(att->Type == GL_NONE); @@ -2871,7 +3008,7 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, return; case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT: if (att->Type == GL_TEXTURE) { - *params = att->TextureLevel; + *params = att->TextureLevel; } else if (att->Type == GL_NONE) { _mesa_error(ctx, err, diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h index 77fdef415..61aa1f503 100644 --- a/mesalib/src/mesa/main/fbobject.h +++ b/mesalib/src/mesa/main/fbobject.h @@ -114,6 +114,9 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers); extern void GLAPIENTRY _mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers); +extern void GLAPIENTRY +_mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers); + extern void GLAPIENTRY _mesa_RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); @@ -127,6 +130,15 @@ extern void GLAPIENTRY _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); +extern void GLAPIENTRY +_mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat, + GLsizei width, GLsizei height); + +extern void GLAPIENTRY +_mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples, + GLenum internalformat, + GLsizei width, GLsizei height); + extern void GLAPIENTRY _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image); @@ -134,6 +146,10 @@ extern void GLAPIENTRY _mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params); +void GLAPIENTRY +_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, + GLint *params); + extern GLboolean GLAPIENTRY _mesa_IsFramebuffer(GLuint framebuffer); diff --git a/mesalib/src/mesa/main/ffvertex_prog.c b/mesalib/src/mesa/main/ffvertex_prog.c index 395b00e15..edf7e3390 100644 --- a/mesalib/src/mesa/main/ffvertex_prog.c +++ b/mesalib/src/mesa/main/ffvertex_prog.c @@ -619,13 +619,13 @@ static void emit_op3fn(struct tnl_program *p, #define emit_op3(p, op, dst, mask, src0, src1, src2) \ - emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__) + emit_op3fn(p, op, dst, mask, src0, src1, src2, __func__, __LINE__) #define emit_op2(p, op, dst, mask, src0, src1) \ - emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__) + emit_op3fn(p, op, dst, mask, src0, src1, undef, __func__, __LINE__) #define emit_op1(p, op, dst, mask, src0) \ - emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__) + emit_op3fn(p, op, dst, mask, src0, undef, undef, __func__, __LINE__) static struct ureg make_temp( struct tnl_program *p, struct ureg reg ) diff --git a/mesalib/src/mesa/main/format_pack.py b/mesalib/src/mesa/main/format_pack.py index f141da83c..2f43a30dd 100644 --- a/mesalib/src/mesa/main/format_pack.py +++ b/mesalib/src/mesa/main/format_pack.py @@ -43,7 +43,6 @@ string = """/* #include -#include "colormac.h" #include "format_pack.h" #include "format_utils.h" #include "macros.h" diff --git a/mesalib/src/mesa/main/format_unpack.h b/mesalib/src/mesa/main/format_unpack.h index eba3c6650..964c6077a 100644 --- a/mesalib/src/mesa/main/format_unpack.h +++ b/mesalib/src/mesa/main/format_unpack.h @@ -25,6 +25,8 @@ #ifndef FORMAT_UNPACK_H #define FORMAT_UNPACK_H +#include "formats.h" + extern void _mesa_unpack_rgba_row(mesa_format format, GLuint n, const void *src, GLfloat dst[][4]); diff --git a/mesalib/src/mesa/main/format_unpack.py b/mesalib/src/mesa/main/format_unpack.py index 53bdf641d..0ae73b897 100644 --- a/mesalib/src/mesa/main/format_unpack.py +++ b/mesalib/src/mesa/main/format_unpack.py @@ -43,7 +43,6 @@ string = """/* #include -#include "colormac.h" #include "format_unpack.h" #include "format_utils.h" #include "macros.h" @@ -333,7 +332,7 @@ _mesa_unpack_rgba_row(mesa_format format, GLuint n, unpack_float_ycbcr_rev(src, dst, n); break; default: - _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, + _mesa_problem(NULL, "%s: bad format %s", __func__, _mesa_get_format_name(format)); return; } @@ -402,7 +401,7 @@ _mesa_unpack_uint_rgba_row(mesa_format format, GLuint n, break; %endfor default: - _mesa_problem(NULL, "%s: bad format %s", __FUNCTION__, + _mesa_problem(NULL, "%s: bad format %s", __func__, _mesa_get_format_name(format)); return; } diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 4e05229cf..8ced57949 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -1393,7 +1393,7 @@ _mesa_base_format_has_channel(GLenum base_format, GLenum pname) return GL_FALSE; default: _mesa_warning(NULL, "%s: Unexpected channel token 0x%x\n", - __FUNCTION__, pname); + __func__, pname); return GL_FALSE; } diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index 29f249980..c4d917ebb 100644 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -433,6 +433,30 @@ _mesa_fls(unsigned int n) #endif } +/** + * Find the last (most significant) bit set in a uint64_t value. + * + * Essentially ffsll() in the reverse direction. + */ +static inline unsigned int +_mesa_flsll(uint64_t n) +{ +#ifdef HAVE___BUILTIN_CLZLL + return n == 0 ? 0 : 64 - __builtin_clzll(n); +#else + unsigned int v = 1; + + if (n == 0) + return 0; + + while (n >>= 1) + v++; + + return v; +#endif +} + + extern GLhalfARB _mesa_float_to_half(float f); diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h index 2d7a6a107..3344ec841 100644 --- a/mesalib/src/mesa/main/macros.h +++ b/mesalib/src/mesa/main/macros.h @@ -789,7 +789,14 @@ NORMALIZE_3FV(GLfloat v[3]) static inline GLboolean DIFFERENT_SIGNS(GLfloat x, GLfloat y) { +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 6334 ) /* sizeof operator applied to an expression with an operator may yield unexpected results */ +#endif return signbit(x) != signbit(y); +#ifdef _MSC_VER +#pragma warning( pop ) +#endif } diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 8e1dba6f0..1c751cfff 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -42,6 +42,7 @@ #include "main/config.h" #include "glapi/glapi.h" #include "math/m_matrix.h" /* GLmatrix */ +#include "glsl/shader_enums.h" #include "util/simple_list.h" /* struct simple_node */ #include "main/formats.h" /* MESA_FORMAT_COUNT */ @@ -279,13 +280,6 @@ typedef enum #define VARYING_BIT_VAR(V) BITFIELD64_BIT(VARYING_SLOT_VAR0 + (V)) /*@}*/ -/** - * Bitflags for system values. - */ -#define SYSTEM_BIT_SAMPLE_ID BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_ID) -#define SYSTEM_BIT_SAMPLE_POS BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_POS) -#define SYSTEM_BIT_SAMPLE_MASK_IN BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_MASK_IN) - /** * Determine if the given gl_varying_slot appears in the fragment shader. */ @@ -395,25 +389,6 @@ typedef enum BUFFER_BIT_COLOR6 | \ BUFFER_BIT_COLOR7) - -/** - * Shader stages. Note that these will become 5 with tessellation. - * - * The order must match how shaders are ordered in the pipeline. - * The GLSL linker assumes that if iEverBound = GL_TRUE; + } + save_pipeline_object(ctx, obj); pipelines[i] = first + i; } } +void GLAPIENTRY +_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines) +{ + GET_CURRENT_CONTEXT(ctx); + + create_program_pipelines(ctx, n, pipelines, false); +} + +void GLAPIENTRY +_mesa_CreateProgramPipelines(GLsizei n, GLuint *pipelines) +{ + GET_CURRENT_CONTEXT(ctx); + + create_program_pipelines(ctx, n, pipelines, true); +} + /** * Determine if ID is the name of an pipeline object. * diff --git a/mesalib/src/mesa/main/pipelineobj.h b/mesalib/src/mesa/main/pipelineobj.h index 7285a78f1..b57bcb99e 100644 --- a/mesalib/src/mesa/main/pipelineobj.h +++ b/mesalib/src/mesa/main/pipelineobj.h @@ -82,6 +82,9 @@ _mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines); extern void GLAPIENTRY _mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines); +void GLAPIENTRY +_mesa_CreateProgramPipelines(GLsizei n, GLuint *pipelines); + extern GLboolean GLAPIENTRY _mesa_IsProgramPipeline(GLuint pipeline); diff --git a/mesalib/src/mesa/main/pixel.c b/mesalib/src/mesa/main/pixel.c index 7162c6fef..ecda2694f 100644 --- a/mesalib/src/mesa/main/pixel.c +++ b/mesalib/src/mesa/main/pixel.c @@ -30,7 +30,6 @@ #include "glheader.h" #include "bufferobj.h" -#include "colormac.h" #include "context.h" #include "macros.h" #include "pixel.h" diff --git a/mesalib/src/mesa/main/pixeltransfer.c b/mesalib/src/mesa/main/pixeltransfer.c index 8bbeeb853..94464ea67 100644 --- a/mesalib/src/mesa/main/pixeltransfer.c +++ b/mesalib/src/mesa/main/pixeltransfer.c @@ -31,7 +31,7 @@ #include "glheader.h" -#include "colormac.h" +#include "macros.h" #include "pixeltransfer.h" #include "imports.h" #include "mtypes.h" diff --git a/mesalib/src/mesa/main/program_resource.c b/mesalib/src/mesa/main/program_resource.c new file mode 100644 index 000000000..b15a13210 --- /dev/null +++ b/mesalib/src/mesa/main/program_resource.c @@ -0,0 +1,417 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2015 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 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. + * + */ + +#include "main/enums.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "main/shaderapi.h" +#include "main/shaderobj.h" +#include "program_resource.h" + +static bool +supported_interface_enum(GLenum iface) +{ + switch (iface) { + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_ATOMIC_COUNTER_BUFFER: + return true; + case GL_VERTEX_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_BUFFER_VARIABLE: + case GL_SHADER_STORAGE_BLOCK: + default: + return false; + } +} + +void GLAPIENTRY +_mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, + GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + unsigned i; + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glGetProgramInterfaceiv"); + if (!shProg) + return; + + if (!params) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(params NULL)"); + return; + } + + /* Validate interface. */ + if (!supported_interface_enum(programInterface)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)", + _mesa_lookup_enum_by_nr(programInterface)); + return; + } + + /* Validate pname against interface. */ + switch(pname) { + case GL_ACTIVE_RESOURCES: + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) + if (shProg->ProgramResourceList[i].Type == programInterface) + (*params)++; + break; + case GL_MAX_NAME_LENGTH: + if (programInterface == GL_ATOMIC_COUNTER_BUFFER) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_lookup_enum_by_nr(programInterface), + _mesa_lookup_enum_by_nr(pname)); + return; + } + /* Name length consists of base name, 3 additional chars '[0]' if + * resource is an array and finally 1 char for string terminator. + */ + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) { + if (shProg->ProgramResourceList[i].Type != programInterface) + continue; + const char *name = + _mesa_program_resource_name(&shProg->ProgramResourceList[i]); + unsigned array_size = + _mesa_program_resource_array_size(&shProg->ProgramResourceList[i]); + *params = MAX2(*params, strlen(name) + (array_size ? 3 : 0) + 1); + } + break; + case GL_MAX_NUM_ACTIVE_VARIABLES: + switch (programInterface) { + case GL_UNIFORM_BLOCK: + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) { + if (shProg->ProgramResourceList[i].Type == programInterface) { + struct gl_uniform_block *block = + (struct gl_uniform_block *) + shProg->ProgramResourceList[i].Data; + *params = MAX2(*params, block->NumUniforms); + } + } + break; + case GL_ATOMIC_COUNTER_BUFFER: + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) { + if (shProg->ProgramResourceList[i].Type == programInterface) { + struct gl_active_atomic_buffer *buffer = + (struct gl_active_atomic_buffer *) + shProg->ProgramResourceList[i].Data; + *params = MAX2(*params, buffer->NumUniforms); + } + } + break; + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_lookup_enum_by_nr(programInterface), + _mesa_lookup_enum_by_nr(pname)); + }; + break; + case GL_MAX_NUM_COMPATIBLE_SUBROUTINES: + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(pname %s)", + _mesa_lookup_enum_by_nr(pname)); + } +} + +static bool +is_xfb_marker(const char *str) +{ + static const char *markers[] = { + "gl_NextBuffer", + "gl_SkipComponents1", + "gl_SkipComponents2", + "gl_SkipComponents3", + "gl_SkipComponents4", + NULL + }; + const char **m = markers; + + if (strncmp(str, "gl_", 3) != 0) + return false; + + for (; *m; m++) + if (strcmp(*m, str) == 0) + return true; + + return false; +} + +/** + * Checks if given name index is legal for GetProgramResourceIndex, + * check is written to be compatible with GL_ARB_array_of_arrays. + */ +static bool +valid_program_resource_index_name(const GLchar *name) +{ + const char *array = strstr(name, "["); + const char *close = strrchr(name, ']'); + + /* Not array, no need for the check. */ + if (!array) + return true; + + /* Last array index has to be zero. */ + if (!close || *--close != '0') + return false; + + return true; +} + +GLuint GLAPIENTRY +_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, + const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_program_resource *res; + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glGetProgramResourceIndex"); + if (!shProg || !name) + return GL_INVALID_INDEX; + + /* + * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX + * should be returned when querying the index assigned to the special names + * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2", + * "gl_SkipComponents3", and "gl_SkipComponents4". + */ + if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING && + is_xfb_marker(name)) + return GL_INVALID_INDEX; + + switch (programInterface) { + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + case GL_TRANSFORM_FEEDBACK_VARYING: + /* Validate name syntax for arrays. */ + if (!valid_program_resource_index_name(name)) + return GL_INVALID_INDEX; + + res = _mesa_program_resource_find_name(shProg, programInterface, name); + if (!res) + return GL_INVALID_INDEX; + + return _mesa_program_resource_index(shProg, res); + case GL_ATOMIC_COUNTER_BUFFER: + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)", + _mesa_lookup_enum_by_nr(programInterface)); + } + + return GL_INVALID_INDEX; +} + +void GLAPIENTRY +_mesa_GetProgramResourceName(GLuint program, GLenum programInterface, + GLuint index, GLsizei bufSize, GLsizei *length, + GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glGetProgramResourceName"); + + /* Set user friendly return values in case of errors. */ + if (name) + *name = '\0'; + if (length) + *length = 0; + + if (!shProg || !name) + return; + + if (programInterface == GL_ATOMIC_COUNTER_BUFFER || + !supported_interface_enum(programInterface)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)", + _mesa_lookup_enum_by_nr(programInterface)); + return; + } + + _mesa_get_program_resource_name(shProg, programInterface, index, bufSize, + length, name, "glGetProgramResourceName"); +} + +void GLAPIENTRY +_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface, + GLuint index, GLsizei propCount, + const GLenum *props, GLsizei bufSize, + GLsizei *length, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceiv"); + + if (!shProg || !params) + return; + + /* The error INVALID_VALUE is generated if is zero. + * Note that we check < 0 here because it makes sense to bail early. + */ + if (propCount <= 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramResourceiv(propCount <= 0)"); + return; + } + + /* No need to write any properties, user requested none. */ + if (bufSize == 0) + return; + + _mesa_get_program_resourceiv(shProg, programInterface, index, + propCount, props, bufSize, length, params); +} + +/** + * Function verifies syntax of given name for GetProgramResourceLocation + * and GetProgramResourceLocationIndex for the following cases: + * + * "array element portion of a string passed to GetProgramResourceLocation + * or GetProgramResourceLocationIndex must not have, a "+" sign, extra + * leading zeroes, or whitespace". + * + * Check is written to be compatible with GL_ARB_array_of_arrays. + */ +static bool +invalid_array_element_syntax(const GLchar *name) +{ + char *first = strchr(name, '['); + char *last = strrchr(name, '['); + + if (!first) + return false; + + /* No '+' or ' ' allowed anywhere. */ + if (strchr(first, '+') || strchr(first, ' ')) + return true; + + /* Check that last array index is 0. */ + if (last[1] == '0' && last[2] != ']') + return true; + + return false; +} + +static struct gl_shader_program * +lookup_linked_program(GLuint program, const char *caller) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *prog = + _mesa_lookup_shader_program_err(ctx, program, caller); + + if (!prog) + return NULL; + + if (prog->LinkStatus == GL_FALSE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", + caller); + return NULL; + } + return prog; +} + +GLint GLAPIENTRY +_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface, + const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + lookup_linked_program(program, "glGetProgramResourceLocation"); + + if (!shProg || !name || invalid_array_element_syntax(name)) + return -1; + + /* Validate programInterface. */ + switch (programInterface) { + case GL_UNIFORM: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + break; + + /* For reference valid cases requiring additional extension support: + * GL_ARB_shader_subroutine + * GL_ARB_tessellation_shader + * GL_ARB_compute_shader + */ + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)", + _mesa_lookup_enum_by_nr(programInterface), name); + } + + return _mesa_program_resource_location(shProg, programInterface, name); +} + +/** + * Returns output index for dual source blending. + */ +GLint GLAPIENTRY +_mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, + const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg = + lookup_linked_program(program, "glGetProgramResourceLocationIndex"); + + if (!shProg || !name || invalid_array_element_syntax(name)) + return -1; + + /* From the GL_ARB_program_interface_query spec: + * + * "For GetProgramResourceLocationIndex, must be + * PROGRAM_OUTPUT." + */ + if (programInterface != GL_PROGRAM_OUTPUT) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramResourceLocationIndex(%s)", + _mesa_lookup_enum_by_nr(programInterface)); + return -1; + } + + return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT, + name); +} diff --git a/mesalib/src/mesa/main/program_resource.h b/mesalib/src/mesa/main/program_resource.h new file mode 100644 index 000000000..326ae1f93 --- /dev/null +++ b/mesalib/src/mesa/main/program_resource.h @@ -0,0 +1,58 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 2015 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, 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 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 PROGRAM_RESOURCE_H +#define PROGRAM_RESOURCE_H + +#include "glheader.h" + +extern void GLAPIENTRY +_mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, + GLenum pname, GLint *params); + +extern GLuint GLAPIENTRY +_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, + const GLchar *name); + +extern void GLAPIENTRY +_mesa_GetProgramResourceName(GLuint program, GLenum programInterface, + GLuint index, GLsizei bufSize, GLsizei *length, + GLchar *name); + +extern void GLAPIENTRY +_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface, + GLuint index, GLsizei propCount, + const GLenum *props, GLsizei bufSize, + GLsizei *length, GLint *params); + +extern GLint GLAPIENTRY +_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface, + const GLchar *name); + +extern GLint GLAPIENTRY +_mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, + const GLchar *name); + +#endif diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c index 0842b540d..fbccf3fe6 100644 --- a/mesalib/src/mesa/main/queryobj.c +++ b/mesalib/src/mesa/main/queryobj.c @@ -233,18 +233,22 @@ get_query_binding_point(struct gl_context *ctx, GLenum target, GLuint index) } } - -void GLAPIENTRY -_mesa_GenQueries(GLsizei n, GLuint *ids) +/** + * Create $n query objects and store them in *ids. Make them of type $target + * if dsa is set. Called from _mesa_GenQueries() and _mesa_CreateQueries(). + */ +static void +create_queries(struct gl_context *ctx, GLenum target, GLsizei n, GLuint *ids, + bool dsa) { + const char *func = dsa ? "glGenQueries" : "glCreateQueries"; GLuint first; - GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glGenQueries(%d)\n", n); + _mesa_debug(ctx, "%s(%d)\n", func, n); if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)"); + _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func); return; } @@ -255,8 +259,12 @@ _mesa_GenQueries(GLsizei n, GLuint *ids) struct gl_query_object *q = ctx->Driver.NewQueryObject(ctx, first + i); if (!q) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; + } else if (dsa) { + /* Do the equivalent of binding the buffer with a target */ + q->Target = target; + q->EverBound = GL_TRUE; } ids[i] = first + i; _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q); @@ -264,6 +272,36 @@ _mesa_GenQueries(GLsizei n, GLuint *ids) } } +void GLAPIENTRY +_mesa_GenQueries(GLsizei n, GLuint *ids) +{ + GET_CURRENT_CONTEXT(ctx); + create_queries(ctx, 0, n, ids, false); +} + +void GLAPIENTRY +_mesa_CreateQueries(GLenum target, GLsizei n, GLuint *ids) +{ + GET_CURRENT_CONTEXT(ctx); + + switch (target) { + case GL_SAMPLES_PASSED: + case GL_ANY_SAMPLES_PASSED: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + case GL_TIME_ELAPSED: + case GL_TIMESTAMP: + case GL_PRIMITIVES_GENERATED: + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glCreateQueries(invalid target = %s)", + _mesa_lookup_enum_by_nr(target)); + return; + } + + create_queries(ctx, target, n, ids, true); +} + void GLAPIENTRY _mesa_DeleteQueries(GLsizei n, const GLuint *ids) @@ -424,6 +462,18 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) } } + /* This possibly changes the target of a buffer allocated by + * CreateQueries. Issue 39) in the ARB_direct_state_access extension states + * the following: + * + * "CreateQueries adds a , so strictly speaking the + * command isn't needed for BeginQuery/EndQuery, but in the end, this also + * isn't a selector, so we decided not to change it." + * + * Updating the target of the query object should be acceptable, so let's + * do that. + */ + q->Target = target; q->Active = GL_TRUE; q->Result = 0; @@ -541,6 +591,18 @@ _mesa_QueryCounter(GLuint id, GLenum target) return; } + /* This possibly changes the target of a buffer allocated by + * CreateQueries. Issue 39) in the ARB_direct_state_access extension states + * the following: + * + * "CreateQueries adds a , so strictly speaking the + * command isn't needed for BeginQuery/EndQuery, but in the end, this also + * isn't a selector, so we decided not to change it." + * + * Updating the target of the query object should be acceptable, so let's + * do that. + */ + q->Target = target; q->Result = 0; q->Ready = GL_FALSE; @@ -710,8 +772,8 @@ _mesa_GetQueryObjectiv(GLuint id, GLenum pname, GLint *params) } break; case GL_QUERY_RESULT_AVAILABLE_ARB: - if (!q->Ready) - ctx->Driver.CheckQuery( ctx, q ); + if (!q->Ready) + ctx->Driver.CheckQuery( ctx, q ); *params = q->Ready; break; default: @@ -761,8 +823,8 @@ _mesa_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) } break; case GL_QUERY_RESULT_AVAILABLE_ARB: - if (!q->Ready) - ctx->Driver.CheckQuery( ctx, q ); + if (!q->Ready) + ctx->Driver.CheckQuery( ctx, q ); *params = q->Ready; break; default: @@ -801,8 +863,8 @@ _mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params) *params = q->Result; break; case GL_QUERY_RESULT_AVAILABLE_ARB: - if (!q->Ready) - ctx->Driver.CheckQuery( ctx, q ); + if (!q->Ready) + ctx->Driver.CheckQuery( ctx, q ); *params = q->Ready; break; default: @@ -841,8 +903,8 @@ _mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) *params = q->Result; break; case GL_QUERY_RESULT_AVAILABLE_ARB: - if (!q->Ready) - ctx->Driver.CheckQuery( ctx, q ); + if (!q->Ready) + ctx->Driver.CheckQuery( ctx, q ); *params = q->Ready; break; default: @@ -851,6 +913,45 @@ _mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) } } +/** + * New with GL_ARB_query_buffer_object + */ +void GLAPIENTRY +_mesa_GetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjectiv"); +} + + +void GLAPIENTRY +_mesa_GetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjectuiv"); +} + + +void GLAPIENTRY +_mesa_GetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjecti64v"); +} + + +void GLAPIENTRY +_mesa_GetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryBufferObjectui64v"); +} + + /** * Allocate/init the context state related to query objects. */ diff --git a/mesalib/src/mesa/main/queryobj.h b/mesalib/src/mesa/main/queryobj.h index 6cbcabd46..d1036fcce 100644 --- a/mesalib/src/mesa/main/queryobj.h +++ b/mesalib/src/mesa/main/queryobj.h @@ -51,6 +51,8 @@ _mesa_free_queryobj_data(struct gl_context *ctx); void GLAPIENTRY _mesa_GenQueries(GLsizei n, GLuint *ids); void GLAPIENTRY +_mesa_CreateQueries(GLenum target, GLsizei n, GLuint *ids); +void GLAPIENTRY _mesa_DeleteQueries(GLsizei n, const GLuint *ids); GLboolean GLAPIENTRY _mesa_IsQuery(GLuint id); @@ -77,5 +79,17 @@ void GLAPIENTRY _mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params); void GLAPIENTRY _mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params); +void GLAPIENTRY +_mesa_GetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset); +void GLAPIENTRY +_mesa_GetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset); +void GLAPIENTRY +_mesa_GetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset); +void GLAPIENTRY +_mesa_GetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset); #endif /* QUERYOBJ_H */ diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c index d66b0b5e8..a3aacc66a 100644 --- a/mesalib/src/mesa/main/samplerobj.c +++ b/mesalib/src/mesa/main/samplerobj.c @@ -181,19 +181,18 @@ _mesa_delete_sampler_object(struct gl_context *ctx, free(sampObj); } - -void GLAPIENTRY -_mesa_GenSamplers(GLsizei count, GLuint *samplers) +static void +create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers, + const char *caller) { - GET_CURRENT_CONTEXT(ctx); GLuint first; GLint i; if (MESA_VERBOSE & VERBOSE_API) - _mesa_debug(ctx, "glGenSamplers(%d)\n", count); + _mesa_debug(ctx, "%s(%d)\n", caller, count); if (count < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGenSamplers"); + _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", caller); return; } @@ -211,6 +210,20 @@ _mesa_GenSamplers(GLsizei count, GLuint *samplers) } } +void GLAPIENTRY +_mesa_GenSamplers(GLsizei count, GLuint *samplers) +{ + GET_CURRENT_CONTEXT(ctx); + create_samplers(ctx, count, samplers, "glGenSamplers"); +} + +void GLAPIENTRY +_mesa_CreateSamplers(GLsizei count, GLuint *samplers) +{ + GET_CURRENT_CONTEXT(ctx); + create_samplers(ctx, count, samplers, "glCreateSamplers"); +} + void GLAPIENTRY _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers) diff --git a/mesalib/src/mesa/main/samplerobj.h b/mesalib/src/mesa/main/samplerobj.h index 1bb3193e4..7bea91114 100644 --- a/mesalib/src/mesa/main/samplerobj.h +++ b/mesalib/src/mesa/main/samplerobj.h @@ -32,6 +32,9 @@ extern "C" { #endif +#include "mtypes.h" + + struct dd_function_table; static inline struct gl_sampler_object * @@ -80,6 +83,8 @@ _mesa_init_sampler_object_functions(struct dd_function_table *driver); void GLAPIENTRY _mesa_GenSamplers(GLsizei count, GLuint *samplers); void GLAPIENTRY +_mesa_CreateSamplers(GLsizei count, GLuint *samplers); +void GLAPIENTRY _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers); GLboolean GLAPIENTRY _mesa_IsSampler(GLuint sampler); diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp index df9081b73..b5f1d082c 100644 --- a/mesalib/src/mesa/main/shader_query.cpp +++ b/mesalib/src/mesa/main/shader_query.cpp @@ -34,11 +34,33 @@ #include "shaderobj.h" #include "program/hash_table.h" #include "../glsl/program.h" +#include "uniforms.h" +#include "main/enums.h" extern "C" { #include "shaderapi.h" } +static GLint +program_resource_location(struct gl_shader_program *shProg, + struct gl_program_resource *res, const char *name); + +/** + * Declare convenience functions to return resource data in a given type. + * Warning! this is not type safe so be *very* careful when using these. + */ +#define DECL_RESOURCE_FUNC(name, type) \ +const type * RESOURCE_ ## name (gl_program_resource *res) { \ + assert(res->Data); \ + return (type *) res->Data; \ +} + +DECL_RESOURCE_FUNC(VAR, ir_variable); +DECL_RESOURCE_FUNC(UBO, gl_uniform_block); +DECL_RESOURCE_FUNC(UNI, gl_uniform_storage); +DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer); +DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_varying_info); + void GLAPIENTRY _mesa_BindAttribLocation(GLhandleARB program, GLuint index, const GLcharARB *name) @@ -129,45 +151,41 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index, return; } - exec_list *const ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; - unsigned current_index = 0; - - foreach_in_list(ir_instruction, node, ir) { - const ir_variable *const var = node->as_variable(); - - if (!is_active_attrib(var)) - continue; + struct gl_program_resource *res = + _mesa_program_resource_find_index(shProg, GL_PROGRAM_INPUT, + desired_index); - if (current_index == desired_index) { - const char *var_name = var->name; + /* User asked for index that does not exist. */ + if (!res) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); + return; + } - /* Since gl_VertexID may be lowered to gl_VertexIDMESA, we need to - * consider gl_VertexIDMESA as gl_VertexID for purposes of checking - * active attributes. - */ - if (var->data.mode == ir_var_system_value && - var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { - var_name = "gl_VertexID"; - } + const ir_variable *const var = RESOURCE_VAR(res); - _mesa_copy_string(name, maxLength, length, var_name); + if (!is_active_attrib(var)) + return; - if (size) - *size = (var->type->is_array()) ? var->type->length : 1; + const char *var_name = var->name; - if (type) - *type = var->type->gl_type; + /* Since gl_VertexID may be lowered to gl_VertexIDMESA, we need to + * consider gl_VertexIDMESA as gl_VertexID for purposes of checking + * active attributes. + */ + if (var->data.mode == ir_var_system_value && + var->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) { + var_name = "gl_VertexID"; + } - return; - } + _mesa_copy_string(name, maxLength, length, var_name); - current_index++; - } + if (size) + _mesa_program_resource_prop(shProg, res, desired_index, GL_ARRAY_SIZE, + size, "glGetActiveAttrib"); - /* If the loop did not return early, the caller must have asked for - * an index that did not exit. Set an error. - */ - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); + if (type) + _mesa_program_resource_prop(shProg, res, desired_index, GL_TYPE, + (GLint *) type, "glGetActiveAttrib"); } /* Locations associated with shader variables (array or non-array) can be @@ -252,31 +270,25 @@ _mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name) if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) return -1; - exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->ir; - foreach_in_list(ir_instruction, node, ir) { - const ir_variable *const var = node->as_variable(); - - /* The extra check against VERT_ATTRIB_GENERIC0 is because - * glGetAttribLocation cannot be used on "conventional" attributes. - * - * From page 95 of the OpenGL 3.0 spec: - * - * "If name is not an active attribute, if name is a conventional - * attribute, or if an error occurs, -1 will be returned." - */ - if (var == NULL - || var->data.mode != ir_var_shader_in - || var->data.location == -1 - || var->data.location < VERT_ATTRIB_GENERIC0) - continue; - - int index = get_matching_index(var, (const char *) name); + struct gl_program_resource *res = + _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT, name); - if (index >= 0) - return var->data.location + index - VERT_ATTRIB_GENERIC0; - } + if (!res) + return -1; - return -1; + GLint loc = program_resource_location(shProg, res, name); + + /* The extra check against against 0 is made because of builtin-attribute + * locations that have offset applied. Function program_resource_location + * can return built-in attribute locations < 0 and glGetAttribLocation + * cannot be used on "conventional" attributes. + * + * From page 95 of the OpenGL 3.0 spec: + * + * "If name is not an active attribute, if name is a conventional + * attribute, or if an error occurs, -1 will be returned." + */ + return (loc >= 0) ? loc : -1; } @@ -416,29 +428,8 @@ _mesa_GetFragDataIndex(GLuint program, const GLchar *name) if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) return -1; - exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir; - foreach_in_list(ir_instruction, node, ir) { - const ir_variable *const var = node->as_variable(); - - /* The extra check against FRAG_RESULT_DATA0 is because - * glGetFragDataLocation cannot be used on "conventional" attributes. - * - * From page 95 of the OpenGL 3.0 spec: - * - * "If name is not an active attribute, if name is a conventional - * attribute, or if an error occurs, -1 will be returned." - */ - if (var == NULL - || var->data.mode != ir_var_shader_out - || var->data.location == -1 - || var->data.location < FRAG_RESULT_DATA0) - continue; - - if (get_matching_index(var, (const char *) name) >= 0) - return var->data.index; - } - - return -1; + return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT, + name); } GLint GLAPIENTRY @@ -472,29 +463,612 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name) if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) return -1; - exec_list *ir = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir; - foreach_in_list(ir_instruction, node, ir) { - const ir_variable *const var = node->as_variable(); + struct gl_program_resource *res = + _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name); - /* The extra check against FRAG_RESULT_DATA0 is because - * glGetFragDataLocation cannot be used on "conventional" attributes. - * - * From page 95 of the OpenGL 3.0 spec: + if (!res) + return -1; + + GLint loc = program_resource_location(shProg, res, name); + + /* The extra check against against 0 is made because of builtin-attribute + * locations that have offset applied. Function program_resource_location + * can return built-in attribute locations < 0 and glGetFragDataLocation + * cannot be used on "conventional" attributes. + * + * From page 95 of the OpenGL 3.0 spec: + * + * "If name is not an active attribute, if name is a conventional + * attribute, or if an error occurs, -1 will be returned." + */ + return (loc >= 0) ? loc : -1; +} + +const char* +_mesa_program_resource_name(struct gl_program_resource *res) +{ + switch (res->Type) { + case GL_UNIFORM_BLOCK: + return RESOURCE_UBO(res)->Name; + case GL_TRANSFORM_FEEDBACK_VARYING: + return RESOURCE_XFB(res)->Name; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return RESOURCE_VAR(res)->name; + case GL_UNIFORM: + return RESOURCE_UNI(res)->name; + default: + assert(!"support for resource type not implemented"); + } + return NULL; +} + + +unsigned +_mesa_program_resource_array_size(struct gl_program_resource *res) +{ + switch (res->Type) { + case GL_TRANSFORM_FEEDBACK_VARYING: + return RESOURCE_XFB(res)->Size > 1 ? + RESOURCE_XFB(res)->Size : 0; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return RESOURCE_VAR(res)->data.max_array_access; + case GL_UNIFORM: + return RESOURCE_UNI(res)->array_elements; + case GL_ATOMIC_COUNTER_BUFFER: + case GL_UNIFORM_BLOCK: + return 0; + default: + assert(!"support for resource type not implemented"); + } + return 0; +} + +static int +array_index_of_resource(struct gl_program_resource *res, + const char *name) +{ + assert(res->Data); + + switch (res->Type) { + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return get_matching_index(RESOURCE_VAR(res), name); + default: + assert(!"support for resource type not implemented"); + } +} + +/* Find a program resource with specific name in given interface. + */ +struct gl_program_resource * +_mesa_program_resource_find_name(struct gl_shader_program *shProg, + GLenum programInterface, const char *name) +{ + struct gl_program_resource *res = shProg->ProgramResourceList; + for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) { + if (res->Type != programInterface) + continue; + + /* Resource basename. */ + const char *rname = _mesa_program_resource_name(res); + unsigned baselen = strlen(rname); + + switch (programInterface) { + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_UNIFORM_BLOCK: + case GL_UNIFORM: + if (strncmp(rname, name, baselen) == 0) { + /* Basename match, check if array or struct. */ + if (name[baselen] == '\0' || + name[baselen] == '[' || + name[baselen] == '.') { + return res; + } + } + break; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + if (array_index_of_resource(res, name) >= 0) + return res; + break; + default: + assert(!"not implemented for given interface"); + } + } + return NULL; +} + +static GLuint +calc_resource_index(struct gl_shader_program *shProg, + struct gl_program_resource *res) +{ + unsigned i; + GLuint index = 0; + for (i = 0; i < shProg->NumProgramResourceList; i++) { + if (&shProg->ProgramResourceList[i] == res) + return index; + if (shProg->ProgramResourceList[i].Type == res->Type) + index++; + } + return GL_INVALID_INDEX; +} + +/** + * Calculate index for the given resource. + */ +GLuint +_mesa_program_resource_index(struct gl_shader_program *shProg, + struct gl_program_resource *res) +{ + if (!res) + return GL_INVALID_INDEX; + + switch (res->Type) { + case GL_UNIFORM_BLOCK: + return RESOURCE_UBO(res)- shProg->UniformBlocks; + case GL_ATOMIC_COUNTER_BUFFER: + return RESOURCE_ATC(res) - shProg->AtomicBuffers; + case GL_TRANSFORM_FEEDBACK_VARYING: + default: + return calc_resource_index(shProg, res); + } +} + +/* Find a program resource with specific index in given interface. + */ +struct gl_program_resource * +_mesa_program_resource_find_index(struct gl_shader_program *shProg, + GLenum programInterface, GLuint index) +{ + struct gl_program_resource *res = shProg->ProgramResourceList; + int idx = -1; + + for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) { + if (res->Type != programInterface) + continue; + + switch (res->Type) { + case GL_UNIFORM_BLOCK: + case GL_ATOMIC_COUNTER_BUFFER: + if (_mesa_program_resource_index(shProg, res) == index) + return res; + + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_UNIFORM: + if (++idx == (int) index) + return res; + break; + default: + assert(!"not implemented for given interface"); + } + } + return NULL; +} + +/* Get full name of a program resource. + */ +bool +_mesa_get_program_resource_name(struct gl_shader_program *shProg, + GLenum programInterface, GLuint index, + GLsizei bufSize, GLsizei *length, + GLchar *name, const char *caller) +{ + GET_CURRENT_CONTEXT(ctx); + + /* Find resource with given interface and index. */ + struct gl_program_resource *res = + _mesa_program_resource_find_index(shProg, programInterface, index); + + /* The error INVALID_VALUE is generated if is greater than + * or equal to the number of entries in the active resource list for + * . + */ + if (!res) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(index %u)", caller, index); + return false; + } + + if (bufSize < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize %d)", caller, bufSize); + return false; + } + + GLsizei localLength; + + if (length == NULL) + length = &localLength; + + _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res)); + + /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 + * spec says: + * + * "If the active uniform is an array, the uniform name returned in + * name will always be the name of the uniform array appended with + * "[0]"." + * + * The same text also appears in the OpenGL 4.2 spec. It does not, + * however, appear in any previous spec. Previous specifications are + * ambiguous in this regard. However, either name can later be passed + * to glGetUniformLocation (and related APIs), so there shouldn't be any + * harm in always appending "[0]" to uniform array names. + * + * Geometry shader stage has different naming convention where the 'normal' + * condition is an array, therefore for variables referenced in geometry + * stage we do not add '[0]'. + * + * Note, that TCS outputs and TES inputs should not have index appended + * either. + */ + bool add_index = !(((programInterface == GL_PROGRAM_INPUT) && + res->StageReferences & (1 << MESA_SHADER_GEOMETRY))); + + if (add_index && _mesa_program_resource_array_size(res)) { + int i; + + /* The comparison is strange because *length does *NOT* include the + * terminating NUL, but maxLength does. + */ + for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++) + name[*length + i] = "[0]"[i]; + + name[*length + i] = '\0'; + *length += i; + } + return true; +} + +static GLint +program_resource_location(struct gl_shader_program *shProg, + struct gl_program_resource *res, const char *name) +{ + unsigned index, offset; + int array_index = -1; + + if (res->Type == GL_PROGRAM_INPUT || res->Type == GL_PROGRAM_OUTPUT) { + array_index = array_index_of_resource(res, name); + if (array_index < 0) + return -1; + } + + /* VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 are decremented as these + * offsets are used internally to differentiate between built-in attributes + * and user-defined attributes. + */ + switch (res->Type) { + case GL_PROGRAM_INPUT: + return RESOURCE_VAR(res)->data.location + array_index - VERT_ATTRIB_GENERIC0; + case GL_PROGRAM_OUTPUT: + return RESOURCE_VAR(res)->data.location + array_index - FRAG_RESULT_DATA0; + case GL_UNIFORM: + index = _mesa_get_uniform_location(shProg, name, &offset); + + if (index == GL_INVALID_INDEX) + return -1; + + /* From the GL_ARB_uniform_buffer_object spec: * - * "If name is not an active attribute, if name is a conventional - * attribute, or if an error occurs, -1 will be returned." + * "The value -1 will be returned if does not correspond to an + * active uniform variable name in , if is associated + * with a named uniform block, or if starts with the reserved + * prefix "gl_"." */ - if (var == NULL - || var->data.mode != ir_var_shader_out - || var->data.location == -1 - || var->data.location < FRAG_RESULT_DATA0) - continue; + if (RESOURCE_UNI(res)->block_index != -1 || + RESOURCE_UNI(res)->atomic_buffer_index != -1) + return -1; - int index = get_matching_index(var, (const char *) name); + /* location in remap table + array element offset */ + return RESOURCE_UNI(res)->remap_location + offset; - if (index >= 0) - return var->data.location + index - FRAG_RESULT_DATA0; + default: + return -1; } +} - return -1; +/** + * Function implements following location queries: + * glGetAttribLocation + * glGetFragDataLocation + * glGetUniformLocation + */ +GLint +_mesa_program_resource_location(struct gl_shader_program *shProg, + GLenum programInterface, const char *name) +{ + struct gl_program_resource *res = + _mesa_program_resource_find_name(shProg, programInterface, name); + + /* Resource not found. */ + if (!res) + return -1; + + return program_resource_location(shProg, res, name); +} + +/** + * Function implements following index queries: + * glGetFragDataIndex + */ +GLint +_mesa_program_resource_location_index(struct gl_shader_program *shProg, + GLenum programInterface, const char *name) +{ + struct gl_program_resource *res = + _mesa_program_resource_find_name(shProg, programInterface, name); + + /* Non-existent variable or resource is not referenced by fragment stage. */ + if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT))) + return -1; + + return RESOURCE_VAR(res)->data.index; +} + +static uint8_t +stage_from_enum(GLenum ref) +{ + switch (ref) { + case GL_REFERENCED_BY_VERTEX_SHADER: + return MESA_SHADER_VERTEX; + case GL_REFERENCED_BY_GEOMETRY_SHADER: + return MESA_SHADER_GEOMETRY; + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return MESA_SHADER_FRAGMENT; + default: + assert(!"shader stage not supported"); + return MESA_SHADER_STAGES; + } +} + +/** + * Check if resource is referenced by given 'referenced by' stage enum. + * ATC and UBO resources hold stage references of their own. + */ +static bool +is_resource_referenced(struct gl_shader_program *shProg, + struct gl_program_resource *res, + GLuint index, uint8_t stage) +{ + if (res->Type == GL_ATOMIC_COUNTER_BUFFER) + return RESOURCE_ATC(res)->StageReferences[stage]; + + if (res->Type == GL_UNIFORM_BLOCK) + return shProg->UniformBlockStageIndex[stage][index] != -1; + + return res->StageReferences & (1 << stage); +} + +static unsigned +get_buffer_property(struct gl_shader_program *shProg, + struct gl_program_resource *res, const GLenum prop, + GLint *val, const char *caller) +{ + GET_CURRENT_CONTEXT(ctx); + if (res->Type != GL_UNIFORM_BLOCK && + res->Type != GL_ATOMIC_COUNTER_BUFFER) + goto invalid_operation; + + if (res->Type == GL_UNIFORM_BLOCK) { + switch (prop) { + case GL_BUFFER_BINDING: + *val = RESOURCE_UBO(res)->Binding; + return 1; + case GL_BUFFER_DATA_SIZE: + *val = RESOURCE_UBO(res)->UniformBufferSize; + return 1; + case GL_NUM_ACTIVE_VARIABLES: + *val = RESOURCE_UBO(res)->NumUniforms; + return 1; + case GL_ACTIVE_VARIABLES: + for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) { + const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName; + struct gl_program_resource *uni = + _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname); + *val++ = + _mesa_program_resource_index(shProg, uni); + } + return RESOURCE_UBO(res)->NumUniforms; + } + } else if (res->Type == GL_ATOMIC_COUNTER_BUFFER) { + switch (prop) { + case GL_BUFFER_BINDING: + *val = RESOURCE_ATC(res)->Binding; + return 1; + case GL_BUFFER_DATA_SIZE: + *val = RESOURCE_ATC(res)->MinimumSize; + return 1; + case GL_NUM_ACTIVE_VARIABLES: + *val = RESOURCE_ATC(res)->NumUniforms; + return 1; + case GL_ACTIVE_VARIABLES: + for (unsigned i = 0; i < RESOURCE_ATC(res)->NumUniforms; i++) + *val++ = RESOURCE_ATC(res)->Uniforms[i]; + return RESOURCE_ATC(res)->NumUniforms; + } + } + assert(!"support for property type not implemented"); + +invalid_operation: + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller, + _mesa_lookup_enum_by_nr(res->Type), + _mesa_lookup_enum_by_nr(prop)); + + return 0; +} + +unsigned +_mesa_program_resource_prop(struct gl_shader_program *shProg, + struct gl_program_resource *res, GLuint index, + const GLenum prop, GLint *val, const char *caller) +{ + GET_CURRENT_CONTEXT(ctx); + +#define VALIDATE_TYPE(type)\ + if (res->Type != type)\ + goto invalid_operation; + + switch(prop) { + case GL_NAME_LENGTH: + if (res->Type == GL_ATOMIC_COUNTER_BUFFER) + goto invalid_operation; + /* Base name +3 if array '[0]' + terminator. */ + *val = strlen(_mesa_program_resource_name(res)) + + (_mesa_program_resource_array_size(res) > 0 ? 3 : 0) + 1; + return 1; + case GL_TYPE: + switch (res->Type) { + case GL_UNIFORM: + *val = RESOURCE_UNI(res)->type->gl_type; + return 1; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + *val = RESOURCE_VAR(res)->type->gl_type; + return 1; + case GL_TRANSFORM_FEEDBACK_VARYING: + *val = RESOURCE_XFB(res)->Type; + return 1; + default: + goto invalid_operation; + } + case GL_ARRAY_SIZE: + switch (res->Type) { + case GL_UNIFORM: + *val = MAX2(RESOURCE_UNI(res)->array_elements, 1); + return 1; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + *val = MAX2(RESOURCE_VAR(res)->type->length, 1); + return 1; + case GL_TRANSFORM_FEEDBACK_VARYING: + *val = MAX2(RESOURCE_XFB(res)->Size, 1); + return 1; + default: + goto invalid_operation; + } + case GL_OFFSET: + VALIDATE_TYPE(GL_UNIFORM); + *val = RESOURCE_UNI(res)->offset; + return 1; + case GL_BLOCK_INDEX: + VALIDATE_TYPE(GL_UNIFORM); + *val = RESOURCE_UNI(res)->block_index; + return 1; + case GL_ARRAY_STRIDE: + VALIDATE_TYPE(GL_UNIFORM); + *val = RESOURCE_UNI(res)->array_stride; + return 1; + case GL_MATRIX_STRIDE: + VALIDATE_TYPE(GL_UNIFORM); + *val = RESOURCE_UNI(res)->matrix_stride; + return 1; + case GL_IS_ROW_MAJOR: + VALIDATE_TYPE(GL_UNIFORM); + *val = RESOURCE_UNI(res)->row_major; + return 1; + case GL_ATOMIC_COUNTER_BUFFER_INDEX: + VALIDATE_TYPE(GL_UNIFORM); + *val = RESOURCE_UNI(res)->atomic_buffer_index; + return 1; + case GL_BUFFER_BINDING: + case GL_BUFFER_DATA_SIZE: + case GL_NUM_ACTIVE_VARIABLES: + case GL_ACTIVE_VARIABLES: + return get_buffer_property(shProg, res, prop, val, caller); + case GL_REFERENCED_BY_VERTEX_SHADER: + case GL_REFERENCED_BY_GEOMETRY_SHADER: + case GL_REFERENCED_BY_FRAGMENT_SHADER: + switch (res->Type) { + case GL_UNIFORM: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_UNIFORM_BLOCK: + case GL_ATOMIC_COUNTER_BUFFER: + *val = is_resource_referenced(shProg, res, index, + stage_from_enum(prop)); + return 1; + default: + goto invalid_operation; + } + case GL_LOCATION: + switch (res->Type) { + case GL_UNIFORM: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + *val = program_resource_location(shProg, res, + _mesa_program_resource_name(res)); + return 1; + default: + goto invalid_operation; + } + case GL_LOCATION_INDEX: + if (res->Type != GL_PROGRAM_OUTPUT) + goto invalid_operation; + *val = RESOURCE_VAR(res)->data.index; + return 1; + + /* GL_ARB_tessellation_shader */ + case GL_IS_PER_PATCH: + case GL_REFERENCED_BY_TESS_CONTROL_SHADER: + case GL_REFERENCED_BY_TESS_EVALUATION_SHADER: + /* GL_ARB_compute_shader */ + case GL_REFERENCED_BY_COMPUTE_SHADER: + default: + _mesa_error(ctx, GL_INVALID_ENUM, "%s(%s prop %s)", caller, + _mesa_lookup_enum_by_nr(res->Type), + _mesa_lookup_enum_by_nr(prop)); + return 0; + } + +#undef VALIDATE_TYPE + +invalid_operation: + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller, + _mesa_lookup_enum_by_nr(res->Type), + _mesa_lookup_enum_by_nr(prop)); + return 0; +} + +extern void +_mesa_get_program_resourceiv(struct gl_shader_program *shProg, + GLenum programInterface, GLuint index, GLsizei propCount, + const GLenum *props, GLsizei bufSize, + GLsizei *length, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + GLint *val = (GLint *) params; + const GLenum *prop = props; + GLsizei amount = 0; + + struct gl_program_resource *res = + _mesa_program_resource_find_index(shProg, programInterface, index); + + /* No such resource found or bufSize negative. */ + if (!res || bufSize < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramResourceiv(%s index %d bufSize %d)", + _mesa_lookup_enum_by_nr(programInterface), index, bufSize); + return; + } + + /* Write propCount values until error occurs or bufSize reached. */ + for (int i = 0; i < propCount && i < bufSize; i++, val++, prop++) { + int props_written = + _mesa_program_resource_prop(shProg, res, index, *prop, val, + "glGetProgramResourceiv"); + + /* Error happened. */ + if (props_written == 0) + return; + + amount += props_written; + } + + /* If is not NULL, the actual number of integer values + * written to will be written to . + */ + if (length) + *length = amount; } diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 30716f5e3..77e2b8745 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -882,10 +882,9 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) sh->CompileStatus = GL_FALSE; } else { if (ctx->_Shader->Flags & GLSL_DUMP) { - fprintf(stderr, "GLSL source for %s shader %d:\n", + _mesa_log("GLSL source for %s shader %d:\n", _mesa_shader_stage_to_string(sh->Stage), sh->Name); - fprintf(stderr, "%s\n", sh->Source); - fflush(stderr); + _mesa_log("%s\n", sh->Source); } /* this call will set the shader->CompileStatus field to indicate if @@ -899,27 +898,25 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) if (ctx->_Shader->Flags & GLSL_DUMP) { if (sh->CompileStatus) { - fprintf(stderr, "GLSL IR for shader %d:\n", sh->Name); - _mesa_print_ir(stderr, sh->ir, NULL); - fprintf(stderr, "\n\n"); + _mesa_log("GLSL IR for shader %d:\n", sh->Name); + _mesa_print_ir(_mesa_get_log_file(), sh->ir, NULL); + _mesa_log("\n\n"); } else { - fprintf(stderr, "GLSL shader %d failed to compile.\n", sh->Name); + _mesa_log("GLSL shader %d failed to compile.\n", sh->Name); } if (sh->InfoLog && sh->InfoLog[0] != 0) { - fprintf(stderr, "GLSL shader %d info log:\n", sh->Name); - fprintf(stderr, "%s\n", sh->InfoLog); + _mesa_log("GLSL shader %d info log:\n", sh->Name); + _mesa_log("%s\n", sh->InfoLog); } - fflush(stderr); } } if (!sh->CompileStatus) { if (ctx->_Shader->Flags & GLSL_DUMP_ON_ERROR) { - fprintf(stderr, "GLSL source for %s shader %d:\n", + _mesa_log("GLSL source for %s shader %d:\n", _mesa_shader_stage_to_string(sh->Stage), sh->Name); - fprintf(stderr, "%s\n", sh->Source); - fprintf(stderr, "Info Log:\n%s\n", sh->InfoLog); - fflush(stderr); + _mesa_log("%s\n", sh->Source); + _mesa_log("Info Log:\n%s\n", sh->InfoLog); } if (ctx->_Shader->Flags & GLSL_REPORT_ERRORS) { diff --git a/mesalib/src/mesa/main/shaderapi.h b/mesalib/src/mesa/main/shaderapi.h index 047d2562d..aba6d5d83 100644 --- a/mesalib/src/mesa/main/shaderapi.h +++ b/mesalib/src/mesa/main/shaderapi.h @@ -219,6 +219,51 @@ extern GLuint GLAPIENTRY _mesa_CreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const *strings); +/* GL_ARB_program_resource_query */ +extern const char* +_mesa_program_resource_name(struct gl_program_resource *res); + +extern unsigned +_mesa_program_resource_array_size(struct gl_program_resource *res); + +extern GLuint +_mesa_program_resource_index(struct gl_shader_program *shProg, + struct gl_program_resource *res); + +extern struct gl_program_resource * +_mesa_program_resource_find_name(struct gl_shader_program *shProg, + GLenum programInterface, const char *name); + +extern struct gl_program_resource * +_mesa_program_resource_find_index(struct gl_shader_program *shProg, + GLenum programInterface, GLuint index); + +extern bool +_mesa_get_program_resource_name(struct gl_shader_program *shProg, + GLenum programInterface, GLuint index, + GLsizei bufSize, GLsizei *length, + GLchar *name, const char *caller); + +extern GLint +_mesa_program_resource_location(struct gl_shader_program *shProg, + GLenum programInterface, const char *name); + +extern GLint +_mesa_program_resource_location_index(struct gl_shader_program *shProg, + GLenum programInterface, const char *name); + +extern unsigned +_mesa_program_resource_prop(struct gl_shader_program *shProg, + struct gl_program_resource *res, GLuint index, + const GLenum prop, GLint *val, const char *caller); + +extern void +_mesa_get_program_resourceiv(struct gl_shader_program *shProg, + GLenum programInterface, GLuint index, + GLsizei propCount, const GLenum *props, + GLsizei bufSize, GLsizei *length, + GLint *params); + #ifdef __cplusplus } #endif diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index d7620c8ef..e42896036 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -315,6 +315,12 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg) ralloc_free(shProg->AtomicBuffers); shProg->AtomicBuffers = NULL; shProg->NumAtomicBuffers = 0; + + if (shProg->ProgramResourceList) { + ralloc_free(shProg->ProgramResourceList); + shProg->ProgramResourceList = NULL; + shProg->NumProgramResourceList = 0; + } } diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c index dadfb3c8c..cc84c6148 100644 --- a/mesalib/src/mesa/main/state.c +++ b/mesalib/src/mesa/main/state.c @@ -269,28 +269,6 @@ update_program_constants(struct gl_context *ctx) -static void -update_viewport_matrix(struct gl_context *ctx) -{ - const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; - unsigned i; - - assert(depthMax > 0); - - /* Compute scale and bias values. This is really driver-specific - * and should be maintained elsewhere if at all. - * NOTE: RasterPos uses this. - */ - for (i = 0; i < ctx->Const.MaxViewports; i++) { - double scale[3], translate[3]; - - _mesa_get_viewport_xform(ctx, i, scale, translate); - _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap, - scale, translate, depthMax); - } -} - - /** * Update the ctx->Polygon._FrontBit flag. */ @@ -407,9 +385,6 @@ _mesa_update_state_locked( struct gl_context *ctx ) if (new_state & _NEW_PIXEL) _mesa_update_pixel( ctx, new_state ); - if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) - update_viewport_matrix(ctx); - if (new_state & (_NEW_MULTISAMPLE | _NEW_BUFFERS)) update_multisample( ctx ); @@ -507,7 +482,7 @@ _mesa_set_varying_vp_inputs( struct gl_context *ctx, ctx->FragmentProgram._TexEnvProgram) { ctx->NewState |= _NEW_VARYING_VP_INPUTS; } - /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/ + /*printf("%s %x\n", __func__, varying_inputs);*/ } } diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c index 00234d4cc..0fd1a3683 100644 --- a/mesalib/src/mesa/main/texcompress.c +++ b/mesalib/src/mesa/main/texcompress.c @@ -32,7 +32,6 @@ #include "glheader.h" #include "imports.h" -#include "colormac.h" #include "context.h" #include "formats.h" #include "mtypes.h" diff --git a/mesalib/src/mesa/main/texcompress_fxt1.c b/mesalib/src/mesa/main/texcompress_fxt1.c index 562359410..f06f04882 100644 --- a/mesalib/src/mesa/main/texcompress_fxt1.c +++ b/mesalib/src/mesa/main/texcompress_fxt1.c @@ -31,7 +31,6 @@ #include "glheader.h" #include "imports.h" -#include "colormac.h" #include "image.h" #include "macros.h" #include "mipmap.h" diff --git a/mesalib/src/mesa/main/texcompress_rgtc.c b/mesalib/src/mesa/main/texcompress_rgtc.c index f40e4e6c0..66de1f17d 100644 --- a/mesalib/src/mesa/main/texcompress_rgtc.c +++ b/mesalib/src/mesa/main/texcompress_rgtc.c @@ -35,7 +35,6 @@ #include "glheader.h" #include "imports.h" -#include "colormac.h" #include "image.h" #include "macros.h" #include "mipmap.h" diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c index 41d00d4e9..7ce3cb88e 100644 --- a/mesalib/src/mesa/main/texcompress_s3tc.c +++ b/mesalib/src/mesa/main/texcompress_s3tc.c @@ -29,13 +29,8 @@ * GL_EXT_texture_compression_s3tc support. */ -#ifndef USE_EXTERNAL_DXTN_LIB -#define USE_EXTERNAL_DXTN_LIB 1 -#endif - #include "glheader.h" #include "imports.h" -#include "colormac.h" #include "dlopen.h" #include "image.h" #include "macros.h" @@ -77,7 +72,6 @@ _mesa_init_texture_s3tc( struct gl_context *ctx ) { /* called during context initialization */ ctx->Mesa_DXTn = GL_FALSE; -#if USE_EXTERNAL_DXTN_LIB if (!dxtlibhandle) { dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, 0); if (!dxtlibhandle) { @@ -118,9 +112,6 @@ _mesa_init_texture_s3tc( struct gl_context *ctx ) if (dxtlibhandle) { ctx->Mesa_DXTn = GL_TRUE; } -#else - (void) ctx; -#endif } /** diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 1ef728660..b5d42d304 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -32,7 +32,6 @@ #include #include "main/glheader.h" #include "main/blend.h" -#include "main/colormac.h" #include "main/context.h" #include "main/enums.h" #include "main/formats.h" diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c index 0a7f983fb..1af9d47f0 100644 --- a/mesalib/src/mesa/main/texstate.c +++ b/mesalib/src/mesa/main/texstate.c @@ -31,8 +31,6 @@ #include #include "glheader.h" #include "bufferobj.h" -#include "colormac.h" -#include "colortab.h" #include "context.h" #include "enums.h" #include "macros.h" diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 7ad9d2b68..152520598 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -53,7 +53,6 @@ #include "glheader.h" #include "bufferobj.h" -#include "colormac.h" #include "format_pack.h" #include "format_utils.h" #include "image.h" diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c index ce678c864..103011ce5 100644 --- a/mesalib/src/mesa/main/transformfeedback.c +++ b/mesalib/src/mesa/main/transformfeedback.c @@ -514,22 +514,24 @@ _mesa_EndTransformFeedback(void) * Helper used by BindBufferRange() and BindBufferBase(). */ static void -bind_buffer_range(struct gl_context *ctx, GLuint index, +bind_buffer_range(struct gl_context *ctx, + struct gl_transform_feedback_object *obj, + GLuint index, struct gl_buffer_object *bufObj, - GLintptr offset, GLsizeiptr size) + GLintptr offset, GLsizeiptr size, + bool dsa) { - struct gl_transform_feedback_object *obj = - ctx->TransformFeedback.CurrentObject; - /* Note: no need to FLUSH_VERTICES or flag NewTransformFeedback, because * transform feedback buffers can't be changed while transform feedback is * active. */ - /* The general binding point */ - _mesa_reference_buffer_object(ctx, - &ctx->TransformFeedback.CurrentBuffer, - bufObj); + if (!dsa) { + /* The general binding point */ + _mesa_reference_buffer_object(ctx, + &ctx->TransformFeedback.CurrentBuffer, + bufObj); + } /* The per-attribute binding point */ _mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset, size); @@ -539,75 +541,209 @@ bind_buffer_range(struct gl_context *ctx, GLuint index, /** * Specify a buffer object to receive transform feedback results. Plus, * specify the starting offset to place the results, and max size. - * Called from the glBindBufferRange() function. + * Called from the glBindBufferRange() and glTransformFeedbackBufferRange + * functions. */ void _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx, - GLuint index, - struct gl_buffer_object *bufObj, - GLintptr offset, - GLsizeiptr size) + struct gl_transform_feedback_object *obj, + GLuint index, + struct gl_buffer_object *bufObj, + GLintptr offset, + GLsizeiptr size, + bool dsa) { - struct gl_transform_feedback_object *obj; + const char *gl_methd_name; + if (dsa) + gl_methd_name = "glTransformFeedbackBufferRange"; + else + gl_methd_name = "glBindBufferRange"; - obj = ctx->TransformFeedback.CurrentObject; if (obj->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindBufferRange(transform feedback active)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)", + gl_methd_name); return; } if (index >= ctx->Const.MaxTransformFeedbackBuffers) { - _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index); + /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is + * generated if index is greater than or equal to the number of binding + * points for transform feedback, as described in section 6.7.1." + */ + _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)", + gl_methd_name, index); return; } if (size & 0x3) { - /* must a multiple of four */ - _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size); + /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */ + _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be a multiple of " + "four)", gl_methd_name, (int) size); return; } if (offset & 0x3) { - /* must be multiple of four */ - _mesa_error(ctx, GL_INVALID_VALUE, - "glBindBufferRange(offset=%d)", (int) offset); + /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */ + _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be a multiple " + "of four)", gl_methd_name, (int) offset); return; - } + } + + if (offset < 0) { + /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is + * generated by BindBufferRange if offset is negative." + * + * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error + * is generated by TransformFeedbackBufferRange if offset is negative." + */ + _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be >= 0)", + gl_methd_name, + (int) offset); + return; + } - bind_buffer_range(ctx, index, bufObj, offset, size); + if (size <= 0 && (dsa || bufObj != ctx->Shared->NullBufferObj)) { + /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is + * generated by BindBufferRange if buffer is non-zero and size is less + * than or equal to zero." + * + * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error + * is generated by TransformFeedbackBufferRange if size is less than or + * equal to zero." + */ + _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be > 0)", + gl_methd_name, (int) size); + return; + } + + bind_buffer_range(ctx, obj, index, bufObj, offset, size, dsa); } /** * Specify a buffer object to receive transform feedback results. * As above, but start at offset = 0. - * Called from the glBindBufferBase() function. + * Called from the glBindBufferBase() and glTransformFeedbackBufferBase() + * functions. */ void _mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx, - GLuint index, - struct gl_buffer_object *bufObj) + struct gl_transform_feedback_object *obj, + GLuint index, + struct gl_buffer_object *bufObj, + bool dsa) { - struct gl_transform_feedback_object *obj; - - obj = ctx->TransformFeedback.CurrentObject; - if (obj->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindBufferBase(transform feedback active)"); + "%s(transform feedback active)", + dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase"); return; } if (index >= ctx->Const.MaxTransformFeedbackBuffers) { - _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index); + _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)", + dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase", + index); + return; + } + + bind_buffer_range(ctx, obj, index, bufObj, 0, 0, dsa); +} + +/** + * Wrapper around lookup_transform_feedback_object that throws + * GL_INVALID_OPERATION if id is not in the hash table. After calling + * _mesa_error, it returns NULL. + */ +static struct gl_transform_feedback_object * +lookup_transform_feedback_object_err(struct gl_context *ctx, + GLuint xfb, const char* func) +{ + struct gl_transform_feedback_object *obj; + + obj = _mesa_lookup_transform_feedback_object(ctx, xfb); + if (!obj) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(xfb=%u: non-generated object name)", func, xfb); + } + + return obj; +} + +/** + * Wrapper around _mesa_lookup_bufferobj that throws GL_INVALID_VALUE if id + * is not in the hash table. Specialised version for the + * transform-feedback-related functions. After calling _mesa_error, it + * returns NULL. + */ +static struct gl_buffer_object * +lookup_transform_feedback_bufferobj_err(struct gl_context *ctx, + GLuint buffer, const char* func) +{ + struct gl_buffer_object *bufObj; + + /* OpenGL 4.5 core profile, 13.2, pdf page 444: buffer must be zero or the + * name of an existing buffer object. + */ + if (buffer == 0) { + bufObj = ctx->Shared->NullBufferObj; + } else { + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!bufObj) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid buffer=%u)", func, + buffer); + } + } + + return bufObj; +} + +void GLAPIENTRY +_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_transform_feedback_object *obj; + struct gl_buffer_object *bufObj; + + obj = lookup_transform_feedback_object_err(ctx, xfb, + "glTransformFeedbackBufferBase"); + if(!obj) { + return; + } + + bufObj = lookup_transform_feedback_bufferobj_err(ctx, buffer, + "glTransformFeedbackBufferBase"); + if(!bufObj) { return; } - bind_buffer_range(ctx, index, bufObj, 0, 0); + _mesa_bind_buffer_base_transform_feedback(ctx, obj, index, bufObj, true); } +void GLAPIENTRY +_mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_transform_feedback_object *obj; + struct gl_buffer_object *bufObj; + + obj = lookup_transform_feedback_object_err(ctx, xfb, + "glTransformFeedbackBufferRange"); + if(!obj) { + return; + } + + bufObj = lookup_transform_feedback_bufferobj_err(ctx, buffer, + "glTransformFeedbackBufferRange"); + if(!bufObj) { + return; + } + + _mesa_bind_buffer_range_transform_feedback(ctx, obj, index, bufObj, offset, + size, true); +} /** * Specify a buffer object to receive transform feedback results, plus the @@ -660,7 +796,7 @@ _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, return; } - bind_buffer_range(ctx, index, bufObj, offset, 0); + bind_buffer_range(ctx, obj, index, bufObj, offset, 0, false); } @@ -784,7 +920,7 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei *size, GLenum *type, GLchar *name) { const struct gl_shader_program *shProg; - const struct gl_transform_feedback_info *linked_xfb_info; + struct gl_program_resource *res; GET_CURRENT_CONTEXT(ctx); shProg = _mesa_lookup_shader_program(ctx, program); @@ -794,22 +930,27 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, return; } - linked_xfb_info = &shProg->LinkedTransformFeedback; - if (index >= (GLuint) linked_xfb_info->NumVarying) { + res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg, + GL_TRANSFORM_FEEDBACK_VARYING, + index); + if (!res) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetTransformFeedbackVarying(index=%u)", index); return; } /* return the varying's name and length */ - _mesa_copy_string(name, bufSize, length, - linked_xfb_info->Varyings[index].Name); + _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res)); /* return the datatype and value's size (in datatype units) */ if (type) - *type = linked_xfb_info->Varyings[index].Type; + _mesa_program_resource_prop((struct gl_shader_program *) shProg, + res, index, GL_TYPE, (GLint*) type, + "glGetTransformFeedbackVarying"); if (size) - *size = linked_xfb_info->Varyings[index].Size; + _mesa_program_resource_prop((struct gl_shader_program *) shProg, + res, index, GL_ARRAY_SIZE, (GLint*) size, + "glGetTransformFeedbackVarying"); } @@ -817,6 +958,10 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, struct gl_transform_feedback_object * _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) { + /* OpenGL 4.5 core profile, 13.2 pdf page 444: "xfb must be zero, indicating + * the default transform feedback object, or the name of an existing + * transform feedback object." + */ if (name == 0) { return ctx->TransformFeedback.DefaultObject; } @@ -825,25 +970,24 @@ _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) _mesa_HashLookup(ctx->TransformFeedback.Objects, name); } - -/** - * Create new transform feedback objects. Transform feedback objects - * encapsulate the state related to transform feedback to allow quickly - * switching state (and drawing the results, below). - * Part of GL_ARB_transform_feedback2. - */ -void GLAPIENTRY -_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names) +static void +create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids, + bool dsa) { GLuint first; - GET_CURRENT_CONTEXT(ctx); + const char* func; + + if (dsa) + func = "glCreateTransformFeedbacks"; + else + func = "glGenTransformFeedbacks"; if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGenTransformFeedbacks(n < 0)"); + _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func); return; } - if (!names) + if (!ids) return; /* we don't need contiguous IDs, but this might be faster */ @@ -854,18 +998,56 @@ _mesa_GenTransformFeedbacks(GLsizei n, GLuint *names) struct gl_transform_feedback_object *obj = ctx->Driver.NewTransformFeedback(ctx, first + i); if (!obj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; } - names[i] = first + i; + ids[i] = first + i; _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj); + if (dsa) { + /* this is normally done at bind time in the non-dsa case */ + obj->EverBound = GL_TRUE; + } } } else { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTransformFeedbacks"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); } } +/** + * Create new transform feedback objects. Transform feedback objects + * encapsulate the state related to transform feedback to allow quickly + * switching state (and drawing the results, below). + * Part of GL_ARB_transform_feedback2. + */ +void GLAPIENTRY +_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names) +{ + GET_CURRENT_CONTEXT(ctx); + + /* GenTransformFeedbacks should just reserve the object names that a + * subsequent call to BindTransformFeedback should actively create. For + * the sake of simplicity, we reserve the names and create the objects + * straight away. + */ + + create_transform_feedbacks(ctx, n, names, false); +} + +/** + * Create new transform feedback objects. Transform feedback objects + * encapsulate the state related to transform feedback to allow quickly + * switching state (and drawing the results, below). + * Part of GL_ARB_direct_state_access. + */ +void GLAPIENTRY +_mesa_CreateTransformFeedbacks(GLsizei n, GLuint *names) +{ + GET_CURRENT_CONTEXT(ctx); + + create_transform_feedbacks(ctx, n, names, true); +} + /** * Is the given ID a transform feedback object? @@ -1026,3 +1208,89 @@ _mesa_ResumeTransformFeedback(void) assert(ctx->Driver.ResumeTransformFeedback); ctx->Driver.ResumeTransformFeedback(ctx, obj); } + +extern void GLAPIENTRY +_mesa_GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) +{ + struct gl_transform_feedback_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = lookup_transform_feedback_object_err(ctx, xfb, + "glGetTransformFeedbackiv"); + if(!obj) { + return; + } + + switch(pname) { + case GL_TRANSFORM_FEEDBACK_PAUSED: + *param = obj->Paused; + break; + case GL_TRANSFORM_FEEDBACK_ACTIVE: + *param = obj->Active; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTransformFeedbackiv(pname=%i)", pname); + } +} + +extern void GLAPIENTRY +_mesa_GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, + GLint *param) +{ + struct gl_transform_feedback_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = lookup_transform_feedback_object_err(ctx, xfb, + "glGetTransformFeedbacki_v"); + if(!obj) { + return; + } + + if (index >= ctx->Const.MaxTransformFeedbackBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetTransformFeedbacki_v(index=%i)", index); + return; + } + + switch(pname) { + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + *param = obj->BufferNames[index]; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTransformFeedbacki_v(pname=%i)", pname); + } +} + +extern void GLAPIENTRY +_mesa_GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, + GLint64 *param) +{ + struct gl_transform_feedback_object *obj; + GET_CURRENT_CONTEXT(ctx); + + obj = lookup_transform_feedback_object_err(ctx, xfb, + "glGetTransformFeedbacki64_v"); + if(!obj) { + return; + } + + if (index >= ctx->Const.MaxTransformFeedbackBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetTransformFeedbacki64_v(index=%i)", index); + return; + } + + switch(pname) { + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + *param = obj->Offset[index]; + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + *param = obj->RequestedSize[index]; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTransformFeedbacki64_v(pname=%i)", pname); + } +} diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h index 87f4080e0..bb9729cdb 100644 --- a/mesalib/src/mesa/main/transformfeedback.h +++ b/mesalib/src/mesa/main/transformfeedback.h @@ -65,15 +65,18 @@ _mesa_EndTransformFeedback(void); extern void _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx, + struct gl_transform_feedback_object *obj, GLuint index, struct gl_buffer_object *bufObj, GLintptr offset, - GLsizeiptr size); + GLsizeiptr size, bool dsa); extern void _mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx, + struct gl_transform_feedback_object *obj, GLuint index, - struct gl_buffer_object *bufObj); + struct gl_buffer_object *bufObj, + bool dsa); extern void GLAPIENTRY _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, @@ -102,6 +105,9 @@ _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name); extern void GLAPIENTRY _mesa_GenTransformFeedbacks(GLsizei n, GLuint *names); +extern void GLAPIENTRY +_mesa_CreateTransformFeedbacks(GLsizei n, GLuint *names); + extern GLboolean GLAPIENTRY _mesa_IsTransformFeedback(GLuint name); @@ -141,4 +147,24 @@ _mesa_set_transform_feedback_binding(struct gl_context *ctx, tfObj->RequestedSize[index] = size; } +/*** GL_ARB_direct_state_access ***/ + +extern void GLAPIENTRY +_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer); + +extern void GLAPIENTRY +_mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size); + +extern void GLAPIENTRY +_mesa_GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param); + +extern void GLAPIENTRY +_mesa_GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, + GLint *param); + +extern void GLAPIENTRY +_mesa_GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, + GLint64 *param); + #endif /* TRANSFORM_FEEDBACK_H */ diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 2ab5528c3..4e77b3284 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -46,6 +46,7 @@ _mesa_GetActiveUniform(GLuint program, GLuint index, { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; + struct gl_program_resource *res; if (maxLength < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)"); @@ -56,26 +57,51 @@ _mesa_GetActiveUniform(GLuint program, GLuint index, if (!shProg) return; - if (index >= shProg->NumUserUniformStorage) { + res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg, + GL_UNIFORM, index); + + if (!res) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); return; } - const struct gl_uniform_storage *const uni = &shProg->UniformStorage[index]; - - if (nameOut) { - _mesa_get_uniform_name(uni, maxLength, length, nameOut); - } - - if (size) { - /* array_elements is zero for non-arrays, but the API requires that 1 be - * returned. - */ - *size = MAX2(1, uni->array_elements); - } + if (nameOut) + _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength, + length, nameOut, "glGetActiveUniform"); + if (type) + _mesa_program_resource_prop((struct gl_shader_program *) shProg, + res, index, GL_TYPE, (GLint*) type, + "glGetActiveUniform"); + if (size) + _mesa_program_resource_prop((struct gl_shader_program *) shProg, + res, index, GL_ARRAY_SIZE, (GLint*) size, + "glGetActiveUniform"); +} - if (type) { - *type = uni->type->gl_type; +static GLenum +resource_prop_from_uniform_prop(GLenum uni_prop) +{ + switch (uni_prop) { + case GL_UNIFORM_TYPE: + return GL_TYPE; + case GL_UNIFORM_SIZE: + return GL_ARRAY_SIZE; + case GL_UNIFORM_NAME_LENGTH: + return GL_NAME_LENGTH; + case GL_UNIFORM_BLOCK_INDEX: + return GL_BLOCK_INDEX; + case GL_UNIFORM_OFFSET: + return GL_OFFSET; + case GL_UNIFORM_ARRAY_STRIDE: + return GL_ARRAY_STRIDE; + case GL_UNIFORM_MATRIX_STRIDE: + return GL_MATRIX_STRIDE; + case GL_UNIFORM_IS_ROW_MAJOR: + return GL_IS_ROW_MAJOR; + case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX: + return GL_ATOMIC_COUNTER_BUFFER_INDEX; + default: + return 0; } } @@ -88,7 +114,8 @@ _mesa_GetActiveUniformsiv(GLuint program, { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; - GLsizei i; + struct gl_program_resource *res; + GLenum res_prop; if (uniformCount < 0) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -100,80 +127,21 @@ _mesa_GetActiveUniformsiv(GLuint program, if (!shProg) return; - for (i = 0; i < uniformCount; i++) { - GLuint index = uniformIndices[i]; + res_prop = resource_prop_from_uniform_prop(pname); - if (index >= shProg->NumUserUniformStorage) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); - return; + for (int i = 0; i < uniformCount; i++) { + res = _mesa_program_resource_find_index(shProg, GL_UNIFORM, + uniformIndices[i]); + if (!res) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); + break; } - } - - for (i = 0; i < uniformCount; i++) { - GLuint index = uniformIndices[i]; - const struct gl_uniform_storage *uni = &shProg->UniformStorage[index]; - - switch (pname) { - case GL_UNIFORM_TYPE: - params[i] = uni->type->gl_type; - break; - - case GL_UNIFORM_SIZE: - /* array_elements is zero for non-arrays, but the API requires that 1 be - * returned. - */ - params[i] = MAX2(1, uni->array_elements); - break; - case GL_UNIFORM_NAME_LENGTH: - params[i] = strlen(uni->name) + 1; - - /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 - * spec says: - * - * "If the active uniform is an array, the uniform name returned - * in name will always be the name of the uniform array appended - * with "[0]"." - */ - if (uni->array_elements != 0) - params[i] += 3; - break; - - case GL_UNIFORM_BLOCK_INDEX: - params[i] = uni->block_index; - break; - - case GL_UNIFORM_OFFSET: - params[i] = uni->offset; - break; - - case GL_UNIFORM_ARRAY_STRIDE: - params[i] = uni->array_stride; - break; - - case GL_UNIFORM_MATRIX_STRIDE: - params[i] = uni->matrix_stride; - break; - - case GL_UNIFORM_IS_ROW_MAJOR: - params[i] = uni->row_major; - break; - - case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX: - if (!ctx->Extensions.ARB_shader_atomic_counters) - goto invalid_enum; - params[i] = uni->atomic_buffer_index; + if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i], + res_prop, ¶ms[i], + "glGetActiveUniformsiv")) break; - - default: - goto invalid_enum; - } } - - return; - - invalid_enum: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)"); } static struct gl_uniform_storage * diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index fb1482f9c..5548d1d02 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -911,7 +911,6 @@ GLint GLAPIENTRY _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) { struct gl_shader_program *shProg; - GLuint index, offset; GET_CURRENT_CONTEXT(ctx); @@ -931,23 +930,7 @@ _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) return -1; } - index = _mesa_get_uniform_location(shProg, name, &offset); - if (index == GL_INVALID_INDEX) - return -1; - - /* From the GL_ARB_uniform_buffer_object spec: - * - * "The value -1 will be returned if does not correspond to an - * active uniform variable name in , if is associated - * with a named uniform block, or if starts with the reserved - * prefix "gl_"." - */ - if (shProg->UniformStorage[index].block_index != -1 || - shProg->UniformStorage[index].atomic_buffer_index != -1) - return -1; - - /* location in remap table + array element offset */ - return shProg->UniformStorage[index].remap_location + offset; + return _mesa_program_resource_location(shProg, GL_UNIFORM, name); } GLuint GLAPIENTRY @@ -955,7 +938,6 @@ _mesa_GetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName) { GET_CURRENT_CONTEXT(ctx); - GLuint i; struct gl_shader_program *shProg; if (!ctx->Extensions.ARB_uniform_buffer_object) { @@ -968,12 +950,13 @@ _mesa_GetUniformBlockIndex(GLuint program, if (!shProg) return GL_INVALID_INDEX; - for (i = 0; i < shProg->NumUniformBlocks; i++) { - if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName)) - return i; - } + struct gl_program_resource *res = + _mesa_program_resource_find_name(shProg, GL_UNIFORM_BLOCK, + uniformBlockName); + if (!res) + return GL_INVALID_INDEX; - return GL_INVALID_INDEX; + return _mesa_program_resource_index(shProg, res); } void GLAPIENTRY @@ -1003,9 +986,9 @@ _mesa_GetUniformIndices(GLuint program, } for (i = 0; i < uniformCount; i++) { - unsigned offset; - uniformIndices[i] = _mesa_get_uniform_location(shProg, - uniformNames[i], &offset); + struct gl_program_resource *res = + _mesa_program_resource_find_name(shProg, GL_UNIFORM, uniformNames[i]); + uniformIndices[i] = _mesa_program_resource_index(shProg, res); } } @@ -1061,104 +1044,104 @@ _mesa_UniformBlockBinding(GLuint program, } } -void GLAPIENTRY -_mesa_GetActiveUniformBlockiv(GLuint program, - GLuint uniformBlockIndex, - GLenum pname, - GLint *params) + +/** + * Generic program resource property query. + */ +static void +mesa_bufferiv(struct gl_shader_program *shProg, GLenum type, + GLuint index, GLenum pname, GLint *params, const char *caller) { GET_CURRENT_CONTEXT(ctx); - struct gl_shader_program *shProg; - struct gl_uniform_block *block; - unsigned i; + struct gl_program_resource *res = + _mesa_program_resource_find_index(shProg, type, index); - if (!ctx->Extensions.ARB_uniform_buffer_object) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); + if (!res) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufferindex %d)", caller, index); return; } - shProg = _mesa_lookup_shader_program_err(ctx, program, - "glGetActiveUniformBlockiv"); - if (!shProg) - return; - - if (uniformBlockIndex >= shProg->NumUniformBlocks) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetActiveUniformBlockiv(block index %u >= %u)", - uniformBlockIndex, shProg->NumUniformBlocks); - return; - } - - block = &shProg->UniformBlocks[uniformBlockIndex]; - switch (pname) { case GL_UNIFORM_BLOCK_BINDING: - params[0] = block->Binding; + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + _mesa_program_resource_prop(shProg, res, index, GL_BUFFER_BINDING, + params, caller); return; - case GL_UNIFORM_BLOCK_DATA_SIZE: - params[0] = block->UniformBufferSize; + case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE: + _mesa_program_resource_prop(shProg, res, index, GL_BUFFER_DATA_SIZE, + params, caller); return; - case GL_UNIFORM_BLOCK_NAME_LENGTH: - params[0] = strlen(block->Name) + 1; + _mesa_program_resource_prop(shProg, res, index, GL_NAME_LENGTH, + params, caller); return; - - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: { - unsigned count = 0; - - for (i = 0; i < block->NumUniforms; i++) { - unsigned offset; - const int idx = - _mesa_get_uniform_location(shProg, - block->Uniforms[i].IndexName, - &offset); - if (idx != -1) - count++; - } - - params[0] = count; + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS: + _mesa_program_resource_prop(shProg, res, index, GL_NUM_ACTIVE_VARIABLES, + params, caller); return; - } - - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: { - unsigned count = 0; - - for (i = 0; i < block->NumUniforms; i++) { - unsigned offset; - const int idx = - _mesa_get_uniform_location(shProg, - block->Uniforms[i].IndexName, - &offset); - - if (idx != -1) - params[count++] = idx; - } + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES: + _mesa_program_resource_prop(shProg, res, index, GL_ACTIVE_VARIABLES, + params, caller); return; - } - case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: - params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1; + case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER: + _mesa_program_resource_prop(shProg, res, index, + GL_REFERENCED_BY_VERTEX_SHADER, params, + caller); return; - case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER: - if (!_mesa_has_geometry_shaders(ctx)) - break; - params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_GEOMETRY][uniformBlockIndex] != -1; + case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER: + _mesa_program_resource_prop(shProg, res, index, + GL_REFERENCED_BY_GEOMETRY_SHADER, params, + caller); return; - case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: - params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_FRAGMENT][uniformBlockIndex] != -1; + case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER: + _mesa_program_resource_prop(shProg, res, index, + GL_REFERENCED_BY_FRAGMENT_SHADER, params, + caller); + return; + case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER: + params[0] = GL_FALSE; + return; + case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER: + params[0] = GL_FALSE; return; - default: _mesa_error(ctx, GL_INVALID_ENUM, - "glGetActiveUniformBlockiv(pname 0x%x (%s))", - pname, _mesa_lookup_enum_by_nr(pname)); + "%s(pname 0x%x (%s))", caller, pname, + _mesa_lookup_enum_by_nr(pname)); return; } } + +void GLAPIENTRY +_mesa_GetActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_shader_program *shProg; + + if (!ctx->Extensions.ARB_uniform_buffer_object) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); + return; + } + + shProg = _mesa_lookup_shader_program_err(ctx, program, + "glGetActiveUniformBlockiv"); + if (!shProg) + return; + + mesa_bufferiv(shProg, GL_UNIFORM_BLOCK, uniformBlockIndex, pname, params, + "glGetActiveUniformBlockiv"); +} + void GLAPIENTRY _mesa_GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, @@ -1168,7 +1151,6 @@ _mesa_GetActiveUniformBlockName(GLuint program, { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; - struct gl_uniform_block *block; if (!ctx->Extensions.ARB_uniform_buffer_object) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); @@ -1187,18 +1169,11 @@ _mesa_GetActiveUniformBlockName(GLuint program, if (!shProg) return; - if (uniformBlockIndex >= shProg->NumUniformBlocks) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetActiveUniformBlockiv(block index %u >= %u)", - uniformBlockIndex, shProg->NumUniformBlocks); - return; - } - - block = &shProg->UniformBlocks[uniformBlockIndex]; - - if (uniformBlockName) { - _mesa_copy_string(uniformBlockName, bufSize, length, block->Name); - } + if (uniformBlockName) + _mesa_get_program_resource_name(shProg, GL_UNIFORM_BLOCK, + uniformBlockIndex, bufSize, length, + uniformBlockName, + "glGetActiveUniformBlockName"); } void GLAPIENTRY @@ -1226,54 +1201,8 @@ _mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex, if (!shProg) return; - if (uniformIndex >= shProg->NumUserUniformStorage) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); - return; - } - - if (uniformName) { - _mesa_get_uniform_name(& shProg->UniformStorage[uniformIndex], - bufSize, length, uniformName); - } -} - -void -_mesa_get_uniform_name(const struct gl_uniform_storage *uni, - GLsizei maxLength, GLsizei *length, - GLchar *nameOut) -{ - GLsizei localLength; - - if (length == NULL) - length = &localLength; - - _mesa_copy_string(nameOut, maxLength, length, uni->name); - - /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 - * spec says: - * - * "If the active uniform is an array, the uniform name returned in - * name will always be the name of the uniform array appended with - * "[0]"." - * - * The same text also appears in the OpenGL 4.2 spec. It does not, - * however, appear in any previous spec. Previous specifications are - * ambiguous in this regard. However, either name can later be passed - * to glGetUniformLocation (and related APIs), so there shouldn't be any - * harm in always appending "[0]" to uniform array names. - */ - if (uni->array_elements != 0) { - int i; - - /* The comparison is strange because *length does *NOT* include the - * terminating NUL, but maxLength does. - */ - for (i = 0; i < 3 && (*length + i + 1) < maxLength; i++) - nameOut[*length + i] = "[0]"[i]; - - nameOut[*length + i] = '\0'; - *length += i; - } + _mesa_get_program_resource_name(shProg, GL_UNIFORM, uniformIndex, bufSize, + length, uniformName, "glGetActiveUniformName"); } void GLAPIENTRY @@ -1282,8 +1211,6 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; - struct gl_active_atomic_buffer *ab; - GLuint i; if (!ctx->Extensions.ARB_shader_atomic_counters) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -1296,49 +1223,8 @@ _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, if (!shProg) return; - if (bufferIndex >= shProg->NumAtomicBuffers) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetActiveAtomicCounterBufferiv(bufferIndex)"); - return; - } - - ab = &shProg->AtomicBuffers[bufferIndex]; - - switch (pname) { - case GL_ATOMIC_COUNTER_BUFFER_BINDING: - params[0] = ab->Binding; - return; - case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE: - params[0] = ab->MinimumSize; - return; - case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS: - params[0] = ab->NumUniforms; - return; - case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES: - for (i = 0; i < ab->NumUniforms; ++i) - params[i] = ab->Uniforms[i]; - return; - case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER: - params[0] = ab->StageReferences[MESA_SHADER_VERTEX]; - return; - case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER: - params[0] = ab->StageReferences[MESA_SHADER_GEOMETRY]; - return; - case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER: - params[0] = ab->StageReferences[MESA_SHADER_FRAGMENT]; - return; - case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER: - params[0] = GL_FALSE; - return; - case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER: - params[0] = GL_FALSE; - return; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetActiveAtomicCounterBufferiv(pname 0x%x (%s))", - pname, _mesa_lookup_enum_by_nr(pname)); - return; - } + mesa_bufferiv(shProg, GL_ATOMIC_COUNTER_BUFFER, bufferIndex, pname, params, + "glGetActiveAtomicCounterBufferiv"); } void GLAPIENTRY diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h index 0e6113fe9..55fa2357e 100644 --- a/mesalib/src/mesa/main/uniforms.h +++ b/mesalib/src/mesa/main/uniforms.h @@ -398,11 +398,6 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *); extern const struct gl_program_parameter * get_uniform_parameter(struct gl_shader_program *shProg, GLint index); -extern void -_mesa_get_uniform_name(const struct gl_uniform_storage *uni, - GLsizei maxLength, GLsizei *length, - GLchar *nameOut); - struct gl_builtin_uniform_element { const char *field; int tokens[STATE_LENGTH]; diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c index 8e0c3ef5b..7c6d99418 100644 --- a/mesalib/src/mesa/main/version.c +++ b/mesalib/src/mesa/main/version.c @@ -382,6 +382,7 @@ compute_version_es2(const struct gl_extensions *extensions) extensions->ARB_shader_texture_lod && extensions->ARB_texture_float && extensions->ARB_texture_rg && + extensions->ARB_depth_buffer_float && extensions->EXT_draw_buffers2 && /* extensions->ARB_framebuffer_object && */ extensions->EXT_framebuffer_sRGB && diff --git a/mesalib/src/mesa/main/viewport.c b/mesalib/src/mesa/main/viewport.c index 0adce9c78..b27063031 100644 --- a/mesalib/src/mesa/main/viewport.c +++ b/mesalib/src/mesa/main/viewport.c @@ -40,8 +40,6 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y, GLfloat width, GLfloat height) { - double scale[3], translate[3]; - /* clamp width and height to the implementation dependent range */ width = MIN2(width, (GLfloat) ctx->Const.MaxViewportWidth); height = MIN2(height, (GLfloat) ctx->Const.MaxViewportHeight); @@ -72,16 +70,6 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx, ctx->ViewportArray[idx].Y = y; ctx->ViewportArray[idx].Height = height; ctx->NewState |= _NEW_VIEWPORT; - -#if 1 - /* XXX remove this someday. Currently the DRI drivers rely on - * the WindowMap matrix being up to date in the driver's Viewport - * and DepthRange functions. - */ - _mesa_get_viewport_xform(ctx, idx, scale, translate); - _math_matrix_viewport(&ctx->ViewportArray[idx]._WindowMap, - scale, translate, ctx->DrawBuffer->_DepthMaxF); -#endif } struct gl_viewport_inputs { @@ -140,8 +128,8 @@ _mesa_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) /** - * Set new viewport parameters and update derived state (the _WindowMap - * matrix). Usually called from _mesa_Viewport(). + * Set new viewport parameters and update derived state. + * Usually called from _mesa_Viewport(). * * \param ctx GL context. * \param idx Index of the viewport to be updated. @@ -246,8 +234,6 @@ static void set_depth_range_no_notify(struct gl_context *ctx, unsigned idx, GLclampd nearval, GLclampd farval) { - double scale[3], translate[3]; - if (ctx->ViewportArray[idx].Near == nearval && ctx->ViewportArray[idx].Far == farval) return; @@ -255,16 +241,6 @@ set_depth_range_no_notify(struct gl_context *ctx, unsigned idx, ctx->ViewportArray[idx].Near = CLAMP(nearval, 0.0, 1.0); ctx->ViewportArray[idx].Far = CLAMP(farval, 0.0, 1.0); ctx->NewState |= _NEW_VIEWPORT; - -#if 1 - /* XXX remove this someday. Currently the DRI drivers rely on - * the WindowMap matrix being up to date in the driver's Viewport - * and DepthRange functions. - */ - _mesa_get_viewport_xform(ctx, idx, scale, translate); - _math_matrix_viewport(&ctx->ViewportArray[idx]._WindowMap, - scale, translate, ctx->DrawBuffer->_DepthMaxF); -#endif } void @@ -388,7 +364,6 @@ _mesa_DepthRangeIndexed(GLuint index, GLclampd nearval, GLclampd farval) */ void _mesa_init_viewport(struct gl_context *ctx) { - GLfloat depthMax = 65535.0F; /* sorf of arbitrary */ unsigned i; ctx->Transform.ClipOrigin = GL_LOWER_LEFT; @@ -398,8 +373,6 @@ void _mesa_init_viewport(struct gl_context *ctx) * so just initialize all of them. */ for (i = 0; i < MAX_VIEWPORTS; i++) { - double scale[3], translate[3]; - /* Viewport group */ ctx->ViewportArray[i].X = 0; ctx->ViewportArray[i].Y = 0; @@ -407,27 +380,10 @@ void _mesa_init_viewport(struct gl_context *ctx) ctx->ViewportArray[i].Height = 0; ctx->ViewportArray[i].Near = 0.0; ctx->ViewportArray[i].Far = 1.0; - _math_matrix_ctr(&ctx->ViewportArray[i]._WindowMap); - - _mesa_get_viewport_xform(ctx, i, scale, translate); - _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap, - scale, translate, depthMax); } } -/** - * Free the context viewport attribute group data. - * \param ctx the GL context. - */ -void _mesa_free_viewport_data(struct gl_context *ctx) -{ - unsigned i; - - for (i = 0; i < MAX_VIEWPORTS; i++) - _math_matrix_dtr(&ctx->ViewportArray[i]._WindowMap); -} - extern void GLAPIENTRY _mesa_ClipControl(GLenum origin, GLenum depth) { diff --git a/mesalib/src/mesa/main/viewport.h b/mesalib/src/mesa/main/viewport.h index 426e194bd..899dc2d0b 100644 --- a/mesalib/src/mesa/main/viewport.h +++ b/mesalib/src/mesa/main/viewport.h @@ -68,9 +68,6 @@ extern void _mesa_init_viewport(struct gl_context *ctx); -extern void -_mesa_free_viewport_data(struct gl_context *ctx); - extern void GLAPIENTRY _mesa_ClipControl(GLenum origin, GLenum depth); -- cgit v1.2.3